@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
package/package.json CHANGED
@@ -1,103 +1,107 @@
1
1
  {
2
- "name": "@nuskin/foundation-ui-components",
3
- "version": "1.0.2",
4
- "description": "It is a foundation library written in react, that provides common components to all UI pages",
5
- "private": false,
6
- "main": "src/common/index.ts",
7
- "repository": {
8
- "type": "git",
9
- "url": "git@code.tls.nuskin.io:ns-am/content-foundation/foundation-ui-components.git"
10
- },
11
- "homepage": "https://code.tls.nuskin.io/ns-am/content-foundation/foundation-ui-components/blob/master/README.md",
12
- "author": {
13
- "name": "Josh Porter"
14
- },
15
- "publishConfig": {
16
- "access": "public"
17
- },
18
- "keywords": [
19
- "react",
20
- "foundation-ui",
21
- "foundation-ui-components"
22
- ],
23
- "license": "MIT",
24
- "scripts": {
25
- "dev": "next dev",
26
- "start": "next start",
27
- "lint": "next lint",
28
- "test": "next build && jest --coverage",
29
- "test:watch": "jest --watch",
30
- "storybook": "storybook dev -p 6007",
31
- "sb": "yarn storybook",
32
- "build-dev": "yarn build-storybook",
33
- "build-prod": "yarn build-storybook --mode=production",
34
- "build-test": "yarn build-storybook",
35
- "build-storybook": "storybook build -o dist",
36
- "export": "next export",
37
- "prepare": "husky install",
38
- "types:check": "tsc --pretty --noEmit"
39
- },
40
- "dependencies": {
41
- "@emotion/react": "^11.10.6",
42
- "@emotion/styled": "^11.10.6",
43
- "@mui/icons-material": "^5.11.11",
44
- "@mui/material": "5.4.2",
45
- "@next/font": "13.2.4",
46
- "@nuskin/foundation-theme": "1.0.0-develop.5",
47
- "framer-motion": "^10.8.5",
48
- "next": "13.2.4",
49
- "react": "18.2.0",
50
- "react-dom": "18.2.0",
51
- "react-material-ui-carousel": "^3.4.2",
52
- "react-slick": "^0.29.0",
53
- "slick-carousel": "^1.8.1",
54
- "typescript": "4.9.5"
55
- },
56
- "devDependencies": {
57
- "@babel/core": "^7.21.0",
58
- "@babel/preset-env": "^7.20.2",
59
- "@babel/preset-react": "^7.18.6",
60
- "@babel/preset-typescript": "^7.21.0",
61
- "@emotion/jest": "^11.10.5",
62
- "@nuskin/eslint-config": "^1.0.0-setup.1",
63
- "@storybook/addon-actions": "^7.1.0",
64
- "@storybook/addon-essentials": "^7.1.0",
65
- "@storybook/addon-interactions": "^7.1.0",
66
- "@storybook/addon-links": "^7.1.0",
67
- "@storybook/addon-mdx-gfm": "^7.1.0",
68
- "@storybook/jest": "^0.1.0",
69
- "@storybook/nextjs": "^7.1.0",
70
- "@storybook/react": "^7.1.0",
71
- "@storybook/test-runner": "^0.11.0",
72
- "@storybook/testing-library": "^0.2.0",
73
- "@testing-library/jest-dom": "^5.16.5",
74
- "@testing-library/react": "^14.0.0",
75
- "@types/jest": "^29.5.0",
76
- "@types/lodash": "^4.14.191",
77
- "@types/node": "18.15.0",
78
- "@types/ramda": "^0.29.3",
79
- "@types/react": "18.0.28",
80
- "@types/react-dom": "18.0.11",
81
- "@types/react-slick": "^0.23.10",
82
- "@types/react-test-renderer": "^18.0.0",
83
- "@types/testing-library__jest-dom": "^5.14.5",
84
- "babel-jest": "^29.5.0",
85
- "babel-loader": "^9.1.2",
86
- "babel-plugin-emotion": "^11.0.0",
87
- "chromatic": "^6.17.3",
88
- "eslint": "8.36.0",
89
- "eslint-config-next": "13.2.4",
90
- "eslint-config-prettier": "^8.7.0",
91
- "eslint-plugin-json": "^3.1.0",
92
- "eslint-plugin-prettier": "^4.2.1",
93
- "eslint-plugin-storybook": "^0.6.12",
94
- "husky": "^8.0.0",
95
- "jest": "^29.5.0",
96
- "jest-environment-jsdom": "^29.5.0",
97
- "storybook": "^7.1.0"
98
- },
99
- "files": [
100
- "src/common"
101
- ],
102
- "readme": "./README.md"
2
+ "name": "@nuskin/foundation-ui-components",
3
+ "version": "1.1.1",
4
+ "description": "It is a foundation library written in react, that provides common components to all UI pages",
5
+ "private": false,
6
+ "main": "src/common/index.ts",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git@code.tls.nuskin.io:ns-am/content-foundation/foundation-ui-components.git"
10
+ },
11
+ "homepage": "https://code.tls.nuskin.io/ns-am/content-foundation/foundation-ui-components/blob/master/README.md",
12
+ "author": {
13
+ "name": "Josh Porter"
14
+ },
15
+ "publishConfig": {
16
+ "access": "public"
17
+ },
18
+ "keywords": [
19
+ "react",
20
+ "foundation-ui",
21
+ "foundation-ui-components"
22
+ ],
23
+ "license": "MIT",
24
+ "scripts": {
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",
29
+ "build": "next build",
30
+ "dev": "next dev",
31
+ "export": "next export",
32
+ "lint": "next lint",
33
+ "storybook": "storybook dev -p 6007",
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"
42
+ },
43
+ "dependencies": {
44
+ "@emotion/react": "^11.10.6",
45
+ "@emotion/styled": "^11.10.6",
46
+ "@mui/icons-material": "^5.11.11",
47
+ "@mui/material": "5.4.2",
48
+ "@mui/utils": "^5.14.1",
49
+ "@next/font": "13.2.4",
50
+ "@nuskin/foundation-theme": "1.0.0-develop.5",
51
+ "framer-motion": "^10.8.5",
52
+ "next": "13.2.4",
53
+ "react": "18.2.0",
54
+ "react-dom": "18.2.0",
55
+ "react-material-ui-carousel": "^3.4.2",
56
+ "react-slick": "^0.29.0",
57
+ "slick-carousel": "^1.8.1",
58
+ "typescript": "4.9.5"
59
+ },
60
+ "devDependencies": {
61
+ "@babel/core": "^7.21.0",
62
+ "@babel/preset-env": "^7.20.2",
63
+ "@babel/preset-react": "^7.18.6",
64
+ "@babel/preset-typescript": "^7.21.0",
65
+ "@emotion/jest": "^11.10.5",
66
+ "@nuskin/eslint-config": "^1.0.0-setup.1",
67
+ "@storybook/addon-actions": "^7.0.7",
68
+ "@storybook/addon-essentials": "^7.0.7",
69
+ "@storybook/addon-interactions": "^7.0.7",
70
+ "@storybook/addon-links": "^7.0.7",
71
+ "@storybook/addon-mdx-gfm": "^7.0.7",
72
+ "@storybook/jest": "^0.1.0",
73
+ "@storybook/nextjs": "^7.0.7",
74
+ "@storybook/react": "^7.0.7",
75
+ "@storybook/test-runner": "^0.10.0",
76
+ "@storybook/testing-library": "^0.1.0",
77
+ "@testing-library/jest-dom": "^5.16.5",
78
+ "@testing-library/react": "^14.0.0",
79
+ "@testing-library/react-hooks": "^8.0.1",
80
+ "@types/jest": "^29.5.0",
81
+ "@types/lodash": "^4.14.191",
82
+ "@types/node": "18.15.0",
83
+ "@types/ramda": "^0.29.3",
84
+ "@types/react": "18.0.28",
85
+ "@types/react-dom": "18.0.11",
86
+ "@types/react-slick": "^0.23.10",
87
+ "@types/react-test-renderer": "^18.0.0",
88
+ "@types/testing-library__jest-dom": "^5.14.5",
89
+ "babel-jest": "^29.5.0",
90
+ "babel-loader": "^9.1.2",
91
+ "babel-plugin-emotion": "^11.0.0",
92
+ "chromatic": "^6.17.3",
93
+ "eslint": "8.36.0",
94
+ "eslint-config-next": "13.2.4",
95
+ "eslint-config-prettier": "^8.7.0",
96
+ "eslint-plugin-json": "^3.1.0",
97
+ "eslint-plugin-prettier": "^4.2.1",
98
+ "eslint-plugin-storybook": "^0.6.11",
99
+ "jest": "^29.5.0",
100
+ "jest-environment-jsdom": "^29.5.0",
101
+ "storybook": "^7.0.7"
102
+ },
103
+ "files": [
104
+ "src/common"
105
+ ],
106
+ "readme": "./README.md"
103
107
  }
@@ -1,6 +1,5 @@
1
- import { useState, useEffect, useMemo } from 'react';
2
- import NsAccordionItem from './NsAccordionItem';
3
- import { NsAccordionProps } from './types';
1
+ import React, { FC, useMemo } from 'react';
2
+ import { NsAccordionItem, useAccordionMap, NsAccordionProps, AccordionItem } from '..';
4
3
  import { StyledAccordionWrapper } from './ToggleSection.styled';
5
4
 
6
5
  /**
@@ -9,44 +8,30 @@ import { StyledAccordionWrapper } from './ToggleSection.styled';
9
8
  * multiple sections of accordion can remain open at a time
10
9
  *
11
10
  * we can define certain section to remain open by default using `isDefaultOpen` in the
12
- * contentArray item
11
+ * items
13
12
  * if there are multiple items available for default open, but `allowMultipleExpanded`
14
13
  * is false then only first item of default open is made open
15
14
  */
16
- const NsAccordion = ({
17
- additionalProps,
15
+ const createKey = (item: AccordionItem, index: number) => item?.id + index;
16
+ const NsAccordion: FC<NsAccordionProps> = ({
18
17
  allowMultipleExpanded,
19
- contentArray,
18
+ invert,
19
+ level,
20
20
  variant,
21
+ items,
21
22
  headerTypographyVariant,
22
23
  closedIconName,
23
24
  openedIconName,
24
- }: NsAccordionProps) => {
25
+ additionalProps,
26
+ isChild = false,
27
+ }) => {
25
28
  const defaultOpenIds = useMemo(() => {
26
- return contentArray
27
- .map((content, index) => (content?.isDefaultOpen ? index : null))
28
- .filter((e) => typeof e === 'number') as number[];
29
- }, [contentArray]);
30
- const [expandedIds, setExpandedIds] = useState<Array<number>>(defaultOpenIds);
29
+ return items
30
+ ?.map?.((content, index) => (content?.isDefaultOpen ? createKey(content, index) : null))
31
+ .filter((e) => e !== null) as string[];
32
+ }, [items]);
31
33
 
32
- const toggleOpen = (sectionNumber: number, isExpanded: boolean) => {
33
- if (allowMultipleExpanded) {
34
- if (isExpanded) {
35
- setExpandedIds(expandedIds.filter((existingNumber) => existingNumber !== sectionNumber));
36
- } else {
37
- setExpandedIds([...expandedIds, sectionNumber]);
38
- }
39
- } else {
40
- if (isExpanded) {
41
- setExpandedIds([]);
42
- } else {
43
- setExpandedIds([sectionNumber]);
44
- }
45
- }
46
- };
47
- useEffect(() => {
48
- setExpandedIds(allowMultipleExpanded ? defaultOpenIds : [defaultOpenIds[0]]);
49
- }, [allowMultipleExpanded, defaultOpenIds]);
34
+ const { toggleOpen, itemStateMap } = useAccordionMap({ allowMultipleExpanded, defaultOpenIds });
50
35
 
51
36
  return (
52
37
  <StyledAccordionWrapper
@@ -54,19 +39,26 @@ const NsAccordion = ({
54
39
  className="ns-accordion"
55
40
  data-testid={additionalProps?.testid ?? 'ns-accordion-testid'}
56
41
  >
57
- {contentArray.map((content, index) => {
58
- const isOpen = expandedIds.includes(index);
42
+ {items?.map?.((item, index) => {
43
+ const key = createKey(item, index);
44
+ const isOpen = itemStateMap[key] ?? false;
59
45
  return (
60
46
  <NsAccordionItem
61
- variant={variant}
62
- headerTypographyVariant={headerTypographyVariant}
47
+ allowMultipleExpanded={item.allowMultipleExpanded}
48
+ type={item.type}
63
49
  closedIconName={closedIconName}
64
- openedIconName={openedIconName}
65
- key={index}
50
+ content={item.content}
51
+ headerTypographyVariant={headerTypographyVariant}
52
+ invert={invert}
66
53
  isOpen={isOpen}
67
- toggleOpen={() => toggleOpen(index, isOpen)}
68
- content={content?.body}
69
- title={content?.title}
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}
70
62
  />
71
63
  );
72
64
  })}
@@ -1,18 +1,28 @@
1
- import { NsTypography, NsIcon, NsAccordionHeaderProps, AccordionVariant } from '..';
2
- import { styled, ColorUtils } from '@nuskin/foundation-theme';
3
- const { getPaletteColor } = ColorUtils;
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 };
4
9
 
5
- const StyledHeader = styled('header')<{ variant: AccordionVariant }>(({ theme, variant }) => {
6
- const backgroundColor = getPaletteColor(theme, 'primary', 'contrastText') as string;
10
+ const StyledHeader = styled(
11
+ 'header',
12
+ options
13
+ )<StyledType>(({ theme, variant, invert }) => {
14
+ const { headBg, headText } = getAccordionColor({ theme, variant, invert, keys: ['headBg', 'headText'] });
7
15
  let borderBottom = 'none';
8
16
  if (variant === AccordionVariant.Compact) {
9
17
  borderBottom = '1px solid rgb(0,0,0,0.125)';
10
18
  }
11
19
  return {
12
- backgroundColor,
20
+ backgroundColor: headBg,
21
+ color: headText,
13
22
  cursor: 'pointer',
14
23
  display: 'grid',
15
- gridTemplateColumns: '1fr 24px',
24
+ gap: '4px',
25
+ gridTemplateColumns: 'auto 1fr 24px',
16
26
  padding: '9px 16px',
17
27
  borderBottom,
18
28
  } as any;
@@ -31,17 +41,22 @@ const NsAccordionHeader = ({
31
41
  closedIconName,
32
42
  variant,
33
43
  headerTypographyVariant,
44
+ startIcon,
45
+ invert,
46
+ cslp,
34
47
  }: NsAccordionHeaderProps) => {
35
48
  return (
36
49
  <StyledHeader
50
+ invert={invert}
37
51
  role="button"
38
52
  aria-expanded={isOpen ? 'true' : 'false'}
39
53
  className={`section-header ${isOpen ? 'expanded' : ''} ${additionalProps?.className ?? ''}`}
40
54
  onClick={onClick}
41
55
  variant={variant}
42
56
  >
57
+ <HeaderIcon {...startIcon} />
43
58
  {typeof title === 'string' ? (
44
- <NsTypography variant={headerTypographyVariant ?? 'h4'} weight="bold">
59
+ <NsTypography variant={headerTypographyVariant ?? 'h4'} weight="bold" {...(cslp?.header ?? {})}>
45
60
  {title}
46
61
  </NsTypography>
47
62
  ) : (
@@ -54,3 +69,9 @@ const NsAccordionHeader = ({
54
69
  );
55
70
  };
56
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
+ };
@@ -6,9 +6,11 @@ import { StyledToggleSection } from './ToggleSection.styled';
6
6
  /**
7
7
  * this component is used by accordion to pass title
8
8
  * and content
9
+ * cslp:{header:CslpTag, content:CslpTag}
9
10
  */
10
11
  const NsAccordionItem = ({
11
12
  isOpen,
13
+ isChild,
12
14
  toggleOpen,
13
15
  title,
14
16
  content,
@@ -16,11 +18,19 @@ const NsAccordionItem = ({
16
18
  headerTypographyVariant,
17
19
  closedIconName,
18
20
  openedIconName,
21
+ startIcon,
22
+ level,
23
+ additionalProps,
24
+ invert,
25
+ type,
26
+ cslp,
27
+ allowMultipleExpanded,
19
28
  }: NsAccordionItemProps) => {
20
29
  return (
21
30
  <StyledToggleSection variant={variant}>
22
31
  <NsAccordionHeader
23
- additionalProps={{ className: 'accordion-section' }}
32
+ invert={invert}
33
+ additionalProps={{ ...additionalProps, className: 'accordion-section ' + additionalProps?.className }}
24
34
  closedIconName={closedIconName}
25
35
  headerTypographyVariant={headerTypographyVariant}
26
36
  isOpen={isOpen}
@@ -28,10 +38,20 @@ const NsAccordionItem = ({
28
38
  onClick={toggleOpen}
29
39
  title={title}
30
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}
31
54
  />
32
- <NsCollapse isOpen={isOpen} variant={variant}>
33
- {content}
34
- </NsCollapse>
35
55
  </StyledToggleSection>
36
56
  );
37
57
  };
@@ -1,55 +1,116 @@
1
- import { styled, ColorUtils, FoundationTheme } from '@nuskin/foundation-theme';
2
- import { AccordionVariant, NsCollapseProps } from './types.d';
3
- const { getAppColor, getPaletteColor } = ColorUtils;
4
- const getIsLight = (theme: FoundationTheme.Theme) => {
5
- const { palette = { primary: { main: '', contrastText: '' } } } = theme;
6
- return palette.primary.main === getAppColor(theme, 'primary', 'black');
1
+ import { styled } from '@nuskin/foundation-theme';
2
+ import {
3
+ AccordionVariant,
4
+ AccordionVariantType,
5
+ NsCollapseProps,
6
+ AccordionItem,
7
+ NsAccordion,
8
+ AccordionContentTypeObject,
9
+ } from '../';
10
+ import { getAccordionColor } from './colorMap';
11
+ import { ReactElement, isValidElement, useMemo } from 'react';
12
+
13
+ const getLevelOffset = (level: number) => {
14
+ return level > 1 ? (level - 1) * 16 : 0;
7
15
  };
16
+
8
17
  const options = {
9
- shouldForwardProp: (key: string) => key !== 'variant',
18
+ shouldForwardProp: (key: string) => !['variant', 'level'].includes(key),
10
19
  };
20
+
11
21
  export const StyledCollapse = styled(
12
22
  'section',
13
23
  options
14
- )<{ variant: AccordionVariant }>(({ theme, variant }) => {
15
- let backgroundColor = getIsLight(theme)
16
- ? (getAppColor(theme, 'primary', 'gray') as string)
17
- : (getAppColor(theme, 'primary', 'dark') as string);
18
- let borderBottom = 'none';
19
- if (variant === AccordionVariant.Compact) {
20
- backgroundColor = getIsLight(theme)
21
- ? (getAppColor(theme, 'primary', 'white') as string)
22
- : (getAppColor(theme, 'primary', 'dark') as string);
23
- borderBottom = '1px solid rgb(0,0,0,0.125)';
24
+ )<{ variant: AccordionVariantType; level: number; invert: boolean; isChild: boolean }>(
25
+ ({ theme, variant, level, invert, isChild }) => {
26
+ const { contentBg, contentText } = getAccordionColor({
27
+ theme,
28
+ invert,
29
+ variant,
30
+ keys: ['contentBg', 'contentText'],
31
+ });
32
+
33
+ let borderBottom = 'none';
34
+ if (variant === AccordionVariant.Compact) {
35
+ borderBottom = isChild ? 'none' : '1px solid rgb(0,0,0,0.125)';
36
+ }
37
+ return {
38
+ backgroundColor: contentBg,
39
+ color: contentText,
40
+ opacity: 0,
41
+ padding: '0 16px',
42
+ height: 0,
43
+ overflow: 'hidden',
44
+ transition: '0.3s',
45
+ '&.expanded': {
46
+ padding: `9px 0 9px ${getLevelOffset(level)}px`,
47
+ height: 'auto',
48
+ opacity: 1,
49
+ borderBottom,
50
+ },
51
+ '.nsa-content-padded': {
52
+ padding: '0 16px 16px',
53
+ },
54
+ };
24
55
  }
25
- return {
26
- backgroundColor,
27
- color: getPaletteColor(theme, 'primary', 'main') as string,
28
- opacity: 0,
29
- padding: '0 16px',
30
- height: 0,
31
- overflow: 'hidden',
32
- transition: '0.3s',
33
- '&.expanded': {
34
- padding: '9px 16px',
35
- height: 'auto',
36
- opacity: 1,
37
- borderBottom,
38
- },
39
- };
40
- });
56
+ );
41
57
 
42
58
  /**
43
59
  * NsCollapse component adds css animation while showing children items if prop `isOpen` is true,
44
60
  * and while removing children if prop `isOpen` is false
45
61
  */
46
- const NsCollapse = ({ isOpen, children, additionalProps, variant }: NsCollapseProps) => {
62
+ const NsCollapse = ({
63
+ isOpen,
64
+ content,
65
+ additionalProps,
66
+ variant,
67
+ level,
68
+ invert,
69
+ isChild,
70
+ type,
71
+ cslp,
72
+ allowMultipleExpanded,
73
+ }: NsCollapseProps) => {
74
+ const body = useMemo(() => {
75
+ if (isValidElement(content)) {
76
+ return content as ReactElement;
77
+ }
78
+ if (type === AccordionContentTypeObject.html) {
79
+ return (
80
+ <div
81
+ className="nsa-content-padded"
82
+ dangerouslySetInnerHTML={{ __html: content as string }}
83
+ {...(cslp?.content ?? {})}
84
+ />
85
+ );
86
+ } else if (type === AccordionContentTypeObject.text) {
87
+ return (
88
+ <div className="p-4" {...(cslp?.content ?? {})}>
89
+ {content as string}
90
+ </div>
91
+ );
92
+ } else if (type === AccordionContentTypeObject.accordion) {
93
+ return (
94
+ <NsAccordion
95
+ isChild={true}
96
+ invert={invert}
97
+ level={level}
98
+ variant={AccordionVariant.Gray}
99
+ items={content as AccordionItem[]}
100
+ allowMultipleExpanded={allowMultipleExpanded ?? false}
101
+ />
102
+ );
103
+ }
104
+ }, [allowMultipleExpanded, content, cslp?.content, invert, level, type]);
47
105
  return (
48
106
  <StyledCollapse
107
+ isChild={isChild}
108
+ level={level}
49
109
  className={`ns-collapse ${isOpen ? 'expanded' : ''} ${additionalProps?.className ?? ''}`}
50
110
  variant={variant}
111
+ invert={invert}
51
112
  >
52
- {isOpen ? children : null}
113
+ {body}
53
114
  </StyledCollapse>
54
115
  );
55
116
  };
@@ -9,7 +9,16 @@ import { NsToggleSectionProps, NsAccordionItem } from '../';
9
9
  * by default, otherwise children is hidden by default and toggles between visible
10
10
  * and hidden on clicking title
11
11
  */
12
- const NsToggleSection = ({ title, children, additionalProps, defaultOpen, variant }: NsToggleSectionProps) => {
12
+ const NsToggleSection = ({
13
+ title,
14
+ content,
15
+ additionalProps,
16
+ defaultOpen,
17
+ variant,
18
+ invert,
19
+ isChild,
20
+ type,
21
+ }: NsToggleSectionProps) => {
13
22
  const [isExpanded, setIsExpanded] = useState(defaultOpen ?? false);
14
23
 
15
24
  const toggleAccordion = () => {
@@ -17,12 +26,16 @@ const NsToggleSection = ({ title, children, additionalProps, defaultOpen, varian
17
26
  };
18
27
  return (
19
28
  <NsAccordionItem
29
+ type={type}
30
+ level={2}
20
31
  variant={variant}
21
- additionalProps={{ ...additionalProps, className: 'toggle-section ' + additionalProps?.className ?? '' }}
32
+ additionalProps={additionalProps}
22
33
  isOpen={isExpanded}
23
34
  title={title}
24
- content={children}
35
+ content={content}
25
36
  toggleOpen={toggleAccordion}
37
+ invert={invert}
38
+ isChild={isChild}
26
39
  />
27
40
  );
28
41
  };