@nuskin/foundation-ui-components 1.0.2 → 1.1.1

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 (161) hide show
  1. package/package.json +105 -101
  2. package/src/common/accordion/NsAccordion.tsx +32 -40
  3. package/src/common/accordion/NsAccordionHeader.tsx +29 -8
  4. package/src/common/accordion/NsAccordionItem.tsx +24 -4
  5. package/src/common/accordion/NsCollapse.tsx +96 -35
  6. package/src/common/accordion/NsToggleSection.tsx +16 -3
  7. package/src/common/accordion/ToggleSection.styled.tsx +11 -7
  8. package/src/common/accordion/colorMap.ts +117 -0
  9. package/src/common/accordion/enums.ts +18 -0
  10. package/src/common/accordion/index.ts +1 -0
  11. package/src/common/accordion/specs/NsAccordion.spec.tsx +101 -31
  12. package/src/common/accordion/specs/NsAccordionHeader.spec.tsx +77 -10
  13. package/src/common/accordion/specs/NsAccordionItem.spec.tsx +27 -10
  14. package/src/common/accordion/specs/NsCollapse.spec.tsx +109 -17
  15. package/src/common/accordion/specs/NsToggleSection.spec.tsx +50 -14
  16. package/src/common/accordion/stories/NsAccordion.stories.tsx +32 -14
  17. package/src/common/accordion/stories/NsAccordionHeader.stories.tsx +6 -2
  18. package/src/common/accordion/stories/NsAccordionItem.stories.tsx +9 -4
  19. package/src/common/accordion/stories/NsCollapse.stories.tsx +20 -5
  20. package/src/common/accordion/stories/NsToggleSection.stories.tsx +7 -4
  21. package/src/common/accordion/stories/data.tsx +140 -19
  22. package/src/common/accordion/types.d.ts +55 -47
  23. package/src/common/alert/Header.tsx +29 -0
  24. package/src/common/alert/NsAlert.spec.tsx +46 -13
  25. package/src/common/alert/NsAlert.stories.tsx +3 -3
  26. package/src/common/alert/{NsAlert.styled.ts → NsAlert.styled.tsx} +22 -22
  27. package/src/common/alert/NsAlert.tsx +22 -87
  28. package/src/common/alert/types.d.ts +7 -7
  29. package/src/common/auth-dropdown/NsAuthDropdown.spec.tsx +23 -5
  30. package/src/common/auth-dropdown/NsAuthDropdown.stories.tsx +1 -1
  31. package/src/common/auth-dropdown/NsAuthDropdown.styled.ts +11 -7
  32. package/src/common/auth-dropdown/NsAuthDropdown.tsx +4 -4
  33. package/src/common/autocomplete/NsAutocomplete.spec.tsx +34 -11
  34. package/src/common/autocomplete/NsAutocomplete.stories.tsx +19 -3
  35. package/src/common/autocomplete/NsAutocomplete.tsx +63 -24
  36. package/src/common/autocomplete/mock/MockData.ts +50 -7
  37. package/src/common/autocomplete/mock/MockUI.tsx +2 -1
  38. package/src/common/autocomplete/types.d.ts +7 -4
  39. package/src/common/banner/NsBanner.spec.tsx +12 -3
  40. package/src/common/banner/NsBanner.stories.tsx +1 -1
  41. package/src/common/brand-components/NsBrand.stories.tsx +1 -1
  42. package/src/common/brand-components/NsBrandComponent.tsx +2 -2
  43. package/src/common/breadcrumb/NsBreadcrumb.spec.tsx +8 -3
  44. package/src/common/breadcrumb/NsBreadcrumb.stories.tsx +1 -1
  45. package/src/common/breadcrumb/data.ts +8 -5
  46. package/src/common/button/NsButton.spec.tsx +65 -49
  47. package/src/common/button/NsButton.stories.tsx +59 -2
  48. package/src/common/button/NsButton.styled.tsx +49 -66
  49. package/src/common/button/NsButton.tsx +1 -2
  50. package/src/common/button/helper.ts +82 -0
  51. package/src/common/button/types.d.ts +2 -0
  52. package/src/common/card/NsFfgCard.tsx +13 -7
  53. package/src/common/card/specs/NsFfgCard.spec.tsx +18 -8
  54. package/src/common/card/stories/NsBgCard.stories.tsx +1 -1
  55. package/src/common/card/stories/NsBrandProductCard.stories.tsx +1 -1
  56. package/src/common/card/stories/NsFfgCard.stories.tsx +48 -15
  57. package/src/common/card/styled/NsFfgStyled.tsx +10 -7
  58. package/src/common/card/types.d.ts +7 -4
  59. package/src/common/carousal/NsCarousal.tsx +3 -9
  60. package/src/common/carousal/stories/NSCarousal.stories.tsx +1 -1
  61. package/src/common/carousal/stories/NsScrollingCarousal.stories.tsx +1 -1
  62. package/src/common/cart-icon/NsCartIcon.spec.tsx +5 -16
  63. package/src/common/cart-icon/NsCartIcon.stories.tsx +2 -2
  64. package/src/common/cart-icon/NsCartIcon.styled.ts +7 -33
  65. package/src/common/cart-icon/NsCartIcon.tsx +5 -14
  66. package/src/common/cart-icon/types.d.ts +1 -0
  67. package/src/common/checkbox/NsCheckbox.stories.tsx +1 -1
  68. package/src/common/checkbox/NsCheckbox.styled.tsx +15 -16
  69. package/src/common/checkbox/NsCheckbox.tsx +1 -1
  70. package/src/common/column-control/stories/DivArray.stories.tsx +1 -1
  71. package/src/common/column-control/stories/NsColumnControl.stories.tsx +1 -1
  72. package/src/common/column-control/stories/NsFlexColumns.stories.tsx +1 -1
  73. package/src/common/column-control/stories/NsGridColumns.stories.tsx +1 -1
  74. package/src/common/column-control/styled/common.ts +1 -1
  75. package/src/common/column-control/utils.ts +4 -4
  76. package/src/common/common.types.d.ts +14 -5
  77. package/src/common/dropdown/NsDropdown.styled.tsx +23 -18
  78. package/src/common/dropdown/stories/NsDropdown.stories.tsx +1 -1
  79. package/src/common/dropdown/stories/NsDropdownCountry.stories.tsx +1 -1
  80. package/src/common/flag/NsFlag.stories.tsx +1 -1
  81. package/src/common/hooks/index.ts +2 -0
  82. package/src/common/hooks/specs/useWindowSize.spec.tsx +19 -0
  83. package/src/common/hooks/useAccordionMap.tsx +39 -0
  84. package/src/common/hooks/useWindowSize.tsx +30 -0
  85. package/src/common/icon/NsIcon.spec.tsx +1 -1
  86. package/src/common/icon/NsIcon.stories.tsx +4 -1
  87. package/src/common/icon/NsIcon.tsx +6 -2
  88. package/src/common/icon/NsIconVariants.ts +4 -1
  89. package/src/common/icon/icons/AlertErrorIcon.tsx +2 -2
  90. package/src/common/icon/icons/ArrowLeft.tsx +3 -6
  91. package/src/common/icon/icons/ArrowRight.tsx +6 -8
  92. package/src/common/icon/icons/Cart.tsx +7 -32
  93. package/src/common/icon/icons/CartBadge.tsx +2 -2
  94. package/src/common/icon/icons/CloseIcon.tsx +1 -1
  95. package/src/common/icon/icons/ErrorIcon.tsx +2 -2
  96. package/src/common/icon/icons/HamburgerIcon.tsx +5 -2
  97. package/src/common/icon/icons/SearchIcon.tsx +1 -1
  98. package/src/common/icon/icons/SuccessIcon.tsx +2 -7
  99. package/src/common/icon/icons/TrashIcon.tsx +1 -1
  100. package/src/common/icon/icons/UserIcon.tsx +3 -6
  101. package/src/common/icon/icons/UserOutline.tsx +24 -0
  102. package/src/common/icon/icons/WarningIcon.tsx +1 -1
  103. package/src/common/icon/icons/home.tsx +1 -1
  104. package/src/common/image/NsImage.spec.tsx +56 -6
  105. package/src/common/image/NsImage.stories.tsx +1 -1
  106. package/src/common/image/NsImage.tsx +23 -11
  107. package/src/common/image/NsNextImage.stories.tsx +1 -1
  108. package/src/common/index.ts +6 -2
  109. package/src/common/input/InputWrapper.tsx +12 -7
  110. package/src/common/input/NsInputField.tsx +1 -1
  111. package/src/common/label/NsLabel.stories.tsx +1 -1
  112. package/src/common/link/NsLink.stories.tsx +1 -1
  113. package/src/common/modal/NsModal.spec.tsx +46 -0
  114. package/src/common/modal/NsModal.styled.tsx +28 -0
  115. package/src/common/modal/NsModal.tsx +37 -0
  116. package/src/common/modal/helper-component/NsModalContentBox.tsx +32 -0
  117. package/src/common/modal/helper-component/NsModalDefault.tsx +25 -0
  118. package/src/common/modal/helper-component/NsModalStatus.tsx +15 -0
  119. package/src/common/modal/helper-component/NsModalStatusIcon.tsx +14 -0
  120. package/src/common/modal/helper-component/NsModalTitle.tsx +26 -0
  121. package/src/common/modal/index.ts +2 -0
  122. package/src/common/modal/model/NsModalVariantMap.tsx +24 -0
  123. package/src/common/modal/stories/NsModal.stories.tsx +85 -0
  124. package/src/common/modal/stories/mock.tsx +46 -0
  125. package/src/common/modal/types.ts +56 -0
  126. package/src/common/nav-product-card/NsNavProductCard.stories.tsx +1 -1
  127. package/src/common/nav-tab/NavDrawer.tsx +34 -0
  128. package/src/common/nav-tab/NavTitles.tsx +52 -0
  129. package/src/common/nav-tab/NsNavTab.spec.tsx +4 -5
  130. package/src/common/nav-tab/NsNavTab.stories.tsx +4 -4
  131. package/src/common/nav-tab/NsNavTab.styled.tsx +13 -7
  132. package/src/common/nav-tab/NsNavTab.tsx +21 -75
  133. package/src/common/nav-tab/index.ts +1 -1
  134. package/src/common/nav-tab/types.d.ts +3 -3
  135. package/src/common/radiogroup/NsRadioGroup.spec.tsx +24 -25
  136. package/src/common/radiogroup/NsRadioGroup.stories.tsx +14 -32
  137. package/src/common/radiogroup/NsRadioGroup.styled.tsx +20 -19
  138. package/src/common/radiogroup/NsRadioGroup.tsx +6 -5
  139. package/src/common/search-bar/NsSearchBar.tsx +1 -3
  140. package/src/common/select/NsSelect.spec.tsx +10 -17
  141. package/src/common/select/NsSelect.styled.tsx +53 -34
  142. package/src/common/select/stories/NsSelect.stories.tsx +11 -11
  143. package/src/common/select/types.d.ts +3 -3
  144. package/src/common/spinner/NsSpinner.spec.tsx +21 -0
  145. package/src/common/spinner/NsSpinner.stories.tsx +26 -0
  146. package/src/common/spinner/NsSpinner.styled.tsx +344 -0
  147. package/src/common/spinner/NsSpinner.tsx +14 -0
  148. package/src/common/spinner/icons/Spinner.tsx +161 -0
  149. package/src/common/spinner/index.ts +2 -0
  150. package/src/common/spinner/types.ts +5 -0
  151. package/src/common/table/NsTable.stories.tsx +1 -1
  152. package/src/common/table/NsTable.tsx +32 -49
  153. package/src/common/table/NsTableHeader.tsx +30 -51
  154. package/src/common/text-strip/NsTextStrip.stories.tsx +1 -1
  155. package/src/common/typography/NsTypography.stories.tsx +1 -1
  156. package/src/common/util.ts +1 -0
  157. package/src/common/utility/Show.tsx +13 -0
  158. package/src/common/utility/index.ts +1 -0
  159. package/src/common/videos/NsVideo.stories.tsx +1 -1
  160. package/src/common/videos/types.d.ts +1 -1
  161. /package/src/common/brand-components/{NsBrandContanier.styled.tsx → NsBrandContainer.styled.tsx} +0 -0
@@ -1,8 +1,6 @@
1
1
  import { Box } from '@mui/material';
2
2
  import { styled } from '@nuskin/foundation-theme';
3
3
 
4
- const options = {};
5
-
6
4
  const Component = () => {
7
5
  return {
8
6
  backgroundClip: 'border-box',
@@ -10,9 +8,10 @@ const Component = () => {
10
8
  border: '1px solid #eff2f7',
11
9
  borderRadius: '1rem',
12
10
  boxShadow: '0 0.75rem 1.5rem rgba(18, 38, 63, .03)',
11
+ cursor: 'pointer',
13
12
  display: 'flex',
14
13
  flexDirection: 'column' as 'column', // https://github.com/cssinjs/jss/issues/1344
15
- marginBottom: '2rem',
14
+ marginBottom: '16px',
16
15
  transition: 'all .2s ease',
17
16
  textAlign: 'center' as 'center',
18
17
  wordWrap: 'break-word' as 'break-word',
@@ -22,15 +21,19 @@ const Component = () => {
22
21
  '.action-link': {
23
22
  color: '#2CD5C4',
24
23
  textDecoration: 'none',
24
+ fontWeight: 600,
25
25
  },
26
26
  },
27
27
  '.body-text': {
28
- padding: '0 1.5rem 3rem',
29
- fontSize: '1rem',
28
+ padding: '0 1.5rem 4rem',
29
+ fontSize: '16px',
30
30
  color: '#8492a6',
31
31
  },
32
32
  '.top-image': {
33
- padding: '1.5rem 3rem',
33
+ padding: '3rem 1.5rem',
34
+ img: {
35
+ maxWidth: '100%',
36
+ },
34
37
  },
35
38
  '.action-link': {
36
39
  color: '#3c4858',
@@ -41,4 +44,4 @@ const Component = () => {
41
44
  },
42
45
  };
43
46
  };
44
- export const NsFfgStyled = styled(Box, options)<{}>(Component);
47
+ export const NsFfgStyled = styled(Box)(Component);
@@ -1,9 +1,12 @@
1
- import { AdditionalProps } from '../common.types';
2
-
1
+ import { AdditionalProps, CslpTag } from '../common.types';
3
2
  export type NsFfgCardProps = AdditionalProps & {
4
3
  topImageUrl: string;
5
4
  topImageAlt: string;
6
5
  text: string;
7
- actionLink: string;
8
- actionText?: string;
6
+ cardLink: { href: string; title: string };
7
+ onClick(): void;
8
+ cslp?: {
9
+ card_text: CslpTag;
10
+ action_text: CslpTag;
11
+ };
9
12
  };
@@ -1,11 +1,12 @@
1
1
  import Box from '@mui/material/Box';
2
2
  import { styled } from '@nuskin/foundation-theme';
3
- import { useRef, useCallback, ReactNode } from 'react';
3
+ import { useRef, useCallback } from 'react';
4
4
  import Slider from 'react-slick';
5
5
  import 'slick-carousel/slick/slick.css';
6
6
  import 'slick-carousel/slick/slick-theme.css';
7
7
  import defaultCarousalSettings from './slickSetting';
8
8
  import CarousalControl from './CarousalControl';
9
+ import { NsCarousalProps } from './types';
9
10
 
10
11
  const SlickContainer = styled(Box)(() => {
11
12
  return {
@@ -16,15 +17,8 @@ const SlickContainer = styled(Box)(() => {
16
17
  },
17
18
  };
18
19
  });
19
- interface CarousalProps<T = any> {
20
- entries: T[];
21
- // eslint-disable-next-line no-unused-vars
22
- renderEntry(entry: T, index: number): ReactNode;
23
- allEntryLink: string;
24
- settings: any;
25
- }
26
20
 
27
- export default function NsCarousal({ entries, renderEntry, allEntryLink, settings }: CarousalProps) {
21
+ export default function NsCarousal({ entries, renderEntry, allEntryLink, settings }: NsCarousalProps) {
28
22
  const sliderRef = useRef();
29
23
  const prev = useCallback(() => {
30
24
  if (sliderRef.current) {
@@ -9,7 +9,7 @@ type Story = StoryObj<ComponentType>;
9
9
  type MetaStory = Meta<ComponentType>;
10
10
 
11
11
  export default {
12
- title: 'Components/NsCarousal/Brand',
12
+ title: 'Components/Containers/NsCarousal/Brand',
13
13
  component: NsCarousal,
14
14
  argTypes: {},
15
15
  } as MetaStory;
@@ -34,7 +34,7 @@ export const slides = [
34
34
  },
35
35
  ];
36
36
  export default {
37
- title: 'Components/NsCarousal/NsScrollingCarousal',
37
+ title: 'Components/Containers/NsCarousal/NsScrollingCarousal',
38
38
  component: NsScrollingCarousal,
39
39
  decorators: [withCenterDecorator],
40
40
  argTypes: {},
@@ -5,25 +5,14 @@ const { getByTestId } = screen;
5
5
  describe('NsCartIcon', () => {
6
6
  it('renders Cart icon when item count is 0', () => {
7
7
  render(<NsCartIcon itemCount={0} color="primary" size="large" />);
8
- const cartIcon = getByTestId('cart-icon');
8
+ const cartIcon = getByTestId('cart-badge-icon');
9
9
  expect(cartIcon).toBeInTheDocument();
10
10
  });
11
- it('renders Cart icon with optional values', () => {
12
- render(<NsCartIcon itemCount={0} />);
13
- const cartIcon = getByTestId('cart-icon');
14
- expect(cartIcon).toBeInTheDocument();
15
- });
16
-
17
- it('renders Cart Badge icon when item count is greater than 0', () => {
18
- render(<NsCartIcon itemCount={5} color="primary" size="large" />);
19
- const cartBadgeIcon = getByTestId('cart-badge-icon');
20
- expect(cartBadgeIcon).toBeInTheDocument();
21
- });
22
11
 
23
12
  it('renders item count badge when item count is greater than 0', () => {
24
- render(<NsCartIcon itemCount={5} color="primary" size="large" />);
25
- const itemCountBadge = getByTestId('item-count-badge');
26
- expect(itemCountBadge).toBeInTheDocument();
27
- expect(itemCountBadge.textContent).toBe('5');
13
+ const itemCount = 5;
14
+ const { getByText } = render(<NsCartIcon itemCount={5} color="primary" size="large" />);
15
+ const badgeContentElement = getByText(itemCount.toString());
16
+ expect(badgeContentElement).toHaveTextContent('5'); // Adjust the value as per your badge content
28
17
  });
29
18
  });
@@ -7,7 +7,7 @@ type Story = StoryObj<ComponentType>;
7
7
  type MetaStory = Meta<ComponentType>;
8
8
 
9
9
  export default {
10
- title: 'Components/NsCartIcon',
10
+ title: 'Components/Data Display/NsCartIcon',
11
11
  component: NsCartIcon,
12
12
  decorators: [withCenterDecorator],
13
13
  argTypes: {
@@ -19,7 +19,7 @@ export default {
19
19
  },
20
20
  },
21
21
  args: {
22
- itemCount: 1,
22
+ itemCount: 5,
23
23
  color: 'primary',
24
24
  size: 'large',
25
25
  },
@@ -1,40 +1,14 @@
1
- import { Theme } from '@mui/material';
1
+ import { Badge, Theme } from '@mui/material';
2
2
  import { styled, FoundationTheme } from '@nuskin/foundation-theme';
3
- import { NsIconSizeType } from '../icon/types';
4
3
 
5
4
  type ItemCountParams = {
6
- size: NsIconSizeType;
7
- color: FoundationTheme.PaletteColors;
8
5
  theme?: Theme;
6
+ bgcolor: FoundationTheme.PaletteColors;
9
7
  };
10
8
 
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;
9
+ export const StyledBadge = styled(Badge) <ItemCountParams>`
10
+ & .MuiBadge-badge {
11
+ background-color: ${({ bgcolor, theme }) => theme?.palette?.[bgcolor]?.main};
12
+ color: ${({ bgcolor, theme }) => theme?.palette?.[bgcolor]?.contrastText};
13
+ }
40
14
  `;
@@ -1,21 +1,12 @@
1
1
  import { NsIcon } from '../icon';
2
- import { CartIconContainer, ItemCount } from './NsCartIcon.styled';
2
+ import { StyledBadge } from './NsCartIcon.styled';
3
3
  import { NsCartIconProps } from './types.d';
4
4
 
5
- const NsCartIcon = ({ itemCount, size = 'large', color = 'primary' }: NsCartIconProps) => {
5
+ const NsCartIcon = ({ itemCount = 0, size = 'large', color = 'primary', maxItemCount = 999 }: NsCartIconProps) => {
6
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>
7
+ <StyledBadge badgeContent={itemCount} max={maxItemCount} bgcolor={color}>
8
+ <NsIcon testId="cart-badge-icon" name="cart" size={size} color={color} />
9
+ </StyledBadge>
19
10
  );
20
11
  };
21
12
 
@@ -4,4 +4,5 @@ export type NsCartIconProps = {
4
4
  itemCount: number;
5
5
  size?: 'small' | 'medium' | 'large' | 'xLarge';
6
6
  color?: FoundationTheme.PaletteColors;
7
+ maxItemCount?:number;
7
8
  };
@@ -13,7 +13,7 @@ type MetaStory = Meta<ComponentType>;
13
13
  const labelText = 'Checkbox Label';
14
14
  // In this case, we're only passing the label prop.
15
15
  export default {
16
- title: 'Components/NsCheckbox',
16
+ title: 'Components/Inputs/NsCheckbox',
17
17
  component: NsCheckbox,
18
18
  decorators: [withCenterDecorator],
19
19
  argTypes: {
@@ -1,19 +1,18 @@
1
1
  /**
2
2
  * @author [vijayaprathap Kumar] (vpkumar@nuskin.com)
3
- * checkbox.tsx
4
3
  * @description Styled Components for Checkbox
5
4
  */
6
5
  import DoneIcon from '@mui/icons-material/Done';
7
6
 
8
- import { styled } from '@nuskin/foundation-theme';
7
+ import { styled, ColorUtils } from '@nuskin/foundation-theme';
9
8
  import { NsFlag } from '../flag';
10
-
9
+ const { paletteColor, buttonColor } = ColorUtils;
11
10
  /**
12
11
  * Wrapper BpIcon for checkbox.tsx
13
12
  * @params ( theme: { palette }) / Provide the color's to contaier from @nuskin/foundation-theme
14
13
  */
15
14
 
16
- export const BpIcon = styled(DoneIcon)(({ theme: { palette } }) => ({
15
+ export const BpIcon = styled(DoneIcon)(({ theme }) => ({
17
16
  border: '1px solid #8C8C8C',
18
17
  path: {
19
18
  display: 'none',
@@ -25,31 +24,31 @@ export const BpIcon = styled(DoneIcon)(({ theme: { palette } }) => ({
25
24
  outline: '3px solid #94D6E9',
26
25
  },
27
26
  'input:disabled ~ &': {
28
- background: palette?.primary?.buttonState?.hovered,
27
+ background: buttonColor('primary', 'hovered')({ theme }),
29
28
  },
30
29
  }));
31
30
 
32
31
  /**
33
32
  * Wrapper BpCheckedIcon for checkbox.tsx
34
- * @params ( theme: { palette }) / Provide the color's to contaier from @nuskin/foundation-theme
33
+ * @params ( theme: { palette }) / Provide the color's to container from @nuskin/foundation-theme
35
34
  */
36
35
 
37
- export const BpCheckedIcon = styled(BpIcon)(({ theme: { palette } }) => ({
36
+ export const BpCheckedIcon = styled(BpIcon)(({ theme }) => ({
38
37
  path: {
39
38
  display: 'block',
40
39
  },
41
- background: palette?.primary?.main ?? '#fff',
42
- color: palette?.primary?.contrastText ?? '#000',
40
+ background: paletteColor('primary', 'main')({ theme }),
41
+ color: paletteColor('primary', 'contrastText')({ theme }),
43
42
  }));
44
43
 
45
- export const StyledLabel = styled('span')<{ $hasDisabled: boolean }>`
46
- ${({ $hasDisabled, theme: { palette } }) =>
47
- $hasDisabled &&
48
- `
49
- color: ${palette?.primary?.buttonState?.hovered};
50
- `}
51
- `;
44
+ const getLabelColor = (isDisabled: boolean, color: string) => (!isDisabled ? '' : `color: ${color}`);
52
45
 
46
+ export const StyledLabel = styled('span')<{ isDisabled: boolean }>`
47
+ ${({ isDisabled, theme }) => {
48
+ const color = buttonColor('primary', 'hovered')({ theme });
49
+ return getLabelColor(isDisabled, color);
50
+ }}
51
+ `;
53
52
  export const StyledFlagLabel = styled(NsFlag)`
54
53
  margin-right: 16px;
55
54
  `;
@@ -54,7 +54,7 @@ const NsCheckbox = (props: PropsWithChildren<NsCheckboxProps>) => {
54
54
  () => (
55
55
  <NsTypography variant="p-l">
56
56
  <StyledFlagLabel {...flag} size={size} testId={`${name}-flag-label`} />
57
- <StyledLabel className="checkbox-label-text" $hasDisabled={disabled}>
57
+ <StyledLabel className="checkbox-label-text" isDisabled={disabled}>
58
58
  {label}
59
59
  </StyledLabel>
60
60
  </NsTypography>
@@ -7,7 +7,7 @@ type Story = StoryObj<ComponentType>;
7
7
  type MetaStory = Meta<ComponentType>;
8
8
 
9
9
  export default {
10
- title: 'Components/Column/NDivs',
10
+ title: 'Components/Data Display/Column/NDivs',
11
11
  component: DivArray,
12
12
  decorators: [withCenterDecorator],
13
13
  args: {
@@ -9,7 +9,7 @@ type Story = StoryObj<ComponentType>;
9
9
  type MetaStory = Meta<ComponentType>;
10
10
 
11
11
  export default {
12
- title: 'Components/Column/NsColumnControl',
12
+ title: 'Components/Data Display/Column/NsColumnControl',
13
13
  component: NsColumnControl,
14
14
  decorators: [withCenterDecorator],
15
15
  argTypes: {
@@ -9,7 +9,7 @@ type Story = StoryObj<ComponentType>;
9
9
  type MetaStory = Meta<ComponentType>;
10
10
 
11
11
  export default {
12
- title: 'Components/Column/NsFlexColumns',
12
+ title: 'Components/Data Display/Column/NsFlexColumns',
13
13
  component: NsFlexColumns,
14
14
  decorators: [withCenterDecorator],
15
15
  argTypes: {
@@ -9,7 +9,7 @@ type Story = StoryObj<ComponentType>;
9
9
  type MetaStory = Meta<ComponentType>;
10
10
 
11
11
  export default {
12
- title: 'Components/Column/NsGridColumns',
12
+ title: 'Components/Data Display/Column/NsGridColumns',
13
13
  component: NsGridColumns,
14
14
  decorators: [withCenterDecorator],
15
15
  argTypes: {
@@ -21,7 +21,7 @@ export const commonStyles = {
21
21
  ['1','2'] => ['27%','53%']
22
22
  */
23
23
  export function getPercentArray(fractionArray?: string[] | number[]) {
24
- let numbers = fractionArray?.map((numberString) => +numberString)?.filter((num) => 0 < num && num < 10) ?? [];
24
+ const numbers = fractionArray?.map((numberString) => +numberString)?.filter((num) => 0 < num && num < 10) ?? [];
25
25
  const sum = numbers.reduce((currentSum, currentNumber) => currentSum + currentNumber, 0);
26
26
  return numbers.map((currentNumber) => ((currentNumber / sum) * 80).toFixed(2) + '%');
27
27
  }
@@ -40,15 +40,15 @@ const sizeKeyMap: Record<ValueOf<typeof sizeKeyPrefix>, string> = {
40
40
  * @returns {fractions:['1','1','1'], tabletFractions:['1','1'], mobileFractions:['1'] }
41
41
  */
42
42
  export const getColumnSizes = (inputColumnClass: string): sizeObjectType => {
43
- let columnClass = inputColumnClass.trim() as NsColumnControlProps['columnClass'];
43
+ const columnClass = inputColumnClass.trim();
44
44
  const validClasses = columnClass
45
45
  .split(' ')
46
46
  .filter((e) => Object.values(sizeKeyPrefix).some((prefix) => e.startsWith(prefix)));
47
47
  const sizeObject: sizeObjectType = validClasses.reduce((acc: any, current: string) => {
48
- for (let key of Object.values(sizeKeyPrefix)) {
48
+ for (const key of Object.values(sizeKeyPrefix)) {
49
49
  if (current.startsWith(key)) {
50
- let interClass = current.replace(key, '');
51
- let sizes = interClass.split('-').filter((e) => /^[1-9]$/.test(e));
50
+ const interClass = current.replace(key, '');
51
+ const sizes = interClass.split('-').filter((e) => /^[1-9]$/.test(e));
52
52
  acc[sizeKeyMap[key]] = sizes;
53
53
  break;
54
54
  }
@@ -1,12 +1,21 @@
1
- export type ContentStackLiveTags = {
2
- 'data-cslp'?: string;
3
- };
1
+ import { FoundationTheme } from '@nuskin/foundation-theme';
2
+
3
+ export type CslpTag = { 'data-cslp': string };
4
4
 
5
5
  export type AdditionalProps = {
6
- darkModeEnabled?: boolean;
7
6
  additionalProps?: {
8
7
  ariaLabel?: string;
9
8
  testid?: string;
10
9
  className?: string;
11
- } & ContentStackLiveTags;
10
+ 'data-testid'?: string;
11
+ } & Partial<CslpTag>;
12
+ cslp?: Record<string, CslpTag>;
13
+ } & DarkModeEnabledOption;
14
+
15
+ export type Themed = {
16
+ theme: FoundationTheme.Theme;
17
+ };
18
+
19
+ export type DarkModeEnabledOption = {
20
+ darkModeEnabled?: boolean;
12
21
  };
@@ -1,5 +1,6 @@
1
1
  import { styled, ColorUtils, FoundationTheme } from '@nuskin/foundation-theme';
2
- const { getPaletteColor, getAppColor } = ColorUtils;
2
+ import { Themed } from '../common.types';
3
+ const { color, paletteColor, isDarkMode } = ColorUtils;
3
4
 
4
5
  export const DropdownContainer = styled.div<{ disabled: boolean }>`
5
6
  position: relative;
@@ -7,15 +8,22 @@ export const DropdownContainer = styled.div<{ disabled: boolean }>`
7
8
  opacity: ${({ disabled }) => (disabled ? '0.5' : '1')};
8
9
  `;
9
10
 
11
+ /** this function also used for SelectHead */
12
+ export const getDropdownHeadBorder = ({ type, theme }: { type: string } & Themed) => {
13
+ if (type === 'outlined') {
14
+ const borderColor = color('primary', 'black')({ theme });
15
+ return `1px solid ${borderColor}`;
16
+ }
17
+ return 'none';
18
+ };
10
19
  export const DropdownHead = styled.div<{ type: string; disabled: boolean }>`
11
20
  cursor: ${({ disabled }) => (disabled ? 'inherit' : 'pointer')};
12
21
  padding: 5px 10px;
13
22
  display: flex;
14
23
  justify-content: space-between;
15
24
  align-items: center;
16
- border: ${({ type, theme }) =>
17
- type === 'outlined' ? `1px solid ${getAppColor(theme, 'primary', 'black')}` : 'none'};
18
- color: ${({ theme }) => getPaletteColor(theme, 'primary')};
25
+ border: ${getDropdownHeadBorder}
26
+ color: ${paletteColor('primary')};
19
27
  `;
20
28
 
21
29
  export const DropdownButton = styled.div`
@@ -25,27 +33,19 @@ export const DropdownButton = styled.div`
25
33
  export const DropdownList = styled.div<{ borderColor: FoundationTheme.PaletteColors }>`
26
34
  position: absolute;
27
35
  z-index: 100;
28
- border: 1px solid ${({ borderColor, theme }) => getPaletteColor(theme, borderColor)};
36
+ border: 1px solid ${({ borderColor, theme }) => paletteColor(borderColor)({ theme })};
29
37
  padding: 0;
30
38
  margin: 0;
31
39
  width: 100%;
32
- color: ${({ theme }) => getPaletteColor(theme, 'primary', 'main')};
33
- background-color: ${({ theme }) => getPaletteColor(theme, 'primary', 'contrastText')};
40
+ color: ${paletteColor('primary', 'main')};
41
+ background-color: ${paletteColor('primary', 'contrastText')};
34
42
  `;
35
- const getIsLight = (theme: FoundationTheme.Theme) => {
36
- const { palette = { primary: { main: '', contrastText: '' } } } = theme;
37
- return palette.primary.main === getAppColor(theme, 'primary', 'black');
38
- };
39
43
 
40
44
  const getDividerColor = (theme: FoundationTheme.Theme) => {
41
- const isLight = getIsLight(theme);
42
- const dividerColor = isLight ? getAppColor(theme, 'neutral', '30') : getAppColor(theme, 'neutral', '20');
43
- return dividerColor;
45
+ return color('neutral', isDarkMode({ theme }) ? '20' : '30')({ theme });
44
46
  };
45
47
  const getListBgColor = (theme: FoundationTheme.Theme) => {
46
- const isLight = getIsLight(theme);
47
- const bgColor = isLight ? getAppColor(theme, 'accentColorB', '10') : getAppColor(theme, 'accentColorB', '50');
48
- return bgColor;
48
+ return color('accentColorB', isDarkMode({ theme }) ? '50' : '10')({ theme });
49
49
  };
50
50
  export const ListItemContainer = styled.div<{ showListDivider: boolean }>`
51
51
  cursor: pointer;
@@ -61,7 +61,12 @@ export const ListItemContainer = styled.div<{ showListDivider: boolean }>`
61
61
  }
62
62
  `;
63
63
 
64
+ const getBorder = ({ isSelected, theme }: { isSelected: boolean } & Themed) => {
65
+ const borderColor = paletteColor('primary')({ theme });
66
+ return isSelected ? `2px solid ${borderColor}` : 'none';
67
+ };
68
+
64
69
  export const ListItem = styled.span<{ isSelected: boolean }>`
65
70
  padding: 5px 10px;
66
- border-left: ${({ isSelected, theme }) => (isSelected ? `2px solid ${getPaletteColor(theme, 'primary')}` : 'none')};
71
+ border-left: ${getBorder};
67
72
  `;
@@ -8,7 +8,7 @@ type Story = StoryObj<ComponentType>;
8
8
  type MetaStory = Meta<ComponentType>;
9
9
 
10
10
  export default {
11
- title: 'Components/NsDropdown',
11
+ title: 'Components/Inputs/NsDropdown',
12
12
  decorators: [withCenterDecorator],
13
13
  component: NsDropdown,
14
14
  argTypes: {
@@ -8,7 +8,7 @@ type Story = StoryObj<ComponentType>;
8
8
  type MetaStory = Meta<ComponentType>;
9
9
 
10
10
  export default {
11
- title: 'Components/NsDropdown',
11
+ title: 'Components/Inputs/NsDropdown',
12
12
  decorators: [withCenterDecorator],
13
13
  component: NsDropdown,
14
14
  argTypes: {
@@ -7,7 +7,7 @@ type Story = StoryObj<ComponentType>;
7
7
  type MetaStory = Meta<ComponentType>;
8
8
 
9
9
  export default {
10
- title: 'Components/NsFlag',
10
+ title: 'Components/Data Display/NsFlag',
11
11
  component: NsFlag,
12
12
  decorators: [withCenterDecorator],
13
13
  argTypes: {
@@ -0,0 +1,2 @@
1
+ export {default as useWindowSize} from './useWindowSize';
2
+ export {default as useAccordionMap} from './useAccordionMap';
@@ -0,0 +1,19 @@
1
+ import { renderHook, act } from '@testing-library/react-hooks';
2
+ import useWindowSize from '../useWindowSize';
3
+
4
+ describe('useWindowSize', () => {
5
+ it('should return the window size', () => {
6
+ const { result } = renderHook(useWindowSize);
7
+ expect(result.current).toEqual({ width: window.innerWidth, height: window.innerHeight });
8
+ });
9
+
10
+ it('should update the window size when the window is resized', () => {
11
+ const { result } = renderHook(() => useWindowSize());
12
+ act(() => {
13
+ window.innerWidth = 500;
14
+ window.innerHeight = 500;
15
+ window.dispatchEvent(new Event('resize'));
16
+ });
17
+ expect(result.current).toEqual({ width: 500, height: 500 });
18
+ });
19
+ });
@@ -0,0 +1,39 @@
1
+ import { useState, useEffect, useCallback } from 'react';
2
+
3
+ type ItemMap = Record<string, boolean>;
4
+ type UseAccordionProp = {
5
+ allowMultipleExpanded?: boolean;
6
+ defaultOpenIds?: string[];
7
+ };
8
+ const reducer = (map: ItemMap, id: string) => {
9
+ map[id] = true;
10
+ return map;
11
+ };
12
+
13
+ const useAccordionMap = ({ allowMultipleExpanded, defaultOpenIds }: UseAccordionProp) => {
14
+ const mapSetter = useCallback(() => {
15
+ let ids = defaultOpenIds;
16
+ if (!allowMultipleExpanded) {
17
+ ids = ids?.slice(0, 1) ?? [];
18
+ }
19
+ return ids?.reduce(reducer, {}) ?? {};
20
+ }, [defaultOpenIds, allowMultipleExpanded]);
21
+
22
+ const [itemStateMap, setItemMap] = useState<ItemMap>(mapSetter);
23
+
24
+ const toggleOpen = (index: string | number) => {
25
+ const key = index + '';
26
+ if (allowMultipleExpanded) {
27
+ setItemMap((prevState) => ({ ...prevState, [key]: !prevState[key] }));
28
+ } else {
29
+ setItemMap({ [key]: !itemStateMap[index] });
30
+ }
31
+ };
32
+
33
+ useEffect(() => {
34
+ setItemMap(mapSetter);
35
+ }, [mapSetter]);
36
+ return { itemStateMap, toggleOpen };
37
+ };
38
+
39
+ export default useAccordionMap;
@@ -0,0 +1,30 @@
1
+ import { useState, useEffect } from 'react';
2
+
3
+ const useWindowSize = () => {
4
+ const [windowSize, setWindowSize] = useState({
5
+ width: window.innerWidth,
6
+ height: window.innerHeight,
7
+ });
8
+
9
+ useEffect(() => {
10
+ function handleResize() {
11
+ setWindowSize({
12
+ width: window?.innerWidth || 300,
13
+ height: window?.innerHeight || 300,
14
+ });
15
+ }
16
+ if (typeof window !== 'undefined') {
17
+ window.addEventListener('resize', handleResize);
18
+ }
19
+
20
+ return () => {
21
+ if (typeof window !== 'undefined') {
22
+ window.removeEventListener('resize', handleResize);
23
+ }
24
+ };
25
+ }, []);
26
+
27
+ return windowSize;
28
+ };
29
+
30
+ export default useWindowSize;