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

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 (123) hide show
  1. package/package.json +1 -1
  2. package/src/common/accordion/NsAccordion.tsx +77 -0
  3. package/src/common/accordion/NsAccordionHeader.tsx +56 -0
  4. package/src/common/accordion/NsAccordionItem.tsx +39 -0
  5. package/src/common/accordion/NsCollapse.tsx +56 -0
  6. package/src/common/accordion/NsToggleSection.tsx +30 -0
  7. package/src/common/accordion/ToggleSection.styled.tsx +28 -0
  8. package/src/common/accordion/index.ts +6 -0
  9. package/src/common/accordion/specs/NsAccordion.spec.tsx +91 -0
  10. package/src/common/accordion/specs/NsAccordionHeader.spec.tsx +47 -0
  11. package/src/common/accordion/specs/NsAccordionItem.spec.tsx +38 -0
  12. package/src/common/accordion/specs/NsCollapse.spec.tsx +37 -0
  13. package/src/common/accordion/specs/NsToggleSection.spec.tsx +33 -0
  14. package/src/common/accordion/stories/NsAccordion.stories.tsx +47 -0
  15. package/src/common/accordion/stories/NsAccordionHeader.stories.tsx +40 -0
  16. package/src/common/accordion/stories/NsAccordionItem.stories.tsx +40 -0
  17. package/src/common/accordion/stories/NsCollapse.stories.tsx +35 -0
  18. package/src/common/accordion/stories/NsToggleSection.stories.tsx +23 -0
  19. package/src/common/accordion/stories/data.tsx +22 -0
  20. package/src/common/accordion/types.d.ts +73 -0
  21. package/src/common/alert/NsAlert.stories.tsx +15 -14
  22. package/src/common/alert/types.d.ts +22 -22
  23. package/src/common/auth-dropdown/NsAuthDropdown.stories.tsx +1 -1
  24. package/src/common/autocomplete/NsAutocomplete.spec.tsx +20 -8
  25. package/src/common/autocomplete/NsAutocomplete.stories.tsx +4 -1
  26. package/src/common/autocomplete/NsAutocomplete.styled.tsx +12 -0
  27. package/src/common/autocomplete/NsAutocomplete.tsx +36 -18
  28. package/src/common/autocomplete/types.d.ts +7 -1
  29. package/src/common/banner/NsBanner.stories.tsx +1 -1
  30. package/src/common/brand-components/NsBrand.stories.tsx +1 -1
  31. package/src/common/breadcrumb/NsBreadcrumb.spec.tsx +1 -7
  32. package/src/common/breadcrumb/NsBreadcrumb.stories.tsx +2 -4
  33. package/src/common/breadcrumb/data.ts +7 -0
  34. package/src/common/button/NsButton.spec.tsx +10 -11
  35. package/src/common/button/NsButton.stories.tsx +1 -1
  36. package/src/common/card/stories/NsBgCard.stories.tsx +1 -3
  37. package/src/common/card/stories/NsBrandProductCard.stories.tsx +1 -1
  38. package/src/common/card/stories/NsFfgCard.stories.tsx +1 -1
  39. package/src/common/card/stories/{data.js → data.ts} +1 -25
  40. package/src/common/carousal/NsScrollingCarousal.tsx +26 -2
  41. package/src/common/carousal/stories/NsScrollingCarousal.stories.tsx +1 -1
  42. package/src/common/carousal/types.d.ts +2 -0
  43. package/src/common/cart-icon/NsCartIcon.stories.tsx +1 -1
  44. package/src/common/checkbox/NsCheckbox.stories.tsx +1 -1
  45. package/src/common/checkbox/NsCheckbox.styled.tsx +2 -2
  46. package/src/common/column-control/NsFlexColumns.tsx +5 -10
  47. package/src/common/column-control/NsGridColumns.tsx +5 -10
  48. package/src/common/column-control/specs/NsColumnControl.spec.tsx +1 -1
  49. package/src/common/column-control/specs/NsFlexColumns.spec.tsx +1 -1
  50. package/src/common/column-control/specs/NsGridColumns.spec.tsx +1 -1
  51. package/src/common/column-control/stories/DivArray.stories.tsx +18 -0
  52. package/src/common/column-control/stories/DivArray.tsx +63 -0
  53. package/src/common/column-control/stories/NsColumnControl.stories.tsx +6 -3
  54. package/src/common/column-control/stories/NsFlexColumns.stories.tsx +13 -9
  55. package/src/common/column-control/stories/NsGridColumns.stories.tsx +12 -8
  56. package/src/common/column-control/stories/common.tsx +1 -1
  57. package/src/common/column-control/styled/StyledFlex.tsx +7 -3
  58. package/src/common/column-control/styled/StyledGrid.tsx +9 -2
  59. package/src/common/column-control/styled/common.ts +2 -2
  60. package/src/common/column-control/types.d.ts +15 -16
  61. package/src/common/common.types.d.ts +1 -0
  62. package/src/common/dropdown/stories/NsDropdown.stories.tsx +1 -1
  63. package/src/common/dropdown/stories/NsDropdownCountry.stories.tsx +1 -1
  64. package/src/common/email-simple/NsEmailSimple.spec.tsx +145 -0
  65. package/src/common/email-simple/NsEmailSimple.stories.tsx +61 -0
  66. package/src/common/email-simple/NsEmailSimple.tsx +71 -0
  67. package/src/common/email-simple/index.ts +2 -0
  68. package/src/common/email-simple/types.d.ts +14 -0
  69. package/src/common/flag/NsFlag.spec.tsx +4 -25
  70. package/src/common/flag/NsFlag.stories.tsx +1 -1
  71. package/src/common/flag/NsFlag.tsx +0 -2
  72. package/src/common/icon/NsIcon.stories.tsx +1 -1
  73. package/src/common/image/NsImage.stories.tsx +1 -1
  74. package/src/common/image/NsNextImage.stories.tsx +1 -1
  75. package/src/common/image/types.d.ts +1 -0
  76. package/src/common/index.ts +3 -0
  77. package/src/common/input/NsInputField.stories.tsx +13 -10
  78. package/src/common/input/NsInputField.tsx +12 -5
  79. package/src/common/input/getAdornmentProps.tsx +4 -0
  80. package/src/common/input/types.d.ts +18 -1
  81. package/src/common/label/NsLabel.stories.tsx +5 -0
  82. package/src/common/label/NsLabel.tsx +16 -19
  83. package/src/common/label/types.d.ts +2 -1
  84. package/src/common/link/NsLink.stories.tsx +1 -1
  85. package/src/common/nav-product-card/NsNavProductCard.stories.tsx +1 -1
  86. package/src/common/nav-tab/NsNavTab.spec.tsx +0 -5
  87. package/src/common/nav-tab/NsNavTab.stories.tsx +1 -1
  88. package/src/common/radiogroup/NsRadioGroup.spec.tsx +63 -0
  89. package/src/common/radiogroup/NsRadioGroup.stories.tsx +101 -0
  90. package/src/common/radiogroup/NsRadioGroup.styled.tsx +56 -0
  91. package/src/common/radiogroup/NsRadioGroup.tsx +46 -0
  92. package/src/common/radiogroup/index.ts +2 -0
  93. package/src/common/radiogroup/types.d.ts +19 -0
  94. package/src/common/select/NsSelect.spec.tsx +200 -0
  95. package/src/common/select/NsSelect.styled.tsx +89 -0
  96. package/src/common/select/NsSelect.tsx +117 -0
  97. package/src/common/select/NsSelectOption.tsx +30 -0
  98. package/src/common/select/index.ts +3 -0
  99. package/src/common/select/stories/NsSelect.stories.tsx +134 -0
  100. package/src/common/select/types.d.ts +34 -0
  101. package/src/common/table/NsExpandableRow.tsx +68 -0
  102. package/src/common/table/NsTable.spec.tsx +69 -41
  103. package/src/common/table/NsTable.stories.tsx +48 -10
  104. package/src/common/table/NsTable.styled.ts +95 -4
  105. package/src/common/table/NsTable.tsx +78 -89
  106. package/src/common/table/NsTableHeader.tsx +52 -38
  107. package/src/common/table/NsTablePagination.tsx +21 -13
  108. package/src/common/table/types.d.ts +21 -8
  109. package/src/common/text-strip/NsTextStrip.stories.tsx +5 -4
  110. package/src/common/text-strip/NsTextStrip.tsx +5 -2
  111. package/src/common/text-strip/types.d.ts +7 -4
  112. package/src/common/typography/NsTypography.stories.tsx +1 -1
  113. package/src/common/validations/regex.ts +3 -0
  114. package/src/common/videos/NsVideo.stories.tsx +1 -1
  115. package/src/common/column-control/stories/NDivs.story.tsx +0 -35
  116. /package/src/common/card/{tests → specs}/BrandLogo.spec.tsx +0 -0
  117. /package/src/common/card/{tests → specs}/NsBgCard.spec.tsx +0 -0
  118. /package/src/common/card/{tests → specs}/NsBrandProductCard.spec.tsx +0 -0
  119. /package/src/common/card/{tests → specs}/NsFfgCard.spec.tsx +0 -0
  120. /package/src/common/carousal/{tests → specs}/Chevron.spec.tsx +0 -0
  121. /package/src/common/carousal/{tests → specs}/NsCarousal.spec.tsx +0 -0
  122. /package/src/common/carousal/{tests → specs}/NsScrollingCarousal.spec.tsx +0 -0
  123. /package/src/common/carousal/{tests → specs}/RenderBrand.spec.tsx +0 -0
@@ -0,0 +1,40 @@
1
+ import type { StoryObj, Meta } from '@storybook/react';
2
+ import { withCenterDecorator } from '@/stories/decorators/withCenterDecorator';
3
+ import { NsAccordionItem } from '@/common/index';
4
+
5
+ type ComponentType = typeof NsAccordionItem;
6
+ type Story = StoryObj<ComponentType>;
7
+ type MetaStory = Meta<ComponentType>;
8
+
9
+ export default {
10
+ title: 'Components/Accordion/NsAccordionItem',
11
+ component: NsAccordionItem,
12
+ decorators: [withCenterDecorator],
13
+ argTypes: {
14
+ isOpen: {
15
+ control: 'boolean',
16
+ description: 'if true renders NsAccordionItem in open state, and close state otherwise',
17
+ },
18
+ content: {},
19
+ title: {
20
+ control: 'string',
21
+ description: 'text used for header of section',
22
+ },
23
+ },
24
+ } as MetaStory;
25
+
26
+ export const OpenSection: Story = {
27
+ args: {
28
+ isOpen: true,
29
+ content: 'Nuskin Description',
30
+ title: 'Nuskin',
31
+ },
32
+ };
33
+
34
+ export const ClosedSection: Story = {
35
+ args: {
36
+ isOpen: false,
37
+ content: 'Nuskin Description',
38
+ title: 'Nuskin',
39
+ },
40
+ };
@@ -0,0 +1,35 @@
1
+ import type { StoryObj, Meta } from '@storybook/react';
2
+ import { withCenterDecorator } from '@/stories/decorators/withCenterDecorator';
3
+ import { NsCollapse } from '../';
4
+
5
+ type ComponentType = typeof NsCollapse;
6
+ type Story = StoryObj<ComponentType>;
7
+ type MetaStory = Meta<ComponentType>;
8
+
9
+ export default {
10
+ title: 'Components/Accordion/NsCollapse',
11
+ component: NsCollapse,
12
+ decorators: [withCenterDecorator],
13
+ argTypes: {
14
+ isOpen: {
15
+ control: 'boolean',
16
+ description: 'if true renders NsCollapse in open state, and close state otherwise',
17
+ },
18
+ children: {
19
+ control: 'React Node',
20
+ description: 'Content for NsCollapse',
21
+ },
22
+ },
23
+ } as MetaStory;
24
+ export const Closed: Story = {
25
+ args: {
26
+ isOpen: false,
27
+ children: 'Nuskin Description',
28
+ },
29
+ };
30
+ export const Open: Story = {
31
+ args: {
32
+ isOpen: true,
33
+ children: 'Nuskin Description',
34
+ },
35
+ };
@@ -0,0 +1,23 @@
1
+ import type { StoryObj, Meta } from '@storybook/react';
2
+ import { withCenterDecorator } from '@/stories/decorators/withCenterDecorator';
3
+ import { NsToggleSection } from '../..';
4
+
5
+ type ComponentType = typeof NsToggleSection;
6
+ type Story = StoryObj<ComponentType>;
7
+ type MetaStory = Meta<ComponentType>;
8
+
9
+ export default {
10
+ title: 'Components/Accordion/NsToggleSection',
11
+ component: NsToggleSection,
12
+ decorators: [withCenterDecorator],
13
+ argTypes: {
14
+ title: { control: 'string' },
15
+ },
16
+ args: {
17
+ title: 'Nuskin',
18
+ children: 'Nuskin Details',
19
+
20
+ },
21
+ } as MetaStory;
22
+
23
+ export const DefaultAccordion: Story = {};
@@ -0,0 +1,22 @@
1
+ import { NsAccordionProps } from '../types';
2
+
3
+ export const contentArray: NsAccordionProps['contentArray'] = [
4
+ {
5
+ title: 'Nuskin',
6
+ body: <div>Nuskin Details</div>,
7
+ isDefaultOpen: true,
8
+ },
9
+ {
10
+ title: 'Nuskin',
11
+ body: <div>Nuskin Details</div>,
12
+ isDefaultOpen: true,
13
+ },
14
+ {
15
+ title: 'Nuskin',
16
+ body: <div>Nuskin Details</div>,
17
+ },
18
+ {
19
+ title: 'Nuskin',
20
+ body: <div>Nuskin Details</div>,
21
+ },
22
+ ];
@@ -0,0 +1,73 @@
1
+ import { PropsWithChildren, ReactNode } from 'react';
2
+ import { AdditionalProps } from '../common.types';
3
+ import { NsIconNameType } from '../icon';
4
+ import { Variants } from '../typography';
5
+
6
+ export type NsAccordionHeaderProps = AdditionalProps & {
7
+ title: string | ReactNode;
8
+ // eslint-disable-next-line no-unused-vars
9
+ onClick: (...args: any[]) => void;
10
+ /** a flag for the header, based on which header can change properties */
11
+ isOpen?: boolean;
12
+ /** NsIcon's icon name to be shown in opened state */
13
+ openedIconName?: NsIconNameType;
14
+ /** NsIcon's icon name to be shown in closed state */
15
+ closedIconName?: NsIconNameType;
16
+ variant: AccordionVariant;
17
+ headerTypographyVariant?: Variants;
18
+ };
19
+
20
+ export type NsCollapseProps = AdditionalProps &
21
+ PropsWithChildren<{
22
+ isOpen: boolean;
23
+ variant: AccordionVariant;
24
+ }>;
25
+
26
+ export type NsFramerCollapseProps = NsCollapseProps & {
27
+ transitionDetails?: {
28
+ duration?: number;
29
+ ease?: number[];
30
+ };
31
+ };
32
+
33
+ export type NsToggleSectionProps = AdditionalProps &
34
+ PropsWithChildren<{
35
+ title: string | ReactNode;
36
+ /** if true, NsToggle is rendered in open state, that collapsible section is visible */
37
+ defaultOpen?: boolean;
38
+ variant: AccordionVariant;
39
+ }>;
40
+
41
+ export type NsAccordionItemProps = AdditionalProps & {
42
+ isOpen: boolean;
43
+ // eslint-disable-next-line no-unused-vars
44
+ toggleOpen(index: number, isOpen: boolean): void;
45
+ title: string | ReactNode;
46
+ content: ReactNode;
47
+ variant: AccordionVariant;
48
+ headerTypographyVariant?: Variants;
49
+ /** NsIcon's icon name to be shown in opened state */
50
+ openedIconName?: NsIconNameType;
51
+ /** NsIcon's icon name to be shown in closed state */
52
+ closedIconName?: NsIconNameType;
53
+ };
54
+ export type NsAccordionProps = AdditionalProps & {
55
+ allowMultipleExpanded: boolean;
56
+ contentArray: {
57
+ title: string | ReactNode;
58
+ body: ReactNode;
59
+ isDefaultOpen?: boolean;
60
+ }[];
61
+ variant: AccordionVariant;
62
+ headerTypographyVariant?: Variants;
63
+ /** NsIcon's icon name to be shown in opened state */
64
+ openedIconName?: NsIconNameType;
65
+ /** NsIcon's icon name to be shown in closed state */
66
+ closedIconName?: NsIconNameType;
67
+ };
68
+ export enum AccordionVariant {
69
+ // eslint-disable-next-line no-unused-vars
70
+ Basic = 'basic', // basic is as per figma
71
+ // eslint-disable-next-line no-unused-vars
72
+ Compact = 'compact', // compact is as per test.nuskin.com
73
+ }
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import type { Meta, StoryObj } from '@storybook/react';
3
3
  import NsAlert from './NsAlert';
4
- import { withCenterDecorator } from '../../stories/decorators/withCenterDecorator';
4
+ import { withCenterDecorator } from '@/stories/decorators/withCenterDecorator';
5
5
 
6
6
  type ComponentType = typeof NsAlert;
7
7
  type Story = StoryObj<ComponentType>;
@@ -12,14 +12,14 @@ export default {
12
12
  component: NsAlert,
13
13
  decorators: [withCenterDecorator],
14
14
  argTypes: {
15
- context: {
15
+ context: {
16
16
  control: 'select',
17
- options: ['error', 'info', 'notice', 'success', 'warning']
17
+ options: ['error', 'info', 'notice', 'success', 'warning'],
18
18
  },
19
- type: {
19
+ type: {
20
20
  control: 'select',
21
- options: ['auto', 'banner', 'card']
22
- }
21
+ options: ['auto', 'banner', 'card'],
22
+ },
23
23
  },
24
24
  args: {
25
25
  context: 'info',
@@ -28,15 +28,16 @@ export default {
28
28
  type: 'banner',
29
29
  visible: true,
30
30
  onDismiss: () => {},
31
- body:
32
- <span>{`Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt
31
+ body: (
32
+ <span>{`Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt
33
33
  ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco
34
- laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
35
- reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
36
- pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa
37
- qui officia deserunt mollit anim id est laborum.`}</span>,
38
- foot: <span>Some message goes here.</span>
39
- }
34
+ laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in
35
+ reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla
36
+ pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa
37
+ qui officia deserunt mollit anim id est laborum.`}</span>
38
+ ),
39
+ foot: <span>Some message goes here.</span>,
40
+ },
40
41
  } as MetaStory;
41
42
 
42
43
  export const AuthDropdown: Story = {};
@@ -1,15 +1,15 @@
1
1
  import { ReactNode, CSSProperties } from 'react';
2
2
 
3
3
  export interface NsAlertProps {
4
- context?: string,
5
- title?: string,
6
- threshhold?: number,
7
- type?: string,
8
- visible?: boolean,
9
- head?: ReactNode,
10
- body?: ReactNode,
11
- onDismiss?: () => void,
12
- foot?: ReactNode
4
+ context?: string;
5
+ title?: string;
6
+ threshhold?: number; // TODO: update to threshold, i.e. remove extra h
7
+ type?: string;
8
+ visible?: boolean;
9
+ head?: ReactNode;
10
+ body?: ReactNode;
11
+ onDismiss?: () => void;
12
+ foot?: ReactNode;
13
13
  }
14
14
 
15
15
  export interface HeaderProps {
@@ -18,28 +18,28 @@ export interface HeaderProps {
18
18
  }
19
19
 
20
20
  export type AlertContainerParams = {
21
- visible: boolean
21
+ visible: boolean;
22
22
  };
23
23
 
24
- export type ContextType = 'error' | 'info' | 'notice'| 'success' | 'warning';
24
+ export type ContextType = 'error' | 'info' | 'notice' | 'success' | 'warning';
25
25
  export type AlertType = 'auto' | 'banner' | 'card';
26
26
 
27
27
  export type AlertParams = {
28
- context: ContextType,
29
- type: AlertType
30
- }
28
+ context: ContextType;
29
+ type: AlertType;
30
+ };
31
31
 
32
32
  export type CustomCSSProperties = CSSProperties & {
33
33
  'min-height'?: string;
34
- 'content-column-start'? : string;
35
- 'content-column-end'? : string;
36
- 'bar-position'? : string;
37
- 'foot-visibility'? : string;
38
- 'foot-display'? : string;
34
+ 'content-column-start'?: string;
35
+ 'content-column-end'?: string;
36
+ 'bar-position'?: string;
37
+ 'foot-visibility'?: string;
38
+ 'foot-display'?: string;
39
39
  };
40
40
 
41
41
  export interface TypeMapCSS {
42
- banner: CustomCSSProperties,
43
- card: CustomCSSProperties,
44
- auto?: CustomCSSProperties
42
+ banner: CustomCSSProperties;
43
+ card: CustomCSSProperties;
44
+ auto?: CustomCSSProperties;
45
45
  }
@@ -1,6 +1,6 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react';
2
2
  import { NsAuthDropdown } from './';
3
- import { withCenterDecorator } from '../../stories/decorators/withCenterDecorator';
3
+ import { withCenterDecorator } from '@/stories/decorators/withCenterDecorator';
4
4
 
5
5
  type ComponentType = typeof NsAuthDropdown;
6
6
  type Story = StoryObj<ComponentType>;
@@ -1,9 +1,10 @@
1
1
  import React from 'react';
2
- import { render, screen, waitFor } from '@testing-library/react';
2
+ import { render, screen, waitFor } from '@/test-utils/index';
3
3
  import { NsAutocomplete } from '@/common/index';
4
4
  import { OptionUiComponent } from './mock/MockUI';
5
5
  import { AutocompleteMockList } from './mock/MockData';
6
6
  import userEvent from '@testing-library/user-event';
7
+ import { act } from 'react-dom/test-utils';
7
8
 
8
9
  describe('CustomAutocomplete', () => {
9
10
  test('should render autocomplete component', () => {
@@ -29,11 +30,16 @@ describe('CustomAutocomplete', () => {
29
30
  />
30
31
  );
31
32
  const autocompleteInput = screen.getByPlaceholderText('autocomplete-input');
32
- userEvent.type(autocompleteInput, 'GS Facial');
33
- await waitFor(() => {
34
- const option1 = screen.getByText('GS Facial Gels 2pk Subscription');
35
- expect(option1).toBeInTheDocument();
33
+ act(() => {
34
+ userEvent.type(autocompleteInput, 'GS Facial');
36
35
  });
36
+ await waitFor(
37
+ () => {
38
+ const option1 = screen.getByText('GS Facial Gels 2pk Subscription');
39
+ expect(option1).toBeInTheDocument();
40
+ },
41
+ { timeout: 5000 }
42
+ );
37
43
  }, 40000);
38
44
 
39
45
  test('selects an option when clicking on it', async () => {
@@ -45,7 +51,9 @@ describe('CustomAutocomplete', () => {
45
51
  />
46
52
  );
47
53
  const autocompleteInput = screen.getByPlaceholderText('autocomplete-input');
48
- userEvent.type(autocompleteInput, 'GS Facial');
54
+ act(() => {
55
+ userEvent.type(autocompleteInput, 'GS Facial');
56
+ });
49
57
  await waitFor(() => {
50
58
  const optionLi = screen.getByText('GS Facial Spa');
51
59
  userEvent.click(optionLi);
@@ -66,7 +74,9 @@ describe('CustomAutocomplete', () => {
66
74
  />
67
75
  );
68
76
  const autocompleteInput = screen.getByPlaceholderText('autocomplete-input');
69
- userEvent.type(autocompleteInput, 'GS Facial');
77
+ act(() => {
78
+ userEvent.type(autocompleteInput, 'GS Facial');
79
+ });
70
80
  await waitFor(() => {
71
81
  const loadMoreButton = screen.getByTestId('autocomplete-loadmore-id');
72
82
  userEvent.click(loadMoreButton);
@@ -87,7 +97,9 @@ describe('CustomAutocomplete', () => {
87
97
  />
88
98
  );
89
99
  const autocompleteInput = screen.getByPlaceholderText('autocomplete-input');
90
- userEvent.type(autocompleteInput, 'GS Facial');
100
+ act(() => {
101
+ userEvent.type(autocompleteInput, 'GS Facial');
102
+ });
91
103
  await waitFor(() => {
92
104
  const clearButton = screen.getByTestId('autocomplete-clear-id');
93
105
  userEvent.click(clearButton);
@@ -7,11 +7,12 @@
7
7
  import React from 'react';
8
8
  import type { StoryObj, Meta } from '@storybook/react';
9
9
 
10
- import { withCenterDecorator } from '../../stories/decorators/withCenterDecorator';
10
+ import { withCenterDecorator } from '@/stories/decorators/withCenterDecorator';
11
11
  import { NsAutocomplete } from './';
12
12
  import { AutocompleteMockList } from './mock/MockData';
13
13
  import { OptionUiComponent } from './mock/MockUI';
14
14
  import { NsAutocompleteProps } from './types.d';
15
+ import { NsIcon } from '../icon';
15
16
 
16
17
  type ComponentType = typeof NsAutocomplete;
17
18
  type Story = StoryObj<ComponentType>;
@@ -42,6 +43,8 @@ export default {
42
43
  throw new Error('Function not implemented.');
43
44
  },
44
45
  },
46
+ iconStart: <NsIcon name="search" />,
47
+ iconEnd: <NsIcon name="close" size='small'/>,
45
48
  placeholder: 'search',
46
49
  },
47
50
  } as MetaStory;
@@ -0,0 +1,12 @@
1
+ import { styled } from '@nuskin/foundation-theme';
2
+
3
+ import { NsInputField } from '../input';
4
+
5
+ export const StyledTextField = styled(NsInputField)`
6
+ .MuiAutocomplete-inputRoot {
7
+ padding-right: 10px !important;
8
+ }
9
+ .muiautocomplete-popupindicator {
10
+ display: none;
11
+ }
12
+ `;
@@ -1,20 +1,23 @@
1
- import * as React from 'react';
2
- import { NsInputField } from '../input';
1
+ import React, { useState, PropsWithChildren, useRef } from 'react';
3
2
  import { Autocomplete, AutocompleteRenderGroupParams, List, AutocompleteRenderInputParams } from '@mui/material';
4
- import { useState, PropsWithChildren, useRef } from 'react';
5
- import { NsTypography } from '../typography';
6
- import { NsAutocompleteProps, OptionsProps, ComponentboxProps } from './types.d';
7
- import { NsButton } from '../button';
3
+ import { NsTypography, NsButton } from '../';
4
+ import { NsAutocompleteProps, OptionsProps, ComponentBoxProps } from './types.d';
5
+ import { StyledTextField } from './NsAutocomplete.styled';
8
6
 
9
7
  const NsAutocomplete = ({
10
8
  id = 'custom_autocomplete_dropdown',
11
9
  options = [],
12
10
  renderOptions,
11
+ loading,
12
+ noOptionsText,
13
13
  onSelect,
14
+ onChange,
14
15
  clear,
15
16
  seeMore,
16
17
  placeholder,
17
18
  className,
19
+ iconStart,
20
+ iconEnd,
18
21
  }: PropsWithChildren<NsAutocompleteProps>) => {
19
22
  const inputRef = useRef(null);
20
23
 
@@ -27,10 +30,21 @@ const NsAutocomplete = ({
27
30
  };
28
31
 
29
32
  const renderInput = (params: AutocompleteRenderInputParams) => (
30
- <NsInputField {...params} placeholder={placeholder} inputRef={inputRef} />
33
+ <StyledTextField
34
+ {...params}
35
+ onChange={onChange}
36
+ placeholder={placeholder}
37
+ inputRef={inputRef}
38
+ InputProps={{
39
+ ...params.InputProps,
40
+ startAdornment: iconStart,
41
+ endAdornment: iconEnd,
42
+ }}
43
+ />
31
44
  );
32
45
 
33
- const renderOption = (props: ComponentboxProps, option: OptionsProps) => (
46
+ // TODO: @vijayprathap need to check if we can remove object spread of ...props and ...params in renderInput
47
+ const renderOption = (props: ComponentBoxProps, option: OptionsProps) => (
34
48
  <li {...props}>
35
49
  <OptionUI {...props} option={option} />
36
50
  </li>
@@ -43,7 +57,7 @@ const NsAutocomplete = ({
43
57
  const renderGroupName = ({ key, group, children }: AutocompleteRenderGroupParams) => (
44
58
  <li key={key}>
45
59
  {group ? (
46
- <NsTypography variant="p-s" className="p-3">
60
+ <NsTypography variant="p-m" weight="bold" className="p-3">
47
61
  {group}
48
62
  </NsTypography>
49
63
  ) : null}
@@ -59,7 +73,9 @@ const NsAutocomplete = ({
59
73
  return (
60
74
  <div className="text-right p-3">
61
75
  <NsButton onClick={onClear} data-testid="autocomplete-clear-id">
62
- <NsTypography variant={'p-xs'}>{text}</NsTypography>
76
+ <NsTypography variant={'p-xs'} weight="bold">
77
+ {text}
78
+ </NsTypography>
63
79
  </NsButton>
64
80
  </div>
65
81
  );
@@ -73,20 +89,20 @@ const NsAutocomplete = ({
73
89
  return (
74
90
  <div className="text-center p-3">
75
91
  <NsButton onClick={onSeeMore} data-testid="autocomplete-loadmore-id">
76
- <NsTypography variant="p-xs">{text}</NsTypography>
92
+ <NsTypography variant="p-xs" weight="bold">
93
+ {text}
94
+ </NsTypography>
77
95
  </NsButton>
78
96
  </div>
79
97
  );
80
98
  };
81
99
 
82
- const renderListBoxComponent = ({ children, ...otherProps }: ComponentboxProps) => (
83
- <>
100
+ const renderListBoxComponent = ({ children, ...otherProps }: ComponentBoxProps) => (
101
+ <List {...otherProps}>
84
102
  {renderClearButton()}
85
- <List {...otherProps}>
86
- {children}
87
- {renderSeeMoreButton()}
88
- </List>
89
- </>
103
+ {children}
104
+ {renderSeeMoreButton()}
105
+ </List>
90
106
  );
91
107
 
92
108
  return (
@@ -95,6 +111,8 @@ const NsAutocomplete = ({
95
111
  disablePortal
96
112
  className={className}
97
113
  options={options}
114
+ loading={loading}
115
+ noOptionsText={noOptionsText}
98
116
  groupBy={renderGroupBy}
99
117
  getOptionLabel={renderOptionLabel}
100
118
  renderOption={renderOption}
@@ -6,9 +6,13 @@ import { ComponentsProps } from '@mui/material';
6
6
  export type NsAutocompleteProps = {
7
7
  id?: string;
8
8
  options: OptionsProps[];
9
+ loading?:boolean;
9
10
  renderOptions: React.ComponentType<any>;
11
+ noOptionsText ?:string;
10
12
  // eslint-disable-next-line no-unused-vars
11
13
  onSelect?: (params: OptionsProps | null) => void;
14
+ // eslint-disable-next-line no-unused-vars
15
+ onChange?: (params) => void;
12
16
  clear?: {
13
17
  text: string;
14
18
  show?: boolean; //default to false
@@ -21,6 +25,8 @@ export type NsAutocompleteProps = {
21
25
  };
22
26
  placeholder?: string;
23
27
  className?: string;
28
+ iconStart?: string | React.ReactNode;
29
+ iconEnd?: string | React.ReactNode;
24
30
  } & AdditionalProps;
25
31
 
26
32
  export type ListUiProps = {
@@ -36,4 +42,4 @@ export type OptionsProps = {
36
42
  groupBgColor?: string;
37
43
  };
38
44
 
39
- export type ComponentboxProps = ComponentsProps & HTMLAttributes<HTMLElement>;
45
+ export type ComponentBoxProps = ComponentsProps & HTMLAttributes<HTMLElement>;
@@ -7,7 +7,7 @@
7
7
  import React from 'react';
8
8
  import type { StoryObj, Meta } from '@storybook/react';
9
9
  import { NsBanner, NsTypography, NsButton } from '../';
10
- import { withCenterDecorator } from '../../stories/decorators/withCenterDecorator';
10
+ import { withCenterDecorator } from '@/stories/decorators/withCenterDecorator';
11
11
 
12
12
  type ComponentType = typeof NsBanner;
13
13
  type Story = StoryObj<ComponentType>;
@@ -1,6 +1,6 @@
1
1
  import type { StoryObj, Meta } from '@storybook/react';
2
2
  import { NsBrandComponent } from './';
3
- import { withCenterDecorator } from '../../stories/decorators/withCenterDecorator';
3
+ import { withCenterDecorator } from '@/stories/decorators/withCenterDecorator';
4
4
 
5
5
  type ComponentType = typeof NsBrandComponent;
6
6
  type Story = StoryObj<ComponentType>;
@@ -1,14 +1,8 @@
1
1
  import React from 'react';
2
2
  import { render, screen } from '@testing-library/react';
3
3
  import { NsBreadcrumb } from './';
4
- import { ItemProps } from './types.d';
4
+ import { breadcrumbItems } from './data';
5
5
  const { getByText } = screen;
6
- export const breadcrumbItems: ItemProps[] = [
7
- { label: 'Home', href: '/', icon: 'home' },
8
- { label: 'Products', href: '/products' },
9
- { label: 'Shirts', href: '/products/shirts' },
10
- { label: 'Blue shirt', href: '/products/shirts/blue' },
11
- ];
12
6
 
13
7
  describe('Breadcrumb', () => {
14
8
  it('renders breadcrumb items', () => {
@@ -1,14 +1,12 @@
1
1
  /**
2
- * @author [Vijayaprathap Kumar] (vpkumar@nuskin.com)
3
- * NsBanner.stories.tsx
4
2
  * @description NsBanner component.
5
3
  */
6
4
 
7
5
  import type { Meta, StoryObj } from '@storybook/react';
8
6
 
9
7
  import { NsBreadcrumb } from './';
10
- import { withCenterDecorator } from '../../stories/decorators/withCenterDecorator';
11
- import { breadcrumbItems } from './NsBreadcrumb.spec';
8
+ import { withCenterDecorator } from '@/stories/decorators/withCenterDecorator';
9
+ import { breadcrumbItems } from './data';
12
10
 
13
11
  type ComponentType = typeof NsBreadcrumb;
14
12
  type Story = StoryObj<ComponentType>;
@@ -0,0 +1,7 @@
1
+ import { ItemProps } from './types';
2
+ export const breadcrumbItems: ItemProps[] = [
3
+ { label: 'Home', href: '/', icon: 'home' },
4
+ { label: 'Products', href: '/products' },
5
+ { label: 'Shirts', href: '/products/shirts' },
6
+ { label: 'Blue shirt', href: '/products/shirts/blue' },
7
+ ];