@nuskin/foundation-ui-components 1.0.0-cft-35.6 → 1.0.0-cft-35.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +14 -0
- package/package.json +2 -2
- package/src/common/brand-components/{Brand.stories.tsx → NsBrand.stories.tsx} +6 -6
- package/src/common/brand-components/{BrandComponent.spec.tsx → NsBrandComponent.spec.tsx} +4 -5
- package/src/common/brand-components/{BrandComponent.tsx → NsBrandComponent.tsx} +4 -4
- package/src/common/brand-components/{BrandContanier.styled.tsx → NsBrandContanier.styled.tsx} +2 -2
- package/src/common/brand-components/index.ts +2 -2
- package/src/common/brand-components/types.d.ts +5 -5
- package/src/common/button/{Button.spec.tsx → NsButton.spec.tsx} +1 -1
- package/src/common/button/{Button.stories.tsx → NsButton.stories.tsx} +8 -8
- package/src/common/button/NsButton.styled.tsx +90 -0
- package/src/common/button/NsButton.tsx +13 -0
- package/src/common/button/index.ts +2 -2
- package/src/common/button/types.d.ts +1 -1
- package/src/common/card/stories/NsBgCard.stories.tsx +1 -1
- package/src/common/card/stories/NsBrandProductCard.stories.tsx +1 -1
- package/src/common/carousal/IconWrapper.tsx +1 -1
- package/src/common/cart-icon/NsCartIcon.spec.tsx +23 -0
- package/src/common/cart-icon/NsCartIcon.stories.tsx +24 -0
- package/src/common/cart-icon/NsCartIcon.styled.ts +40 -0
- package/src/common/cart-icon/NsCartIcon.tsx +22 -0
- package/src/common/cart-icon/index.ts +2 -0
- package/src/common/cart-icon/types.d.ts +7 -0
- package/src/common/checkbox/NsCheckbox.stories.tsx +1 -1
- package/src/common/flag/NsFlag.stories.tsx +1 -1
- package/src/common/flag/NsFlag.styled.tsx +13 -7
- package/src/common/flag/types.d.ts +2 -2
- package/src/common/icon/IconMap.ts +23 -0
- package/src/common/icon/NsIcon.spec.tsx +29 -0
- package/src/common/icon/NsIcon.stories.tsx +37 -0
- package/src/common/icon/NsIcon.styled.tsx +19 -0
- package/src/common/icon/NsIcon.tsx +19 -0
- package/src/common/icon/icons/Cart.tsx +37 -0
- package/src/common/icon/icons/CartBadge.tsx +36 -0
- package/src/common/icon/icons/CheckShield.tsx +16 -0
- package/src/common/icon/icons/CheckVerified.tsx +16 -0
- package/src/common/icon/icons/ErrorIcon.tsx +27 -0
- package/src/common/icon/icons/InfoFilled.tsx +16 -0
- package/src/common/icon/icons/InfoOutlined.tsx +31 -0
- package/src/common/icon/icons/SuccessIcon.tsx +37 -0
- package/src/common/icon/icons/TrashIcon.tsx +30 -0
- package/src/common/icon/icons/error.svg +3 -0
- package/src/common/icon/icons/success.svg +10 -0
- package/src/common/icon/icons/trash.svg +3 -0
- package/src/common/icon/index.ts +2 -0
- package/src/common/icon/types.d.ts +20 -0
- package/src/common/index.ts +5 -1
- package/src/common/input/InputFieldWrapper.tsx +12 -0
- package/src/common/input/InputWrapper.tsx +77 -0
- package/src/common/input/NsInputField.spec.tsx +10 -0
- package/src/common/input/NsInputField.stories.tsx +48 -0
- package/src/common/input/NsInputField.tsx +43 -0
- package/src/common/input/getAdornmentProps.tsx +30 -0
- package/src/common/input/index.ts +2 -0
- package/src/common/input/types.d.ts +13 -0
- package/src/common/label/NsLabel.spec.tsx +11 -0
- package/src/common/label/NsLabel.stories.tsx +28 -0
- package/src/common/label/NsLabel.tsx +35 -0
- package/src/common/label/index.ts +2 -0
- package/src/common/label/types.d.ts +9 -0
- package/src/common/link/NsLink.stories.tsx +4 -4
- package/src/common/nav-product-card/NsNavProductCard.stories.tsx +1 -1
- package/src/common/nav-tab/NsNavTab.spec.tsx +4 -4
- package/src/common/nav-tab/NsNavTab.stories.tsx +3 -3
- package/src/common/nav-tab/NsNavTab.styled.tsx +2 -4
- package/src/common/nav-tab/NsNavTab.tsx +1 -1
- package/src/common/nav-tab/types.d.ts +4 -4
- package/src/common/typography/{Typography.spec.tsx → NsTypography.spec.tsx} +22 -4
- package/src/common/typography/{Typography.stories.tsx → NsTypography.stories.tsx} +5 -5
- package/src/common/typography/{Typography.tsx → NsTypography.tsx} +4 -4
- package/src/common/typography/Typography.styled.tsx +8 -4
- package/src/common/typography/index.ts +2 -2
- package/src/common/typography/types.d.ts +24 -24
- package/src/common/button/Button.styled.tsx +0 -80
- package/src/common/button/Button.tsx +0 -13
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,17 @@
|
|
|
1
|
+
# [1.0.0-cft-35.7](https://code.tls.nuskin.io/ns-am/content-foundation/foundation-ui-components/compare/v1.0.0-cft-35.6...v1.0.0-cft-35.7) (2023-04-10)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Fix
|
|
5
|
+
|
|
6
|
+
* increase test coverage ([91c79cc](https://code.tls.nuskin.io/ns-am/content-foundation/foundation-ui-components/commit/91c79ccc2a07792ed94a232c6e77593e778cb6e1))
|
|
7
|
+
* refactor component hierarchy and naming components ([107eda4](https://code.tls.nuskin.io/ns-am/content-foundation/foundation-ui-components/commit/107eda443a56869deacdb47f822ce4af76b8ce17))
|
|
8
|
+
* story book module fix ([9b77c79](https://code.tls.nuskin.io/ns-am/content-foundation/foundation-ui-components/commit/9b77c79e3507a4f39342378f58d8c0aeb1882c96))
|
|
9
|
+
|
|
10
|
+
### New
|
|
11
|
+
|
|
12
|
+
* added new NsInputField ([6f6b4a6](https://code.tls.nuskin.io/ns-am/content-foundation/foundation-ui-components/commit/6f6b4a6b0db776427e56bbf6d70885cef5660476))
|
|
13
|
+
* CX130-109 Added common icon component and Cart icon ([6cda585](https://code.tls.nuskin.io/ns-am/content-foundation/foundation-ui-components/commit/6cda58514e3821f886d6d952c8d73751d33e796d))
|
|
14
|
+
|
|
1
15
|
# [1.0.0-cft-35.6](https://code.tls.nuskin.io/ns-am/content-foundation/foundation-ui-components/compare/v1.0.0-cft-35.5...v1.0.0-cft-35.6) (2023-03-30)
|
|
2
16
|
|
|
3
17
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nuskin/foundation-ui-components",
|
|
3
|
-
"version": "1.0.0-cft-35.
|
|
3
|
+
"version": "1.0.0-cft-35.7",
|
|
4
4
|
"description": "It is a foundation library written in react, that provides commom components to all UI pages",
|
|
5
5
|
"private": false,
|
|
6
6
|
"main": "src/common/index.ts",
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
"@mui/icons-material": "^5.11.11",
|
|
40
40
|
"@mui/material": "5.4.2",
|
|
41
41
|
"@next/font": "13.2.4",
|
|
42
|
-
"@nuskin/foundation-theme": "1.0.0-cft-33.
|
|
42
|
+
"@nuskin/foundation-theme": "1.0.0-cft-33.12",
|
|
43
43
|
"@types/jest": "^29.5.0",
|
|
44
44
|
"framer-motion": "^10.8.5",
|
|
45
45
|
"next": "13.2.4",
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { ComponentStory, ComponentMeta } from '@storybook/react';
|
|
3
|
-
import
|
|
3
|
+
import NsBrandComponent from './NsBrandComponent';
|
|
4
4
|
|
|
5
5
|
export default {
|
|
6
|
-
title: 'Components/
|
|
7
|
-
component:
|
|
6
|
+
title: 'Components/NsBrandComponent',
|
|
7
|
+
component: NsBrandComponent,
|
|
8
8
|
decorators: [
|
|
9
9
|
(story) => (
|
|
10
10
|
<div style={{ textAlign: 'center', marginTop: '20px' }}>{story()}</div>
|
|
@@ -21,8 +21,8 @@ export default {
|
|
|
21
21
|
size: '100px',
|
|
22
22
|
variant: 'stacked',
|
|
23
23
|
},
|
|
24
|
-
} as ComponentMeta<typeof
|
|
24
|
+
} as ComponentMeta<typeof NsBrandComponent>;
|
|
25
25
|
|
|
26
|
-
export const Brand: ComponentStory<typeof
|
|
27
|
-
<
|
|
26
|
+
export const Brand: ComponentStory<typeof NsBrandComponent> = (args) => (
|
|
27
|
+
<NsBrandComponent {...args} />
|
|
28
28
|
);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import BrandComponent from './
|
|
1
|
+
import BrandComponent from './NsBrandComponent';
|
|
2
2
|
import { render } from '@testing-library/react';
|
|
3
3
|
|
|
4
4
|
describe('checking brand component', () => {
|
|
@@ -37,12 +37,11 @@ describe('checking brand component', () => {
|
|
|
37
37
|
expect(paths.length).toBe(17);
|
|
38
38
|
});
|
|
39
39
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
const { getByTestId } = render(<BrandComponent variant="dummy" />);
|
|
40
|
+
it('6. should render BrandComponent with dummy variant', () => {
|
|
41
|
+
const { getByTestId } = render(<BrandComponent />);
|
|
43
42
|
const svg = getByTestId('logo');
|
|
44
43
|
const paths = svg.querySelectorAll('path');
|
|
45
44
|
expect(paths.length).toBe(8);
|
|
46
45
|
});
|
|
47
|
-
|
|
46
|
+
|
|
48
47
|
});
|
|
@@ -4,8 +4,8 @@ import NSLogoMark from './icons/NSLogoMark';
|
|
|
4
4
|
import NSLogoPoweredBy from './icons/NSLogoPoweredBy';
|
|
5
5
|
import NSLogoStacked from './icons/NSLogoStacked';
|
|
6
6
|
import NSLogoWordMark from './icons/NSWordMark';
|
|
7
|
-
import LogoContainer from './
|
|
8
|
-
import {
|
|
7
|
+
import LogoContainer from './NsBrandContanier.styled';
|
|
8
|
+
import { NsBrandComponentProps } from './types';
|
|
9
9
|
|
|
10
10
|
const VariantMap = {
|
|
11
11
|
stacked: NSLogoStacked,
|
|
@@ -15,7 +15,7 @@ const VariantMap = {
|
|
|
15
15
|
poweredBy: NSLogoPoweredBy,
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
-
const
|
|
18
|
+
const NsBrandComponent = (props: PropsWithChildren<NsBrandComponentProps>) => {
|
|
19
19
|
const { variant = 'stacked', size = '108px', color = 'primary' } = props;
|
|
20
20
|
const renderBrand = useCallback(() => {
|
|
21
21
|
const BrandComponent = VariantMap[variant || 'stacked'];
|
|
@@ -24,4 +24,4 @@ const BrandComponent = (props: PropsWithChildren<BrandComponentProps>) => {
|
|
|
24
24
|
return <LogoContainer size={size}>{renderBrand()}</LogoContainer>;
|
|
25
25
|
};
|
|
26
26
|
|
|
27
|
-
export default
|
|
27
|
+
export default NsBrandComponent;
|
package/src/common/brand-components/{BrandContanier.styled.tsx → NsBrandContanier.styled.tsx}
RENAMED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { styled } from '@nuskin/foundation-theme';
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const NsBrandContainer = styled.div<{ size: string }>`
|
|
4
4
|
svg {
|
|
5
5
|
font-size: ${({ size }) => size};
|
|
6
6
|
height: auto;
|
|
7
7
|
}
|
|
8
8
|
`;
|
|
9
9
|
|
|
10
|
-
export default
|
|
10
|
+
export default NsBrandContainer;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { default } from './
|
|
2
|
-
export type {
|
|
1
|
+
export { default } from './NsBrandComponent';
|
|
2
|
+
export type { NsBrandComponentProps } from './types';
|
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { FoundationTheme } from '@nuskin/foundation-theme';
|
|
2
2
|
|
|
3
|
-
export type
|
|
3
|
+
export type NsBrandComponentProps = {
|
|
4
4
|
variant?: 'stacked' | 'horizontal' | 'poweredBy' | 'logomark' | 'wordmark';
|
|
5
5
|
size?: string;
|
|
6
|
-
color?:
|
|
7
|
-
}
|
|
6
|
+
color?: FoundationTheme.PaletteColors;
|
|
7
|
+
};
|
|
8
8
|
|
|
9
9
|
export type SVGLogoProps = {
|
|
10
10
|
color: string;
|
|
11
|
-
}
|
|
11
|
+
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { render, screen } from '../../../test-utils/index';
|
|
3
3
|
import nuskinTheme from '@nuskin/foundation-theme/src/themes/genome-foundation';
|
|
4
|
-
import Button from './
|
|
4
|
+
import Button from './NsButton';
|
|
5
5
|
|
|
6
6
|
const { palette } = nuskinTheme;
|
|
7
7
|
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { ComponentStory, ComponentMeta } from '@storybook/react';
|
|
3
|
-
import
|
|
3
|
+
import NsButton from './NsButton';
|
|
4
4
|
import { ShoppingCart } from '@mui/icons-material';
|
|
5
5
|
|
|
6
6
|
export default {
|
|
7
|
-
title: 'Components/
|
|
8
|
-
component:
|
|
7
|
+
title: 'Components/NsButton',
|
|
8
|
+
component: NsButton,
|
|
9
9
|
decorators: [(story) => <div style={{ textAlign: 'center', marginTop: '20px' }}>{story()}</div>],
|
|
10
10
|
argTypes: {
|
|
11
11
|
children: {
|
|
@@ -26,14 +26,14 @@ export default {
|
|
|
26
26
|
variant: 'contained',
|
|
27
27
|
fullWidth: false,
|
|
28
28
|
},
|
|
29
|
-
} as ComponentMeta<typeof
|
|
29
|
+
} as ComponentMeta<typeof NsButton>;
|
|
30
30
|
|
|
31
|
-
export const button: ComponentStory<typeof
|
|
31
|
+
export const button: ComponentStory<typeof NsButton> = (args) => <NsButton {...args} />;
|
|
32
32
|
|
|
33
|
-
export const IconOnlyButton: ComponentStory<typeof
|
|
34
|
-
<
|
|
33
|
+
export const IconOnlyButton: ComponentStory<typeof NsButton> = (args) => (
|
|
34
|
+
<NsButton {...args} iconOnly>
|
|
35
35
|
<ShoppingCart />
|
|
36
|
-
</
|
|
36
|
+
</NsButton>
|
|
37
37
|
);
|
|
38
38
|
|
|
39
39
|
IconOnlyButton.argTypes = {
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { Button as MUIButton } from '@mui/material';
|
|
2
|
+
|
|
3
|
+
import { styled, ColorUtils, FoundationTheme } from '@nuskin/foundation-theme';
|
|
4
|
+
import { ButtonConfig } from '@nuskin/foundation-theme/src/themes/types/button';
|
|
5
|
+
import { NsButtonProps } from './types';
|
|
6
|
+
|
|
7
|
+
const {
|
|
8
|
+
getPaletteColor,
|
|
9
|
+
getButtonStateColor,
|
|
10
|
+
} = ColorUtils;
|
|
11
|
+
|
|
12
|
+
const getButtonConfig = (theme: FoundationTheme.Theme, attribute: keyof ButtonConfig) => {
|
|
13
|
+
const { config } = theme || {};
|
|
14
|
+
return config?.components?.button?.[attribute] || '';
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
const StyledButton = styled(MUIButton)<NsButtonProps>`
|
|
18
|
+
gap: 10px;
|
|
19
|
+
border-radius: ${({ theme}) => getButtonConfig(theme, 'borderRadius')} || 0;
|
|
20
|
+
:focus {
|
|
21
|
+
border: 1px solid ${({ theme}) => getButtonConfig(theme, 'focusColor')} !important;
|
|
22
|
+
}
|
|
23
|
+
:disabled {
|
|
24
|
+
background-color: ${({ theme, color }) => getButtonStateColor(theme, color, 'disabled')};
|
|
25
|
+
color: ${({ theme, color }) => getButtonStateColor(theme, color, 'disabledText')};
|
|
26
|
+
}
|
|
27
|
+
${({ theme: { config }, size }) => {
|
|
28
|
+
return size === 'medium' ? config?.components?.button?.size?.medium?.padding : ''
|
|
29
|
+
}}
|
|
30
|
+
${({ theme: { config}, size }) => {
|
|
31
|
+
return size === 'large' ? config?.components?.button?.size?.large?.padding : ''
|
|
32
|
+
}}
|
|
33
|
+
${({ variant, theme, color = 'primary' }) => {
|
|
34
|
+
return variant === 'contained' ?
|
|
35
|
+
`
|
|
36
|
+
background-color: ${getPaletteColor(theme, color)};
|
|
37
|
+
:hover {
|
|
38
|
+
background-color: ${getButtonStateColor(theme, color, 'hovered')};
|
|
39
|
+
}
|
|
40
|
+
:active {
|
|
41
|
+
background-color: ${getButtonStateColor(theme, color, 'pressed')};
|
|
42
|
+
}
|
|
43
|
+
:focus {
|
|
44
|
+
background-color: ${getButtonStateColor(theme, color, 'focused')};
|
|
45
|
+
}
|
|
46
|
+
`
|
|
47
|
+
: ''
|
|
48
|
+
}}
|
|
49
|
+
${({ variant, theme, color = 'primary' }) =>
|
|
50
|
+
variant === 'outlined' &&
|
|
51
|
+
`
|
|
52
|
+
border-color: ${getPaletteColor(theme, color)};
|
|
53
|
+
color: ${getPaletteColor(theme, color)};
|
|
54
|
+
:hover {
|
|
55
|
+
border-color: ${getButtonStateColor(theme, color, 'hovered')};
|
|
56
|
+
color: ${getPaletteColor(theme, color)};
|
|
57
|
+
}
|
|
58
|
+
:active {
|
|
59
|
+
border-color: ${getButtonStateColor(theme, color, 'pressed')};
|
|
60
|
+
color: ${getPaletteColor(theme, color)};
|
|
61
|
+
}
|
|
62
|
+
`}
|
|
63
|
+
${({ variant, theme, color = 'primary' }) =>
|
|
64
|
+
variant === 'text' &&
|
|
65
|
+
`
|
|
66
|
+
text-decoration: underline 1px !important;
|
|
67
|
+
text-underline-offset: 4px;
|
|
68
|
+
padding: 0;
|
|
69
|
+
min-width: auto;
|
|
70
|
+
background-color: transparent !important;
|
|
71
|
+
text-decoration-color: ${getPaletteColor(theme, color)};
|
|
72
|
+
color: ${getPaletteColor(theme, color)};
|
|
73
|
+
:hover {
|
|
74
|
+
color: ${getButtonStateColor(theme, color, 'hovered')};
|
|
75
|
+
text-decoration-color: ${getButtonStateColor(theme, color, 'hovered')};
|
|
76
|
+
}
|
|
77
|
+
:active {
|
|
78
|
+
color: ${getPaletteColor(theme, color)};
|
|
79
|
+
text-decoration-color: ${getButtonStateColor(theme, color, 'pressed')};
|
|
80
|
+
}
|
|
81
|
+
`}
|
|
82
|
+
${({ iconOnly }) =>
|
|
83
|
+
iconOnly &&
|
|
84
|
+
`
|
|
85
|
+
padding: 10px;
|
|
86
|
+
min-width: unset;
|
|
87
|
+
`}
|
|
88
|
+
`;
|
|
89
|
+
|
|
90
|
+
export default StyledButton;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { PropsWithChildren } from 'react';
|
|
2
|
+
import StyledButton from './NsButton.styled';
|
|
3
|
+
import { NsButtonProps } from './types';
|
|
4
|
+
|
|
5
|
+
const NsButton = ({ children, ...props }: PropsWithChildren<NsButtonProps>) => {
|
|
6
|
+
return (
|
|
7
|
+
<StyledButton {...props} disableRipple>
|
|
8
|
+
{children}
|
|
9
|
+
</StyledButton>
|
|
10
|
+
);
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export default NsButton;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { default } from './
|
|
2
|
-
export type {
|
|
1
|
+
export { default } from './NsButton';
|
|
2
|
+
export type { NsButtonProps } from './types';
|
|
@@ -3,7 +3,7 @@ import NsBgCard from '../NsBgCard';
|
|
|
3
3
|
|
|
4
4
|
export default {
|
|
5
5
|
component: NsBgCard,
|
|
6
|
-
title: 'Components/
|
|
6
|
+
title: 'Components/NsCard/NsBgCard',
|
|
7
7
|
argTypes: {},
|
|
8
8
|
decorators: [(story) => <div style={{ textAlign: 'center', marginTop: '20px' }}>{story()}</div>],
|
|
9
9
|
} as ComponentMeta<typeof NsBgCard>;
|
|
@@ -3,7 +3,7 @@ import NsBrandProductCard from '../NsBrandProductCard';
|
|
|
3
3
|
|
|
4
4
|
export default {
|
|
5
5
|
component: NsBrandProductCard,
|
|
6
|
-
title: 'Components/
|
|
6
|
+
title: 'Components/NsCard/NsBrandProductCard',
|
|
7
7
|
argTypes: {},
|
|
8
8
|
decorators: [(story) => <div style={{ textAlign: 'center', marginTop: '20px' }}>{story()}</div>],
|
|
9
9
|
} as ComponentMeta<typeof NsBrandProductCard>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { PropsWithChildren } from 'react';
|
|
2
2
|
import { styled } from '@nuskin/foundation-theme';
|
|
3
3
|
import { Box } from '@mui/material';
|
|
4
|
-
|
|
4
|
+
// TODO: check if this can be updated with NsIcon
|
|
5
5
|
type IconWrapperProps = PropsWithChildren<{
|
|
6
6
|
onClick(): void;
|
|
7
7
|
className?: string;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { NsCartIcon } from './';
|
|
2
|
+
import { render } from '../../../test-utils';
|
|
3
|
+
|
|
4
|
+
describe('NsCartIcon', () => {
|
|
5
|
+
it('renders Cart icon when item count is 0', () => {
|
|
6
|
+
const { getByTestId } = render(<NsCartIcon itemCount={0} color="primary" size="large" />);
|
|
7
|
+
const cartIcon = getByTestId('cart-icon');
|
|
8
|
+
expect(cartIcon).toBeInTheDocument();
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
it('renders Cart Badge icon when item count is greater than 0', () => {
|
|
12
|
+
const { getByTestId } = render(<NsCartIcon itemCount={5} color="primary" size="large" />);
|
|
13
|
+
const cartBadgeIcon = getByTestId('cart-badge-icon');
|
|
14
|
+
expect(cartBadgeIcon).toBeInTheDocument();
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('renders item count badge when item count is greater than 0', () => {
|
|
18
|
+
const { getByTestId } = render(<NsCartIcon itemCount={5} color="primary" size="large" />);
|
|
19
|
+
const itemCountBadge = getByTestId('item-count-badge');
|
|
20
|
+
expect(itemCountBadge).toBeInTheDocument();
|
|
21
|
+
expect(itemCountBadge.textContent).toBe('5');
|
|
22
|
+
});
|
|
23
|
+
});
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ComponentStory, ComponentMeta } from '@storybook/react';
|
|
3
|
+
import { NsCartIcon } from './';
|
|
4
|
+
|
|
5
|
+
export default {
|
|
6
|
+
title: 'Components/NsCartIcon',
|
|
7
|
+
component: NsCartIcon,
|
|
8
|
+
decorators: [(story) => <div style={{ textAlign: 'center', marginTop: '20px' }}>{story()}</div>],
|
|
9
|
+
argTypes: {
|
|
10
|
+
itemCount: { control: 'number', defaultValue: 1 },
|
|
11
|
+
size: { control: 'select', options: ['small', 'medium', 'large', 'xLarge'] },
|
|
12
|
+
color: {
|
|
13
|
+
control: 'select',
|
|
14
|
+
options: ['primary', 'secondary', 'success', 'error', 'warning', 'info'],
|
|
15
|
+
},
|
|
16
|
+
},
|
|
17
|
+
args: {
|
|
18
|
+
itemCount: 1,
|
|
19
|
+
color: 'primary',
|
|
20
|
+
size: 'large',
|
|
21
|
+
},
|
|
22
|
+
} as ComponentMeta<typeof NsCartIcon>;
|
|
23
|
+
|
|
24
|
+
export const CartIcon: ComponentStory<typeof NsCartIcon> = (args) => <NsCartIcon {...args} />;
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { Theme } from '@mui/material';
|
|
2
|
+
import { styled, FoundationTheme } from '@nuskin/foundation-theme';
|
|
3
|
+
import { NsIconSizeType } from '../icon/types';
|
|
4
|
+
|
|
5
|
+
type ItemCountParams = {
|
|
6
|
+
size: NsIconSizeType;
|
|
7
|
+
color: FoundationTheme.PaletteColors;
|
|
8
|
+
theme?: Theme;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
export const CartIconContainer = styled.div`
|
|
12
|
+
position: relative;
|
|
13
|
+
display: inline-block;
|
|
14
|
+
`;
|
|
15
|
+
|
|
16
|
+
const BadgeFontSizeMap = {
|
|
17
|
+
small: '8px',
|
|
18
|
+
medium: '10px',
|
|
19
|
+
large: '12px',
|
|
20
|
+
xLarge: '14px',
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const BadgePosMap = {
|
|
24
|
+
small: '-8px',
|
|
25
|
+
medium: '-6px',
|
|
26
|
+
large: '-4px',
|
|
27
|
+
xLarge: '-1px',
|
|
28
|
+
};
|
|
29
|
+
|
|
30
|
+
export const ItemCount = styled.span<ItemCountParams>`
|
|
31
|
+
color: ${({ color, theme }) => theme?.palette?.[color]?.main};
|
|
32
|
+
font-size: ${({ size }) => BadgeFontSizeMap[size]};
|
|
33
|
+
right: ${({ size }) => BadgePosMap[size]};
|
|
34
|
+
text-align: center;
|
|
35
|
+
font-weight: 600;
|
|
36
|
+
position: absolute;
|
|
37
|
+
width: 32px;
|
|
38
|
+
height: auto;
|
|
39
|
+
top: -4px;
|
|
40
|
+
`;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { NsIcon } from '../icon';
|
|
2
|
+
import { CartIconContainer, ItemCount } from './NsCartIcon.styled';
|
|
3
|
+
import { NsCartIconProps } from './types';
|
|
4
|
+
|
|
5
|
+
const NsCartIcon = ({ itemCount, size = 'large', color = 'primary' }: NsCartIconProps) => {
|
|
6
|
+
return (
|
|
7
|
+
<CartIconContainer>
|
|
8
|
+
{itemCount > 0 ? (
|
|
9
|
+
<NsIcon testId="cart-badge-icon" name="cartBadge" color={color} size={size} />
|
|
10
|
+
) : (
|
|
11
|
+
<NsIcon testId="cart-icon" name="cart" color={color} size={size} />
|
|
12
|
+
)}
|
|
13
|
+
{itemCount > 0 && (
|
|
14
|
+
<ItemCount data-testid="item-count-badge" color={color} size={size}>
|
|
15
|
+
{itemCount}
|
|
16
|
+
</ItemCount>
|
|
17
|
+
)}
|
|
18
|
+
</CartIconContainer>
|
|
19
|
+
);
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
export default NsCartIcon;
|
|
@@ -11,7 +11,7 @@ import NsCheckbox from './NsCheckbox';
|
|
|
11
11
|
|
|
12
12
|
// In this case, we're only passing the label prop.
|
|
13
13
|
export default {
|
|
14
|
-
title: 'Components',
|
|
14
|
+
title: 'Components/NsCheckbox',
|
|
15
15
|
component: NsCheckbox,
|
|
16
16
|
decorators: [(story) => <div style={{ textAlign: 'center', marginTop: '20px' }}>{story()}</div>],
|
|
17
17
|
argTypes: {
|
|
@@ -4,7 +4,7 @@ import { ComponentStory, ComponentMeta } from '@storybook/react';
|
|
|
4
4
|
import NsFlag from './NsFlag';
|
|
5
5
|
|
|
6
6
|
export default {
|
|
7
|
-
title: 'Components',
|
|
7
|
+
title: 'Components/NsFlag',
|
|
8
8
|
component: NsFlag,
|
|
9
9
|
decorators: [(story) => <div style={{ textAlign: 'center', marginTop: '20px' }}>{story()}</div>],
|
|
10
10
|
argTypes: {
|
|
@@ -5,14 +5,13 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { Theme } from '@mui/material';
|
|
8
|
-
import { styled } from '@nuskin/foundation-theme';
|
|
9
|
-
import { PaletteColorNames } from '@nuskin/foundation-theme/src/themes/types';
|
|
8
|
+
import { styled, ColorUtils, FoundationTheme } from '@nuskin/foundation-theme';
|
|
10
9
|
|
|
11
10
|
import { NsFlagSize } from './types';
|
|
12
11
|
|
|
13
12
|
type NsFlagThemeParams = {
|
|
14
13
|
$size: NsFlagSize;
|
|
15
|
-
$bgColor?:
|
|
14
|
+
$bgColor?: FoundationTheme.PaletteColors;
|
|
16
15
|
theme?: Theme;
|
|
17
16
|
};
|
|
18
17
|
|
|
@@ -34,15 +33,22 @@ const makeFlagSize = ({ $size }: { $size: NsFlagSize }) => {
|
|
|
34
33
|
return sizeValue / FLAG_SCALE_VALUE;
|
|
35
34
|
};
|
|
36
35
|
|
|
37
|
-
const
|
|
38
|
-
|
|
36
|
+
const {
|
|
37
|
+
getPaletteColor,
|
|
38
|
+
} = ColorUtils;
|
|
39
|
+
|
|
40
|
+
const makeFlagBorder = ({ $size, $bgColor = 'accentColorA', theme}: NsFlagThemeParams) => {
|
|
41
|
+
if (theme) {
|
|
42
|
+
return `${makeFlagSize({ $size })}px solid ${getPaletteColor(theme, $bgColor)}`;
|
|
43
|
+
}
|
|
44
|
+
return '';
|
|
39
45
|
};
|
|
40
46
|
|
|
41
47
|
export const StyledFlag = styled('span')<NsFlagThemeParams>`
|
|
42
48
|
min-width: 29px;
|
|
43
49
|
height: ${getFlagHeight}px;
|
|
44
|
-
color: ${({ $bgColor = 'accentColorA', theme }) => theme
|
|
45
|
-
background: ${({ $bgColor = 'accentColorA', theme }) => theme
|
|
50
|
+
color: ${({ $bgColor = 'accentColorA', theme }) => getPaletteColor(theme, $bgColor, 'contrastText')};
|
|
51
|
+
background: ${({ $bgColor = 'accentColorA', theme }) => getPaletteColor(theme, $bgColor)};
|
|
46
52
|
position: relative;
|
|
47
53
|
padding: 0 15px;
|
|
48
54
|
display: inline-grid;
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* @description Extend the FlagProps interface to include message, color and size prop.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import {
|
|
7
|
+
import { FoundationTheme } from '@nuskin/foundation-theme';
|
|
8
8
|
|
|
9
9
|
export type NsFlagSize = 'small' | 'medium' | 'large';
|
|
10
10
|
|
|
@@ -14,5 +14,5 @@ export type NsFlagProps = {
|
|
|
14
14
|
message?: string;
|
|
15
15
|
testId?: string;
|
|
16
16
|
/** Displays background color for flag container */
|
|
17
|
-
color?:
|
|
17
|
+
color?: FoundationTheme.PaletteColors;
|
|
18
18
|
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import Cart from './icons/Cart';
|
|
2
|
+
import CartBadge from './icons/CartBadge';
|
|
3
|
+
import InfoFilled from './icons/InfoFilled';
|
|
4
|
+
import InfoOutlined from './icons/InfoOutlined';
|
|
5
|
+
import CheckShield from './icons/CheckShield';
|
|
6
|
+
import CheckVerified from './icons/CheckVerified';
|
|
7
|
+
import SuccessIcon from './icons/SuccessIcon';
|
|
8
|
+
import ErrorIcon from './icons/ErrorIcon';
|
|
9
|
+
import TrashIcon from './icons/TrashIcon';
|
|
10
|
+
|
|
11
|
+
const IconVariants = {
|
|
12
|
+
cart: Cart,
|
|
13
|
+
cartBadge: CartBadge,
|
|
14
|
+
checkShield: CheckShield,
|
|
15
|
+
checkVerified: CheckVerified,
|
|
16
|
+
error: ErrorIcon,
|
|
17
|
+
infoFilled: InfoFilled,
|
|
18
|
+
infoOutlined: InfoOutlined,
|
|
19
|
+
success: SuccessIcon,
|
|
20
|
+
trash: TrashIcon,
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export default IconVariants;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render } from '../../../test-utils';
|
|
3
|
+
import { NsIcon } from './';
|
|
4
|
+
|
|
5
|
+
describe('NsIcon Component', () => {
|
|
6
|
+
it('renders cartBadge icon with custom size and color', () => {
|
|
7
|
+
const { getByTestId } = render(<NsIcon name="cart" size="medium" color="secondary" />);
|
|
8
|
+
const icon = getByTestId('icon');
|
|
9
|
+
const svgIcon = icon.querySelector('svg');
|
|
10
|
+
expect(svgIcon).toHaveClass('MuiSvgIcon-colorSecondary');
|
|
11
|
+
expect(svgIcon).toHaveClass('MuiSvgIcon-fontSizeMedium');
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it('renders with custom testId', () => {
|
|
15
|
+
const { getByTestId } = render(<NsIcon name="cart" testId="custom-icon" />);
|
|
16
|
+
const icon = getByTestId('custom-icon');
|
|
17
|
+
expect(icon).toBeInTheDocument();
|
|
18
|
+
expect(icon.innerHTML).toContain('svg');
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
it('throws an error if invalid icon name is provided', () => {
|
|
22
|
+
const consoleErrorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
|
23
|
+
// @ts-ignore
|
|
24
|
+
const { queryByTestId } = render(<NsIcon name="invalidIcon" />);
|
|
25
|
+
expect(queryByTestId('icon')).not.toBeInTheDocument();
|
|
26
|
+
expect(consoleErrorSpy).not.toHaveBeenCalled();
|
|
27
|
+
consoleErrorSpy.mockRestore();
|
|
28
|
+
});
|
|
29
|
+
});
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { ComponentStory, ComponentMeta } from '@storybook/react';
|
|
3
|
+
import { NsIcon } from './';
|
|
4
|
+
|
|
5
|
+
export default {
|
|
6
|
+
title: 'Components/NsIcon',
|
|
7
|
+
component: NsIcon,
|
|
8
|
+
decorators: [(story) => <div style={{ textAlign: 'center', marginTop: '20px' }}>{story()}</div>],
|
|
9
|
+
argTypes: {
|
|
10
|
+
size: { control: 'select', options: ['small', 'medium', 'large', 'xLarge'] },
|
|
11
|
+
name: {
|
|
12
|
+
control: 'select',
|
|
13
|
+
options: [
|
|
14
|
+
'cart',
|
|
15
|
+
'cartBadge',
|
|
16
|
+
'checkShield',
|
|
17
|
+
'checkVerified',
|
|
18
|
+
'error',
|
|
19
|
+
'infoFilled',
|
|
20
|
+
'infoOutlined',
|
|
21
|
+
'success',
|
|
22
|
+
'trash',
|
|
23
|
+
],
|
|
24
|
+
},
|
|
25
|
+
color: {
|
|
26
|
+
control: 'select',
|
|
27
|
+
options: ['primary', 'secondary', 'success', 'error', 'warning', 'info'],
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
args: {
|
|
31
|
+
size: 'large',
|
|
32
|
+
name: 'checkShield',
|
|
33
|
+
color: 'success',
|
|
34
|
+
},
|
|
35
|
+
} as ComponentMeta<typeof NsIcon>;
|
|
36
|
+
|
|
37
|
+
export const Icon: ComponentStory<typeof NsIcon> = (args) => <NsIcon {...args} />;
|