Load icons using @svgr (#7928)

* extend svg module

Signed-off-by: Kerry Archibald <kerrya@element.io>

* POC in QuickSettingsButton

Signed-off-by: Kerry Archibald <kerrya@element.io>

* stylelint

Signed-off-by: Kerry Archibald <kerrya@element.io>

* update copyright

Signed-off-by: Kerry Archibald <kerrya@element.io>

* remove aria-hidden, quick docs

Signed-off-by: Kerry Archibald <kerrya@element.io>
This commit is contained in:
Kerry 2022-03-02 10:18:45 +01:00 committed by GitHub
parent d50dae5208
commit e6ea58e84d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 70 additions and 53 deletions

44
docs/icons.md Normal file
View file

@ -0,0 +1,44 @@
# Icons
Icons are loaded using [@svgr/webpack](https://www.npmjs.com/package/@svgr/webpack). This is configured in [element-web](https://github.com/vector-im/element-web/blob/develop/webpack.config.js#L458)
Each .svg exports a `ReactComponent` at the named export `Icon`.
Icons have `role="presentation"` and `aria-hidden` automatically applied. These can be overriden by passing props to the icon component.
eg
```
import { Icon as FavoriteIcon } from 'res/img/element-icons/favorite.svg';
const MyComponent = () => {
return <>
<FavoriteIcon>
<FavoriteIcon className="mx_MyComponent-icon" role="img" aria-hidden="false">
</>;
}
```
## Styling
Icon components are svg elements and can be styled as usual.
```
// _MyComponents.scss
.mx_MyComponent-icon {
height: 20px;
width: 20px;
* {
fill: $accent;
}
}
// MyComponent.tsx
import { Icon as FavoriteIcon } from 'res/img/element-icons/favorite.svg';
const MyComponent = () => {
return <>
<FavoriteIcon>
<FavoriteIcon className="mx_MyComponent-icon" role="img" aria-hidden="false">
</>;
}
```

View file

@ -82,21 +82,6 @@ limitations under the License.
.mx_QuickSettingsButton_pinToSidebarHeading {
padding-left: 24px;
position: relative;
&::before {
background-color: $secondary-content;
content: "";
mask-repeat: no-repeat;
mask-position: center;
mask-size: contain;
mask-image: url('$(res)/img/element-icons/room/pin-upright.svg');
width: 16px;
height: 16px;
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
}
}
.mx_Checkbox {
@ -112,31 +97,9 @@ limitations under the License.
font-size: $font-15px;
line-height: $font-24px;
color: $secondary-content;
&::before {
background-color: $secondary-content;
content: "";
mask-repeat: no-repeat;
mask-position: center;
mask-size: contain;
width: 16px;
height: 16px;
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
}
}
}
.mx_QuickSettingsButton_favouritesCheckbox .mx_Checkbox_background + div::before {
mask-image: url('$(res)/img/element-icons/roomlist/favorite.svg');
}
.mx_QuickSettingsButton_peopleCheckbox .mx_Checkbox_background + div::before {
mask-image: url('$(res)/img/element-icons/room/members.svg');
}
.mx_QuickSettingsButton_moreOptionsButton {
padding-left: 22px;
margin-left: 22px;
@ -145,20 +108,17 @@ limitations under the License.
color: $secondary-content;
position: relative;
margin-bottom: 16px;
&::before {
background-color: $secondary-content;
content: "";
mask-repeat: no-repeat;
mask-position: center;
mask-size: contain;
width: 16px;
height: 16px;
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
mask-image: url('$(res)/img/element-icons/room/ellipsis.svg');
}
}
}
.mx_QuickSettingsButton_icon {
* {
fill: $secondary-content;
}
width: 16px;
height: 16px;
position: absolute;
left: 0;
top: 50%;
transform: translateY(-50%);
}

2
src/@types/svg.d.ts vendored
View file

@ -1,5 +1,6 @@
/*
Copyright 2021 Šimon Brandner <simon.bra.ag@gmail.com>
Copyright 2022 The Matrix.org Foundation C.I.C.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -16,5 +17,6 @@ limitations under the License.
declare module "*.svg" {
const path: string;
export const Icon: React.FC<React.SVGProps<SVGSVGElement>>;
export default path;
}

View file

@ -29,6 +29,10 @@ import defaultDispatcher from "../../../dispatcher/dispatcher";
import { Action } from "../../../dispatcher/actions";
import { UserTab } from "../dialogs/UserSettingsDialog";
import QuickThemeSwitcher from "./QuickThemeSwitcher";
import { Icon as PinUprightIcon } from '../../../../res/img/element-icons/room/pin-upright.svg';
import { Icon as EllipsisIcon } from '../../../../res/img/element-icons/room/ellipsis.svg';
import { Icon as MembersIcon } from '../../../../res/img/element-icons/room/members.svg';
import { Icon as FavoriteIcon } from '../../../../res/img/element-icons/roomlist/favorite.svg';
const QuickSettingsButton = ({ isPanelCollapsed = false }) => {
const [menuDisplayed, handle, openMenu, closeMenu] = useContextMenu<HTMLDivElement>();
@ -59,13 +63,17 @@ const QuickSettingsButton = ({ isPanelCollapsed = false }) => {
{ _t("All settings") }
</AccessibleButton>
<h4 className="mx_QuickSettingsButton_pinToSidebarHeading">{ _t("Pin to sidebar") }</h4>
<h4 className="mx_QuickSettingsButton_pinToSidebarHeading">
<PinUprightIcon className="mx_QuickSettingsButton_icon" />
{ _t("Pin to sidebar") }
</h4>
<StyledCheckbox
className="mx_QuickSettingsButton_favouritesCheckbox"
checked={!!favouritesEnabled}
onChange={onMetaSpaceChangeFactory(MetaSpace.Favourites, "WebQuickSettingsPinToSidebarCheckbox")}
>
<FavoriteIcon className="mx_QuickSettingsButton_icon" />
{ _t("Favourites") }
</StyledCheckbox>
<StyledCheckbox
@ -73,6 +81,8 @@ const QuickSettingsButton = ({ isPanelCollapsed = false }) => {
checked={!!peopleEnabled}
onChange={onMetaSpaceChangeFactory(MetaSpace.People, "WebQuickSettingsPinToSidebarCheckbox")}
>
<MembersIcon className="mx_QuickSettingsButton_icon" />
{ _t("People") }
</StyledCheckbox>
<AccessibleButton
@ -85,6 +95,7 @@ const QuickSettingsButton = ({ isPanelCollapsed = false }) => {
});
}}
>
<EllipsisIcon className="mx_QuickSettingsButton_icon" />
{ _t("More options") }
</AccessibleButton>