Иконки
Руководство и рекомендации по использованию иконок в Material-UI.
Material-UI обеспечивает поддержку иконок тремя способами:
- Стандартные иконки Material Design экспортированы как React компоненты (SVG иконки).
- С помощью компонента SvgIcon, React-обёртки для пользовательских SVG иконок.
- С помощью компонента Icon, React-обёртки для пользовательских иконочных шрифтов.
Material Иконки
Material Design has standardized over 1,100 official icons, each in five different "themes" (see below). For each SVG icon, we export the respective React component from the @material-ui/icons package. Вы можете найти полный список этих иконок здесь.
Инструкция по установке
Установите пакет в каталог проекта командой:
// через npm
npm install @material-ui/icons
// через yarn
yarn add @material-ui/icons
These components use the Material-UI SvgIcon
component to render the SVG path for each icon, and so have a peer-dependency on @materialui/core
.
If you aren't already using Material-UI in your project, you can add it with:
// with npm
npm install @material-ui/core
// with yarn
yarn add @material-ui/core
Использование
Импорт иконок с помощью одного из этих двух вариантов:
Вариант 1:
import AccessAlarmIcon from '@material-ui/icons/AccessAlarm'; import ThreeDRotation from '@material-ui/icons/ThreeDRotation';
Вариант 2:
import { AccessAlarm, ThreeDRotation } from '@material-ui/icons';
The safest for bundle size is Option 1, but some developers prefer Option 2. Make sure you follow the minimizing bundle size guide before using the second approach.
Each Material icon also has a "theme": Filled (default), Outlined, Rounded, Two-tone, and Sharp. To import the icon component with a theme other than the default, append the theme name to the icon name. For example @material-ui/icons/Delete
icon with:
- Filled theme (default) is exported as
@material-ui/icons/Delete
, - Outlined theme is exported as
@material-ui/icons/DeleteOutlined
, - Rounded theme is exported as
@material-ui/icons/DeleteRounded
, - Twotone theme is exported as
@material-ui/icons/DeleteTwoTone
, - Sharp theme is exported as
@material-ui/icons/DeleteSharp
.
Note: The Material Design specification names the icons using "snake_case" naming (for example
delete_forever
,add_a_photo
), while@material-ui/icons
exports the respective icons using "PascalCase" naming (for exampleDeleteForever
,AddAPhoto
). There are three exceptions to this naming rule:3d_rotation
exported asThreeDRotation
,4k
exported asFourK
, and360
exported asThreeSixty
.
Filled
Outlined
Rounded
Two Tone
Sharp
Edge-cases
Тестирование
For testing purposes, each icon exposed from @material-ui/icons
has a data-testid
attribute with the name of the icon. Например:
import DeleteIcon from '@material-ui/icons/Delete';
has the following attribute once mounted:
<svg data-testid="DeleteIcon"></svg>
SvgIcon
If you need a custom SVG icon (not available in the Material Icons) you can use the SvgIcon
wrapper. This component extends the native <svg>
element:
- It comes with built-in accessibility.
- SVG elements should be scaled for a 24x24px viewport so that the resulting icon can be used as is, or included as a child for other Material-UI components that use icons. (This can be customized with the
viewBox
attribute). - By default, the component inherits the current color. Optionally, you can apply one of the theme colors using the
color
prop.
function HomeIcon(props) {
return (
<SvgIcon {...props}>
<path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z" />
</SvgIcon>
);
}
Цвет
<HomeIcon />
<HomeIcon color="primary" />
<HomeIcon color="secondary" />
<HomeIcon color="action" />
<HomeIcon color="disabled" />
<HomeIcon sx={{ color: green[500] }} />
<HomeIcon fontSize="small" />
<HomeIcon />
<HomeIcon fontSize="large" />
<HomeIcon sx={{ fontSize: 40 }} />
Component prop
You can use the SvgIcon
wrapper even if your icons are saved in the .svg
format. svgr has loaders to import SVG files and use them as React components. For example, with webpack:
// webpack.config.js
{
test: /\.svg$/,
use: ['@svgr/webpack'],
}
// ---
import StarIcon from './star.svg';
<SvgIcon component={StarIcon} viewBox="0 0 600 476.6" />
It's also possible to use it with "url-loader" or "file-loader". This is the approach used by Create React App.
// webpack.config.js
{
test: /\.svg$/,
use: ['@svgr/webpack', 'url-loader'],
}
// ---
import { ReactComponent as StarIcon } from './star.svg';
<SvgIcon component={StarIcon} viewBox="0 0 600 476.6" />
createSvgIcon
The createSvgIcon
utility component is used to create the Material icons. It can be used to wrap an SVG path with an SvgIcon component.
const HomeIcon = createSvgIcon(
<path d="M10 20v-6h4v6h5v-8h3L12 3 2 12h3v8z" />,
'Home',
);
<HomeIcon />
<HomeIcon color="primary" />
Font Awesome
If you find that there are layout issues when using FontAwesomeIcon from @fortawesome/react-fontawesome
, you can try passing the Font Awesome SVG data directly to SvgIcon.
Font Awesome можно использовать с компонентом Icon
следующим образом:
<IconButton aria-label="Example">
<FontAwesomeIcon icon={faEllipsisV} />
</IconButton>
<IconButton aria-label="Example">
<FontAwesomeSvgIcon icon={faEllipsisV} />
</IconButton>
<Button variant="contained" startIcon={<FontAwesomeIcon icon={faInfo} />}>
Example
</Button>
<Button variant="contained" startIcon={<FontAwesomeSvgIcon icon={faInfo} />}>
Example
</Button>
FontAwesomeIcon's fullWidth
prop can also be used to approximate the correct dimensions, but it isn't perfect.
Шрифтовые иконки Material
MDI
materialdesignicons.com provides over 2,000 icons. For the wanted icon, copy the SVG path
they provide, and use it as the child of the SvgIcon
component, or with createSvgIcon()
.
Note: mdi-material-ui has already wrapped each of these SVG icons with the SvgIcon
component, so you don't have to do it yourself.
Icon (Font icons)
Компонент Icon
отображает иконку из любого иконочного шрифта с поддержкой лигатур. Компонент Icon
отображает иконку из любого иконочного шрифта с поддержкой лигатур. Чтобы использовать иконку, просто оберните её имя (лигатуру шрифта) в компонент Icon
, например:
import Icon from '@material-ui/core/Icon';
<Icon>star</Icon>
По умолчанию иконка наследует текущий цвет текста. При желании вы можете установить цвет иконки с помощью одного из свойств цвета темы: primary
, secondary
, action
, error
или disabled
.
Шрифтовые иконки Material
Icon
will by default set the correct base class name for the Material Icons font (filled variant). All you need to do is load the font, for instance, via Google Web Fonts:
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons" />
<Icon>add_circle</Icon>
<Icon color="primary">add_circle</Icon>
<Icon sx={{ color: green[500] }}>add_circle</Icon>
<Icon fontSize="small">add_circle</Icon>
<Icon sx={{ fontSize: 30 }}>add_circle</Icon>
Custom font
For other fonts, you can customize the baseline class name using the baseClassName
prop. For instance, you can display two-tone icons with Material Design:
import Icon from '@material-ui/core/Icon';
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css?family=Material+Icons+Two+Tone"
// Import the two tones MD variant ^^^^^^^^
/>;
<Icon baseClassName="material-icons-two-tone">add_circle</Icon>
Global base class name
Modifying the baseClassName
prop for each component usage is repetitive. You can change the default prop globally with the theme
const theme = createTheme({
components: {
MuiIcon: {
defaultProps: {
// Replace the `material-icons` default value.
baseClassName: 'material-icons-two-tone',
},
},
},
});
Then, you can use the two-tone font directly:
<Icon>add_circle</Icon>
Font Awesome
Font Awesome can be used with the Icon
component as follows:
<Icon baseClassName="fas" className="fa-plus-circle" />
<Icon baseClassName="fas" className="fa-plus-circle" color="primary" />
<Icon
baseClassName="fas"
className="fa-plus-circle"
sx={{ color: green[500] }}
/>
<Icon baseClassName="fas" className="fa-plus-circle" fontSize="small" />
<Icon baseClassName="fas" className="fa-plus-circle" sx={{ fontSize: 30 }} />
Note that the Font Awesome icons weren't designed like the Material Design icons (compare the two previous demos). The fa icons are cropped to use all the space available. You can adjust for this with a global override:
const theme = createTheme({
components: {
MuiIcon: {
styleOverrides: {
root: {
// Match 24px = 3 * 2 + 1.125 * 16
boxSizing: 'content-box',
padding: 3,
fontSize: '1.125rem',
},
},
},
},
});
<ThemeProvider theme={theme}>
<Chip icon={<MdPhone />} label="Call me" />
<Chip icon={<Icon className="fas fa-phone-alt" />} label="Call me" />
</ThemeProvider>
Font vs SVG. Which approach to use?
Both approaches work fine, however there are some subtle differences, especially in terms of performance and rendering quality. Whenever possible SVG is preferred as it allows code splitting, supports more icons, and renders faster and better.
For more details, take a look at why GitHub migrated from font icons to SVG icons.
Доступность
Icons can convey all sorts of meaningful information, so it's important to ensure they are accessible where appropriate. There are two use cases you'll want to consider:
- Decorative icons that are only being used for visual or branding reinforcement. Если удалить их со страницы, пользователи всё равно смогут её использовать, им всё будет понятно.
- Semantic icons are ones that you're using to convey meaning, rather than just pure decoration. This includes icons without text next to them that are used as interactive controls — buttons, form elements, toggles, etc.
Decorative icons
If your icons are purely decorative, you're already done! The aria-hidden=true
attribute is added so that your icons are properly accessible (invisible).
Semantic icons
Semantic SVG icons
You should include the titleAccess
prop with a meaningful value. The role="img"
attribute and the <title>
element are added so that your icons are correctly accessible.
In the case of focusable interactive elements, for example when used with an icon button, you can use the aria-label
prop:
import IconButton from '@material-ui/core/IconButton';
import SvgIcon from '@material-ui/core/SvgIcon';
// ...
<IconButton aria-label="delete">
<SvgIcon>
<path d="M20 12l-1.41-1.41L13 16.17V4h-2v12.17l-5.58-5.59L4 12l8 8 8-8z" />
</SvgIcon>
</IconButton>
Semantic font icons
You need to provide a text alternative that is only visible to assistive technologies.
import Icon from '@material-ui/core/Icon';
import { visuallyHidden } from '@material-ui/utils';
import { makeStyles } from '@material-ui/core/styles';
const classes = makeStyles({ visuallyHidden })();
// ...
<Icon>add_circle</Icon>
<Typography variant="srOnly">Создать пользователя</Typography>