@nuskin/foundation-ui-components 1.0.0-cft-35.13 → 1.0.0-develop.10

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 (247) hide show
  1. package/package.json +21 -11
  2. package/src/common/accordion/NsAccordion.tsx +69 -0
  3. package/src/common/accordion/NsAccordionHeader.tsx +77 -0
  4. package/src/common/accordion/NsAccordionItem.tsx +59 -0
  5. package/src/common/accordion/NsCollapse.tsx +110 -0
  6. package/src/common/accordion/NsToggleSection.tsx +43 -0
  7. package/src/common/accordion/ToggleSection.styled.tsx +32 -0
  8. package/src/common/accordion/colorMap.ts +117 -0
  9. package/src/common/accordion/enums.ts +8 -0
  10. package/src/common/accordion/index.ts +7 -0
  11. package/src/common/accordion/specs/NsAccordion.spec.tsx +163 -0
  12. package/src/common/accordion/specs/NsAccordionHeader.spec.tsx +130 -0
  13. package/src/common/accordion/specs/NsAccordionItem.spec.tsx +79 -0
  14. package/src/common/accordion/specs/NsCollapse.spec.tsx +129 -0
  15. package/src/common/accordion/specs/NsToggleSection.spec.tsx +74 -0
  16. package/src/common/accordion/stories/NsAccordion.stories.tsx +65 -0
  17. package/src/common/accordion/stories/NsAccordionHeader.stories.tsx +44 -0
  18. package/src/common/accordion/stories/NsAccordionItem.stories.tsx +45 -0
  19. package/src/common/accordion/stories/NsCollapse.stories.tsx +50 -0
  20. package/src/common/accordion/stories/NsToggleSection.stories.tsx +26 -0
  21. package/src/common/accordion/stories/data.tsx +143 -0
  22. package/src/common/accordion/types.d.ts +81 -0
  23. package/src/common/alert/Header.tsx +29 -0
  24. package/src/common/alert/NsAlert.spec.tsx +62 -29
  25. package/src/common/alert/NsAlert.stories.tsx +18 -17
  26. package/src/common/alert/NsAlert.styled.tsx +124 -0
  27. package/src/common/alert/NsAlert.tsx +27 -110
  28. package/src/common/alert/index.ts +2 -2
  29. package/src/common/alert/types.d.ts +23 -23
  30. package/src/common/auth-dropdown/NsAuthDropdown.spec.tsx +24 -6
  31. package/src/common/auth-dropdown/NsAuthDropdown.stories.tsx +2 -2
  32. package/src/common/auth-dropdown/NsAuthDropdown.styled.ts +21 -16
  33. package/src/common/auth-dropdown/NsAuthDropdown.tsx +7 -6
  34. package/src/common/auth-dropdown/index.ts +1 -1
  35. package/src/common/auth-dropdown/types.d.ts +3 -1
  36. package/src/common/autocomplete/NsAutocomplete.spec.tsx +69 -24
  37. package/src/common/autocomplete/NsAutocomplete.stories.tsx +64 -7
  38. package/src/common/autocomplete/NsAutocomplete.styled.tsx +12 -0
  39. package/src/common/autocomplete/NsAutocomplete.tsx +100 -46
  40. package/src/common/autocomplete/index.ts +2 -1
  41. package/src/common/autocomplete/mock/MockData.ts +50 -7
  42. package/src/common/autocomplete/mock/MockUI.tsx +2 -1
  43. package/src/common/autocomplete/{types.ts → types.d.ts} +18 -8
  44. package/src/common/banner/NsBanner.spec.tsx +13 -4
  45. package/src/common/banner/NsBanner.stories.tsx +2 -2
  46. package/src/common/banner/NsBanner.styled.tsx +1 -1
  47. package/src/common/banner/NsBanner.tsx +1 -1
  48. package/src/common/banner/index.ts +1 -1
  49. package/src/common/brand-components/NsBrand.stories.tsx +2 -2
  50. package/src/common/brand-components/NsBrandComponent.tsx +6 -3
  51. package/src/common/brand-components/index.ts +1 -1
  52. package/src/common/breadcrumb/NsBreadcrumb.spec.tsx +8 -9
  53. package/src/common/breadcrumb/NsBreadcrumb.stories.tsx +3 -5
  54. package/src/common/breadcrumb/NsBreadcrumb.tsx +5 -3
  55. package/src/common/breadcrumb/data.ts +10 -0
  56. package/src/common/breadcrumb/index.ts +1 -1
  57. package/src/common/button/NsButton.spec.tsx +66 -51
  58. package/src/common/button/NsButton.stories.tsx +61 -4
  59. package/src/common/button/NsButton.styled.tsx +54 -72
  60. package/src/common/button/NsButton.tsx +9 -3
  61. package/src/common/button/helper.ts +82 -0
  62. package/src/common/button/index.ts +1 -1
  63. package/src/common/button/types.d.ts +3 -0
  64. package/src/common/card/NsFfgCard.tsx +14 -8
  65. package/src/common/card/specs/NsFfgCard.spec.tsx +33 -0
  66. package/src/common/card/stories/NsBgCard.stories.tsx +2 -4
  67. package/src/common/card/stories/NsBrandProductCard.stories.tsx +2 -2
  68. package/src/common/card/stories/NsFfgCard.stories.tsx +49 -16
  69. package/src/common/card/stories/{data.js → data.ts} +1 -25
  70. package/src/common/card/styled/NsFfgStyled.tsx +9 -7
  71. package/src/common/card/types.d.ts +7 -4
  72. package/src/common/carousal/NsScrollingCarousal.tsx +61 -0
  73. package/src/common/carousal/index.ts +3 -0
  74. package/src/common/carousal/{tests → specs}/NsCarousal.spec.tsx +2 -2
  75. package/src/common/carousal/specs/NsScrollingCarousal.spec.tsx +61 -0
  76. package/src/common/carousal/stories/NSCarousal.stories.tsx +2 -2
  77. package/src/common/carousal/stories/NsScrollingCarousal.stories.tsx +52 -0
  78. package/src/common/carousal/types.d.ts +23 -0
  79. package/src/common/cart-icon/NsCartIcon.spec.tsx +1 -1
  80. package/src/common/cart-icon/NsCartIcon.stories.tsx +2 -2
  81. package/src/common/cart-icon/NsCartIcon.tsx +1 -1
  82. package/src/common/cart-icon/index.ts +1 -1
  83. package/src/common/checkbox/NsCheckbox.spec.tsx +2 -2
  84. package/src/common/checkbox/NsCheckbox.stories.tsx +2 -2
  85. package/src/common/checkbox/NsCheckbox.styled.tsx +15 -16
  86. package/src/common/checkbox/NsCheckbox.tsx +2 -2
  87. package/src/common/checkbox/index.ts +1 -1
  88. package/src/common/checkbox/types.d.ts +1 -7
  89. package/src/common/column-control/NsColumnControl.tsx +1 -1
  90. package/src/common/column-control/NsFlexColumns.tsx +22 -0
  91. package/src/common/column-control/NsGridColumns.tsx +22 -0
  92. package/src/common/column-control/index.ts +3 -1
  93. package/src/common/column-control/{NsColumnControl.spec.tsx → specs/NsColumnControl.spec.tsx} +3 -3
  94. package/src/common/column-control/specs/NsFlexColumns.spec.tsx +24 -0
  95. package/src/common/column-control/specs/NsGridColumns.spec.tsx +24 -0
  96. package/src/common/column-control/stories/DivArray.stories.tsx +18 -0
  97. package/src/common/column-control/stories/DivArray.tsx +63 -0
  98. package/src/common/column-control/{NsColumnControl.stories.tsx → stories/NsColumnControl.stories.tsx} +9 -16
  99. package/src/common/column-control/stories/NsFlexColumns.stories.tsx +63 -0
  100. package/src/common/column-control/stories/NsGridColumns.stories.tsx +63 -0
  101. package/src/common/column-control/stories/common.tsx +14 -0
  102. package/src/common/column-control/styled/StyledFlex.tsx +45 -0
  103. package/src/common/column-control/styled/StyledGrid.tsx +40 -0
  104. package/src/common/column-control/styled/common.ts +27 -0
  105. package/src/common/column-control/types.d.ts +15 -16
  106. package/src/common/column-control/utils.ts +5 -5
  107. package/src/common/common.types.d.ts +21 -0
  108. package/src/common/dropdown/NsDropdown.spec.tsx +1 -1
  109. package/src/common/dropdown/NsDropdown.styled.tsx +23 -18
  110. package/src/common/dropdown/NsDropdown.tsx +1 -1
  111. package/src/common/dropdown/NsDropdownOption.tsx +1 -1
  112. package/src/common/dropdown/index.ts +1 -1
  113. package/src/common/dropdown/stories/NsDropdown.stories.tsx +2 -2
  114. package/src/common/dropdown/stories/NsDropdownCountry.stories.tsx +2 -2
  115. package/src/common/dropdown/types.d.ts +3 -1
  116. package/src/common/email-simple/NsEmailSimple.spec.tsx +145 -0
  117. package/src/common/email-simple/NsEmailSimple.stories.tsx +61 -0
  118. package/src/common/email-simple/NsEmailSimple.tsx +71 -0
  119. package/src/common/email-simple/index.ts +2 -0
  120. package/src/common/email-simple/types.d.ts +14 -0
  121. package/src/common/flag/NsFlag.spec.tsx +5 -25
  122. package/src/common/flag/NsFlag.stories.tsx +2 -2
  123. package/src/common/flag/NsFlag.styled.tsx +7 -9
  124. package/src/common/flag/NsFlag.tsx +1 -3
  125. package/src/common/flag/index.ts +1 -1
  126. package/src/common/flag/types.d.ts +0 -2
  127. package/src/common/hooks/index.ts +2 -0
  128. package/src/common/hooks/specs/useWindowSize.spec.tsx +19 -0
  129. package/src/common/hooks/useAccordionMap.tsx +39 -0
  130. package/src/common/hooks/useWindowSize.tsx +30 -0
  131. package/src/common/icon/NsIcon.spec.tsx +1 -1
  132. package/src/common/icon/NsIcon.stories.tsx +2 -2
  133. package/src/common/icon/NsIcon.styled.tsx +1 -1
  134. package/src/common/icon/NsIcon.tsx +1 -1
  135. package/src/common/icon/NsIconVariants.ts +9 -4
  136. package/src/common/icon/icons/AlertErrorIcon.tsx +15 -6
  137. package/src/common/icon/icons/HamburgerIcon.tsx +29 -0
  138. package/src/common/icon/icons/UserIcon.tsx +30 -0
  139. package/src/common/icon/icons/WarningIcon.tsx +14 -5
  140. package/src/common/icon/index.ts +1 -1
  141. package/src/common/icon/types.d.ts +1 -0
  142. package/src/common/image/NsImage.spec.tsx +57 -7
  143. package/src/common/image/NsImage.stories.tsx +2 -2
  144. package/src/common/image/NsImage.tsx +24 -12
  145. package/src/common/image/NsNextImage.spec.tsx +1 -1
  146. package/src/common/image/NsNextImage.stories.tsx +2 -2
  147. package/src/common/image/NsNextImage.tsx +1 -1
  148. package/src/common/image/index.ts +1 -1
  149. package/src/common/image/types.d.ts +1 -0
  150. package/src/common/index.ts +14 -10
  151. package/src/common/input/InputFieldWrapper.tsx +4 -4
  152. package/src/common/input/InputWrapper.tsx +12 -7
  153. package/src/common/input/NsInputField.stories.tsx +13 -10
  154. package/src/common/input/NsInputField.tsx +13 -6
  155. package/src/common/input/getAdornmentProps.tsx +5 -1
  156. package/src/common/input/index.ts +1 -1
  157. package/src/common/input/types.d.ts +18 -1
  158. package/src/common/label/NsLabel.stories.tsx +6 -1
  159. package/src/common/label/NsLabel.tsx +21 -20
  160. package/src/common/label/index.ts +1 -1
  161. package/src/common/label/types.d.ts +2 -1
  162. package/src/common/link/NsLink.spec.tsx +1 -1
  163. package/src/common/link/NsLink.stories.tsx +2 -2
  164. package/src/common/link/NsLink.tsx +1 -1
  165. package/src/common/link/index.ts +1 -1
  166. package/src/common/modal/NsModal.spec.tsx +46 -0
  167. package/src/common/modal/NsModal.styled.tsx +28 -0
  168. package/src/common/modal/NsModal.tsx +37 -0
  169. package/src/common/modal/helper-component/NsModalContentBox.tsx +32 -0
  170. package/src/common/modal/helper-component/NsModalDefault.tsx +25 -0
  171. package/src/common/modal/helper-component/NsModalStatus.tsx +15 -0
  172. package/src/common/modal/helper-component/NsModalStatusIcon.tsx +14 -0
  173. package/src/common/modal/helper-component/NsModalTitle.tsx +26 -0
  174. package/src/common/modal/index.ts +2 -0
  175. package/src/common/modal/model/NsModalVariantMap.tsx +24 -0
  176. package/src/common/modal/stories/NsModal.stories.tsx +86 -0
  177. package/src/common/modal/stories/mock.tsx +46 -0
  178. package/src/common/modal/types.ts +56 -0
  179. package/src/common/nav-product-card/NsNavProductCard.spec.tsx +1 -1
  180. package/src/common/nav-product-card/NsNavProductCard.stories.tsx +2 -2
  181. package/src/common/nav-product-card/NsNavProductCard.tsx +1 -1
  182. package/src/common/nav-product-card/index.ts +1 -1
  183. package/src/common/nav-tab/NsNavTab.spec.tsx +2 -7
  184. package/src/common/nav-tab/NsNavTab.stories.tsx +2 -2
  185. package/src/common/nav-tab/NsNavTab.styled.tsx +7 -4
  186. package/src/common/nav-tab/NsNavTab.tsx +1 -1
  187. package/src/common/nav-tab/index.ts +1 -1
  188. package/src/common/nav-tab/types.d.ts +2 -2
  189. package/src/common/radiogroup/NsRadioGroup.spec.tsx +63 -0
  190. package/src/common/radiogroup/NsRadioGroup.stories.tsx +84 -0
  191. package/src/common/radiogroup/NsRadioGroup.styled.tsx +52 -0
  192. package/src/common/radiogroup/NsRadioGroup.tsx +62 -0
  193. package/src/common/radiogroup/index.ts +2 -0
  194. package/src/common/radiogroup/types.d.ts +20 -0
  195. package/src/common/search-bar/NsSeachBar.spec.tsx +1 -1
  196. package/src/common/search-bar/NsSearchBar.tsx +1 -3
  197. package/src/common/select/NsSelect.spec.tsx +193 -0
  198. package/src/common/select/NsSelect.styled.tsx +104 -0
  199. package/src/common/select/NsSelect.tsx +117 -0
  200. package/src/common/select/NsSelectOption.tsx +30 -0
  201. package/src/common/select/index.ts +3 -0
  202. package/src/common/select/stories/NsSelect.stories.tsx +134 -0
  203. package/src/common/select/types.d.ts +34 -0
  204. package/src/common/spinner/NsSpinner.spec.tsx +21 -0
  205. package/src/common/spinner/NsSpinner.stories.tsx +26 -0
  206. package/src/common/spinner/NsSpinner.styled.tsx +344 -0
  207. package/src/common/spinner/NsSpinner.tsx +14 -0
  208. package/src/common/spinner/icons/Spinner.tsx +161 -0
  209. package/src/common/spinner/index.ts +2 -0
  210. package/src/common/spinner/types.ts +5 -0
  211. package/src/common/table/NsExpandableRow.tsx +68 -0
  212. package/src/common/table/NsTable.spec.tsx +174 -0
  213. package/src/common/table/NsTable.stories.tsx +161 -0
  214. package/src/common/table/NsTable.styled.ts +127 -0
  215. package/src/common/table/NsTable.tsx +133 -0
  216. package/src/common/table/NsTableHeader.tsx +41 -0
  217. package/src/common/table/NsTablePagination.tsx +28 -0
  218. package/src/common/table/helper.ts +33 -0
  219. package/src/common/table/index.ts +2 -0
  220. package/src/common/table/types.d.ts +57 -0
  221. package/src/common/text-strip/NsTextStrip.spec.tsx +30 -0
  222. package/src/common/text-strip/NsTextStrip.stories.tsx +33 -0
  223. package/src/common/text-strip/NsTextStrip.tsx +47 -0
  224. package/src/common/text-strip/index.ts +2 -0
  225. package/src/common/text-strip/types.d.ts +17 -0
  226. package/src/common/typography/NsTypography.stories.tsx +2 -2
  227. package/src/common/typography/NsTypography.tsx +1 -1
  228. package/src/common/typography/Typography.styled.tsx +4 -4
  229. package/src/common/typography/index.ts +1 -1
  230. package/src/common/util.ts +1 -0
  231. package/src/common/utility/Show.tsx +13 -0
  232. package/src/common/utility/index.ts +1 -0
  233. package/src/common/validations/regex.ts +3 -0
  234. package/src/common/videos/NsVideo.stories.tsx +2 -2
  235. package/src/common/videos/NsVideo.tsx +1 -1
  236. package/src/common/videos/index.ts +1 -1
  237. package/src/common/videos/types.d.ts +1 -1
  238. package/src/common/alert/NsAlert.styled.ts +0 -124
  239. package/src/common/card/tests/NsFfgCard.spec.tsx +0 -23
  240. package/src/common/column-control/NDivs.story.tsx +0 -35
  241. package/src/common/common.types.ts +0 -10
  242. /package/src/common/brand-components/{NsBrandContanier.styled.tsx → NsBrandContainer.styled.tsx} +0 -0
  243. /package/src/common/card/{tests → specs}/BrandLogo.spec.tsx +0 -0
  244. /package/src/common/card/{tests → specs}/NsBgCard.spec.tsx +0 -0
  245. /package/src/common/card/{tests → specs}/NsBrandProductCard.spec.tsx +0 -0
  246. /package/src/common/carousal/{tests → specs}/Chevron.spec.tsx +0 -0
  247. /package/src/common/carousal/{tests → specs}/RenderBrand.spec.tsx +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nuskin/foundation-ui-components",
3
- "version": "1.0.0-cft-35.13",
3
+ "version": "1.0.0-develop.10",
4
4
  "description": "It is a foundation library written in react, that provides common components to all UI pages",
5
5
  "private": false,
6
6
  "main": "src/common/index.ts",
@@ -10,8 +10,7 @@
10
10
  },
11
11
  "homepage": "https://code.tls.nuskin.io/ns-am/content-foundation/foundation-ui-components/blob/master/README.md",
12
12
  "author": {
13
- "name": "Ruthraj Palanisamy",
14
- "email": "rpalanisamy@nuskin.com"
13
+ "name": "Josh Porter"
15
14
  },
16
15
  "publishConfig": {
17
16
  "access": "public"
@@ -23,24 +22,32 @@
23
22
  ],
24
23
  "license": "MIT",
25
24
  "scripts": {
26
- "dev": "next dev",
25
+ "build-storybook": "storybook build -o dist",
26
+ "build-dev": "yarn build-storybook",
27
+ "build-prod": "yarn build-storybook --mode=production",
28
+ "build-test": "yarn build-storybook",
27
29
  "build": "next build",
28
- "start": "next start",
30
+ "dev": "next dev",
31
+ "export": "next export",
29
32
  "lint": "next lint",
30
- "test": "jest",
31
- "test:coverage": "yarn test --coverage",
32
- "test:watch": "jest --watch",
33
33
  "storybook": "storybook dev -p 6007",
34
- "build-storybook": "storybook build"
34
+ "sb": "yarn storybook",
35
+ "start": "next start",
36
+ "test": "next build && jest --coverage",
37
+ "test:pattern": "jest --coverage --testNamePattern accordion/*",
38
+ "test:watch": "jest --watch",
39
+ "test:failed": "npx jest --onlyFailures",
40
+ "test:coverage": "yarn test --coverage",
41
+ "types:check": "tsc --pretty --noEmit"
35
42
  },
36
43
  "dependencies": {
37
44
  "@emotion/react": "^11.10.6",
38
45
  "@emotion/styled": "^11.10.6",
39
46
  "@mui/icons-material": "^5.11.11",
40
47
  "@mui/material": "5.4.2",
48
+ "@mui/utils": "^5.14.1",
41
49
  "@next/font": "13.2.4",
42
- "@nuskin/foundation-theme": "1.0.0-cft-33.12",
43
- "@types/jest": "^29.5.0",
50
+ "@nuskin/foundation-theme": "1.0.0-develop.5",
44
51
  "framer-motion": "^10.8.5",
45
52
  "next": "13.2.4",
46
53
  "react": "18.2.0",
@@ -69,8 +76,11 @@
69
76
  "@storybook/testing-library": "^0.1.0",
70
77
  "@testing-library/jest-dom": "^5.16.5",
71
78
  "@testing-library/react": "^14.0.0",
79
+ "@testing-library/react-hooks": "^8.0.1",
80
+ "@types/jest": "^29.5.0",
72
81
  "@types/lodash": "^4.14.191",
73
82
  "@types/node": "18.15.0",
83
+ "@types/ramda": "^0.29.3",
74
84
  "@types/react": "18.0.28",
75
85
  "@types/react-dom": "18.0.11",
76
86
  "@types/react-slick": "^0.23.10",
@@ -0,0 +1,69 @@
1
+ import React, { FC, useMemo } from 'react';
2
+ import { NsAccordionItem, useAccordionMap, NsAccordionProps, AccordionItem } from '..';
3
+ import { StyledAccordionWrapper } from './ToggleSection.styled';
4
+
5
+ /**
6
+ * NsAccordion can be used to show a list of items with title and body
7
+ * it accepts a `boolean` prop `allowMultipleExpanded` which when true,
8
+ * multiple sections of accordion can remain open at a time
9
+ *
10
+ * we can define certain section to remain open by default using `isDefaultOpen` in the
11
+ * items
12
+ * if there are multiple items available for default open, but `allowMultipleExpanded`
13
+ * is false then only first item of default open is made open
14
+ */
15
+ const createKey = (item: AccordionItem, index: number) => item?.id + index;
16
+ const NsAccordion: FC<NsAccordionProps> = ({
17
+ allowMultipleExpanded,
18
+ invert,
19
+ level,
20
+ variant,
21
+ items,
22
+ headerTypographyVariant,
23
+ closedIconName,
24
+ openedIconName,
25
+ additionalProps,
26
+ isChild = false,
27
+ }) => {
28
+ const defaultOpenIds = useMemo(() => {
29
+ return items
30
+ ?.map?.((content, index) => (content?.isDefaultOpen ? createKey(content, index) : null))
31
+ .filter((e) => e !== null) as string[];
32
+ }, [items]);
33
+
34
+ const { toggleOpen, itemStateMap } = useAccordionMap({ allowMultipleExpanded, defaultOpenIds });
35
+
36
+ return (
37
+ <StyledAccordionWrapper
38
+ variant={variant}
39
+ className="ns-accordion"
40
+ data-testid={additionalProps?.testid ?? 'ns-accordion-testid'}
41
+ >
42
+ {items?.map?.((item, index) => {
43
+ const key = createKey(item, index);
44
+ const isOpen = itemStateMap[key] ?? false;
45
+ return (
46
+ <NsAccordionItem
47
+ allowMultipleExpanded={item.allowMultipleExpanded}
48
+ type={item.type}
49
+ closedIconName={closedIconName}
50
+ content={item.content}
51
+ headerTypographyVariant={headerTypographyVariant}
52
+ invert={invert}
53
+ isOpen={isOpen}
54
+ isChild={isChild}
55
+ key={key}
56
+ level={level}
57
+ openedIconName={openedIconName}
58
+ startIcon={item.icon}
59
+ toggleOpen={() => toggleOpen(createKey(item, index))}
60
+ title={<div className="nsa-item-title">{item.title}</div>}
61
+ variant={variant}
62
+ />
63
+ );
64
+ })}
65
+ </StyledAccordionWrapper>
66
+ );
67
+ };
68
+
69
+ export default NsAccordion;
@@ -0,0 +1,77 @@
1
+ import { NsTypography, NsIcon, NsAccordionHeaderProps, AccordionVariant, NsIconProps, AccordionVariantType } from '..';
2
+ import { styled } from '@nuskin/foundation-theme';
3
+ import { isValidIconName } from '../icon/NsIconVariants';
4
+ import { getAccordionColor } from './colorMap';
5
+ const options = {
6
+ shouldForwardProp: (propKey: string) => !['variant', 'invert'].includes(propKey),
7
+ };
8
+ type StyledType = { variant: AccordionVariantType; invert: boolean };
9
+
10
+ const StyledHeader = styled(
11
+ 'header',
12
+ options
13
+ )<StyledType>(({ theme, variant, invert }) => {
14
+ const { headBg, headText } = getAccordionColor({ theme, variant, invert, keys: ['headBg', 'headText'] });
15
+ let borderBottom = 'none';
16
+ if (variant === AccordionVariant.Compact) {
17
+ borderBottom = '1px solid rgb(0,0,0,0.125)';
18
+ }
19
+ return {
20
+ backgroundColor: headBg,
21
+ color: headText,
22
+ cursor: 'pointer',
23
+ display: 'grid',
24
+ gap: '4px',
25
+ gridTemplateColumns: 'auto 1fr 24px',
26
+ padding: '9px 16px',
27
+ borderBottom,
28
+ } as any;
29
+ });
30
+
31
+ /**
32
+ * NsAccordionHeader is primarily used by NsToggleSection and NsAccordionItem
33
+ * as a header, so it accepts `title` , `isOpen` and `onClick`
34
+ */
35
+ const NsAccordionHeader = ({
36
+ title,
37
+ onClick,
38
+ isOpen,
39
+ additionalProps,
40
+ openedIconName,
41
+ closedIconName,
42
+ variant,
43
+ headerTypographyVariant,
44
+ startIcon,
45
+ invert,
46
+ cslp,
47
+ }: NsAccordionHeaderProps) => {
48
+ return (
49
+ <StyledHeader
50
+ invert={invert}
51
+ role="button"
52
+ aria-expanded={isOpen ? 'true' : 'false'}
53
+ className={`section-header ${isOpen ? 'expanded' : ''} ${additionalProps?.className ?? ''}`}
54
+ onClick={onClick}
55
+ variant={variant}
56
+ >
57
+ <HeaderIcon {...startIcon} />
58
+ {typeof title === 'string' ? (
59
+ <NsTypography variant={headerTypographyVariant ?? 'h4'} weight="bold" {...(cslp?.header ?? {})}>
60
+ {title}
61
+ </NsTypography>
62
+ ) : (
63
+ title
64
+ )}
65
+ <span className="header-icon">
66
+ <NsIcon name={isOpen ? openedIconName ?? 'arrowUp' : closedIconName ?? 'arrowDown'} />
67
+ </span>
68
+ </StyledHeader>
69
+ );
70
+ };
71
+ export default NsAccordionHeader;
72
+
73
+ const HeaderIcon = (props: Partial<NsIconProps>) => {
74
+ const hasIcon = props?.name ? isValidIconName(props?.name) : false;
75
+ if (!hasIcon) return <span />;
76
+ return <NsIcon {...(props as NsIconProps)} />;
77
+ };
@@ -0,0 +1,59 @@
1
+ import React from 'react';
2
+ import { NsAccordionItemProps, NsCollapse } from '..';
3
+ import NsAccordionHeader from './NsAccordionHeader';
4
+ import { StyledToggleSection } from './ToggleSection.styled';
5
+
6
+ /**
7
+ * this component is used by accordion to pass title
8
+ * and content
9
+ * cslp:{header:CslpTag, content:CslpTag}
10
+ */
11
+ const NsAccordionItem = ({
12
+ isOpen,
13
+ isChild,
14
+ toggleOpen,
15
+ title,
16
+ content,
17
+ variant,
18
+ headerTypographyVariant,
19
+ closedIconName,
20
+ openedIconName,
21
+ startIcon,
22
+ level,
23
+ additionalProps,
24
+ invert,
25
+ type,
26
+ cslp,
27
+ allowMultipleExpanded,
28
+ }: NsAccordionItemProps) => {
29
+ return (
30
+ <StyledToggleSection variant={variant}>
31
+ <NsAccordionHeader
32
+ invert={invert}
33
+ additionalProps={{ ...additionalProps, className: 'accordion-section ' + additionalProps?.className }}
34
+ closedIconName={closedIconName}
35
+ headerTypographyVariant={headerTypographyVariant}
36
+ isOpen={isOpen}
37
+ openedIconName={openedIconName}
38
+ onClick={toggleOpen}
39
+ title={title}
40
+ variant={variant}
41
+ startIcon={startIcon}
42
+ cslp={cslp}
43
+ />
44
+ <NsCollapse
45
+ type={type}
46
+ isChild={isChild}
47
+ isOpen={isOpen}
48
+ variant={variant}
49
+ level={level}
50
+ invert={invert}
51
+ content={content}
52
+ cslp={cslp}
53
+ allowMultipleExpanded={allowMultipleExpanded}
54
+ />
55
+ </StyledToggleSection>
56
+ );
57
+ };
58
+
59
+ export default NsAccordionItem;
@@ -0,0 +1,110 @@
1
+ import { styled } from '@nuskin/foundation-theme';
2
+ import { AccordionVariant, AccordionVariantType, NsCollapseProps, AccordionItem, NsAccordion } from '../';
3
+ import { getAccordionColor } from './colorMap';
4
+ import { ReactElement, isValidElement, useMemo } from 'react';
5
+
6
+ const getLevelOffset = (level: number) => {
7
+ return level > 1 ? (level - 1) * 16 : 0;
8
+ };
9
+
10
+ const options = {
11
+ shouldForwardProp: (key: string) => !['variant', 'level'].includes(key),
12
+ };
13
+
14
+ export const StyledCollapse = styled(
15
+ 'section',
16
+ options
17
+ )<{ variant: AccordionVariantType; level: number; invert: boolean; isChild: boolean }>(
18
+ ({ theme, variant, level, invert, isChild }) => {
19
+ const { contentBg, contentText } = getAccordionColor({
20
+ theme,
21
+ invert,
22
+ variant,
23
+ keys: ['contentBg', 'contentText'],
24
+ });
25
+
26
+ let borderBottom = 'none';
27
+ if (variant === AccordionVariant.Compact) {
28
+ borderBottom = isChild ? 'none' : '1px solid rgb(0,0,0,0.125)';
29
+ }
30
+ return {
31
+ backgroundColor: contentBg,
32
+ color: contentText,
33
+ opacity: 0,
34
+ padding: '0 16px',
35
+ height: 0,
36
+ overflow: 'hidden',
37
+ transition: '0.3s',
38
+ '&.expanded': {
39
+ padding: `9px 0 9px ${getLevelOffset(level)}px`,
40
+ height: 'auto',
41
+ opacity: 1,
42
+ borderBottom,
43
+ },
44
+ '.nsa-content-padded': {
45
+ padding: '0 16px 16px',
46
+ },
47
+ };
48
+ }
49
+ );
50
+
51
+ /**
52
+ * NsCollapse component adds css animation while showing children items if prop `isOpen` is true,
53
+ * and while removing children if prop `isOpen` is false
54
+ */
55
+ const NsCollapse = ({
56
+ isOpen,
57
+ content,
58
+ additionalProps,
59
+ variant,
60
+ level,
61
+ invert,
62
+ isChild,
63
+ type,
64
+ cslp,
65
+ allowMultipleExpanded,
66
+ }: NsCollapseProps) => {
67
+ const body = useMemo(() => {
68
+ if (isValidElement(content)) {
69
+ return content as ReactElement;
70
+ }
71
+ if (type === 'html') {
72
+ return (
73
+ <div
74
+ className="nsa-content-padded"
75
+ dangerouslySetInnerHTML={{ __html: content as string }}
76
+ {...(cslp?.content ?? {})}
77
+ />
78
+ );
79
+ } else if (type === 'text') {
80
+ return (
81
+ <div className="p-4" {...(cslp?.content ?? {})}>
82
+ {content as string}
83
+ </div>
84
+ );
85
+ } else if (type === 'accordion') {
86
+ return (
87
+ <NsAccordion
88
+ isChild={true}
89
+ invert={invert}
90
+ level={level}
91
+ variant={AccordionVariant.Gray}
92
+ items={content as AccordionItem[]}
93
+ allowMultipleExpanded={allowMultipleExpanded ?? false}
94
+ />
95
+ );
96
+ }
97
+ }, [allowMultipleExpanded, content, cslp?.content, invert, level, type]);
98
+ return (
99
+ <StyledCollapse
100
+ isChild={isChild}
101
+ level={level}
102
+ className={`ns-collapse ${isOpen ? 'expanded' : ''} ${additionalProps?.className ?? ''}`}
103
+ variant={variant}
104
+ invert={invert}
105
+ >
106
+ {body}
107
+ </StyledCollapse>
108
+ );
109
+ };
110
+ export default NsCollapse;
@@ -0,0 +1,43 @@
1
+ import React, { useState } from 'react';
2
+ import { NsToggleSectionProps, NsAccordionItem } from '../';
3
+
4
+ /**
5
+ * NsToggleSection takes prop `title` and prop `children` and toggles
6
+ * children with animation when clicked on title
7
+ *
8
+ * it also has a `defaultOpen` prop, which when true, children is visible
9
+ * by default, otherwise children is hidden by default and toggles between visible
10
+ * and hidden on clicking title
11
+ */
12
+ const NsToggleSection = ({
13
+ title,
14
+ content,
15
+ additionalProps,
16
+ defaultOpen,
17
+ variant,
18
+ invert,
19
+ isChild,
20
+ type,
21
+ }: NsToggleSectionProps) => {
22
+ const [isExpanded, setIsExpanded] = useState(defaultOpen ?? false);
23
+
24
+ const toggleAccordion = () => {
25
+ setIsExpanded(!isExpanded);
26
+ };
27
+ return (
28
+ <NsAccordionItem
29
+ type={type}
30
+ level={2}
31
+ variant={variant}
32
+ additionalProps={additionalProps}
33
+ isOpen={isExpanded}
34
+ title={title}
35
+ content={content}
36
+ toggleOpen={toggleAccordion}
37
+ invert={invert}
38
+ isChild={isChild}
39
+ />
40
+ );
41
+ };
42
+
43
+ export default NsToggleSection;
@@ -0,0 +1,32 @@
1
+ import { styled } from '@nuskin/foundation-theme';
2
+ import { AccordionVariant, AccordionVariantType } from '../';
3
+
4
+ const border = '1px solid rgb(0,0,0,0.125)';
5
+
6
+ type StyledType = { variant: AccordionVariantType };
7
+
8
+ export const StyledToggleSection = styled('section')<StyledType>(({ variant }) => {
9
+ if (variant === AccordionVariant.Compact) {
10
+ return { borderRight: border };
11
+ }
12
+ return {
13
+ margin: '5px 0',
14
+ };
15
+ });
16
+
17
+ export const StyledAccordionWrapper = styled('div')<StyledType>(({ variant }) => {
18
+ if (variant === AccordionVariant.Compact) {
19
+ return {
20
+ display: 'flex',
21
+ flexDirection: 'column',
22
+ gap: '0',
23
+ borderTop: border,
24
+ borderLeft: border,
25
+ };
26
+ }
27
+ return {
28
+ display: 'flex',
29
+ flexDirection: 'column',
30
+ gap: '10px',
31
+ };
32
+ });
@@ -0,0 +1,117 @@
1
+ import {Themed} from '../common.types';
2
+ import {AccordionVariantType} from './enums';
3
+ import {ColorUtils, FoundationTheme} from '@nuskin/foundation-theme';
4
+ const {isDarkMode, color} = ColorUtils;
5
+ const compKeys = ['contentBg', 'contentText', 'headBg', 'headText'];
6
+ type CompKeys = (typeof compKeys)[number];
7
+ type VariantColors = Record<
8
+ CompKeys,
9
+ {
10
+ light: [FoundationTheme.AppColors, string];
11
+ dark: [FoundationTheme.AppColors, string];
12
+ }
13
+ >;
14
+
15
+ const colorObject: Record<string, [FoundationTheme.AppColors, string]> = {
16
+ n10: ['primary', 'dark'], // #121212
17
+ n20: ['primary', 'black'], // #252525
18
+ n40: ['neutral', '80'], // #444444
19
+ n45: ['neutral', '70'], // #5f5f5f
20
+ n50: ['neutral', '60'], // #8c8c8c
21
+ n80: ['neutral', '50'], // #b2b2b2
22
+ n85: ['neutral', '40'], // #e0e0e0
23
+ n90: ['neutral', '30'], // #ededed
24
+ n95: ['primary', 'gray'], // #f5f5f5
25
+ n100: ['primary', 'white'], // #fff
26
+ };
27
+ export const colorMap: Record<AccordionVariantType, VariantColors> = {
28
+ basic: {
29
+ contentBg: {
30
+ light: colorObject.n95,
31
+ dark: colorObject.n20,
32
+ },
33
+ contentText: {
34
+ light: colorObject.n10,
35
+ dark: colorObject.n95,
36
+ },
37
+ headBg: {
38
+ light: colorObject.n100,
39
+ dark: colorObject.n20,
40
+ },
41
+ headText: {
42
+ light: colorObject.n10,
43
+ dark: colorObject.n95,
44
+ },
45
+ },
46
+ compact: {
47
+ contentBg: {
48
+ light: colorObject.n100,
49
+ dark: colorObject.n10,
50
+ },
51
+ contentText: {
52
+ light: colorObject.n10,
53
+ dark: colorObject.n90,
54
+ },
55
+ headBg: {
56
+ light: colorObject.n100,
57
+ dark: colorObject.n10,
58
+ },
59
+ headText: {
60
+ light: colorObject.n10,
61
+ dark: colorObject.n90,
62
+ },
63
+ },
64
+ gray: {
65
+ contentBg: {
66
+ light: colorObject.n85,
67
+ dark: colorObject.n40,
68
+ },
69
+ contentText: {
70
+ light: colorObject.n40,
71
+ dark: colorObject.n85,
72
+ },
73
+ headBg: {
74
+ light: colorObject.n90,
75
+ dark: colorObject.n45,
76
+ },
77
+ headText: {
78
+ light: colorObject.n45,
79
+ dark: colorObject.n90,
80
+ },
81
+ },
82
+ stripe: {
83
+ contentBg: {
84
+ light: colorObject.n90,
85
+ dark: colorObject.n45,
86
+ },
87
+ contentText: {
88
+ light: colorObject.n45,
89
+ dark: colorObject.n90,
90
+ },
91
+ headBg: {
92
+ light: colorObject.n100,
93
+ dark: colorObject.n40,
94
+ },
95
+ headText: {
96
+ light: colorObject.n40,
97
+ dark: colorObject.n100,
98
+ },
99
+ },
100
+ };
101
+
102
+ type GetAccordionColor = {
103
+ variant: AccordionVariantType;
104
+ invert: boolean;
105
+ keys: CompKeys[];
106
+ } & Themed;
107
+ export const getAccordionColor = ({theme, variant, invert, keys}: GetAccordionColor): Record<CompKeys, string> => {
108
+ const isDark = invert ? !isDarkMode({theme}) : isDarkMode({theme});
109
+ const darkLabel = isDark ? 'dark' : 'light';
110
+ const result: Record<string, string> = {};
111
+ for (const colorKey of keys) {
112
+ const [appColorBg, appSubColorBg] = colorMap[variant][colorKey][darkLabel];
113
+ const colorValue = color(appColorBg, appSubColorBg)({theme});
114
+ result[colorKey] = colorValue;
115
+ }
116
+ return result;
117
+ };
@@ -0,0 +1,8 @@
1
+ export const AccordionVariant = {
2
+ Basic: 'basic',
3
+ Compact: 'compact',
4
+ Gray: 'gray',
5
+ Stripe: 'stripe',
6
+ } as const;
7
+ const variantValues = Object.values(AccordionVariant);
8
+ export type AccordionVariantType = (typeof variantValues)[number];
@@ -0,0 +1,7 @@
1
+ export { default as NsCollapse } from './NsCollapse';
2
+ export { default as NsAccordionHeader } from './NsAccordionHeader';
3
+ export { default as NsToggleSection } from './NsToggleSection';
4
+ export { default as NsAccordionItem } from './NsAccordionItem';
5
+ export { default as NsAccordion } from './NsAccordion';
6
+ export * from './types.d';
7
+ export * from './enums';