Use custom SvgIcon component wrapper around InlineSVG

next-virtuoso-proof
Alex Gleason 2 years ago
parent 17ee19aca7
commit 423c005437
No known key found for this signature in database
GPG Key ID: 7211D1F99744FBB7

@ -37,16 +37,14 @@ const SidebarNavigationLink = ({ icon, text, to, count }: ISidebarNavigationLink
</span> </span>
) : null} ) : null}
<div className='h-5 w-5'> <Icon
<Icon src={icon}
src={icon} size={20}
className={classNames({ className={classNames({
'h-full w-full': true, 'text-primary-700 dark:text-white': !isActive,
'text-primary-700 dark:text-white': !isActive, 'text-white': isActive,
'text-white': isActive, })}
})} />
/>
</div>
</span> </span>
<Text weight='semibold' theme='inherit'>{text}</Text> <Text weight='semibold' theme='inherit'>{text}</Text>

@ -33,7 +33,7 @@ const SidebarNavigation = () => {
{account && ( {account && (
<> <>
<SidebarNavigationLink <SidebarNavigationLink
to={`/@${account.get('acct')}`} to={`/@${account.acct}`}
icon={require('icons/user.svg')} icon={require('icons/user.svg')}
text={<FormattedMessage id='tabs_bar.profile' defaultMessage='Profile' />} text={<FormattedMessage id='tabs_bar.profile' defaultMessage='Profile' />}
/> />
@ -79,7 +79,7 @@ const SidebarNavigation = () => {
/> />
)} */} )} */}
{(account && instance.get('invites_enabled')) && ( {(account && instance.invites_enabled) && (
<SidebarNavigationLink <SidebarNavigationLink
to={`${baseURL}/invites`} to={`${baseURL}/invites`}
icon={require('@tabler/icons/icons/mailbox.svg')} icon={require('@tabler/icons/icons/mailbox.svg')}
@ -101,7 +101,7 @@ const SidebarNavigation = () => {
src={require('@tabler/icons/icons/users.svg')} src={require('@tabler/icons/icons/users.svg')}
className={classNames('primary-navigation__icon', { 'svg-icon--active': location.pathname === '/timeline/local' })} className={classNames('primary-navigation__icon', { 'svg-icon--active': location.pathname === '/timeline/local' })}
/> />
{instance.get('title')} {instance.title}
</NavLink> </NavLink>
) : ( ) : (
<NavLink to='/timeline/local' className='btn grouped'> <NavLink to='/timeline/local' className='btn grouped'>

@ -1,8 +1,7 @@
import classNames from 'classnames'; import classNames from 'classnames';
import React from 'react'; import React from 'react';
import InlineSVG from 'react-inlinesvg';
import { Text } from 'soapbox/components/ui'; import { Text, Icon } from 'soapbox/components/ui';
import { shortNumberFormat } from 'soapbox/utils/numbers'; import { shortNumberFormat } from 'soapbox/utils/numbers';
const COLORS = { const COLORS = {
@ -53,10 +52,10 @@ const StatusActionButton = React.forwardRef((props: IStatusActionButton, ref: Re
)} )}
{...filteredProps} {...filteredProps}
> >
<InlineSVG <Icon
src={icon} src={icon}
className={classNames( className={classNames(
'p-1 rounded-full box-content', 'rounded-full',
'group-focus:outline-none group-focus:ring-2 group-focus:ring-offset-2 dark:ring-offset-0 group-focus:ring-primary-500', 'group-focus:outline-none group-focus:ring-2 group-focus:ring-offset-2 dark:ring-offset-0 group-focus:ring-primary-500',
{ {
'fill-accent-300 hover:fill-accent-300': active && filled && color === COLORS.accent, 'fill-accent-300 hover:fill-accent-300': active && filled && color === COLORS.accent,

@ -1,10 +1,10 @@
import classNames from 'classnames'; import classNames from 'classnames';
import React from 'react'; import React from 'react';
import InlineSVG from 'react-inlinesvg';
import { defineMessages, useIntl } from 'react-intl'; import { defineMessages, useIntl } from 'react-intl';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
import { Text } from 'soapbox/components/ui'; import { Text } from 'soapbox/components/ui';
import SvgIcon from 'soapbox/components/ui/icon/svg-icon';
const sizes = { const sizes = {
md: 'p-4 sm:rounded-xl', md: 'p-4 sm:rounded-xl',
@ -54,7 +54,7 @@ const CardHeader: React.FC<ICardHeader> = ({ children, backHref, onBackClick }):
return ( return (
<Comp {...backAttributes} className='mr-2 text-gray-900 dark:text-gray-100' aria-label={intl.formatMessage(messages.back)}> <Comp {...backAttributes} className='mr-2 text-gray-900 dark:text-gray-100' aria-label={intl.formatMessage(messages.back)}>
<InlineSVG src={require('@tabler/icons/icons/arrow-left.svg')} className='h-6 w-6' /> <SvgIcon src={require('@tabler/icons/icons/arrow-left.svg')} className='h-6 w-6' />
<span className='sr-only' data-testid='back-button'>Back</span> <span className='sr-only' data-testid='back-button'>Back</span>
</Comp> </Comp>
); );

@ -1,7 +1,7 @@
import classNames from 'classnames'; import classNames from 'classnames';
import React from 'react'; import React from 'react';
import InlineSVG from 'react-inlinesvg';
import SvgIcon from '../icon/svg-icon';
import Text from '../text/text'; import Text from '../text/text';
interface IIconButton extends React.ButtonHTMLAttributes<HTMLButtonElement> { interface IIconButton extends React.ButtonHTMLAttributes<HTMLButtonElement> {
@ -24,7 +24,7 @@ const IconButton = React.forwardRef((props: IIconButton, ref: React.ForwardedRef
{...filteredProps} {...filteredProps}
data-testid='icon-button' data-testid='icon-button'
> >
<InlineSVG src={src} className={iconClassName} /> <SvgIcon src={src} className={iconClassName} />
{text ? ( {text ? (
<Text tag='span' theme='muted' size='sm'> <Text tag='span' theme='muted' size='sm'>

@ -1,14 +1,16 @@
import React from 'react'; import React from 'react';
import InlineSVG from 'react-inlinesvg';
import SvgIcon from './svg-icon';
interface IIcon { interface IIcon {
className?: string, className?: string,
count?: number, count?: number,
alt?: string, alt?: string,
src: string, src: string,
size?: number,
} }
const Icon = ({ src, alt, count, ...filteredProps }: IIcon): JSX.Element => ( const Icon = ({ src, alt, count, size, ...filteredProps }: IIcon): JSX.Element => (
<div className='relative' data-testid='icon'> <div className='relative' data-testid='icon'>
{count ? ( {count ? (
<span className='absolute -top-2 -right-3 block px-1.5 py-0.5 bg-accent-500 text-xs text-white rounded-full ring-2 ring-white'> <span className='absolute -top-2 -right-3 block px-1.5 py-0.5 bg-accent-500 text-xs text-white rounded-full ring-2 ring-white'>
@ -16,7 +18,7 @@ const Icon = ({ src, alt, count, ...filteredProps }: IIcon): JSX.Element => (
</span> </span>
) : null} ) : null}
<InlineSVG src={src} title={alt} {...filteredProps} /> <SvgIcon src={src} size={size} alt={alt} {...filteredProps} />
</div> </div>
); );

@ -0,0 +1,23 @@
import React from 'react';
import InlineSVG from 'react-inlinesvg';
interface ISvgIcon {
className?: string,
alt?: string,
src: string,
size?: number,
}
/** Renders an inline SVG with an empty frame loading state */
const SvgIcon = ({ src, alt, size = 24, className }: ISvgIcon): JSX.Element => (
<InlineSVG
className={className}
src={src}
title={alt}
width={size}
height={size}
loader={<div style={{ width: size, height: size }} />}
/>
);
export default SvgIcon;

@ -1,9 +1,9 @@
import classNames from 'classnames'; import classNames from 'classnames';
import React from 'react'; import React from 'react';
import InlineSVG from 'react-inlinesvg';
import { defineMessages, useIntl } from 'react-intl'; import { defineMessages, useIntl } from 'react-intl';
import Icon from '../icon/icon'; import Icon from '../icon/icon';
import SvgIcon from '../icon/svg-icon';
import Tooltip from '../tooltip/tooltip'; import Tooltip from '../tooltip/tooltip';
const messages = defineMessages({ const messages = defineMessages({
@ -72,7 +72,7 @@ const Input = React.forwardRef<HTMLInputElement, IInput>(
tabIndex={-1} tabIndex={-1}
className='text-gray-400 hover:text-gray-500 h-full px-2 focus:ring-primary-500 focus:ring-2' className='text-gray-400 hover:text-gray-500 h-full px-2 focus:ring-primary-500 focus:ring-2'
> >
<InlineSVG <SvgIcon
src={revealed ? require('@tabler/icons/icons/eye-off.svg') : require('@tabler/icons/icons/eye.svg')} src={revealed ? require('@tabler/icons/icons/eye-off.svg') : require('@tabler/icons/icons/eye.svg')}
className='h-4 w-4' className='h-4 w-4'
/> />

@ -6,7 +6,6 @@ import PropTypes from 'prop-types';
import React from 'react'; import React from 'react';
import ImmutablePropTypes from 'react-immutable-proptypes'; import ImmutablePropTypes from 'react-immutable-proptypes';
import ImmutablePureComponent from 'react-immutable-pure-component'; import ImmutablePureComponent from 'react-immutable-pure-component';
import InlineSVG from 'react-inlinesvg';
import { defineMessages, injectIntl } from 'react-intl'; import { defineMessages, injectIntl } from 'react-intl';
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { Link } from 'react-router-dom'; import { Link } from 'react-router-dom';
@ -16,6 +15,7 @@ import Avatar from 'soapbox/components/avatar';
import Badge from 'soapbox/components/badge'; import Badge from 'soapbox/components/badge';
import StillImage from 'soapbox/components/still_image'; import StillImage from 'soapbox/components/still_image';
import { HStack, IconButton, Menu, MenuButton, MenuItem, MenuList, MenuLink, MenuDivider } from 'soapbox/components/ui'; import { HStack, IconButton, Menu, MenuButton, MenuItem, MenuList, MenuLink, MenuDivider } from 'soapbox/components/ui';
import SvgIcon from 'soapbox/components/ui/icon/svg-icon';
import ActionButton from 'soapbox/features/ui/components/action_button'; import ActionButton from 'soapbox/features/ui/components/action_button';
import { import {
isLocal, isLocal,
@ -614,7 +614,7 @@ class Header extends ImmutablePureComponent {
return ( return (
<Comp key={idx} {...itemProps} className='group'> <Comp key={idx} {...itemProps} className='group'>
<div className='flex items-center'> <div className='flex items-center'>
<InlineSVG src={menuItem.icon} className='mr-3 h-5 w-5 text-gray-400 group-hover:text-gray-500' /> <SvgIcon src={menuItem.icon} className='mr-3 h-5 w-5 text-gray-400 group-hover:text-gray-500' />
<div className='truncate'>{menuItem.text}</div> <div className='truncate'>{menuItem.text}</div>
</div> </div>

@ -2,12 +2,12 @@ import classNames from 'classnames';
import { Map as ImmutableMap } from 'immutable'; import { Map as ImmutableMap } from 'immutable';
import debounce from 'lodash/debounce'; import debounce from 'lodash/debounce';
import * as React from 'react'; import * as React from 'react';
import InlineSVG from 'react-inlinesvg';
import { defineMessages, useIntl } from 'react-intl'; import { defineMessages, useIntl } from 'react-intl';
import { useDispatch } from 'react-redux'; import { useDispatch } from 'react-redux';
import { useHistory } from 'react-router-dom'; import { useHistory } from 'react-router-dom';
import AutosuggestAccountInput from 'soapbox/components/autosuggest_account_input'; import AutosuggestAccountInput from 'soapbox/components/autosuggest_account_input';
import SvgIcon from 'soapbox/components/ui/icon/svg-icon';
import { useAppSelector } from 'soapbox/hooks'; import { useAppSelector } from 'soapbox/hooks';
import { import {
@ -140,12 +140,12 @@ const Search = (props: ISearch) => {
className='absolute inset-y-0 right-0 px-3 flex items-center cursor-pointer' className='absolute inset-y-0 right-0 px-3 flex items-center cursor-pointer'
onClick={handleClear} onClick={handleClear}
> >
<InlineSVG <SvgIcon
src={require('@tabler/icons/icons/search.svg')} src={require('@tabler/icons/icons/search.svg')}
className={classNames('h-4 w-4 text-gray-400', { hidden: hasValue })} className={classNames('h-4 w-4 text-gray-400', { hidden: hasValue })}
/> />
<InlineSVG <SvgIcon
src={require('@tabler/icons/icons/x.svg')} src={require('@tabler/icons/icons/x.svg')}
className={classNames('h-4 w-4 text-gray-400', { hidden: !hasValue })} className={classNames('h-4 w-4 text-gray-400', { hidden: !hasValue })}
aria-label={intl.formatMessage(messages.placeholder)} aria-label={intl.formatMessage(messages.placeholder)}

@ -1,5 +1,4 @@
import React from 'react'; import React from 'react';
import InlineSVG from 'react-inlinesvg';
import { FormattedMessage, defineMessages, useIntl } from 'react-intl'; import { FormattedMessage, defineMessages, useIntl } from 'react-intl';
import { useDispatch } from 'react-redux'; import { useDispatch } from 'react-redux';
import { Link, useHistory } from 'react-router-dom'; import { Link, useHistory } from 'react-router-dom';
@ -7,6 +6,7 @@ import { Link, useHistory } from 'react-router-dom';
import { changeSettingImmediate } from 'soapbox/actions/settings'; import { changeSettingImmediate } from 'soapbox/actions/settings';
import snackbar from 'soapbox/actions/snackbar'; import snackbar from 'soapbox/actions/snackbar';
import { Text } from 'soapbox/components/ui'; import { Text } from 'soapbox/components/ui';
import SvgIcon from 'soapbox/components/ui/icon/svg-icon';
import Column from '../ui/components/column'; import Column from '../ui/components/column';
@ -32,7 +32,7 @@ const Developers = () => {
<Column label={intl.formatMessage(messages.heading)}> <Column label={intl.formatMessage(messages.heading)}>
<div className='grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-2'> <div className='grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-2'>
<Link to='/developers/apps/create' className='bg-gray-200 dark:bg-gray-600 p-4 rounded flex flex-col items-center justify-center space-y-2 hover:-translate-y-1 transition-transform'> <Link to='/developers/apps/create' className='bg-gray-200 dark:bg-gray-600 p-4 rounded flex flex-col items-center justify-center space-y-2 hover:-translate-y-1 transition-transform'>
<InlineSVG src={require('@tabler/icons/icons/apps.svg')} className='dark:text-gray-100' /> <SvgIcon src={require('@tabler/icons/icons/apps.svg')} className='dark:text-gray-100' />
<Text> <Text>
<FormattedMessage id='developers.navigation.app_create_label' defaultMessage='Create an app' /> <FormattedMessage id='developers.navigation.app_create_label' defaultMessage='Create an app' />
@ -40,7 +40,7 @@ const Developers = () => {
</Link> </Link>
<Link to='/developers/settings_store' className='bg-gray-200 dark:bg-gray-600 p-4 rounded flex flex-col items-center justify-center space-y-2 hover:-translate-y-1 transition-transform'> <Link to='/developers/settings_store' className='bg-gray-200 dark:bg-gray-600 p-4 rounded flex flex-col items-center justify-center space-y-2 hover:-translate-y-1 transition-transform'>
<InlineSVG src={require('@tabler/icons/icons/code-plus.svg')} className='dark:text-gray-100' /> <SvgIcon src={require('@tabler/icons/icons/code-plus.svg')} className='dark:text-gray-100' />
<Text> <Text>
<FormattedMessage id='developers.navigation.settings_store_label' defaultMessage='Settings store' /> <FormattedMessage id='developers.navigation.settings_store_label' defaultMessage='Settings store' />
@ -48,7 +48,7 @@ const Developers = () => {
</Link> </Link>
<Link to='/error' className='bg-gray-200 dark:bg-gray-600 p-4 rounded flex flex-col items-center justify-center space-y-2 hover:-translate-y-1 transition-transform'> <Link to='/error' className='bg-gray-200 dark:bg-gray-600 p-4 rounded flex flex-col items-center justify-center space-y-2 hover:-translate-y-1 transition-transform'>
<InlineSVG src={require('@tabler/icons/icons/mood-sad.svg')} className='dark:text-gray-100' /> <SvgIcon src={require('@tabler/icons/icons/mood-sad.svg')} className='dark:text-gray-100' />
<Text> <Text>
<FormattedMessage id='developers.navigation.intentional_error_label' defaultMessage='Trigger an error' /> <FormattedMessage id='developers.navigation.intentional_error_label' defaultMessage='Trigger an error' />
@ -56,7 +56,7 @@ const Developers = () => {
</Link> </Link>
<button onClick={leaveDevelopers} className='bg-gray-200 dark:bg-gray-600 p-4 rounded flex flex-col items-center justify-center space-y-2 hover:-translate-y-1 transition-transform'> <button onClick={leaveDevelopers} className='bg-gray-200 dark:bg-gray-600 p-4 rounded flex flex-col items-center justify-center space-y-2 hover:-translate-y-1 transition-transform'>
<InlineSVG src={require('@tabler/icons/icons/logout.svg')} className='dark:text-gray-100' /> <SvgIcon src={require('@tabler/icons/icons/logout.svg')} className='dark:text-gray-100' />
<Text> <Text>
<FormattedMessage id='developers.navigation.leave_developers_label' defaultMessage='Leave developers' /> <FormattedMessage id='developers.navigation.leave_developers_label' defaultMessage='Leave developers' />

Loading…
Cancel
Save