@nuskin/foundation-ui-components 1.0.0-cft-35.6 → 1.0.0-cft-35.8

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.
Files changed (81) hide show
  1. package/CHANGELOG.md +41 -0
  2. package/package.json +2 -2
  3. package/src/common/banner/NsBanner.spec.tsx +19 -0
  4. package/src/common/banner/NsBanner.stories.tsx +42 -0
  5. package/src/common/banner/NsBanner.styled.tsx +23 -0
  6. package/src/common/banner/NsBanner.tsx +33 -0
  7. package/src/common/banner/index.ts +1 -0
  8. package/src/common/banner/types.d.ts +14 -0
  9. package/src/common/brand-components/{Brand.stories.tsx → NsBrand.stories.tsx} +6 -6
  10. package/src/common/brand-components/{BrandComponent.spec.tsx → NsBrandComponent.spec.tsx} +4 -5
  11. package/src/common/brand-components/{BrandComponent.tsx → NsBrandComponent.tsx} +4 -4
  12. package/src/common/brand-components/{BrandContanier.styled.tsx → NsBrandContanier.styled.tsx} +2 -2
  13. package/src/common/brand-components/index.ts +2 -2
  14. package/src/common/brand-components/types.d.ts +5 -5
  15. package/src/common/button/{Button.spec.tsx → NsButton.spec.tsx} +1 -1
  16. package/src/common/button/{Button.stories.tsx → NsButton.stories.tsx} +8 -8
  17. package/src/common/button/NsButton.styled.tsx +90 -0
  18. package/src/common/button/NsButton.tsx +13 -0
  19. package/src/common/button/index.ts +2 -2
  20. package/src/common/button/types.d.ts +1 -1
  21. package/src/common/card/stories/NsBgCard.stories.tsx +1 -1
  22. package/src/common/card/stories/NsBrandProductCard.stories.tsx +1 -1
  23. package/src/common/carousal/IconWrapper.tsx +1 -1
  24. package/src/common/cart-icon/NsCartIcon.spec.tsx +23 -0
  25. package/src/common/cart-icon/NsCartIcon.stories.tsx +24 -0
  26. package/src/common/cart-icon/NsCartIcon.styled.ts +40 -0
  27. package/src/common/cart-icon/NsCartIcon.tsx +22 -0
  28. package/src/common/cart-icon/index.ts +2 -0
  29. package/src/common/cart-icon/types.d.ts +7 -0
  30. package/src/common/checkbox/NsCheckbox.stories.tsx +1 -1
  31. package/src/common/flag/NsFlag.stories.tsx +1 -1
  32. package/src/common/flag/NsFlag.styled.tsx +13 -7
  33. package/src/common/flag/types.d.ts +2 -2
  34. package/src/common/icon/IconMap.ts +23 -0
  35. package/src/common/icon/NsIcon.spec.tsx +29 -0
  36. package/src/common/icon/NsIcon.stories.tsx +37 -0
  37. package/src/common/icon/NsIcon.styled.tsx +19 -0
  38. package/src/common/icon/NsIcon.tsx +19 -0
  39. package/src/common/icon/icons/Cart.tsx +37 -0
  40. package/src/common/icon/icons/CartBadge.tsx +36 -0
  41. package/src/common/icon/icons/CheckShield.tsx +16 -0
  42. package/src/common/icon/icons/CheckVerified.tsx +16 -0
  43. package/src/common/icon/icons/ErrorIcon.tsx +27 -0
  44. package/src/common/icon/icons/InfoFilled.tsx +16 -0
  45. package/src/common/icon/icons/InfoOutlined.tsx +31 -0
  46. package/src/common/icon/icons/SuccessIcon.tsx +37 -0
  47. package/src/common/icon/icons/TrashIcon.tsx +30 -0
  48. package/src/common/icon/icons/error.svg +3 -0
  49. package/src/common/icon/icons/success.svg +10 -0
  50. package/src/common/icon/icons/trash.svg +3 -0
  51. package/src/common/icon/index.ts +2 -0
  52. package/src/common/icon/types.d.ts +20 -0
  53. package/src/common/index.ts +8 -1
  54. package/src/common/input/InputFieldWrapper.tsx +12 -0
  55. package/src/common/input/InputWrapper.tsx +77 -0
  56. package/src/common/input/NsInputField.spec.tsx +10 -0
  57. package/src/common/input/NsInputField.stories.tsx +48 -0
  58. package/src/common/input/NsInputField.tsx +43 -0
  59. package/src/common/input/getAdornmentProps.tsx +30 -0
  60. package/src/common/input/index.ts +2 -0
  61. package/src/common/input/types.d.ts +13 -0
  62. package/src/common/label/NsLabel.spec.tsx +11 -0
  63. package/src/common/label/NsLabel.stories.tsx +28 -0
  64. package/src/common/label/NsLabel.tsx +35 -0
  65. package/src/common/label/index.ts +2 -0
  66. package/src/common/label/types.d.ts +9 -0
  67. package/src/common/link/NsLink.stories.tsx +4 -4
  68. package/src/common/nav-product-card/NsNavProductCard.stories.tsx +1 -1
  69. package/src/common/nav-tab/NsNavTab.spec.tsx +4 -4
  70. package/src/common/nav-tab/NsNavTab.stories.tsx +3 -3
  71. package/src/common/nav-tab/NsNavTab.styled.tsx +2 -4
  72. package/src/common/nav-tab/NsNavTab.tsx +4 -4
  73. package/src/common/nav-tab/types.d.ts +4 -4
  74. package/src/common/typography/{Typography.spec.tsx → NsTypography.spec.tsx} +22 -4
  75. package/src/common/typography/{Typography.stories.tsx → NsTypography.stories.tsx} +5 -5
  76. package/src/common/typography/{Typography.tsx → NsTypography.tsx} +6 -4
  77. package/src/common/typography/Typography.styled.tsx +7 -4
  78. package/src/common/typography/index.ts +2 -2
  79. package/src/common/typography/types.d.ts +25 -24
  80. package/src/common/button/Button.styled.tsx +0 -80
  81. package/src/common/button/Button.tsx +0 -13
package/CHANGELOG.md CHANGED
@@ -1,3 +1,44 @@
1
+ # [1.0.0-cft-35.8](https://code.tls.nuskin.io/ns-am/content-foundation/foundation-ui-components/compare/v1.0.0-cft-35.7...v1.0.0-cft-35.8) (2023-04-10)
2
+
3
+
4
+ ### Fis
5
+
6
+ * format code ([8587727](https://code.tls.nuskin.io/ns-am/content-foundation/foundation-ui-components/commit/85877278980afed666a55eabd7ba8a86ba14f236))
7
+
8
+ ### Fix
9
+
10
+ * button import name chnaged ([47522e3](https://code.tls.nuskin.io/ns-am/content-foundation/foundation-ui-components/commit/47522e3f8c2e940ac720d204d69448a0b46442ce))
11
+ * conflict ([971e4a5](https://code.tls.nuskin.io/ns-am/content-foundation/foundation-ui-components/commit/971e4a50c88a545f2890a62349f2ebd06759384a))
12
+ * merge issue ([67a72ce](https://code.tls.nuskin.io/ns-am/content-foundation/foundation-ui-components/commit/67a72ce440c27b88a339e68f4c74a39c1c23b9a1))
13
+ * Typography and banner ui updates ([99a8322](https://code.tls.nuskin.io/ns-am/content-foundation/foundation-ui-components/commit/99a8322c968c9b31dca4bc1d0d3652d47a65338b))
14
+
15
+ ### FIX
16
+
17
+ * build issue ([935b132](https://code.tls.nuskin.io/ns-am/content-foundation/foundation-ui-components/commit/935b1322d47841eb554ad514cb9880b9e9f48e52))
18
+ * typo fix ([32d5fa7](https://code.tls.nuskin.io/ns-am/content-foundation/foundation-ui-components/commit/32d5fa7dc09ec60ce3698b6c638ea9351405ef28))
19
+
20
+ ### New
21
+
22
+ * Nsbaner Ui #CFT-118 ([d1896fd](https://code.tls.nuskin.io/ns-am/content-foundation/foundation-ui-components/commit/d1896fd00fc1c7cc22a0db931507ec6096e7fdef)), closes [#CFT-118](https://code.tls.nuskin.io/ns-am/content-foundation/foundation-ui-components/issues/CFT-118)
23
+
24
+ ### Update
25
+
26
+ * Code format ([7244ea1](https://code.tls.nuskin.io/ns-am/content-foundation/foundation-ui-components/commit/7244ea1fcef2bdb75dd45d7af04809e763cff8dd))
27
+
28
+ # [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)
29
+
30
+
31
+ ### Fix
32
+
33
+ * increase test coverage ([91c79cc](https://code.tls.nuskin.io/ns-am/content-foundation/foundation-ui-components/commit/91c79ccc2a07792ed94a232c6e77593e778cb6e1))
34
+ * refactor component hierarchy and naming components ([107eda4](https://code.tls.nuskin.io/ns-am/content-foundation/foundation-ui-components/commit/107eda443a56869deacdb47f822ce4af76b8ce17))
35
+ * story book module fix ([9b77c79](https://code.tls.nuskin.io/ns-am/content-foundation/foundation-ui-components/commit/9b77c79e3507a4f39342378f58d8c0aeb1882c96))
36
+
37
+ ### New
38
+
39
+ * added new NsInputField ([6f6b4a6](https://code.tls.nuskin.io/ns-am/content-foundation/foundation-ui-components/commit/6f6b4a6b0db776427e56bbf6d70885cef5660476))
40
+ * CX130-109 Added common icon component and Cart icon ([6cda585](https://code.tls.nuskin.io/ns-am/content-foundation/foundation-ui-components/commit/6cda58514e3821f886d6d952c8d73751d33e796d))
41
+
1
42
  # [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
43
 
3
44
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nuskin/foundation-ui-components",
3
- "version": "1.0.0-cft-35.6",
3
+ "version": "1.0.0-cft-35.8",
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.10",
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",
@@ -0,0 +1,19 @@
1
+ import React from 'react';
2
+ import { render } from '@testing-library/react';
3
+ import NsBanner from './';
4
+
5
+ describe('Hero component', () => {
6
+ it('renders banner image and title', () => {
7
+ const childText = 'Welcome to My Website';
8
+ const image = 'https://example.com/banner.jpg';
9
+ const { getByAltText, getByText } = render(
10
+ <NsBanner imageUrl={image} altText="Banner image">
11
+ <h1>{childText}</h1>
12
+ </NsBanner>
13
+ );
14
+ const childElement = getByText(childText);
15
+ const imageElement = getByAltText('Banner image');
16
+ expect(childElement).toBeInTheDocument();
17
+ expect(imageElement).toBeInTheDocument();
18
+ });
19
+ });
@@ -0,0 +1,42 @@
1
+ /**
2
+ * @author [Vijayaprathap Kumar] (vpkumar@nuskin.com)
3
+ * NsBanner.stories.tsx
4
+ * @description NsBanner component.
5
+ */
6
+
7
+ import React from 'react';
8
+ import { ComponentStory, ComponentMeta } from '@storybook/react';
9
+
10
+ import Banner from './';
11
+ import Typography from '../typography';
12
+ import Button from '../button/NsButton';
13
+
14
+ export default {
15
+ title: 'Components',
16
+ component: Banner,
17
+ decorators: [(story) => <div style={{ textAlign: 'center', marginTop: '20px' }}>{story()}</div>],
18
+ argTypes: {
19
+ children: {
20
+ control: 'text', // use the text control to edit children prop
21
+ },
22
+ },
23
+ args: {
24
+ imageUrl: 'https://media.nuskin.com/m/e2f6d26058b2e7d/webimage-us-collagen-strawberry-hompage-banner.png',
25
+ altText: 'NsBanner',
26
+ alignment: 'center',
27
+ justify: 'start',
28
+ children: (
29
+ <div>
30
+ <Typography className="w-80" variant="h1" colorOverride="#000000">
31
+ Limited time offers on LumiSpa iO cleansers and bundles!
32
+ </Typography>
33
+ <Typography variant="p-m" className="my-5" colorOverride="#000000">
34
+ Learn more about what I do and how I can help you
35
+ </Typography>
36
+ <Button variant="contained">Contact me</Button>
37
+ </div>
38
+ ),
39
+ },
40
+ } as ComponentMeta<typeof Banner>;
41
+
42
+ export const NsBanner: ComponentStory<typeof Banner> = (args) => <Banner {...args} />;
@@ -0,0 +1,23 @@
1
+ import { styled } from '@nuskin/foundation-theme';
2
+ import { AlignmentType } from './types';
3
+
4
+ export const StyledBanner = styled.section`
5
+ position: relative;
6
+ display: flex;
7
+ justify-content: space-evenly;
8
+ img {
9
+ width: 100%;
10
+ object-fit: cover;
11
+ }
12
+ `;
13
+
14
+ export const StyledHeroText = styled.div<{ $justify: AlignmentType; $alignment: AlignmentType }>`
15
+ height: 100%;
16
+ display: flex;
17
+ width: 100%;
18
+ position: absolute;
19
+ top: 0;
20
+ justify-content: ${({ $justify }) => $justify};
21
+ align-items: ${({ $alignment }) => $alignment};
22
+ text-align: left;
23
+ `;
@@ -0,0 +1,33 @@
1
+ /**
2
+ * @author [Vijayaprathap Kumar] (vpkumar@nuskin.com)
3
+ * NsBanner.tsx
4
+ * @description NsBanner component with a image background
5
+ */
6
+
7
+ import React, { PropsWithChildren } from 'react';
8
+
9
+ import { NsBannerProps } from './types';
10
+ import { StyledBanner, StyledHeroText } from './NsBanner.styled';
11
+
12
+ const NsBanner = (props: PropsWithChildren<NsBannerProps>) => {
13
+ const {
14
+ children,
15
+ imageUrl = '',
16
+ altText = 'NsBanner',
17
+ alignment = 'center',
18
+ justify = 'start',
19
+ className = '',
20
+ additionalProps = {},
21
+ } = props;
22
+
23
+ return (
24
+ <StyledBanner className={className}>
25
+ <img src={imageUrl} alt={altText} id="bgImage" {...additionalProps} />
26
+ <StyledHeroText $alignment={alignment} $justify={justify}>
27
+ <div className="mx-14">{children}</div>
28
+ </StyledHeroText>
29
+ </StyledBanner>
30
+ );
31
+ };
32
+
33
+ export default NsBanner;
@@ -0,0 +1 @@
1
+ export { default } from './NsBanner';
@@ -0,0 +1,14 @@
1
+ import React from 'react';
2
+
3
+ import { AdditionalProps } from '../common.types';
4
+
5
+ export type AlignmentType = 'start' | 'center' | 'end';
6
+
7
+ export type NsBannerProps = {
8
+ children: React.ReactNode;
9
+ imageUrl: string;
10
+ altText?: string;
11
+ alignment?: AlignmentType;
12
+ justify?: AlignmentType;
13
+ className?: string;
14
+ } & AdditionalProps;
@@ -1,10 +1,10 @@
1
1
  import React from 'react';
2
2
  import { ComponentStory, ComponentMeta } from '@storybook/react';
3
- import BrandComponent from './BrandComponent';
3
+ import NsBrandComponent from './NsBrandComponent';
4
4
 
5
5
  export default {
6
- title: 'Components/Brand',
7
- component: BrandComponent,
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 BrandComponent>;
24
+ } as ComponentMeta<typeof NsBrandComponent>;
25
25
 
26
- export const Brand: ComponentStory<typeof BrandComponent> = (args) => (
27
- <BrandComponent {...args} />
26
+ export const Brand: ComponentStory<typeof NsBrandComponent> = (args) => (
27
+ <NsBrandComponent {...args} />
28
28
  );
@@ -1,4 +1,4 @@
1
- import BrandComponent from './BrandComponent';
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
- xit('6. should render BrandComponent with dummy variant', () => {
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 './BrandContanier.styled';
8
- import { BrandComponentProps } from './types';
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 BrandComponent = (props: PropsWithChildren<BrandComponentProps>) => {
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 BrandComponent;
27
+ export default NsBrandComponent;
@@ -1,10 +1,10 @@
1
1
  import { styled } from '@nuskin/foundation-theme';
2
2
 
3
- const BrandContainer = styled.div<{ size: string }>`
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 BrandContainer;
10
+ export default NsBrandContainer;
@@ -1,2 +1,2 @@
1
- export { default } from './BrandComponent';
2
- export type { BrandComponentProps } from './types';
1
+ export { default } from './NsBrandComponent';
2
+ export type { NsBrandComponentProps } from './types';
@@ -1,11 +1,11 @@
1
- import { PaletteColorNames } from '@nuskin/foundation-theme/src/themes/types';
1
+ import { FoundationTheme } from '@nuskin/foundation-theme';
2
2
 
3
- export type BrandComponentProps = {
3
+ export type NsBrandComponentProps = {
4
4
  variant?: 'stacked' | 'horizontal' | 'poweredBy' | 'logomark' | 'wordmark';
5
5
  size?: string;
6
- color?: PaletteColorNames;
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 './Button';
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 Button from './Button';
3
+ import NsButton from './NsButton';
4
4
  import { ShoppingCart } from '@mui/icons-material';
5
5
 
6
6
  export default {
7
- title: 'Components/Button',
8
- component: Button,
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 Button>;
29
+ } as ComponentMeta<typeof NsButton>;
30
30
 
31
- export const button: ComponentStory<typeof Button> = (args) => <Button {...args} />;
31
+ export const button: ComponentStory<typeof NsButton> = (args) => <NsButton {...args} />;
32
32
 
33
- export const IconOnlyButton: ComponentStory<typeof Button> = (args) => (
34
- <Button {...args} iconOnly>
33
+ export const IconOnlyButton: ComponentStory<typeof NsButton> = (args) => (
34
+ <NsButton {...args} iconOnly>
35
35
  <ShoppingCart />
36
- </Button>
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 './Button';
2
- export type { ButtonProps } from './types';
1
+ export { default } from './NsButton';
2
+ export type { NsButtonProps } from './types';
@@ -1,6 +1,6 @@
1
1
  import { ButtonProps as MUIButtonProps } from '@mui/material';
2
2
 
3
- export type ButtonProps = Pick<
3
+ export type NsButtonProps = Pick<
4
4
  MUIButtonProps,
5
5
  | 'size'
6
6
  | 'variant'
@@ -3,7 +3,7 @@ import NsBgCard from '../NsBgCard';
3
3
 
4
4
  export default {
5
5
  component: NsBgCard,
6
- title: 'Components/Card/NsBgCard',
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/Card/NsBrandProductCard',
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;
@@ -0,0 +1,2 @@
1
+ export { default as NsCartIcon } from './NsCartIcon';
2
+ export type { NsCartIconProps } from './types';
@@ -0,0 +1,7 @@
1
+ import { FoundationTheme } from '@nuskin/foundation-theme';
2
+
3
+ export type NsCartIconProps = {
4
+ itemCount: number;
5
+ size?: 'small' | 'medium' | 'large' | 'xLarge';
6
+ color?: FoundationTheme.PaletteColors;
7
+ };
@@ -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: {