@nuskin/foundation-ui-components 1.3.0 → 1.4.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 (38) hide show
  1. package/package.json +4 -4
  2. package/src/common/auth-dropdown/NsAuthDropdown.tsx +6 -6
  3. package/src/common/button/NsButton.stories.tsx +3 -2
  4. package/src/common/button/NsButton.tsx +27 -2
  5. package/src/common/button/types.d.ts +21 -17
  6. package/src/common/card/NsFfgCard.tsx +2 -2
  7. package/src/common/cart-icon/NsCartIcon.styled.tsx +14 -0
  8. package/src/common/dropdown/NsDropdown.tsx +6 -6
  9. package/src/common/email-simple/NsEmailSimple.tsx +1 -1
  10. package/src/common/flag/NsFlag.spec.tsx +14 -2
  11. package/src/common/flag/NsFlag.styled.tsx +2 -5
  12. package/src/common/hooks/useOnClickOutside.tsx +11 -14
  13. package/src/common/icon/NsIcon.spec.tsx +11 -2
  14. package/src/common/icon/NsIcon.stories.tsx +2 -1
  15. package/src/common/icon/NsIcon.styled.tsx +13 -10
  16. package/src/common/icon/NsIcon.tsx +9 -6
  17. package/src/common/icon/icons/UserIcon.tsx +8 -1
  18. package/src/common/icon/types.d.ts +3 -2
  19. package/src/common/progress/NsProgress.spec.tsx +2 -2
  20. package/src/common/progress/NsProgress.stories.tsx +10 -5
  21. package/src/common/progress/NsProgress.styled.tsx +30 -12
  22. package/src/common/progress/NsProgress.tsx +18 -16
  23. package/src/common/progress/types.d.ts +2 -2
  24. package/src/common/radiogroup/NsRadioGroup.spec.tsx +2 -2
  25. package/src/common/radiogroup/NsRadioGroup.stories.tsx +2 -2
  26. package/src/common/radiogroup/NsRadioGroup.tsx +5 -3
  27. package/src/common/radiogroup/types.d.ts +11 -12
  28. package/src/common/select/NsSelect.styled.tsx +37 -69
  29. package/src/common/select/NsSelect.tsx +86 -91
  30. package/src/common/select/NsSelectOption.tsx +10 -14
  31. package/src/common/select/specs/NsSelect.spec.tsx +183 -0
  32. package/src/common/select/specs/NsSelectOption.spec.tsx +32 -0
  33. package/src/common/select/stories/NsSelect.stories.tsx +25 -80
  34. package/src/common/select/stories/countries.ts +53 -0
  35. package/src/common/select/types.d.ts +21 -8
  36. package/src/common/table/NsTable.stories.tsx +1 -0
  37. package/src/common/cart-icon/NsCartIcon.styled.ts +0 -14
  38. package/src/common/select/NsSelect.spec.tsx +0 -274
package/package.json CHANGED
@@ -1,8 +1,7 @@
1
1
  {
2
2
  "name": "@nuskin/foundation-ui-components",
3
- "version": "1.3.0",
3
+ "version": "1.4.1",
4
4
  "description": "It is a foundation library written in react, that provides common components to all UI pages",
5
- "private": false,
6
5
  "main": "src/common/index.ts",
7
6
  "repository": {
8
7
  "type": "git",
@@ -47,7 +46,7 @@
47
46
  "@mui/material": "5.4.2",
48
47
  "@mui/utils": "^5.14.1",
49
48
  "@next/font": "13.2.4",
50
- "@nuskin/foundation-theme": "1.0.0-develop.5",
49
+ "@nuskin/foundation-theme": "^1.0.0",
51
50
  "framer-motion": "^10.8.5",
52
51
  "next": "13.2.4",
53
52
  "react": "18.2.0",
@@ -103,5 +102,6 @@
103
102
  "files": [
104
103
  "src/common"
105
104
  ],
106
- "readme": "./README.md"
105
+ "readme": "./README.md",
106
+ "packageManager": "yarn@3.6.3"
107
107
  }
@@ -25,26 +25,26 @@ const NsAuthDropdown = ({
25
25
  darkModeEnabled = true,
26
26
  }: NsAuthDropdownProps) => {
27
27
  const [isOpen, setIsOpen] = useState(false);
28
- const dropdowneRef = useRef<HTMLDivElement | null>(null);
28
+ const dropdownRef = useRef<HTMLDivElement | null>(null);
29
29
 
30
30
  const handleToggle = useCallback(() => {
31
31
  setIsOpen(!isOpen);
32
32
  }, [isOpen]);
33
33
 
34
- const handleClose = () => {
34
+ const handleClose = useCallback(() => {
35
35
  setIsOpen(false);
36
- };
36
+ },[]);
37
37
 
38
- useOnClickOutside(dropdowneRef, handleClose);
38
+ useOnClickOutside(dropdownRef?.current, handleClose);
39
39
 
40
40
  const handleOnMouseLeave = useCallback(() => {
41
41
  if (closeOnMouseLeave) {
42
42
  handleClose();
43
43
  }
44
- }, [closeOnMouseLeave]);
44
+ }, [closeOnMouseLeave, handleClose]);
45
45
 
46
46
  return (
47
- <AuthDropdownContainer ref={dropdowneRef}>
47
+ <AuthDropdownContainer ref={dropdownRef}>
48
48
  <AuthHead data-testid="auth-head" onClick={handleToggle} darkModeEnabled={darkModeEnabled}>
49
49
  <Button>{titleText}</Button>
50
50
  <NsIcon testId="chevron-icon" name={isOpen ? 'arrowUp' : 'arrowDown'} color="primary" />
@@ -6,7 +6,6 @@ import { withCenterDecorator } from '@/stories/decorators/withCenterDecorator';
6
6
  import { within } from '@storybook/testing-library';
7
7
  import { expect } from '@storybook/jest';
8
8
  import { nuskinTheme } from '@nuskin/foundation-theme';
9
-
10
9
  const { palette } = nuskinTheme;
11
10
 
12
11
  type ComponentType = typeof NsButton;
@@ -40,7 +39,9 @@ export default {
40
39
  },
41
40
  } as MetaStory;
42
41
 
43
- export const button: Story = {};
42
+ export const button: Story = {
43
+ args: {},
44
+ };
44
45
 
45
46
  export const IconOnlyButton: Story = {
46
47
  render: (args: any) => (
@@ -4,13 +4,38 @@ import { useTheme } from '@mui/material/styles';
4
4
  import StyledButton from './NsButton.styled';
5
5
 
6
6
  import { NsButtonProps } from './types.d';
7
+ import { NsIcon } from '../icon';
7
8
 
8
9
  const NsButton = ({ children, darkModeEnabled = true, ...props }: PropsWithChildren<NsButtonProps>) => {
9
- const { color } = props;
10
+ const { color, startIconName, endIconName, variant } = props;
10
11
  const { palette } = useTheme();
11
12
  const btnColor = color && palette?.[color] ? color : 'primary';
13
+ let iconColor = btnColor;
14
+ if (variant === 'contained') {
15
+ if (btnColor === 'secondary') {
16
+ iconColor = 'primary';
17
+ } else {
18
+ iconColor = 'secondary';
19
+ }
20
+ }
21
+ let startIcon = props.startIcon;
22
+ if (!startIcon && startIconName) {
23
+ startIcon = <NsIcon name={startIconName} color={iconColor} size={props.size} />;
24
+ }
25
+ let endIcon = props.endIcon;
26
+ if (!endIcon && endIconName) {
27
+ endIcon = <NsIcon name={endIconName} color={iconColor} size={props.size} />;
28
+ }
29
+
12
30
  return (
13
- <StyledButton {...props} color={btnColor} disableRipple darkModeEnabled={darkModeEnabled}>
31
+ <StyledButton
32
+ {...props}
33
+ startIcon={startIcon}
34
+ endIcon={endIcon}
35
+ color={btnColor}
36
+ disableRipple
37
+ darkModeEnabled={darkModeEnabled}
38
+ >
14
39
  {children}
15
40
  </StyledButton>
16
41
  );
@@ -1,22 +1,26 @@
1
1
  import { ButtonProps as MUIButtonProps } from '@mui/material';
2
+ import { NsIconProps } from '../icon';
2
3
 
3
4
  export type NsButtonProps = Pick<
4
- MUIButtonProps,
5
- | 'size'
6
- | 'variant'
7
- | 'disabled'
8
- | 'fullWidth'
9
- | 'color'
10
- | 'type'
11
- | 'onBlur'
12
- | 'onClick'
13
- | 'onChange'
14
- | 'onFocus'
15
- | 'aria-label'
16
- | 'className'
17
- | 'startIcon'
18
- | 'endIcon'
5
+ MUIButtonProps,
6
+ | 'aria-label'
7
+ | 'className'
8
+ | 'color'
9
+ | 'disabled'
10
+ | 'endIcon'
11
+ | 'fullWidth'
12
+ | 'href'
13
+ | 'onBlur'
14
+ | 'onClick'
15
+ | 'onChange'
16
+ | 'onFocus'
17
+ | 'size'
18
+ | 'startIcon'
19
+ | 'type'
20
+ | 'variant'
19
21
  > & {
20
- iconOnly?: boolean;
21
- darkModeEnabled?: boolean;
22
+ iconOnly?: boolean;
23
+ darkModeEnabled?: boolean;
24
+ startIconName?: NsIconProps['name'];
25
+ endIconName?: NsIconProps['name'];
22
26
  };
@@ -1,4 +1,4 @@
1
- import { NsNextImage, NsLink } from '../';
1
+ import { NsLink, NsImage } from '../';
2
2
  import { NsFfgStyled } from './styled/NsFfgStyled';
3
3
  import { NsFfgCardProps } from './types.d';
4
4
 
@@ -10,7 +10,7 @@ const NsFfgCard = ({ cardLink, text, topImageUrl, topImageAlt, additionalProps,
10
10
  className={additionalProps?.className ?? ''}
11
11
  >
12
12
  <header className="top-image">
13
- <NsNextImage height={192} width={288} alt={topImageAlt} src={topImageUrl} />
13
+ <NsImage height={192} width={288} alt={topImageAlt} src={topImageUrl} />
14
14
  </header>
15
15
  <article className="body-text" {...cslp?.card_text}>
16
16
  {text}
@@ -0,0 +1,14 @@
1
+ import { Badge, Theme } from '@mui/material';
2
+ import { ColorUtils, styled, FoundationTheme } from '@nuskin/foundation-theme';
3
+
4
+ type ItemCountParams = {
5
+ theme?: Theme;
6
+ bgcolor: FoundationTheme.PaletteColors;
7
+ };
8
+ const { paletteColor } = ColorUtils;
9
+ export const StyledBadge = styled(Badge)<ItemCountParams>`
10
+ & .MuiBadge-badge {
11
+ background-color: ${({ bgcolor, theme }) => paletteColor(bgcolor)({ theme })};
12
+ color: ${({ bgcolor, theme }) => paletteColor(bgcolor, 'contrastText')({ theme })};
13
+ }
14
+ `;
@@ -19,24 +19,24 @@ const NsDropdown: React.FC<DropdownProps> = ({
19
19
  }) => {
20
20
  const [isOpen, setIsOpen] = useState(false);
21
21
  const [value, setValue] = useState(selectedValue || '');
22
- const dropdowneRef = useRef<HTMLDivElement | null>(null);
22
+ const dropdownRef = useRef<HTMLDivElement | null>(null);
23
23
 
24
24
  const handleToggle = useCallback(() => {
25
25
  if (disabled) return;
26
26
  setIsOpen((x) => !x);
27
27
  }, [disabled]);
28
28
 
29
- const handleClose = () => {
29
+ const handleClose = useCallback(() => {
30
30
  setIsOpen(false);
31
- };
31
+ }, []);
32
32
 
33
- useOnClickOutside(dropdowneRef, handleClose);
33
+ useOnClickOutside(dropdownRef?.current, handleClose);
34
34
 
35
35
  const handleOnMouseLeave = useCallback(() => {
36
36
  if (closeOnMouseLeave) {
37
37
  handleClose();
38
38
  }
39
- }, [closeOnMouseLeave]);
39
+ }, [closeOnMouseLeave, handleClose]);
40
40
 
41
41
  const handleSelect = (input: string) => {
42
42
  onSelect(input);
@@ -45,7 +45,7 @@ const NsDropdown: React.FC<DropdownProps> = ({
45
45
  };
46
46
 
47
47
  return (
48
- <DropdownContainer disabled={disabled} ref={dropdowneRef}>
48
+ <DropdownContainer disabled={disabled} ref={dropdownRef}>
49
49
  <DropdownHead data-testid="dropdown-head" disabled={disabled} type={type} onClick={handleToggle}>
50
50
  <DropdownButton>{selectedLabel || placeholder}</DropdownButton>
51
51
  <NsIcon testId="chevron-icon" name={isOpen ? 'arrowUp' : 'arrowDown'} color="primary" />
@@ -43,7 +43,7 @@ const NsEmailSimple = (props: NsEmailSimpleProps) => {
43
43
  errorMessageValue = '';
44
44
  }
45
45
  } catch (error) {
46
- console.log('API error', error);
46
+ console.error('API error', error);
47
47
  }
48
48
  } else {
49
49
  //TODO What happens when user does not pass valid checkEmail function
@@ -1,10 +1,10 @@
1
+ import { render } from '@/test-utils/index';
1
2
  import React from 'react';
2
3
 
3
- import { render } from '@/test-utils/index';
4
4
  import { NsFlag } from '../';
5
5
 
6
6
  describe('FlagComponent', () => {
7
- it('renders a div element with background color and text', () => {
7
+ it('1. renders a div element with background color and text', () => {
8
8
  const text = 'NU SKIN';
9
9
  const { getByText } = render(<NsFlag message="NU SKIN" color="accentColorA" />);
10
10
  const divElement = getByText(text);
@@ -12,4 +12,16 @@ describe('FlagComponent', () => {
12
12
  expect(divElement).toBeInTheDocument();
13
13
  expect(divElement).toHaveTextContent(text);
14
14
  });
15
+ it('2. should render a flag with default size, color, and testId when only message prop is provided', () => {
16
+ const props = {
17
+ message: 'Test Message',
18
+ };
19
+ const { getByTestId } = render(<NsFlag {...props} />);
20
+ const flag = getByTestId('ns-flag-component');
21
+ expect(flag).toBeInTheDocument();
22
+ expect(flag).toHaveStyle('height: 20px');
23
+ expect(flag).toHaveStyle('color: #ffffff');
24
+ expect(flag).toHaveStyle('background: #f56767');
25
+ expect(flag).toHaveTextContent(props.message);
26
+ });
15
27
  });
@@ -27,7 +27,7 @@ const FlagHeightMap = {
27
27
  };
28
28
 
29
29
  const getFlagHeight = ({ $size }: { $size: NsFlagSize }) => {
30
- return FlagHeightMap[$size] || FlagHeightMap['small' as NsFlagSize];
30
+ return FlagHeightMap[$size];
31
31
  };
32
32
 
33
33
  const makeFlagSize = ({ $size }: { $size: NsFlagSize }) => {
@@ -36,10 +36,7 @@ const makeFlagSize = ({ $size }: { $size: NsFlagSize }) => {
36
36
  };
37
37
 
38
38
  const makeFlagBorder = ({ $size, $bgColor = 'accentColorA', theme }: NsFlagThemeParams) => {
39
- if (theme) {
40
- return `${makeFlagSize({ $size })}px solid ${paletteColor($bgColor)({ theme })}`;
41
- }
42
- return '';
39
+ return `${makeFlagSize({ $size })}px solid ${paletteColor($bgColor)({ theme })}`;
43
40
  };
44
41
 
45
42
  export const StyledFlag = styled('span')<NsFlagThemeParams>`
@@ -1,28 +1,25 @@
1
- import { RefObject, useCallback, useEffect } from 'react';
1
+ import { useEffect } from 'react';
2
2
 
3
3
  export type Handler = () => void;
4
4
 
5
- export function useOnClickOutside<T extends HTMLElement = HTMLElement>(
6
- ref: RefObject<T>,
5
+ export function useOnClickOutside(
6
+ element: HTMLDivElement | null,
7
7
  handler: Handler = () => {},
8
8
  mouseEvent: 'click' | 'mousedown' | 'mouseup' = 'click'
9
9
  ): void {
10
- const handleEventListener = useCallback(
11
- (event: MouseEvent) => {
12
- const el = ref?.current;
13
- if (!el || el.contains(event.target as Node)) {
10
+ useEffect(() => {
11
+ const eventListener = (event: MouseEvent) => {
12
+ // Do nothing if clicking ref's element or descendent elements
13
+ if (!element || element.contains(event.target as Node)) {
14
14
  return;
15
15
  }
16
16
  handler?.();
17
- },
18
- [ref, handler]
19
- );
20
- useEffect(() => {
17
+ };
21
18
  if (document) {
22
- document.addEventListener(mouseEvent, handleEventListener);
19
+ document.addEventListener(mouseEvent, eventListener);
23
20
  return () => {
24
- document.removeEventListener(mouseEvent, handleEventListener);
21
+ document.removeEventListener(mouseEvent, eventListener);
25
22
  };
26
23
  }
27
- }, [mouseEvent, handleEventListener]);
24
+ }, [mouseEvent, handler, element]);
28
25
  }
@@ -1,11 +1,12 @@
1
1
  import { render, screen } from '@/test-utils/index';
2
+ import { fireEvent } from '@storybook/testing-library';
2
3
  import React from 'react';
3
4
 
4
5
  import { NsIcon, NsIconNameType, NsIconVariants } from './';
5
6
 
6
7
  describe('NsIcon Component', () => {
7
8
  it('1. renders cartBadge icon with custom size and color', () => {
8
- const { getByTestId } = render(<NsIcon name="cart" size="medium" color="secondary" />);
9
+ const { getByTestId } = render(<NsIcon name="cart" size={'medium'} color="secondary" />);
9
10
  const icon = getByTestId('icon');
10
11
  const svgIcon = icon.querySelector('svg');
11
12
  // expect(svgIcon).toHaveClass('MuiSvgIcon-colorSecondary');
@@ -35,8 +36,16 @@ describe('NsIcon Component', () => {
35
36
  consoleErrorSpy.mockRestore();
36
37
  });
37
38
  it('5. renders default color of alertErrorIcon', () => {
38
- const { getByTestId } = render(<NsIcon name="alertError" size="medium" />);
39
+ const { getByTestId } = render(<NsIcon name="alertError" size={'medium'} />);
39
40
  const icon = getByTestId('alertError');
40
41
  expect(icon).toBeInTheDocument();
41
42
  });
43
+ it('6. calls onClick event handler', () => {
44
+ const onClick = jest.fn();
45
+ const { getByTestId } = render(<NsIcon name="alertError" size="medium" onClick={onClick} />);
46
+ const icon = getByTestId('alertError');
47
+ expect(icon).toBeInTheDocument();
48
+ fireEvent.click(icon);
49
+ expect(onClick).toHaveBeenCalled();
50
+ });
42
51
  });
@@ -1,3 +1,4 @@
1
+ import { PaletteColors } from '@nuskin/foundation-theme';
1
2
  import type { StoryObj, Meta } from '@storybook/react';
2
3
  import { withCenterDecorator } from '@/stories/decorators/withCenterDecorator';
3
4
  import { NsIcon, NsIconVariants } from './';
@@ -18,7 +19,7 @@ export default {
18
19
  },
19
20
  color: {
20
21
  control: 'select',
21
- options: ['primary', 'secondary', 'success', 'error', 'warning', 'info'],
22
+ options: PaletteColors,
22
23
  },
23
24
  colorOverride: {
24
25
  control: 'color',
@@ -1,19 +1,22 @@
1
1
  import { styled } from '@nuskin/foundation-theme';
2
2
  import { NsIconSizeType } from './types.d';
3
3
 
4
- const iconSize = {
4
+ export const iconSize: Record<NsIconSizeType, string> = {
5
5
  small: '16px',
6
6
  medium: '20px',
7
7
  large: '24px',
8
8
  xLarge: '30px',
9
9
  };
10
+ type IconWrapperType = { size: NsIconSizeType };
10
11
 
11
- export const IconContainer = styled.div<{ size: NsIconSizeType }>`
12
- display: flex;
13
- place-content: center;
14
- place-items: center;
15
- svg {
16
- width: ${({ size }) => iconSize[size]};
17
- height: ${({ size }) => iconSize[size]};
18
- }
19
- `;
12
+ export const IconWrapper = styled('div')<IconWrapperType>(({ size }) => {
13
+ return {
14
+ display: 'flex',
15
+ placeContent: 'center',
16
+ placeItems: 'center',
17
+ svg: {
18
+ width: iconSize[size],
19
+ height: iconSize[size],
20
+ },
21
+ };
22
+ });
@@ -1,19 +1,22 @@
1
1
  import { useTheme } from '@mui/material';
2
2
  import { ColorUtils } from '@nuskin/foundation-theme';
3
- import { IconContainer } from './NsIcon.styled';
3
+
4
+ import { IconWrapper } from './NsIcon.styled';
4
5
  import IconVariants from './NsIconVariants';
5
- import { NsIconProps } from './types.d';
6
+ import { NsIconNameType, NsIconProps } from './types.d';
6
7
 
7
8
  const { paletteColor } = ColorUtils;
9
+
8
10
  const NsIcon = ({
9
11
  name,
10
- size = 'large',
12
+ size,
11
13
  color = 'primary',
12
14
  testId = 'icon',
13
15
  className,
14
16
  colorOverride,
17
+ onClick = () => {},
15
18
  }: NsIconProps) => {
16
- const Icon = IconVariants[name];
19
+ const Icon = IconVariants[name as NsIconNameType];
17
20
  const theme = useTheme();
18
21
  const iconColor = paletteColor(color)({ theme });
19
22
  if (!Icon) {
@@ -21,9 +24,9 @@ const NsIcon = ({
21
24
  }
22
25
 
23
26
  return (
24
- <IconContainer data-testid={testId} size={size} className={className}>
27
+ <IconWrapper data-testid={testId} size={size || 'large'} className={className} onClick={onClick}>
25
28
  <Icon color={colorOverride ? colorOverride : (iconColor as any)} />
26
- </IconContainer>
29
+ </IconWrapper>
27
30
  );
28
31
  };
29
32
 
@@ -6,7 +6,13 @@ import SvgIcon, { SvgIconProps } from '@mui/material/SvgIcon';
6
6
  */
7
7
  const UserIcon = (props: SvgIconProps) => {
8
8
  return (
9
- <SvgIcon viewBox="0 0 24 24" data-testid="userIcon" xmlns="http://www.w3.org/2000/svg" {...props}>
9
+ <SvgIcon
10
+ viewBox="0 0 24 24"
11
+ data-testid="userIcon"
12
+ xmlns="http://www.w3.org/2000/svg"
13
+ {...props}
14
+ fill="transparent"
15
+ >
10
16
  <path
11
17
  fillRule="evenodd"
12
18
  clipRule="evenodd"
@@ -17,6 +23,7 @@ const UserIcon = (props: SvgIconProps) => {
17
23
  <path
18
24
  d="M19 20C18.9425 19.3229 19 17.5669 17.3793 17.2226C14.7126 16.6144 13.931 16.4078 14.1034 14.2272C15.8046 13.0796 15.7816 11.0252 15.7471 8.74139C15.7471 6.67508 14.0695 5 12 5C9.93052 5 8.25287 6.67508 8.25287 8.74139C8.25287 11.0367 8.25287 13.137 9.89655 14.2272C10.0575 16.4078 9.28736 16.6144 6.62069 17.2226C5 17.5669 5.05747 19.3229 5 20"
19
25
  stroke={props.color}
26
+ fill={props.color}
20
27
  strokeWidth="2"
21
28
  strokeLinecap="round"
22
29
  />
@@ -1,15 +1,16 @@
1
1
  import { FoundationTheme } from '@nuskin/foundation-theme';
2
+ import { HTMLProps } from 'react';
3
+
2
4
  import { NsIconVariants } from '.';
3
5
 
4
6
  export type NsIconSizeType = 'small' | 'medium' | 'large' | 'xLarge';
5
7
 
6
8
  export type NsIconNameType = keyof typeof NsIconVariants;
7
9
 
8
- export type NsIconProps = {
10
+ export type NsIconProps = HTMLProps & {
9
11
  name: NsIconNameType;
10
12
  size?: NsIconSizeType;
11
13
  color?: FoundationTheme.PaletteColors;
12
14
  testId?: string;
13
- className?: string;
14
15
  colorOverride?: string;
15
16
  };
@@ -4,7 +4,7 @@ import Progress from './NsProgress';
4
4
 
5
5
  describe(' NsProgress Component', () => {
6
6
  test('should render Progress bar', () => {
7
- render(<Progress color="primary" value={10}></Progress>);
7
+ render(<Progress barColor="primary" value={10}></Progress>);
8
8
 
9
9
  const pbar = screen.getByRole('progressbar');
10
10
 
@@ -16,7 +16,7 @@ describe(' NsProgress Component', () => {
16
16
  const value = 50;
17
17
 
18
18
  // Render the StyledProgress component with the value prop
19
- const { container } = render(<Progress color="primary" value={value} />);
19
+ const { container } = render(<Progress barColor="primary" value={value} />);
20
20
 
21
21
  // Get the progress bar element
22
22
  const progressBar = container.querySelector('.MuiLinearProgress-bar');
@@ -1,6 +1,7 @@
1
1
  import { withCenterDecorator } from '@/stories/decorators/withCenterDecorator';
2
2
  import type { StoryObj, Meta } from '@storybook/react';
3
3
  import NsProgress from './NsProgress';
4
+ import { PaletteColors } from '@nuskin/foundation-theme';
4
5
 
5
6
  type ComponentType = typeof NsProgress;
6
7
  type Story = StoryObj<ComponentType>;
@@ -8,10 +9,12 @@ type MetaStory = Meta<ComponentType>;
8
9
 
9
10
  export default {
10
11
  component: NsProgress,
11
- title: 'Input/NsProgress',
12
+ title: 'Components/Inputs/NsProgress',
12
13
  decorators: [withCenterDecorator],
13
14
  argTypes: {
14
- color: {
15
+ barColor: {
16
+ control: 'select',
17
+ options: PaletteColors,
15
18
  description: 'defines the color for the completed progress',
16
19
  },
17
20
  height: {
@@ -21,6 +24,8 @@ export default {
21
24
  description: 'value of the progress done',
22
25
  },
23
26
  backgroundColor: {
27
+ control: 'select',
28
+ options: PaletteColors,
24
29
  description: 'color of incomplete progress',
25
30
  },
26
31
  },
@@ -28,9 +33,9 @@ export default {
28
33
 
29
34
  export const ProgressBar: Story = {
30
35
  args: {
31
- color: 'primary',
32
- backgroundColor: '#19dbdb',
33
- value: undefined,
36
+ barColor: 'primary',
37
+ backgroundColor: 'secondary',
38
+ value: 40,
34
39
  height: '10px',
35
40
  body: <span>{'% Complete'}</span>,
36
41
  },
@@ -2,8 +2,9 @@ import { styled, ColorUtils } from '@nuskin/foundation-theme';
2
2
  import { LinearProgress } from '@mui/material';
3
3
  import CheckCircleIcon from '@mui/icons-material/CheckCircle';
4
4
  import { NsProgressProps } from './types';
5
+ import { NsTypography } from '../typography';
5
6
 
6
- const { color } = ColorUtils;
7
+ const { color, paletteColor } = ColorUtils;
7
8
  export const StyledCheckCircle = styled(CheckCircleIcon)`
8
9
  color: ${color('neutral', '50')};
9
10
  padding-top: 0.6em;
@@ -11,29 +12,46 @@ export const StyledCheckCircle = styled(CheckCircleIcon)`
11
12
  justify-self: flex-end;
12
13
  `;
13
14
 
14
- export const PercentDiv = styled('div')`
15
- color: ${color('primary', '100')};
15
+ export const ProgressInfo = styled(NsTypography)`
16
16
  display: flex;
17
17
  justify-content: flex-end;
18
- font-family: Inter;
19
- font-size: 12px;
20
- font-style: normal;
21
18
  font-weight: 700;
22
19
  text-transform: uppercase;
23
20
  `;
24
21
 
25
22
  export const StyledLinearProgress = styled(LinearProgress)<Omit<NsProgressProps, 'value'>>(
26
- ({ height, backgroundColor, color }) => ({
23
+ ({ height, backgroundColor, barColor, theme }) => ({
27
24
  width: '334px',
28
25
  height,
29
- backgroundColor,
30
- borderRadius: '3px',
26
+ backgroundColor: paletteColor(backgroundColor)({ theme }),
27
+ borderRadius: '8px',
31
28
  display: 'inline-block',
32
29
 
33
30
  '.MuiLinearProgress-bar': {
34
- backgroundColor: color,
31
+ backgroundColor: paletteColor(barColor)({ theme }),
35
32
  },
36
33
  })
37
34
  );
38
-
39
- export default StyledLinearProgress;
35
+ export const StyledProgress = styled('div')(() => {
36
+ return {
37
+ display: 'grid',
38
+ gridTemplateRows: '30px 30px',
39
+ '.progress-info': {
40
+ justifyContent: 'flex-end',
41
+ display: 'flex',
42
+ alignItems: 'center',
43
+ },
44
+ '.progress-bar': {
45
+ display: 'flex',
46
+ alignItems: 'center',
47
+ '.MuiSvgIcon-root': {
48
+ padding: '0',
49
+ margin: '0',
50
+ height: '100%',
51
+ position: 'relative',
52
+ left: '-4px',
53
+ scale: '1.3',
54
+ },
55
+ },
56
+ };
57
+ });