Skip to content

Commit

Permalink
Merge pull request #586 from catho/QTM-778
Browse files Browse the repository at this point in the history
feat(Icon.jsx): Added icons outside the MUI, updating unit tests and …
  • Loading branch information
MarcosViniciusPC authored Sep 19, 2024
2 parents e248366 + 9074436 commit d9e14bb
Show file tree
Hide file tree
Showing 8 changed files with 131 additions and 16 deletions.
17 changes: 17 additions & 0 deletions components/Icon/Custom/BoxSeamFill.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
const BoxSeamFill = ({ size = 24, color, ...rest }) => (
<svg
xmlns="http://www.w3.org/2000/svg"
height={size}
width={size}
fill={color}
viewBox="0 0 16 16"
{...rest}
>
<path
fillRule="evenodd"
d="M15.528 2.973a.75.75 0 0 1 .472.696v8.662a.75.75 0 0 1-.472.696l-7.25 2.9a.75.75 0 0 1-.557 0l-7.25-2.9A.75.75 0 0 1 0 12.331V3.669a.75.75 0 0 1 .471-.696L7.443.184l.01-.003.268-.108a.75.75 0 0 1 .558 0l.269.108.01.003zM10.404 2 4.25 4.461 1.846 3.5 1 3.839v.4l6.5 2.6v7.922l.5.2.5-.2V6.84l6.5-2.6v-.4l-.846-.339L8 5.961 5.596 5l6.154-2.461z"
/>
</svg>
);

export default BoxSeamFill;
14 changes: 14 additions & 0 deletions components/Icon/Custom/Dentistry.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const Dentistry = ({ size = 24, color, ...rest }) => (
<svg
xmlns="http://www.w3.org/2000/svg"
height={size}
width={size}
fill={color}
viewBox="0 -960 960 960"
{...rest}
>
<path d="M680-875q66 0 113 47t47 113q0 11-1.5 29.5T834-643l-55 403q-5 38-34.5 62T677-154q-23 0-42.5-10T602-192L495-348q-2-4-6.5-5.5T479-355q-4 0-16 9L359-195q-14 20-34.5 30.5T281-154q-38 0-67-24.5T180-241l-54-402q-3-24-4.5-42.5T120-715q0-66 47-113t113-47q36 0 57.5 9.5T379-845q20 11 42.5 20.5T480-815q36 0 58.5-9.5T581-845q20-11 42-20.5t57-9.5Z" />
</svg>
);

export default Dentistry;
14 changes: 14 additions & 0 deletions components/Icon/Custom/EcgHeart.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
const EcgHeart = ({ size = 24, color, ...rest }) => (
<svg
xmlns="http://www.w3.org/2000/svg"
height={size}
width={size}
fill={color}
viewBox="0 -960 960 960"
{...rest}
>
<path d="M645-840q100 0 167.5 74T880-590q0 18-2 35.5t-7 34.5H621l-68-102q-5-8-14-13t-19-5q-13 0-23.5 8T482-612l-54 162-35-52q-5-8-14-13t-19-5H89q-5-17-7-34.5T80-589q0-103 67-177t167-74q48 0 90.5 19t75.5 53q32-34 74.5-53t90.5-19ZM480-120q-18 0-34.5-6.5T416-146L148-415q-6-6-11-12t-10-13h211l68 102q5 8 14 13t19 5q13 0 24-8t15-20l54-162 34 52q6 8 15 13t19 5h232l-10 12-10 12-269 270q-13 13-29 19.5t-34 6.5Z" />
</svg>
);

export default EcgHeart;
41 changes: 30 additions & 11 deletions components/Icon/Icon.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,9 @@ import Warning from '@mui/icons-material/Warning';
import WatchLater from '@mui/icons-material/WatchLater';
import Whatshot from '@mui/icons-material/Whatshot';
import Work from '@mui/icons-material/Work';
import BoxSeamFill from './Custom/BoxSeamFill';
import Dentistry from './Custom/Dentistry';
import EcgHeart from './Custom/EcgHeart';

import { theme } from '../shared';
import icons from '../shared/icons';
Expand All @@ -126,7 +129,13 @@ const sizes = {
xlarge: baseFontSize * 2.5, // 40
};

const Icon = ({ name, skin = '', style = {}, size = 'medium', ...props }) => {
export const customIcons = {
box_seam_fill: BoxSeamFill,
dentistry: Dentistry,
ecg_heart: EcgHeart,
};

const Icon = ({ name, skin = '', style = {}, size = 'medium', ...rest }) => {
const components = {
access_time: AccessTime,
accessible_forward: AccessibleForward,
Expand Down Expand Up @@ -240,23 +249,33 @@ const Icon = ({ name, skin = '', style = {}, size = 'medium', ...props }) => {
watch_later: WatchLater,
whatshot: Whatshot,
work: Work,
...customIcons,
};

if (!components[name]) return <span>{name}</span>;

const SelectedIcon = components[name];
const sizeInPx = sizes[size];

const isCustomIcon = Object.values(customIcons).includes(SelectedIcon);

const customIconProps = { size: sizeInPx, color: skin };
const muiIconProps = {
style: {
color: skin,
fontSize: sizeInPx,
maxWidth: sizeInPx,
...style,
},
};

const iconProps = {
...(isCustomIcon ? customIconProps : muiIconProps),
...rest,
};

return (
<SelectedIcon
{...props}
style={{
color: skin,
fontSize: sizes[size],
maxWidth: sizes[size],
...style,
}}
data-qtm-preloader="icon"
>
<SelectedIcon {...iconProps} data-qtm-preloader="icon">
{name}
</SelectedIcon>
);
Expand Down
27 changes: 27 additions & 0 deletions components/Icon/Icon.unit.test.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ describe('<Icon />', () => {
const { container: tree3D } = render(<Icon name="accessible_forward" />);
const { container: treeFilter } = render(<Icon name="check_circle" />);
const { container: treeArrow } = render(<Icon name="search" />);
const { container: customIcon } = render(<Icon name="box_seam_fill" />);
const { container: withColor } = render(<Icon name="star" skin="tomato" />);
const { container: withSmallSize } = render(
<Icon name="search" size="small" />,
Expand All @@ -26,6 +27,7 @@ describe('<Icon />', () => {
expect(tree3D).toMatchSnapshot();
expect(treeFilter).toMatchSnapshot();
expect(treeArrow).toMatchSnapshot();
expect(customIcon).toMatchSnapshot();
expect(withColor).toMatchSnapshot();
expect(withSmallSize).toMatchSnapshot();
expect(withMediumSize).toMatchSnapshot();
Expand All @@ -42,4 +44,29 @@ describe('<Icon />', () => {
expect(consoleErrorMock).toBeCalled();
consoleErrorMock.mockRestore();
});

it('must have size and color props when it is a custom icon', () => {
const smallSizeInPX = '16';
const color = '#ffffff';

const { container } = render(
<Icon name="box_seam_fill" size="small" skin={color} />,
);
const icon = container.querySelector('svg');

expect(icon).toHaveAttribute('width', smallSizeInPX);
expect(icon).toHaveAttribute('height', smallSizeInPX);
expect(icon).toHaveAttribute('fill', color);
expect(icon).not.toHaveAttribute('style');
});

it('must have style prop when it is a MUI icon', () => {
const { container } = render(<Icon name="access_time" />);
const icon = container.querySelector('svg');

expect(icon).not.toHaveAttribute('width');
expect(icon).not.toHaveAttribute('height');
expect(icon).not.toHaveAttribute('fill');
expect(icon).toHaveAttribute('style');
});
});
28 changes: 23 additions & 5 deletions components/Icon/__snapshots__/Icon.unit.test.jsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,24 @@ exports[`<Icon /> Should match the snapshot 3`] = `
`;

exports[`<Icon /> Should match the snapshot 4`] = `
<div>
<svg
data-qtm-preloader="icon"
fill=""
height="24"
viewBox="0 0 16 16"
width="24"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M15.528 2.973a.75.75 0 0 1 .472.696v8.662a.75.75 0 0 1-.472.696l-7.25 2.9a.75.75 0 0 1-.557 0l-7.25-2.9A.75.75 0 0 1 0 12.331V3.669a.75.75 0 0 1 .471-.696L7.443.184l.01-.003.268-.108a.75.75 0 0 1 .558 0l.269.108.01.003zM10.404 2 4.25 4.461 1.846 3.5 1 3.839v.4l6.5 2.6v7.922l.5.2.5-.2V6.84l6.5-2.6v-.4l-.846-.339L8 5.961 5.596 5l6.154-2.461z"
fill-rule="evenodd"
/>
</svg>
</div>
`;

exports[`<Icon /> Should match the snapshot 5`] = `
<div>
<svg
aria-hidden="true"
Expand All @@ -77,7 +95,7 @@ exports[`<Icon /> Should match the snapshot 4`] = `
</div>
`;

exports[`<Icon /> Should match the snapshot 5`] = `
exports[`<Icon /> Should match the snapshot 6`] = `
<div>
<svg
aria-hidden="true"
Expand All @@ -95,7 +113,7 @@ exports[`<Icon /> Should match the snapshot 5`] = `
</div>
`;

exports[`<Icon /> Should match the snapshot 6`] = `
exports[`<Icon /> Should match the snapshot 7`] = `
<div>
<svg
aria-hidden="true"
Expand All @@ -113,7 +131,7 @@ exports[`<Icon /> Should match the snapshot 6`] = `
</div>
`;

exports[`<Icon /> Should match the snapshot 7`] = `
exports[`<Icon /> Should match the snapshot 8`] = `
<div>
<svg
aria-hidden="true"
Expand All @@ -131,7 +149,7 @@ exports[`<Icon /> Should match the snapshot 7`] = `
</div>
`;

exports[`<Icon /> Should match the snapshot 8`] = `
exports[`<Icon /> Should match the snapshot 9`] = `
<div>
<svg
aria-hidden="true"
Expand All @@ -149,7 +167,7 @@ exports[`<Icon /> Should match the snapshot 8`] = `
</div>
`;

exports[`<Icon /> Should match the snapshot 9`] = `
exports[`<Icon /> Should match the snapshot 10`] = `
<div>
<svg
aria-hidden="true"
Expand Down
3 changes: 3 additions & 0 deletions components/Icon/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ export type IconNames =
| 'border_style'
| 'border_top'
| 'border_vertical'
| 'box_seam_fill'
| 'branding_watermark'
| 'brightness_1'
| 'brightness_2'
Expand Down Expand Up @@ -229,6 +230,7 @@ export type IconNames =
| 'device_hub'
| 'devices'
| 'devices_other'
| 'dentistry'
| 'dialer_sip'
| 'dialpad'
| 'directions_bike'
Expand Down Expand Up @@ -257,6 +259,7 @@ export type IconNames =
| 'drag_handle'
| 'drive_eta'
| 'dvr'
| 'ecg_heart'
| 'edit'
| 'edit_location'
| 'eject'
Expand Down
3 changes: 3 additions & 0 deletions components/shared/icons.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const icons = [
'attach_money',
'auto_graph',
'block',
'box_seam_fill',
'cached',
'camera',
'chat',
Expand All @@ -37,8 +38,10 @@ const icons = [
'credit_card',
'date_range',
'delete',
'dentistry',
'description_outlined',
'done',
'ecg_heart',
'edit',
'emoji_people',
'equalizer',
Expand Down

0 comments on commit d9e14bb

Please sign in to comment.