@nuskin/foundation-ui-components 1.0.0-develop.4 → 1.0.0-develop.5

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 (36) hide show
  1. package/package.json +9 -4
  2. package/src/common/accordion/specs/NsAccordion.spec.tsx +3 -1
  3. package/src/common/accordion/specs/NsAccordionHeader.spec.tsx +21 -5
  4. package/src/common/accordion/specs/NsAccordionItem.spec.tsx +29 -5
  5. package/src/common/accordion/specs/NsCollapse.spec.tsx +4 -4
  6. package/src/common/accordion/specs/NsToggleSection.spec.tsx +10 -5
  7. package/src/common/alert/NsAlert.spec.tsx +0 -1
  8. package/src/common/alert/NsAlert.styled.ts +10 -10
  9. package/src/common/alert/NsAlert.tsx +4 -3
  10. package/src/common/auth-dropdown/NsAuthDropdown.styled.ts +12 -11
  11. package/src/common/auth-dropdown/NsAuthDropdown.tsx +2 -1
  12. package/src/common/auth-dropdown/types.d.ts +3 -1
  13. package/src/common/brand-components/NsBrandComponent.tsx +3 -0
  14. package/src/common/breadcrumb/NsBreadcrumb.tsx +4 -2
  15. package/src/common/button/NsButton.spec.tsx +1 -1
  16. package/src/common/button/NsButton.stories.tsx +1 -1
  17. package/src/common/button/NsButton.styled.tsx +25 -23
  18. package/src/common/button/NsButton.tsx +9 -2
  19. package/src/common/button/types.d.ts +1 -0
  20. package/src/common/common.types.d.ts +1 -0
  21. package/src/common/dropdown/types.d.ts +3 -1
  22. package/src/common/flag/NsFlag.spec.tsx +1 -0
  23. package/src/common/flag/NsFlag.styled.tsx +5 -5
  24. package/src/common/icon/types.d.ts +1 -0
  25. package/src/common/input/InputFieldWrapper.tsx +4 -4
  26. package/src/common/label/NsLabel.tsx +11 -7
  27. package/src/common/nav-tab/NsNavTab.styled.tsx +7 -4
  28. package/src/common/radiogroup/NsRadioGroup.spec.tsx +2 -1
  29. package/src/common/radiogroup/NsRadioGroup.stories.tsx +2 -1
  30. package/src/common/radiogroup/NsRadioGroup.styled.tsx +26 -32
  31. package/src/common/radiogroup/NsRadioGroup.tsx +20 -5
  32. package/src/common/radiogroup/types.d.ts +4 -3
  33. package/src/common/select/NsSelect.styled.tsx +19 -23
  34. package/src/common/table/NsTable.styled.ts +69 -66
  35. package/src/common/text-strip/NsTextStrip.tsx +10 -7
  36. package/src/common/typography/Typography.styled.tsx +3 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nuskin/foundation-ui-components",
3
- "version": "1.0.0-develop.4",
3
+ "version": "1.0.0-develop.5",
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",
@@ -31,7 +31,10 @@
31
31
  "test:coverage": "yarn test --coverage",
32
32
  "test:watch": "jest --watch",
33
33
  "storybook": "storybook dev -p 6007",
34
- "build-storybook": "storybook build"
34
+ "build-storybook": "storybook build",
35
+ "export": "next export",
36
+ "prepare": "husky install",
37
+ "types:check": "tsc --pretty --noEmit"
35
38
  },
36
39
  "dependencies": {
37
40
  "@emotion/react": "^11.10.6",
@@ -39,8 +42,7 @@
39
42
  "@mui/icons-material": "^5.11.11",
40
43
  "@mui/material": "5.4.2",
41
44
  "@next/font": "13.2.4",
42
- "@nuskin/foundation-theme": "1.0.0-cft-33.12",
43
- "@types/jest": "^29.5.0",
45
+ "@nuskin/foundation-theme": "1.0.0-develop.5",
44
46
  "framer-motion": "^10.8.5",
45
47
  "next": "13.2.4",
46
48
  "react": "18.2.0",
@@ -69,8 +71,10 @@
69
71
  "@storybook/testing-library": "^0.1.0",
70
72
  "@testing-library/jest-dom": "^5.16.5",
71
73
  "@testing-library/react": "^14.0.0",
74
+ "@types/jest": "^29.5.0",
72
75
  "@types/lodash": "^4.14.191",
73
76
  "@types/node": "18.15.0",
77
+ "@types/ramda": "^0.29.3",
74
78
  "@types/react": "18.0.28",
75
79
  "@types/react-dom": "18.0.11",
76
80
  "@types/react-slick": "^0.23.10",
@@ -86,6 +90,7 @@
86
90
  "eslint-plugin-json": "^3.1.0",
87
91
  "eslint-plugin-prettier": "^4.2.1",
88
92
  "eslint-plugin-storybook": "^0.6.11",
93
+ "husky": "^8.0.0",
89
94
  "jest": "^29.5.0",
90
95
  "jest-environment-jsdom": "^29.5.0",
91
96
  "storybook": "^7.0.7"
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import { render, fireEvent, screen } from '@/test-utils/index';
3
- import { NsAccordion, NsAccordionProps } from '@/common/index';
3
+ import { AccordionVariant, NsAccordion, NsAccordionProps } from '@/common/index';
4
4
 
5
5
  const generateContentArray = (count: number) => {
6
6
  const arr = [] as NsAccordionProps['contentArray'];
@@ -22,6 +22,7 @@ describe('NsAccordion', () => {
22
22
  },
23
23
  allowMultipleExpanded: false,
24
24
  contentArray,
25
+ variant: AccordionVariant.Basic,
25
26
  };
26
27
 
27
28
  it('renders without error', () => {
@@ -68,6 +69,7 @@ describe('NsAccordion', () => {
68
69
  },
69
70
  allowMultipleExpanded: false,
70
71
  contentArray,
72
+ variant: AccordionVariant.Basic,
71
73
  };
72
74
  const { getAllByText } = render(<NsAccordion {...defaultProps} allowMultipleExpanded />);
73
75
  const [title1, title2, title3] = getAllByText(/Title /i);
@@ -1,18 +1,29 @@
1
1
  import React from 'react';
2
2
  import { render, fireEvent } from '@/test-utils/index';
3
- import { NsAccordionHeader } from '@/common/index';
3
+ import { NsAccordionHeader, AccordionVariant } from '@/common/index';
4
4
 
5
5
  describe('NsAccordionHeader', () => {
6
6
  it('renders title correctly', () => {
7
7
  const onClick = jest.fn();
8
8
  const title = 'Section Header';
9
- const { getByText } = render(<NsAccordionHeader title={title} onClick={onClick} />);
9
+ const { getByText } = render(
10
+ <NsAccordionHeader
11
+ variant={AccordionVariant.Basic}
12
+ title={title}
13
+ onClick={onClick}
14
+ />
15
+ );
10
16
  expect(getByText(title)).toBeInTheDocument();
11
17
  });
12
18
 
13
19
  it('calls onClick handler when clicked', () => {
14
20
  const onClick = jest.fn();
15
- const { container } = render(<NsAccordionHeader title="Section Header" onClick={onClick} />);
21
+ const { container } = render(
22
+ <NsAccordionHeader
23
+ variant={AccordionVariant.Basic}
24
+ title="Section Header"
25
+ onClick={onClick}
26
+ />);
16
27
  const header = container.querySelector('header');
17
28
  if (header) {
18
29
  fireEvent.click(header);
@@ -25,6 +36,7 @@ describe('NsAccordionHeader', () => {
25
36
  const onClick = jest.fn();
26
37
  const { container } = render(
27
38
  <NsAccordionHeader
39
+ variant={AccordionVariant.Basic}
28
40
  title="Section Header"
29
41
  additionalProps={{ className: additionalClassName }}
30
42
  onClick={onClick}
@@ -35,13 +47,17 @@ describe('NsAccordionHeader', () => {
35
47
 
36
48
  it('renders with expanded class when isOpen is true', () => {
37
49
  const onClick = jest.fn();
38
- const { container } = render(<NsAccordionHeader title="Section Header" isOpen onClick={onClick} />);
50
+ const { container } = render(
51
+ <NsAccordionHeader variant={AccordionVariant.Basic} title="Section Header" isOpen onClick={onClick} />
52
+ );
39
53
  expect(container.querySelector('header')).toHaveClass('expanded');
40
54
  });
41
55
 
42
56
  it('renders with header icon', () => {
43
57
  const onClick = jest.fn();
44
- const { getByTestId } = render(<NsAccordionHeader title="Section Header" onClick={onClick} />);
58
+ const { getByTestId } = render(
59
+ <NsAccordionHeader variant={AccordionVariant.Basic} title="Section Header" onClick={onClick} />
60
+ );
45
61
  expect(getByTestId('icon')).toBeInTheDocument();
46
62
  });
47
63
  });
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import { render, fireEvent } from '@/test-utils/index';
3
- import { NsAccordionItem } from '@/common/index';
3
+ import { NsAccordionItem, AccordionVariant } from '@/common/index';
4
4
 
5
5
  describe('NsAccordionItem', () => {
6
6
  const title = 'Accordion Section Title';
@@ -8,7 +8,13 @@ describe('NsAccordionItem', () => {
8
8
 
9
9
  it('renders title correctly', () => {
10
10
  const { getByText } = render(
11
- <NsAccordionItem isOpen={false} toggleOpen={() => {}} title={title} content={content} />
11
+ <NsAccordionItem
12
+ variant={AccordionVariant.Basic}
13
+ isOpen={false}
14
+ toggleOpen={() => {}}
15
+ title={title}
16
+ content={content}
17
+ />
12
18
  );
13
19
  expect(getByText(title)).toBeInTheDocument();
14
20
  });
@@ -16,7 +22,13 @@ describe('NsAccordionItem', () => {
16
22
  it('calls toggleOpen function when clicked on the section header', () => {
17
23
  const toggleOpen = jest.fn();
18
24
  const { getByText } = render(
19
- <NsAccordionItem isOpen={false} toggleOpen={toggleOpen} title={title} content={content} />
25
+ <NsAccordionItem
26
+ variant={AccordionVariant.Basic}
27
+ isOpen={false}
28
+ toggleOpen={toggleOpen}
29
+ title={title}
30
+ content={content}
31
+ />
20
32
  );
21
33
  fireEvent.click(getByText(title));
22
34
  expect(toggleOpen).toHaveBeenCalledTimes(1);
@@ -24,14 +36,26 @@ describe('NsAccordionItem', () => {
24
36
 
25
37
  it('renders content when isOpen is true', () => {
26
38
  const { getByText } = render(
27
- <NsAccordionItem isOpen={true} toggleOpen={() => {}} title={title} content={content} />
39
+ <NsAccordionItem
40
+ variant={AccordionVariant.Basic}
41
+ isOpen={true}
42
+ toggleOpen={() => {}}
43
+ title={title}
44
+ content={content}
45
+ />
28
46
  );
29
47
  expect(getByText(content)).toBeInTheDocument();
30
48
  });
31
49
 
32
50
  it('does not render content when isOpen is false', () => {
33
51
  const { queryByText } = render(
34
- <NsAccordionItem isOpen={false} toggleOpen={() => {}} title={title} content={content} />
52
+ <NsAccordionItem
53
+ variant={AccordionVariant.Basic}
54
+ isOpen={false}
55
+ toggleOpen={() => {}}
56
+ title={title}
57
+ content={content}
58
+ />
35
59
  );
36
60
  expect(queryByText(content)).toBeNull();
37
61
  });
@@ -1,11 +1,11 @@
1
1
  import React from 'react';
2
2
  import { render, screen } from '@/test-utils/index';
3
- import { NsCollapse } from '@/common/index';
3
+ import { NsCollapse, AccordionVariant } from '@/common/index';
4
4
 
5
5
  describe('NsCollapse', () => {
6
6
  it('renders children when isOpen is true', () => {
7
7
  const { getByText } = render(
8
- <NsCollapse isOpen>
8
+ <NsCollapse isOpen variant={AccordionVariant.Basic}>
9
9
  <div>Child 1</div>
10
10
  <div>Child 2</div>
11
11
  </NsCollapse>
@@ -16,7 +16,7 @@ describe('NsCollapse', () => {
16
16
 
17
17
  it('does not render children when isOpen is false', () => {
18
18
  render(
19
- <NsCollapse isOpen={false}>
19
+ <NsCollapse isOpen={false} variant={AccordionVariant.Basic}>
20
20
  <div>Child 1</div>
21
21
  <div>Child 2</div>
22
22
  </NsCollapse>
@@ -27,7 +27,7 @@ describe('NsCollapse', () => {
27
27
  it('renders with additional class name', () => {
28
28
  const additionalClassName = 'custom-class';
29
29
  const { container } = render(
30
- <NsCollapse additionalProps={{ className: additionalClassName }} isOpen>
30
+ <NsCollapse additionalProps={{ className: additionalClassName }} isOpen variant={AccordionVariant.Basic}>
31
31
  <div>Child 1</div>
32
32
  <div>Child 2</div>
33
33
  </NsCollapse>
@@ -1,19 +1,24 @@
1
1
  import React from 'react';
2
+
3
+ import { AccordionVariant, NsToggleSection } from '@/common/index';
4
+
2
5
  import { render, fireEvent } from '@/test-utils/index';
3
- import { NsToggleSection } from '@/common/index';
4
6
 
5
7
  describe('NsToggleSection', () => {
6
8
  const title = 'Toggle Section Title';
7
9
  const content = 'Toggle Section Content';
8
10
 
9
11
  it('renders title correctly', () => {
10
- const { getByText } = render(<NsToggleSection title={title}>{content}</NsToggleSection>);
12
+ const { getByText } = render(
13
+ <NsToggleSection variant={AccordionVariant.Basic} title={title}>{content}</NsToggleSection>
14
+ );
11
15
  expect(getByText(title)).toBeInTheDocument();
12
16
  });
13
17
 
14
18
  it('toggles content visibility when clicked on the section header', () => {
15
- const { getByText, queryByText } = render(<NsToggleSection title={title}>{content}</NsToggleSection>);
16
-
19
+ const { getByText, queryByText } = render(
20
+ <NsToggleSection variant={AccordionVariant.Basic} title={title}>{content}</NsToggleSection>
21
+ );
17
22
  expect(queryByText(content)).toBeNull();
18
23
  fireEvent.click(getByText(title));
19
24
  expect(getByText(content)).toBeInTheDocument();
@@ -23,7 +28,7 @@ describe('NsToggleSection', () => {
23
28
 
24
29
  it('sets defaultOpen prop correctly', () => {
25
30
  const { getByText } = render(
26
- <NsToggleSection title={title} defaultOpen>
31
+ <NsToggleSection variant={AccordionVariant.Basic} title={title} defaultOpen>
27
32
  {content}
28
33
  </NsToggleSection>
29
34
  );
@@ -1,6 +1,5 @@
1
1
  import React from 'react';
2
2
  import { render, fireEvent, screen, act } from '@/test-utils/index';
3
- // import { act } from 'react-dom/test-utils';
4
3
  import NsAlert from './NsAlert';
5
4
 
6
5
  const addEventListenerMock = jest.spyOn(window, 'addEventListener');
@@ -1,7 +1,7 @@
1
1
  /* eslint-disable max-len */
2
- import { styled, css } from '@nuskin/foundation-theme';
3
- import { getAppColor } from '@nuskin/foundation-theme/src/utils/color-utils';
4
- import { FoundationTheme } from '@nuskin/foundation-theme/src/themes';
2
+ import { styled, css, ColorUtils, FoundationTheme } from '@nuskin/foundation-theme';
3
+
4
+ const { color } = ColorUtils;
5
5
 
6
6
  import type { AlertContainerParams, AlertType, AlertParams, TypeMapCSS } from './types.d';
7
7
  const gutter_width = '10px';
@@ -43,7 +43,7 @@ export const AlertContainer = styled.div<AlertContainerParams>`
43
43
  }
44
44
  text-align: left;
45
45
  `;
46
-
46
+ //[Todo-Arun] - Fonts should be driven through @next/font and according to theme
47
47
  const fontFamilyStyles = css`
48
48
  font-family: 'proxima-nova', 'OpenSans', 'Pridi', 'NotoSans', 'NotoSansSC', 'NotoSansHebrew', 'NotoSansJapanese',
49
49
  'Hiragino Kaku Gothic Pro', 'Yu Gothic Medium', 'Yu Gothic', Meiryo, 'source-han-sans-japanese',
@@ -57,11 +57,11 @@ export const Alert = styled.div<AlertParams>`
57
57
  grid-template-rows: [row1] auto;
58
58
  grid-auto-row: auto;
59
59
  grid-auto-flow: row;
60
- background-color: ${({ theme }) => getAppColor(theme, 'primary', 'white')};
61
- border: 1px solid ${({ theme }) => getAppColor(theme, 'primary', 'black')};
60
+ background-color: ${color('primary', 'white')};
61
+ border: 1px solid ${color('primary', 'black')};
62
62
  min-height: ${({ type }) => TypeMap?.[type]?.['min-height']};
63
63
  padding: ${({ type }) => TypeMap?.[type]?.['padding']};
64
- color: ${({ context, theme }) => getAppColor(theme, contextType?.[context] as FoundationTheme.AppColors, '40')} };
64
+ color: ${(props) => color(contextType?.[props?.context] as FoundationTheme.AppColors, '40')(props)} };
65
65
  `;
66
66
 
67
67
  export const AlertCloseButton = styled.div`
@@ -92,7 +92,7 @@ export const AlertHead = styled.div`
92
92
  justify-content: center;
93
93
  span {
94
94
  ${fontFamilyStyles}
95
- color: ${({ theme }) => getAppColor(theme, 'primary', 'black')};
95
+ color: ${color('primary', 'black')};
96
96
  font-weight: 600;
97
97
  font-size: 18px;
98
98
  line-height: 20px;
@@ -101,14 +101,14 @@ export const AlertHead = styled.div`
101
101
 
102
102
  export const AlertContent = styled.div<{ type: AlertType }>`
103
103
  margin-top: 8px;
104
- color: ${({ theme }) => getAppColor(theme, 'primary', 'black')};
104
+ color: ${color('primary', 'black')};
105
105
  grid-column-start: ${({ type }) => TypeMap?.[type]?.['content-column-start']};
106
106
  grid-column-end: ${({ type }) => TypeMap?.[type]?.['content-column-end']};
107
107
  `;
108
108
 
109
109
  export const AlertFoot = styled.div<{ type: AlertType }>`
110
110
  margin-top: 8px;
111
- color: ${({ theme }) => getAppColor(theme, 'primary', 'black')};
111
+ color: ${color('primary', 'black')};
112
112
  display: ${({ type }) => TypeMap?.[type]?.['foot-display']};
113
113
  ${fontFamilyStyles}
114
114
  font-weight: 300;
@@ -1,5 +1,6 @@
1
- /* eslint-disable react/require-default-props */
2
1
  import React, { useEffect, useState } from 'react';
2
+ import { FoundationTheme } from '@nuskin/foundation-theme';
3
+
3
4
  import {
4
5
  AlertContainer,
5
6
  Alert,
@@ -13,7 +14,6 @@ import {
13
14
  import type { NsAlertProps, HeaderProps, ContextType, AlertType } from './types.d';
14
15
  import { NsIcon } from '../icon';
15
16
  import { NsIconNameType } from '../icon/types';
16
- import { FoundationTheme } from '@nuskin/foundation-theme/src/themes';
17
17
 
18
18
  const Header: React.FC<HeaderProps> = ({ children, head }) => (
19
19
  <>
@@ -57,7 +57,7 @@ export default function NsAlert({
57
57
  onDismiss = undefined,
58
58
  }: NsAlertProps) {
59
59
  const [alertType, setAlertType] = useState('banner');
60
- const [windowWidth, setWindowWidth] = useState(window.innerWidth);
60
+ const [windowWidth, setWindowWidth] = useState(0);
61
61
 
62
62
  const hasDismissListener = typeof onDismiss === 'function';
63
63
 
@@ -106,6 +106,7 @@ export default function NsAlert({
106
106
  }, [context, type]);
107
107
 
108
108
  useEffect(() => {
109
+ setWindowWidth(window?.innerWidth);
109
110
  window.addEventListener('resize', handleResize);
110
111
  return () => {
111
112
  window.removeEventListener('resize', handleResize);
@@ -1,9 +1,10 @@
1
1
  import { styled, ColorUtils } from '@nuskin/foundation-theme';
2
- import { getAppColor } from '@nuskin/foundation-theme/src/utils/color-utils';
3
- const { getPaletteColor } = ColorUtils;
4
2
 
3
+ //[TODO-Arun] - Use from custom color variables
5
4
  const MAGENTA_COLOR = '#bb29bb';
6
5
 
6
+ const { color, paletteColor } = ColorUtils;
7
+
7
8
  export const AuthDropdownContainer = styled.div`
8
9
  position: relative;
9
10
  display: inline-block;
@@ -19,7 +20,7 @@ export const AuthDropdown = styled.div`
19
20
  z-index: 600;
20
21
  top: calc(100% + 18px);
21
22
  right: 5%;
22
- box-shadow: 0 0 5px 0 ${({ theme }) => getAppColor(theme, 'neutral', '20')};
23
+ box-shadow: 0 0 5px 0 ${color('neutral', '20')};
23
24
  transition: all 0.15s ease-in-out;
24
25
  padding: 25px;
25
26
  `;
@@ -39,21 +40,21 @@ export const Triangle = styled.div`
39
40
  position: absolute;
40
41
  width: 14px;
41
42
  height: 14px;
42
- background-color: ${({ theme }) => getAppColor(theme, 'primary', 'white')};
43
+ background-color: ${color('primary', 'white')};
43
44
  transform: rotate(45deg);
44
45
  top: 17px;
45
46
  left: 5px;
46
- box-shadow: 0 0 5px 0 ${({ theme }) => getAppColor(theme, 'neutral', '20')};
47
+ box-shadow: 0 0 5px 0 ${color('neutral', '20')};
47
48
  }
48
49
  `;
49
50
 
50
- export const AuthHead = styled.div`
51
+ export const AuthHead = styled.div<{ darkModeEnabled: boolean }>`
51
52
  cursor: pointer;
52
53
  padding: 5px 10px;
53
54
  display: flex;
54
55
  justify-content: space-between;
55
56
  align-items: center;
56
- color: ${({ theme }) => getPaletteColor(theme, 'primary')};
57
+ color: ${paletteColor('primary')};
57
58
  `;
58
59
 
59
60
  export const Button = styled.div`
@@ -69,17 +70,17 @@ export const SignInButton = styled(Link)`
69
70
  padding: 13px;
70
71
  width: 100%;
71
72
  background-color: ${MAGENTA_COLOR};
72
- color: ${({ theme }) => getAppColor(theme, 'primary', 'white')};
73
+ color: ${color('primary', 'white')};
73
74
  border: 0;
74
75
  font-size: 16px;
75
76
  &:hover {
76
- background-color: ${({ theme }) => getAppColor(theme, 'neutral', '70')};
77
+ background-color: ${color('neutral', '70')};
77
78
  }
78
79
  `;
79
80
 
80
81
  export const SignUpLinkContainer = styled.div`
81
82
  margin-top: 15px;
82
- color: ${({ theme }) => getAppColor(theme, 'primary', 'main')};
83
+ color: ${color('primary', 'main')};
83
84
  font-size: 13px;
84
85
  line-height: 16px;
85
86
  text-align: left;
@@ -95,7 +96,7 @@ export const SignUpLink = styled(Link)`
95
96
  position: relative;
96
97
  transition: all 0.15s ease-in-out;
97
98
  &:hover {
98
- color: ${({ theme }) => getAppColor(theme, 'neutral', '70')};
99
+ color: ${color('neutral', '70')};
99
100
  font-size: 14px;
100
101
  }
101
102
  &:hover::after {
@@ -20,6 +20,7 @@ const NsAuthDropdown = ({
20
20
  signUpLinkPrefixText,
21
21
  titleText,
22
22
  closeOnMouseLeave = false,
23
+ darkModeEnabled = true,
23
24
  }: NsAuthDropdownProps) => {
24
25
  const [isOpen, setIsOpen] = useState(false);
25
26
 
@@ -35,7 +36,7 @@ const NsAuthDropdown = ({
35
36
 
36
37
  return (
37
38
  <AuthDropdownContainer>
38
- <AuthHead data-testid="auth-head" onClick={handleToggle}>
39
+ <AuthHead data-testid="auth-head" onClick={handleToggle} darkModeEnabled={darkModeEnabled}>
39
40
  <Button>{titleText}</Button>
40
41
  <NsIcon testId="chevron-icon" name={isOpen ? 'arrowUp' : 'arrowDown'} color="primary" />
41
42
  {isOpen ? (
@@ -1,3 +1,5 @@
1
+ import { AdditionalProps } from '../common.types';
2
+
1
3
  export type NsAuthDropdownProps = {
2
4
  signInRedirectLink: string;
3
5
  signUpRedirectLink: string;
@@ -6,4 +8,4 @@ export type NsAuthDropdownProps = {
6
8
  signUpLinkPrefixText: string;
7
9
  titleText: string;
8
10
  closeOnMouseLeave?: boolean;
9
- };
11
+ } & AdditionalProps;
@@ -1,10 +1,12 @@
1
1
  import React, { PropsWithChildren, useCallback } from 'react';
2
+
2
3
  import NSLogoHorizontal from './icons/NSLogoHorizontal';
3
4
  import NSLogoMark from './icons/NSLogoMark';
4
5
  import NSLogoPoweredBy from './icons/NSLogoPoweredBy';
5
6
  import NSLogoStacked from './icons/NSLogoStacked';
6
7
  import NSLogoWordMark from './icons/NSWordMark';
7
8
  import LogoContainer from './NsBrandContanier.styled';
9
+
8
10
  import { NsBrandComponentProps } from './types.d';
9
11
 
10
12
  const VariantMap = {
@@ -19,6 +21,7 @@ const NsBrandComponent = (props: PropsWithChildren<NsBrandComponentProps>) => {
19
21
  const { variant = 'stacked', size = '108px', color = 'primary' } = props;
20
22
  const renderBrand = useCallback(() => {
21
23
  const BrandComponent = VariantMap[variant || 'stacked'];
24
+ // [Todo - Add neutral as FoundationTheme.PaletteColor]
22
25
  return <BrandComponent color={color as any} />;
23
26
  }, [color, variant]);
24
27
  return <LogoContainer size={size}>{renderBrand()}</LogoContainer>;
@@ -12,12 +12,14 @@ import { NsBreadcrumbProps, ItemProps } from './types.d';
12
12
  import { useTheme } from '@mui/material/styles';
13
13
  import { ColorUtils } from '@nuskin/foundation-theme';
14
14
 
15
+ const { color } = ColorUtils;
16
+
15
17
  const NsBreadcrumb = (props: PropsWithChildren<NsBreadcrumbProps>) => {
16
18
  const { items, iconVisibility } = props;
17
19
 
18
20
  const theme = useTheme();
19
- const neutral80 = ColorUtils.getAppColor(theme, 'neutral', '80') as string;
20
- const neutral60 = ColorUtils.getAppColor(theme, 'neutral', '60') as string;
21
+ const neutral80 = color('neutral', '80')(theme);
22
+ const neutral60 = color('neutral', '60')(theme);
21
23
 
22
24
  const getLabel = (item: ItemProps) => {
23
25
  if (item?.href) {
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import { render, screen } from '@/test-utils/index';
3
- import nuskinTheme from '@nuskin/foundation-theme/src/themes/genome-foundation';
3
+ import { nuskinTheme } from '@nuskin/foundation-theme';
4
4
  import Button from './NsButton';
5
5
 
6
6
  const { palette } = nuskinTheme;
@@ -37,7 +37,7 @@ export const button: Story = {};
37
37
 
38
38
  export const IconOnlyButton: Story = {
39
39
  render: (args) => (
40
- <NsButton {...args} iconOnly>
40
+ <NsButton {...args} iconOnly darkModeEnabled={false}>
41
41
  <ShoppingCart />
42
42
  </NsButton>
43
43
  ),
@@ -1,10 +1,11 @@
1
1
  import { Button as MUIButton } from '@mui/material';
2
2
 
3
3
  import { styled, ColorUtils, FoundationTheme } from '@nuskin/foundation-theme';
4
- import { ButtonConfig } from '@nuskin/foundation-theme/src/themes/types/button';
4
+ import { ButtonConfig } from '@nuskin/foundation-theme/src/common/themes/types/button';
5
+
5
6
  import { NsButtonProps } from './types.d';
6
7
 
7
- const { getPaletteColor, getButtonStateColor } = ColorUtils;
8
+ const { buttonColor, paletteColor } = ColorUtils;
8
9
 
9
10
  const getButtonConfig = (theme: FoundationTheme.Theme, attribute: keyof ButtonConfig) => {
10
11
  const { config } = theme || {};
@@ -18,8 +19,8 @@ const StyledButton = styled(MUIButton)<NsButtonProps>`
18
19
  border: 1px solid ${({ theme }) => getButtonConfig(theme, 'focusColor')} !important;
19
20
  }
20
21
  :disabled {
21
- background-color: ${({ theme, color }) => getButtonStateColor(theme, color, 'disabled')};
22
- color: ${({ theme, color }) => getButtonStateColor(theme, color, 'disabledText')};
22
+ background-color: ${(btnProps) => buttonColor(btnProps?.color, 'disabled')};
23
+ color: ${(btnProps) => buttonColor(btnProps?.color, 'disabledText')};
23
24
  }
24
25
  ${({ theme: { config }, size }) => {
25
26
  return size === 'medium' ? config?.components?.button?.size?.medium?.padding : '';
@@ -27,37 +28,38 @@ const StyledButton = styled(MUIButton)<NsButtonProps>`
27
28
  ${({ theme: { config }, size }) => {
28
29
  return size === 'large' ? config?.components?.button?.size?.large?.padding : '';
29
30
  }}
30
- ${({ variant, theme, color = 'primary' }) => {
31
+ ${({ variant, theme, color = 'primary', darkModeEnabled }) => {
31
32
  return variant === 'contained'
32
33
  ? `
33
- background-color: ${getPaletteColor(theme, color)};
34
+ background-color: ${paletteColor(color)({ theme, darkModeEnabled })};
35
+ color: ${paletteColor(color, 'contrastText')({ theme, darkModeEnabled })} !important;
34
36
  :hover {
35
- background-color: ${getButtonStateColor(theme, color, 'hovered')};
37
+ background-color: ${buttonColor(color, 'hovered')({ theme })};
36
38
  }
37
39
  :active {
38
- background-color: ${getButtonStateColor(theme, color, 'pressed')};
40
+ background-color: ${buttonColor(color, 'pressed')({ theme })};
39
41
  }
40
42
  :focus {
41
- background-color: ${getButtonStateColor(theme, color, 'focused')};
43
+ background-color: ${buttonColor(color, 'focused')({ theme })};
42
44
  }
43
45
  `
44
46
  : '';
45
47
  }}
46
- ${({ variant, theme, color = 'primary' }) =>
48
+ ${({ variant, theme, color = 'primary', darkModeEnabled }) =>
47
49
  variant === 'outlined' &&
48
50
  `
49
- border-color: ${getPaletteColor(theme, color)};
50
- color: ${getPaletteColor(theme, color)};
51
+ border-color: ${paletteColor(color)({ theme, darkModeEnabled })};
52
+ color: ${paletteColor(color)({ theme, darkModeEnabled })};
51
53
  :hover {
52
- border-color: ${getButtonStateColor(theme, color, 'hovered')};
53
- color: ${getPaletteColor(theme, color)};
54
+ border-color: ${buttonColor(color, 'hovered')({ theme })};
55
+ color: ${paletteColor(color)({ theme, darkModeEnabled })};
54
56
  }
55
57
  :active {
56
- border-color: ${getButtonStateColor(theme, color, 'pressed')};
57
- color: ${getPaletteColor(theme, color)};
58
+ border-color: ${buttonColor(color, 'pressed')({ theme })};
59
+ color: ${paletteColor(color)({ theme })};
58
60
  }
59
61
  `}
60
- ${({ variant, theme, color = 'primary' }) =>
62
+ ${({ variant, theme, color = 'primary', darkModeEnabled }) =>
61
63
  variant === 'text' &&
62
64
  `
63
65
  text-decoration: underline 1px !important;
@@ -65,15 +67,15 @@ const StyledButton = styled(MUIButton)<NsButtonProps>`
65
67
  padding: 0;
66
68
  min-width: auto;
67
69
  background-color: transparent !important;
68
- text-decoration-color: ${getPaletteColor(theme, color)};
69
- color: ${getPaletteColor(theme, color)};
70
+ text-decoration-color: ${paletteColor(color)({ theme, darkModeEnabled })};
71
+ color: ${paletteColor(color)({ theme, darkModeEnabled })};
70
72
  :hover {
71
- color: ${getButtonStateColor(theme, color, 'hovered')};
72
- text-decoration-color: ${getButtonStateColor(theme, color, 'hovered')};
73
+ color: ${buttonColor(color, 'hovered')({ theme })};
74
+ text-decoration-color: ${buttonColor(color, 'hovered')({ theme })};
73
75
  }
74
76
  :active {
75
- color: ${getPaletteColor(theme, color)};
76
- text-decoration-color: ${getButtonStateColor(theme, color, 'pressed')};
77
+ color: ${paletteColor(color)};
78
+ text-decoration-color: ${buttonColor(color, 'pressed')({ theme })};
77
79
  }
78
80
  `}
79
81
  ${({ iconOnly }) =>