Skip to content

Commit d7a37a7

Browse files
committed
Protect: Add ShieldIcon Component (#40402)
1 parent 1eab9df commit d7a37a7

File tree

14 files changed

+162
-326
lines changed

14 files changed

+162
-326
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
Significance: minor
2+
Type: added
3+
4+
Add ShieldIcon component
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import React from 'react';
2+
3+
const COLORS = {
4+
error: '#D63638',
5+
warning: '#F0B849',
6+
success: '#069E08',
7+
default: '#1d2327',
8+
};
9+
10+
/**
11+
* Protect Shield SVG Icon
12+
*
13+
* @param {object} props - Component props.
14+
* @param {string} props.className - Additional class names.
15+
* @param {string} props.contrast - Icon contrast color. Overrides variant.
16+
* @param {string} props.fill - Icon fill color (default, success, warning, error, or a custom color code string). Overrides variant.
17+
* @param {number} props.height - Icon height (px). Width is calculated based on height.
18+
* @param {string} props.icon - Icon variant (success, error). Overrides variant.
19+
* @param {boolean} props.outline - When enabled, the icon will use an outline style.
20+
* @param {string} props.variant - Icon variant (default, success, error).
21+
*
22+
* @return {React.ReactElement} Protect Shield SVG Icon
23+
*/
24+
export default function ShieldIcon( {
25+
className,
26+
contrast = '#fff',
27+
fill,
28+
height = 32,
29+
icon,
30+
outline = false,
31+
variant = 'default',
32+
}: {
33+
className?: string;
34+
contrast?: string;
35+
fill?: 'default' | 'success' | 'warning' | 'error' | string;
36+
height?: number;
37+
icon?: 'success' | 'error';
38+
outline?: boolean;
39+
variant: 'default' | 'success' | 'warning' | 'error';
40+
} ): JSX.Element {
41+
const shieldFill = COLORS[ fill ] || fill || COLORS[ variant ];
42+
const iconFill = outline ? shieldFill : contrast;
43+
const iconVariant = icon || variant;
44+
45+
return (
46+
<svg
47+
height={ height }
48+
width={ ( height * 76 ) / 93 }
49+
viewBox="0 0 76 93"
50+
fill="none"
51+
xmlns="http://www.w3.org/2000/svg"
52+
className={ className }
53+
>
54+
<path
55+
d={
56+
'M37.5652 0.980293L75.1304 18.0554V43.5097C75.1304 65.2086 61.1942 85.753 41.5427 92.2343C38.9604 93.0862 36.1701 93.0862 33.5878 92.2343C13.9362 85.753 0 65.2086 0 43.5097V18.0554L37.5652 0.980293Z' +
57+
( outline
58+
? ' M8.34783 23.4307V43.5097C8.34783 61.9471 20.286 79.0573 36.2024 84.3068C37.0866 84.5981 38.0438 84.5981 38.928 84.3068C54.8444 79.0573 66.7826 61.9471 66.7826 43.5097V23.4307L37.5652 10.15L8.34783 23.4307Z'
59+
: '' )
60+
}
61+
fill={ shieldFill }
62+
/>
63+
{ 'success' === iconVariant && (
64+
<path
65+
fillRule="evenodd"
66+
clipRule="evenodd"
67+
d="M55.6042 37.0675L34.3578 65.2656L20.898 55.3892L23.878 51.4342L33.33 58.3698L51.5965 34.1267L55.6042 37.0675Z"
68+
fill={ iconFill }
69+
/>
70+
) }
71+
{ [ 'warning', 'error' ].includes( iconVariant ) && (
72+
<path
73+
d="M41.7474 54.1614L43.0546 30H32L33.3071 54.1614H41.7474ZM41.4113 66.7283C42.3076 65.8681 42.7931 64.6713 42.7931 63.1378C42.7931 61.5669 42.345 60.3701 41.4487 59.5098C40.5523 58.6496 39.2452 58.2008 37.4899 58.2008C35.7346 58.2008 34.4275 58.6496 33.4939 59.5098C32.5602 60.3701 32.112 61.5669 32.112 63.1378C32.112 64.6713 32.5975 65.8681 33.5312 66.7283C34.5022 67.5886 35.8093 68 37.4899 68C39.1705 68 40.4776 67.5886 41.4113 66.7283Z"
74+
fill={ iconFill }
75+
/>
76+
) }
77+
</svg>
78+
);
79+
}
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import ShieldIcon from '../index';
2+
3+
export default {
4+
title: 'JS Packages/Components/Sheild Icon',
5+
component: ShieldIcon,
6+
parameters: {
7+
layout: 'centered',
8+
},
9+
argTypes: {
10+
variant: {
11+
control: {
12+
type: 'select',
13+
},
14+
options: [ 'default', 'success', 'warning', 'error' ],
15+
},
16+
icon: {
17+
control: {
18+
type: 'select',
19+
},
20+
options: [ 'success', 'error' ],
21+
},
22+
fill: {
23+
control: 'color',
24+
},
25+
outline: {
26+
control: 'boolean',
27+
},
28+
},
29+
};
30+
31+
export const Default = args => <ShieldIcon { ...args } />;
32+
Default.args = {
33+
variant: 'success',
34+
outline: false,
35+
};
36+
37+
export const Variants = () => {
38+
return (
39+
<div style={ { display: 'flex', flexDirection: 'column', gap: '8px' } }>
40+
<div style={ { display: 'flex', gap: '8px' } }>
41+
<ShieldIcon variant="default" />
42+
<ShieldIcon variant="success" />
43+
<ShieldIcon variant="warning" />
44+
<ShieldIcon variant="error" />
45+
</div>
46+
<div style={ { display: 'flex', gap: '8px' } }>
47+
<ShieldIcon variant="default" outline />
48+
<ShieldIcon variant="success" outline />
49+
<ShieldIcon variant="warning" outline />
50+
<ShieldIcon variant="error" outline />
51+
</div>
52+
</div>
53+
);
54+
};

projects/js-packages/components/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ export { default as ThemeProvider } from './components/theme-provider';
4747
export { default as ThreatFixerButton } from './components/threat-fixer-button';
4848
export { default as ThreatSeverityBadge } from './components/threat-severity-badge';
4949
export { default as ThreatsDataViews } from './components/threats-data-views';
50+
export { default as ShieldIcon } from './components/shield-icon';
5051
export { default as Text, H2, H3, Title } from './components/text';
5152
export { default as ToggleControl } from './components/toggle-control';
5253
export { default as numberFormat } from './components/number-format';
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
Significance: patch
2+
Type: changed
3+
Comment: Refactored icon component code.
4+
5+

projects/plugins/protect/src/js/components/admin-section-hero/index.tsx

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
1-
import { AdminSectionHero as JetpackAdminSectionHero, H3 } from '@automattic/jetpack-components';
1+
import {
2+
AdminSectionHero as JetpackAdminSectionHero,
3+
H3,
4+
ShieldIcon,
5+
} from '@automattic/jetpack-components';
26
import SeventyFiveLayout from '../seventy-five-layout';
3-
import ShieldIcon from '../shield-icon';
47
import AdminSectionHeroNotices from './admin-section-hero-notices';
58
import styles from './styles.module.scss';
69

@@ -12,7 +15,12 @@ interface AdminSectionHeroProps {
1215
}
1316

1417
interface AdminSectionHeroComponent extends React.FC< AdminSectionHeroProps > {
15-
Heading: React.FC< { children: React.ReactNode; showIcon?: boolean; variant?: string } >;
18+
Heading: React.FC< {
19+
children: React.ReactNode;
20+
showIcon?: boolean;
21+
variant?: 'default' | 'success' | 'error';
22+
outline?: boolean;
23+
} >;
1624
Subheading: React.FC< { children: React.ReactNode } >;
1725
}
1826

@@ -53,8 +61,10 @@ AdminSectionHero.Heading = ( {
5361
{ children }
5462
{ showIcon && (
5563
<ShieldIcon
56-
variant={ `${ variant }-outline` }
57-
fill="#1d2327"
64+
height={ 38 }
65+
variant={ variant }
66+
outline
67+
fill="default"
5868
className={ styles[ 'heading-icon' ] }
5969
/>
6070
) }

projects/plugins/protect/src/js/components/admin-section-hero/styles.module.scss

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
}
1414

1515
.heading-icon {
16-
margin-left: var( --spacing-base ); // 8px
16+
margin-left: calc( var( --spacing-base ) * 1.5 ); // 12px
1717
margin-bottom: calc( var( --spacing-base ) / 2 * -1 ); // -4px
1818
}
1919

@@ -23,4 +23,4 @@
2323

2424
.connection-error-col {
2525
margin-top: calc( var( --spacing-base ) * 3 + 1px ); // 25px
26-
}
26+
}

projects/plugins/protect/src/js/components/alert-icon/index.jsx

Lines changed: 0 additions & 74 deletions
This file was deleted.

projects/plugins/protect/src/js/components/alert-icon/stories/index.stories.jsx

Lines changed: 0 additions & 17 deletions
This file was deleted.

projects/plugins/protect/src/js/components/alert-icon/styles.module.scss

Lines changed: 0 additions & 11 deletions
This file was deleted.

0 commit comments

Comments
 (0)