@nuskin/foundation-ui-components 1.0.0-develop.1 → 1.0.0-develop.11

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 (250) 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 +117 -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 +18 -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 +6 -17
  80. package/src/common/cart-icon/NsCartIcon.stories.tsx +3 -3
  81. package/src/common/cart-icon/NsCartIcon.styled.ts +7 -33
  82. package/src/common/cart-icon/NsCartIcon.tsx +6 -15
  83. package/src/common/cart-icon/index.ts +1 -1
  84. package/src/common/cart-icon/types.d.ts +1 -0
  85. package/src/common/checkbox/NsCheckbox.spec.tsx +2 -2
  86. package/src/common/checkbox/NsCheckbox.stories.tsx +2 -2
  87. package/src/common/checkbox/NsCheckbox.styled.tsx +15 -16
  88. package/src/common/checkbox/NsCheckbox.tsx +2 -2
  89. package/src/common/checkbox/index.ts +1 -1
  90. package/src/common/checkbox/types.d.ts +1 -7
  91. package/src/common/column-control/NsColumnControl.tsx +1 -1
  92. package/src/common/column-control/NsFlexColumns.tsx +22 -0
  93. package/src/common/column-control/NsGridColumns.tsx +22 -0
  94. package/src/common/column-control/index.ts +3 -1
  95. package/src/common/column-control/{NsColumnControl.spec.tsx → specs/NsColumnControl.spec.tsx} +3 -3
  96. package/src/common/column-control/specs/NsFlexColumns.spec.tsx +24 -0
  97. package/src/common/column-control/specs/NsGridColumns.spec.tsx +24 -0
  98. package/src/common/column-control/stories/DivArray.stories.tsx +18 -0
  99. package/src/common/column-control/stories/DivArray.tsx +63 -0
  100. package/src/common/column-control/{NsColumnControl.stories.tsx → stories/NsColumnControl.stories.tsx} +9 -16
  101. package/src/common/column-control/stories/NsFlexColumns.stories.tsx +63 -0
  102. package/src/common/column-control/stories/NsGridColumns.stories.tsx +63 -0
  103. package/src/common/column-control/stories/common.tsx +14 -0
  104. package/src/common/column-control/styled/StyledFlex.tsx +45 -0
  105. package/src/common/column-control/styled/StyledGrid.tsx +40 -0
  106. package/src/common/column-control/styled/common.ts +27 -0
  107. package/src/common/column-control/types.d.ts +15 -16
  108. package/src/common/column-control/utils.ts +5 -5
  109. package/src/common/common.types.d.ts +21 -0
  110. package/src/common/dropdown/NsDropdown.spec.tsx +1 -1
  111. package/src/common/dropdown/NsDropdown.styled.tsx +23 -18
  112. package/src/common/dropdown/NsDropdown.tsx +1 -1
  113. package/src/common/dropdown/NsDropdownOption.tsx +1 -1
  114. package/src/common/dropdown/index.ts +1 -1
  115. package/src/common/dropdown/stories/NsDropdown.stories.tsx +2 -2
  116. package/src/common/dropdown/stories/NsDropdownCountry.stories.tsx +2 -2
  117. package/src/common/dropdown/types.d.ts +3 -1
  118. package/src/common/email-simple/NsEmailSimple.spec.tsx +145 -0
  119. package/src/common/email-simple/NsEmailSimple.stories.tsx +61 -0
  120. package/src/common/email-simple/NsEmailSimple.tsx +71 -0
  121. package/src/common/email-simple/index.ts +2 -0
  122. package/src/common/email-simple/types.d.ts +14 -0
  123. package/src/common/flag/NsFlag.spec.tsx +5 -25
  124. package/src/common/flag/NsFlag.stories.tsx +2 -2
  125. package/src/common/flag/NsFlag.styled.tsx +7 -9
  126. package/src/common/flag/NsFlag.tsx +1 -3
  127. package/src/common/flag/index.ts +1 -1
  128. package/src/common/flag/types.d.ts +0 -2
  129. package/src/common/hooks/index.ts +2 -0
  130. package/src/common/hooks/specs/useWindowSize.spec.tsx +19 -0
  131. package/src/common/hooks/useAccordionMap.tsx +39 -0
  132. package/src/common/hooks/useWindowSize.tsx +30 -0
  133. package/src/common/icon/NsIcon.spec.tsx +1 -1
  134. package/src/common/icon/NsIcon.stories.tsx +2 -2
  135. package/src/common/icon/NsIcon.styled.tsx +1 -1
  136. package/src/common/icon/NsIcon.tsx +1 -1
  137. package/src/common/icon/NsIconVariants.ts +9 -4
  138. package/src/common/icon/icons/AlertErrorIcon.tsx +15 -6
  139. package/src/common/icon/icons/Cart.tsx +7 -32
  140. package/src/common/icon/icons/HamburgerIcon.tsx +29 -0
  141. package/src/common/icon/icons/UserIcon.tsx +30 -0
  142. package/src/common/icon/icons/WarningIcon.tsx +14 -5
  143. package/src/common/icon/index.ts +1 -1
  144. package/src/common/icon/types.d.ts +1 -0
  145. package/src/common/image/NsImage.spec.tsx +57 -7
  146. package/src/common/image/NsImage.stories.tsx +2 -2
  147. package/src/common/image/NsImage.tsx +24 -12
  148. package/src/common/image/NsNextImage.spec.tsx +1 -1
  149. package/src/common/image/NsNextImage.stories.tsx +2 -2
  150. package/src/common/image/NsNextImage.tsx +1 -1
  151. package/src/common/image/index.ts +1 -1
  152. package/src/common/image/types.d.ts +1 -0
  153. package/src/common/index.ts +14 -10
  154. package/src/common/input/InputFieldWrapper.tsx +4 -4
  155. package/src/common/input/InputWrapper.tsx +12 -7
  156. package/src/common/input/NsInputField.stories.tsx +13 -10
  157. package/src/common/input/NsInputField.tsx +13 -6
  158. package/src/common/input/getAdornmentProps.tsx +5 -1
  159. package/src/common/input/index.ts +1 -1
  160. package/src/common/input/types.d.ts +18 -1
  161. package/src/common/label/NsLabel.stories.tsx +6 -1
  162. package/src/common/label/NsLabel.tsx +21 -20
  163. package/src/common/label/index.ts +1 -1
  164. package/src/common/label/types.d.ts +2 -1
  165. package/src/common/link/NsLink.spec.tsx +1 -1
  166. package/src/common/link/NsLink.stories.tsx +2 -2
  167. package/src/common/link/NsLink.tsx +1 -1
  168. package/src/common/link/index.ts +1 -1
  169. package/src/common/modal/NsModal.spec.tsx +46 -0
  170. package/src/common/modal/NsModal.styled.tsx +28 -0
  171. package/src/common/modal/NsModal.tsx +37 -0
  172. package/src/common/modal/helper-component/NsModalContentBox.tsx +32 -0
  173. package/src/common/modal/helper-component/NsModalDefault.tsx +25 -0
  174. package/src/common/modal/helper-component/NsModalStatus.tsx +15 -0
  175. package/src/common/modal/helper-component/NsModalStatusIcon.tsx +14 -0
  176. package/src/common/modal/helper-component/NsModalTitle.tsx +26 -0
  177. package/src/common/modal/index.ts +2 -0
  178. package/src/common/modal/model/NsModalVariantMap.tsx +24 -0
  179. package/src/common/modal/stories/NsModal.stories.tsx +86 -0
  180. package/src/common/modal/stories/mock.tsx +46 -0
  181. package/src/common/modal/types.ts +56 -0
  182. package/src/common/nav-product-card/NsNavProductCard.spec.tsx +1 -1
  183. package/src/common/nav-product-card/NsNavProductCard.stories.tsx +2 -2
  184. package/src/common/nav-product-card/NsNavProductCard.tsx +1 -1
  185. package/src/common/nav-product-card/index.ts +1 -1
  186. package/src/common/nav-tab/NsNavTab.spec.tsx +2 -7
  187. package/src/common/nav-tab/NsNavTab.stories.tsx +2 -2
  188. package/src/common/nav-tab/NsNavTab.styled.tsx +7 -4
  189. package/src/common/nav-tab/NsNavTab.tsx +1 -1
  190. package/src/common/nav-tab/index.ts +1 -1
  191. package/src/common/nav-tab/types.d.ts +2 -2
  192. package/src/common/radiogroup/NsRadioGroup.spec.tsx +63 -0
  193. package/src/common/radiogroup/NsRadioGroup.stories.tsx +84 -0
  194. package/src/common/radiogroup/NsRadioGroup.styled.tsx +52 -0
  195. package/src/common/radiogroup/NsRadioGroup.tsx +62 -0
  196. package/src/common/radiogroup/index.ts +2 -0
  197. package/src/common/radiogroup/types.d.ts +20 -0
  198. package/src/common/search-bar/NsSeachBar.spec.tsx +1 -1
  199. package/src/common/search-bar/NsSearchBar.tsx +1 -3
  200. package/src/common/select/NsSelect.spec.tsx +193 -0
  201. package/src/common/select/NsSelect.styled.tsx +104 -0
  202. package/src/common/select/NsSelect.tsx +117 -0
  203. package/src/common/select/NsSelectOption.tsx +30 -0
  204. package/src/common/select/index.ts +3 -0
  205. package/src/common/select/stories/NsSelect.stories.tsx +134 -0
  206. package/src/common/select/types.d.ts +34 -0
  207. package/src/common/spinner/NsSpinner.spec.tsx +21 -0
  208. package/src/common/spinner/NsSpinner.stories.tsx +26 -0
  209. package/src/common/spinner/NsSpinner.styled.tsx +344 -0
  210. package/src/common/spinner/NsSpinner.tsx +14 -0
  211. package/src/common/spinner/icons/Spinner.tsx +161 -0
  212. package/src/common/spinner/index.ts +2 -0
  213. package/src/common/spinner/types.ts +5 -0
  214. package/src/common/table/NsExpandableRow.tsx +68 -0
  215. package/src/common/table/NsTable.spec.tsx +174 -0
  216. package/src/common/table/NsTable.stories.tsx +161 -0
  217. package/src/common/table/NsTable.styled.ts +127 -0
  218. package/src/common/table/NsTable.tsx +133 -0
  219. package/src/common/table/NsTableHeader.tsx +41 -0
  220. package/src/common/table/NsTablePagination.tsx +28 -0
  221. package/src/common/table/helper.ts +33 -0
  222. package/src/common/table/index.ts +2 -0
  223. package/src/common/table/types.d.ts +57 -0
  224. package/src/common/text-strip/NsTextStrip.spec.tsx +30 -0
  225. package/src/common/text-strip/NsTextStrip.stories.tsx +33 -0
  226. package/src/common/text-strip/NsTextStrip.tsx +47 -0
  227. package/src/common/text-strip/index.ts +2 -0
  228. package/src/common/text-strip/types.d.ts +17 -0
  229. package/src/common/typography/NsTypography.stories.tsx +2 -2
  230. package/src/common/typography/NsTypography.tsx +1 -1
  231. package/src/common/typography/Typography.styled.tsx +4 -4
  232. package/src/common/typography/index.ts +1 -1
  233. package/src/common/util.ts +1 -0
  234. package/src/common/utility/Show.tsx +13 -0
  235. package/src/common/utility/index.ts +1 -0
  236. package/src/common/validations/regex.ts +3 -0
  237. package/src/common/videos/NsVideo.stories.tsx +2 -2
  238. package/src/common/videos/NsVideo.tsx +1 -1
  239. package/src/common/videos/index.ts +1 -1
  240. package/src/common/videos/types.d.ts +1 -1
  241. package/src/common/alert/NsAlert.styled.ts +0 -124
  242. package/src/common/card/tests/NsFfgCard.spec.tsx +0 -23
  243. package/src/common/column-control/NDivs.story.tsx +0 -35
  244. package/src/common/common.types.ts +0 -10
  245. /package/src/common/brand-components/{NsBrandContanier.styled.tsx → NsBrandContainer.styled.tsx} +0 -0
  246. /package/src/common/card/{tests → specs}/BrandLogo.spec.tsx +0 -0
  247. /package/src/common/card/{tests → specs}/NsBgCard.spec.tsx +0 -0
  248. /package/src/common/card/{tests → specs}/NsBrandProductCard.spec.tsx +0 -0
  249. /package/src/common/carousal/{tests → specs}/Chevron.spec.tsx +0 -0
  250. /package/src/common/carousal/{tests → specs}/RenderBrand.spec.tsx +0 -0
@@ -0,0 +1,127 @@
1
+ // TODO: const ariel = #f8e9f8;
2
+
3
+ import { styled, ColorUtils } from '@nuskin/foundation-theme';
4
+
5
+ import {
6
+ Table,
7
+ TableContainer,
8
+ TableSortLabel,
9
+ TableRow,
10
+ TableCell
11
+ } from '@mui/material';
12
+ import Pagination from '@mui/material/Pagination';
13
+ import LinearProgress from '@mui/material/LinearProgress';
14
+
15
+ const { color } = ColorUtils;
16
+
17
+ export const StyledTableContainer= styled(TableContainer)`
18
+ background-color: ${color('primary', 'white')};
19
+ `;
20
+
21
+ export const StyledTable = styled(Table)`
22
+ size: medium;
23
+ `;
24
+
25
+ export const StyledTableSortLabel = styled(TableSortLabel)`
26
+ font-size: 12px;
27
+ text-transform: uppercase;
28
+ font-weight: 600;
29
+ line-height: 16px;
30
+ letter-spacing: 0.05em;
31
+ color: rgba(0, 0, 0, 0.54);
32
+ &:hover {
33
+ color: ${color('primary', 'black')};
34
+ }
35
+ `;
36
+
37
+ export const StyledTableLabel = styled.span`
38
+ font-size: 12px;
39
+ text-transform: uppercase;
40
+ font-weight: 700;
41
+ line-height: 16px;
42
+ letter-spacing: 0.05em;
43
+ color: rgba(0, 0, 0, 0.54);
44
+ &:hover {
45
+ cursor: default;
46
+ }
47
+ `;
48
+
49
+ export const StyledPageComponent = styled.div`
50
+ background-color: ${color('primary', 'white')};
51
+ `;
52
+
53
+ export const StyledEmptyRow = styled(TableRow)<{emptyRows: number}>`
54
+ height: ${({ emptyRows }) => 48 * emptyRows}px;
55
+ `;
56
+
57
+ // [Todo-Arun] - Move f8e9f8 to custom color palette
58
+ export const StyledTableRow = styled(TableRow)`
59
+ &:hover {
60
+ background-color: #f8e9f8 !important;
61
+ }
62
+ `;
63
+
64
+ export const StyledTableLastCell = styled(TableCell)`
65
+ display: flex;
66
+ height: 49px;
67
+ align-items: center;
68
+ padding: 0 24px;
69
+ margin-bottom: -0.5px;
70
+
71
+ .action {
72
+ margin-left: auto;
73
+ }
74
+ `;
75
+
76
+ export const StyledOriginalTableCell = styled(TableCell)`
77
+ height: 48px;
78
+ padding: 0 24px;
79
+ `;
80
+
81
+ export const StyledPagination = styled(Pagination)`
82
+ .MuiPagination-ul {
83
+ display: flex;
84
+ justify-content: flex-end;
85
+ background-color: ${color('primary', 'white')};
86
+ }
87
+ & .MuiPaginationItem-previousNext {
88
+ margin: 0.3rem 10px;
89
+ width: 2rem;
90
+ height: 2rem;
91
+ border-radius: 4px;
92
+ }
93
+ & .MuiPaginationItem-page {
94
+ border-radius: 0px;
95
+ width: auto;
96
+ min-width: 34px;
97
+ padding: 0 5px;
98
+ font-size: 16px;
99
+ line-height: 17px;
100
+ border-color: ${color('primary', 'black')};
101
+ }
102
+ & .MuiPaginationItem-root.Mui-selected {
103
+ background-color: ${color('primary', 'black')};
104
+ color: ${color('primary', 'white')};
105
+ }
106
+ `;
107
+
108
+ export const StyledExpandCell= styled(TableCell)`
109
+ padding-bottom: 0;
110
+ padding-top: 0;
111
+ &.remove {
112
+ border: 0;
113
+ }
114
+ `;
115
+
116
+ export const StyledProgressCell = styled(TableCell)`
117
+ padding: 0;
118
+ border: 0;
119
+ `;
120
+
121
+ export const StyledLinearProgress = styled(LinearProgress)`
122
+ && {
123
+ width: 100%;
124
+ height: 7px;
125
+ border-radius: 4px;
126
+ }
127
+ `;
@@ -0,0 +1,133 @@
1
+ import React, { useState, useEffect } from 'react';
2
+ import { TableBody, TableCell, TableRow } from '@mui/material';
3
+ import {
4
+ StyledTable,
5
+ StyledTableContainer,
6
+ StyledEmptyRow,
7
+ StyledProgressCell,
8
+ StyledLinearProgress,
9
+ } from './NsTable.styled';
10
+ import type { NsTableProps, Item, OrderType } from './types';
11
+ import { stableSort, getComparator } from './helper';
12
+ import NsTableHeader from './NsTableHeader';
13
+ import NsTablePagination from './NsTablePagination';
14
+ import ExpandableRow from './NsExpandableRow';
15
+ import Grid from '@mui/material/Grid';
16
+
17
+ export default function NsTable({
18
+ headers = [],
19
+ items = [],
20
+ rows,
21
+ rowsPerPageOptions,
22
+ itemKey,
23
+ expandableContent,
24
+ actionClick,
25
+ showActions = true,
26
+ showExpandedContent = true,
27
+ loading = false,
28
+ isExpandableAll = false,
29
+ }: NsTableProps) {
30
+ const [order, setOrder] = useState<OrderType>('asc');
31
+ const [orderBy, setOrderBy] = useState<keyof Item>(itemKey);
32
+ const [expandMap, setExpandMap] = useState<{ [key: number]: boolean }>({});
33
+ const [page, setPage] = useState(0);
34
+ const [rowsPerPage, setRowsPerPage] = useState(rows);
35
+ const itemKeyList = React.useMemo(() => {
36
+ return items.length ? Object.keys(items[0]) : [];
37
+ }, [items]);
38
+
39
+ useEffect(() => {
40
+ setRowsPerPage(rows);
41
+ setPage(0);
42
+ }, [rows]);
43
+
44
+ const handleRequestSort = (event: React.MouseEvent<unknown>, property: keyof Item) => {
45
+ const isAsc = orderBy === property && order === 'asc';
46
+ setOrder(isAsc ? 'desc' : 'asc');
47
+ setOrderBy(property);
48
+ };
49
+
50
+ const handleClick = (index: number) => {
51
+ if (isExpandableAll) {
52
+ setExpandMap((prevState) => ({ ...prevState, [index]: !prevState[index] }));
53
+ } else {
54
+ setExpandMap({ [index]: !expandMap[index] });
55
+ }
56
+ };
57
+
58
+ const handleChangePage = (newPage: number) => {
59
+ setPage(newPage - 1);
60
+ };
61
+
62
+ const emptyRows = getEmptyRows();
63
+
64
+ const visibleRows = React.useMemo(
65
+ () =>
66
+ stableSort(items, getComparator(order, orderBy)).slice(
67
+ page * rowsPerPage,
68
+ page * rowsPerPage + rowsPerPage
69
+ ),
70
+ [order, orderBy, page, rowsPerPage, items]
71
+ );
72
+
73
+ return (
74
+ <div>
75
+ <StyledTableContainer>
76
+ <StyledTable>
77
+ <NsTableHeader
78
+ headCells={headers}
79
+ order={order}
80
+ orderBy={orderBy as string}
81
+ onRequestSort={handleRequestSort}
82
+ rowCount={items.length}
83
+ />
84
+ <TableBody>
85
+ {loading ? (
86
+ <TableRow>
87
+ <StyledProgressCell colSpan={itemKeyList.length}>
88
+ <Grid container>
89
+ <Grid item xs={12}>
90
+ <StyledLinearProgress />
91
+ </Grid>
92
+ </Grid>
93
+ </StyledProgressCell>
94
+ </TableRow>
95
+ ) : null}
96
+ {visibleRows.map((row, index) => {
97
+ return (
98
+ <ExpandableRow
99
+ key={index}
100
+ expandableContent={expandableContent}
101
+ isExpand={expandMap[index]}
102
+ handleClick={handleClick}
103
+ row={row}
104
+ index={index}
105
+ itemKeyList={itemKeyList}
106
+ actionClick={actionClick}
107
+ showActions={showActions}
108
+ showExpandedContent={showExpandedContent}
109
+ />
110
+ );
111
+ })}
112
+ {emptyRows > 0 ? (
113
+ <StyledEmptyRow emptyRows={emptyRows}>
114
+ <TableCell colSpan={itemKeyList.length} />
115
+ </StyledEmptyRow>
116
+ ) : null}
117
+ </TableBody>
118
+ </StyledTable>
119
+ </StyledTableContainer>
120
+ <NsTablePagination
121
+ rowsPerPageOptions={rowsPerPageOptions}
122
+ count={items.length}
123
+ rowsPerPage={rowsPerPage}
124
+ page={page + 1}
125
+ onPageChange={handleChangePage}
126
+ />
127
+ </div>
128
+ );
129
+
130
+ function getEmptyRows() {
131
+ return page > 0 ? Math.max(0, (1 + page) * rowsPerPage - items.length) : 0;
132
+ }
133
+ }
@@ -0,0 +1,41 @@
1
+ import type { NsTableHeaderProps, Item } from './types';
2
+ import React from 'react';
3
+ import { TableHead, TableRow, Box, TableCell } from '@mui/material';
4
+ import { StyledTableSortLabel, StyledTableLabel } from './NsTable.styled';
5
+ import { visuallyHidden } from '@mui/utils';
6
+
7
+ export default function NsTableHeader(props: NsTableHeaderProps) {
8
+ const { order, orderBy, headCells, onRequestSort } = props;
9
+ const createSortHandler = (property: keyof Item) => (event: React.MouseEvent<unknown>) => {
10
+ onRequestSort(event, property);
11
+ };
12
+
13
+ return (
14
+ <TableHead>
15
+ <TableRow>
16
+ {headCells.map((headCell) =>
17
+ headCell.sortable ? (
18
+ <TableCell key={headCell.id} sortDirection={orderBy === headCell.id ? order : false}>
19
+ <StyledTableSortLabel
20
+ active={orderBy === headCell.id}
21
+ direction={orderBy === headCell.id ? order : 'asc'}
22
+ onClick={createSortHandler(headCell.id)}
23
+ >
24
+ {headCell.label}
25
+ {orderBy === headCell.id ? (
26
+ <Box component="span" sx={visuallyHidden}>
27
+ {order === 'desc' ? 'sorted descending' : 'sorted ascending'}
28
+ </Box>
29
+ ) : null}
30
+ </StyledTableSortLabel>
31
+ </TableCell>
32
+ ) : (
33
+ <TableCell key={headCell.id} sortDirection={false}>
34
+ <StyledTableLabel>{headCell.label}</StyledTableLabel>
35
+ </TableCell>
36
+ )
37
+ )}
38
+ </TableRow>
39
+ </TableHead>
40
+ );
41
+ }
@@ -0,0 +1,28 @@
1
+ import type { NsTablePaginationProps } from './types'
2
+ import React from 'react'
3
+ import { StyledPagination } from './NsTable.styled'
4
+
5
+ export default function NsTablePagination(props: NsTablePaginationProps) {
6
+ const {
7
+ count,
8
+ rowsPerPage,
9
+ page,
10
+ onPageChange,
11
+ } = props;
12
+
13
+ const totalPage = Math.ceil(count / rowsPerPage);
14
+ const handleChange = (event: React.ChangeEvent<unknown>, value: number) => {
15
+ onPageChange(value);
16
+ };
17
+
18
+ return (
19
+ <StyledPagination
20
+ count={totalPage}
21
+ page={page}
22
+ variant="outlined"
23
+ onChange={handleChange}
24
+ shape="rounded"
25
+ color="primary"
26
+ />
27
+ );
28
+ }
@@ -0,0 +1,33 @@
1
+ /* eslint-disable no-unused-vars */
2
+ import type { OrderType } from './types.d';
3
+
4
+ export function descendingComparator<T>(a: T, b: T, orderBy: keyof T) {
5
+ if (b[orderBy] < a[orderBy]) {
6
+ return -1;
7
+ }
8
+ if (b[orderBy] > a[orderBy]) {
9
+ return 1;
10
+ }
11
+ return 0;
12
+ }
13
+
14
+ export function getComparator<Key extends keyof any>(
15
+ order: OrderType,
16
+ orderBy: Key
17
+ ): (a: { [key in Key]: number | string }, b: { [key in Key]: number | string }) => number {
18
+ return order === 'desc'
19
+ ? (a, b) => descendingComparator(a, b, orderBy)
20
+ : (a, b) => -descendingComparator(a, b, orderBy);
21
+ }
22
+
23
+ export function stableSort<T>(array: readonly T[], comparator: (a: T, b: T) => number) {
24
+ const stabilizedThis = array.map((el, index) => [el, index] as [T, number]);
25
+ stabilizedThis.sort((a, b) => {
26
+ const order = comparator(a[0], b[0]);
27
+ if (order !== 0) {
28
+ return order;
29
+ }
30
+ return a[1] - b[1];
31
+ });
32
+ return stabilizedThis.map((el) => el[0]);
33
+ }
@@ -0,0 +1,2 @@
1
+ export { default as NsTable } from './NsTable';
2
+ export type { NsTableProps } from './types.d';
@@ -0,0 +1,57 @@
1
+ /* eslint-disable no-unused-vars */
2
+ import { React } from 'React'
3
+
4
+ export interface Header {
5
+ label: string;
6
+ id: string | number;
7
+ numeric: boolean;
8
+ sortable?: boolean;
9
+ }
10
+
11
+ export interface Item {
12
+ [key: string]: string | number;
13
+ }
14
+
15
+ export interface NsTableProps {
16
+ headers: Header[];
17
+ items: Item[];
18
+ rows: number;
19
+ itemKey: string;
20
+ rowsPerPageOptions: number[];
21
+ isExpandableAll?: boolean;
22
+ showActions?: boolean;
23
+ showExpandedContent?: boolean;
24
+ loading?: boolean;
25
+ expandableContent: (selectedItem: Item, index: number) => React.ReactNode;
26
+ actionClick: (item: Item) => React.ReactNode;
27
+ }
28
+
29
+ export type OrderType = 'asc' | 'desc';
30
+
31
+ export interface NsTableHeaderProps {
32
+ onRequestSort: (event: React.MouseEvent<unknown>, property: keyof Item) => void;
33
+ order: OrderType;
34
+ orderBy: string;
35
+ rowCount: number;
36
+ headCells: readonly Header[];
37
+ }
38
+
39
+ export interface NsTablePaginationProps {
40
+ rowsPerPageOptions: number[],
41
+ count: number;
42
+ rowsPerPage: number;
43
+ page: number,
44
+ onPageChange: (number) => void;
45
+ }
46
+
47
+ export interface NsTableRowProps {
48
+ expandableContent: (selectedItem: Item, index: number) => React.ReactNode;
49
+ isExpand: boolean;
50
+ handleClick: (index: number) => void;
51
+ row: Item;
52
+ index: number;
53
+ itemKeyList: string[];
54
+ showActions: boolean;
55
+ showExpandedContent: boolean;
56
+ actionClick: (item: Item) => React.ReactNode;
57
+ }
@@ -0,0 +1,30 @@
1
+ import React from 'react';
2
+ import { render, screen } from '@testing-library/react';
3
+ import { NsTextStrip } from '@/common/';
4
+
5
+ describe('NsTextStrip component', () => {
6
+ it('renders text description and link', () => {
7
+ const text = 'Free Delivery';
8
+ const description = 'Download the app to access everything Nike';
9
+ const link = { href: 'https://www.nike.com/in/help/a/shipping-delivery-gs', title: 'View Details' };
10
+ render(<NsTextStrip link={link} description={description} text={text} />);
11
+ const element = screen.getByText(text);
12
+ expect(element).toBeInTheDocument();
13
+ const descElement = screen.getByText(description);
14
+ expect(descElement).toBeInTheDocument();
15
+ const anchorElement = screen.getByText(link.title);
16
+ expect(anchorElement.tagName).toBe('A');
17
+ expect(anchorElement).toHaveAttribute('href', link.href);
18
+ });
19
+ it('does not have anchor when link is undefined', () => {
20
+ const text = 'Free Delivery';
21
+ const description = 'Download the app to access everything Nike';
22
+ let link = { title: 'hi' };
23
+ render(<NsTextStrip link={link} description={description} text={text} />);
24
+ const element = screen.getByText(text);
25
+ expect(element).toBeInTheDocument();
26
+ const descElement = screen.getByText(description);
27
+ expect(descElement).toBeInTheDocument();
28
+ expect(() => screen.getByText(link.title)).toThrow();
29
+ });
30
+ });
@@ -0,0 +1,33 @@
1
+ /**
2
+ * NsTextStrip.stories.tsx
3
+ * @description NsTextStrip component.
4
+ */
5
+
6
+ import type { StoryObj, Meta } from '@storybook/react';
7
+ import { NsTextStrip } from '@/common/';
8
+ import { withCenterDecorator } from '@/stories/decorators/withCenterDecorator';
9
+
10
+ type ComponentType = typeof NsTextStrip;
11
+ type Story = StoryObj<ComponentType>;
12
+ type MetaStory = Meta<ComponentType>;
13
+
14
+ export default {
15
+ title: 'Components/Data Display/NsTextStrip',
16
+ component: NsTextStrip,
17
+ decorators: [withCenterDecorator],
18
+ argTypes: {
19
+ alignment: {
20
+ control: 'select',
21
+ options: ['center', 'start', 'end'],
22
+ description: 'specify whether items should be in center, start or end',
23
+ },
24
+ },
25
+ args: {
26
+ text: 'Free Delivery',
27
+ description: 'Download the app to access everything Nike',
28
+ link: { href: 'https://www.nike.com/in/help/a/shipping-delivery-gs', title: 'View Details' },
29
+ alignment: 'center',
30
+ },
31
+ } as MetaStory;
32
+
33
+ export const DefaultTextStrip: Story = {};
@@ -0,0 +1,47 @@
1
+ /**
2
+ * NsTextStrip.tsx
3
+ * @description NsTextStrip component for scrolling text CTA
4
+ */
5
+
6
+ import React from 'react';
7
+
8
+ import { NsTextStripProps } from './types.d';
9
+ import { NsTypography } from '../typography';
10
+ import { NsLink } from '../link';
11
+ import { styled, ColorUtils } from '@nuskin/foundation-theme';
12
+
13
+ const { isDarkMode, paletteColor, color } = ColorUtils;
14
+
15
+ const StyledHeader = styled.header`
16
+ background: ${(props) => (
17
+ !isDarkMode(props)
18
+ ? color('primary', 'gray')
19
+ : paletteColor('primary', 'contrastText')
20
+ )};
21
+ display: flex;
22
+ flex-direction: column;
23
+ min-height: 60px;
24
+ padding: 2px 10px 12px;
25
+ a {
26
+ text-decoration: underline;
27
+ font-weight: 600;
28
+ }
29
+ `;
30
+
31
+ const NsTextStrip = (props: NsTextStripProps) => {
32
+ const { alignment = 'center', text, description, link, className = '' } = props;
33
+
34
+ return (
35
+ <StyledHeader className={`${className} items-${alignment}`}>
36
+ <NsTypography variant="h5" weight="bold">
37
+ {text}
38
+ </NsTypography>
39
+ <NsTypography variant="p-xs">
40
+ {description}&nbsp;
41
+ {link?.href ? <NsLink href={link.href}>{link.title}</NsLink> : ''}
42
+ </NsTypography>
43
+ </StyledHeader>
44
+ );
45
+ };
46
+
47
+ export default NsTextStrip;
@@ -0,0 +1,2 @@
1
+ export { default as NsTextStrip } from './NsTextStrip';
2
+ export type { NsTextStripProps } from './types.d';
@@ -0,0 +1,17 @@
1
+ import { AdditionalProps } from '../common.types';
2
+
3
+ export type AlignmentType = 'start' | 'center' | 'end';
4
+
5
+ export type TextCtaDataType = {
6
+ link?: {
7
+ href?: string;
8
+ title?: string;
9
+ };
10
+ text?: string;
11
+ description?: string;
12
+ };
13
+ export type NsTextStripProps = {
14
+ alignment?: AlignmentType;
15
+ className?: string;
16
+ } & AdditionalProps &
17
+ TextCtaDataType;
@@ -1,5 +1,5 @@
1
1
  import type { StoryObj, Meta } from '@storybook/react';
2
- import { withCenterDecorator } from '../../stories/decorators/withCenterDecorator';
2
+ import { withCenterDecorator } from '@/stories/decorators/withCenterDecorator';
3
3
  import { NsTypography } from './';
4
4
 
5
5
  type ComponentType = typeof NsTypography;
@@ -7,7 +7,7 @@ type Story = StoryObj<ComponentType>;
7
7
  type MetaStory = Meta<ComponentType>;
8
8
 
9
9
  export default {
10
- title: 'Components/NsTypography',
10
+ title: 'Components/Data Display/NsTypography',
11
11
  component: NsTypography,
12
12
  decorators: [withCenterDecorator],
13
13
  argTypes: {
@@ -1,5 +1,5 @@
1
1
  import React, { PropsWithChildren } from 'react';
2
- import { NsTypographyProps } from './types';
2
+ import { NsTypographyProps } from './types.d';
3
3
  import { StyledTypography } from './Typography.styled';
4
4
 
5
5
  const NsTypography = ({
@@ -1,7 +1,7 @@
1
1
  import { styled, ColorUtils } from '@nuskin/foundation-theme';
2
- import { NsTypographyProps } from './types';
2
+ import { NsTypographyProps } from './types.d';
3
3
 
4
- const { getPaletteColor } = ColorUtils;
4
+ const { paletteColor } = ColorUtils;
5
5
 
6
6
  const variantStyles = {
7
7
  h1: 'font-size: 36px; line-height: 44px;',
@@ -29,8 +29,8 @@ const fontWeightMap = {
29
29
 
30
30
  export const StyledTypography = styled.div<NsTypographyProps>`
31
31
  font-family: Inter;
32
- color: ${({ color, theme, colorOverride }) =>
33
- colorOverride?.startsWith('#') ? colorOverride : getPaletteColor(theme, color)};
32
+ color: ${({ color, colorOverride }) =>
33
+ colorOverride?.startsWith('#') ? colorOverride : paletteColor(color)};
34
34
  font-weight: ${({ weight = 'normal' }) => fontWeightMap[weight]};
35
35
  font-style: ${({ fontStyle }) => fontStyle};
36
36
  ${({ variant = 'h1' }) => variantStyles[variant]};
@@ -1,3 +1,3 @@
1
1
  export { default as NsTypography } from './NsTypography';
2
- export type { NsTypographyProps, Variants } from './types';
2
+ export type { NsTypographyProps, Variants } from './types.d';
3
3
  export { default as GlobalFontInter } from './GlobalFontInter';
@@ -0,0 +1 @@
1
+ export const skipDarkModeEnabled = (key: string) => key !== 'darkModeEnabled';
@@ -0,0 +1,13 @@
1
+ import { PropsWithChildren, ReactElement } from 'react';
2
+
3
+ type ShowType = PropsWithChildren & {
4
+ when?: boolean;
5
+ elseContent?: ReactElement;
6
+ };
7
+ const Show = ({ when, children, elseContent }: ShowType): ReactElement => {
8
+ if (when) {
9
+ return <>{children}</>;
10
+ }
11
+ return <>{elseContent}</>;
12
+ };
13
+ export default Show;
@@ -0,0 +1 @@
1
+ export { default as Show } from './Show';
@@ -0,0 +1,3 @@
1
+ export const emailPattern =
2
+ // eslint-disable-next-line max-len
3
+ /^[\s]*[A-Za-z0-9!#$%&*+/=?^_`{|}~-]+(?:\.[A-Za-z0-9!#$%&*+/=?^_`{|}~-]+)*@(?:[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?\.)+[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?[\s]*$/;
@@ -7,14 +7,14 @@
7
7
  import type { Meta, StoryObj } from '@storybook/react';
8
8
 
9
9
  import { NsVideo } from '.';
10
- import { withCenterDecorator } from '../../stories/decorators/withCenterDecorator';
10
+ import { withCenterDecorator } from '@/stories/decorators/withCenterDecorator';
11
11
 
12
12
  type ComponentType = typeof NsVideo;
13
13
  type Story = StoryObj<ComponentType>;
14
14
  type MetaStory = Meta<ComponentType>;
15
15
 
16
16
  export default {
17
- title: 'Components/NsVideo',
17
+ title: 'Components/Data Display/NsVideo',
18
18
  component: NsVideo,
19
19
  decorators: [withCenterDecorator],
20
20
  argTypes: {
@@ -6,7 +6,7 @@
6
6
 
7
7
  import { PropsWithChildren } from 'react';
8
8
 
9
- import { NsVideoProps } from './types';
9
+ import { NsVideoProps } from './types.d';
10
10
 
11
11
  const NsVideo = (props: PropsWithChildren<NsVideoProps>) => {
12
12
  const { src, title, width, height, allowFullScreen } = props;
@@ -1,2 +1,2 @@
1
1
  export { default as NsVideo } from './NsVideo';
2
- export type { NsVideoProps } from './types';
2
+ export type { NsVideoProps } from './types.d';