@nuskin/foundation-ui-components 1.6.1 → 1.8.0-688-v1.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 (64) hide show
  1. package/package.json +45 -45
  2. package/src/common/autocomplete/NsAutocomplete.spec.tsx +37 -82
  3. package/src/common/autocomplete/NsAutocomplete.styled.tsx +2 -0
  4. package/src/common/autocomplete/NsAutocomplete.tsx +59 -61
  5. package/src/common/autocomplete/helper/{ClearButton.tsx → AutoCompleteButton.tsx} +9 -7
  6. package/src/common/autocomplete/helper/SeeMoreButton.tsx +5 -14
  7. package/src/common/autocomplete/helper/renderGroupName.tsx +4 -2
  8. package/src/common/autocomplete/stories/{ACWithoutClose.tsx → NoCloseAutoComplete.tsx} +6 -6
  9. package/src/common/autocomplete/stories/NsAutocomplete.stories.tsx +3 -3
  10. package/src/common/autocomplete/stories/RenderAutoComplete.tsx +5 -5
  11. package/src/common/autocomplete/types.d.ts +21 -8
  12. package/src/common/button/NsButton.spec.tsx +10 -9
  13. package/src/common/button/NsButton.styled.tsx +40 -51
  14. package/src/common/button/NsButton.tsx +3 -2
  15. package/src/common/card/NsBrandCard.tsx +94 -0
  16. package/src/common/card/NsCheckoutCard.tsx +92 -0
  17. package/src/common/card/NsHeroCardLevel1.tsx +106 -0
  18. package/src/common/card/NsHeroCardLevel2.tsx +126 -0
  19. package/src/common/card/NsIconText.tsx +153 -0
  20. package/src/common/card/NsLargeCard.tsx +120 -0
  21. package/src/common/card/NsMediumCard.tsx +64 -0
  22. package/src/common/card/NsPost.tsx +60 -0
  23. package/src/common/card/NsSmallFullCard.tsx +90 -0
  24. package/src/common/card/NsXLargeCard.tsx +80 -0
  25. package/src/common/card/cardSizes.ts +12 -0
  26. package/src/common/card/index.ts +10 -2
  27. package/src/common/card/specs/BrandLogo.spec.tsx +1 -1
  28. package/src/common/card/specs/NsBgCard.spec.tsx +2 -2
  29. package/src/common/card/specs/NsBrandCard.spec.tsx +97 -0
  30. package/src/common/card/specs/NsCheckoutCard.spec.tsx +50 -0
  31. package/src/common/card/specs/NsHeroCardLevel1.spec.tsx +48 -0
  32. package/src/common/card/specs/NsHeroCardLevel2.spec.tsx +51 -0
  33. package/src/common/card/specs/NsIconText.spec.tsx +28 -0
  34. package/src/common/card/specs/NsLargeCard.spec.tsx +41 -0
  35. package/src/common/card/specs/NsMediumCard.spec.tsx +35 -0
  36. package/src/common/card/specs/NsPost.spec.tsx +31 -0
  37. package/src/common/card/specs/NsSmallFullCard.spec.tsx +36 -0
  38. package/src/common/card/specs/NsXLargeCard.spec.tsx +35 -0
  39. package/src/common/card/stories/{NsBrandProductCard.stories.tsx → NsBrandCard.stories.tsx} +9 -4
  40. package/src/common/card/stories/NsCheckoutCard.stories.tsx +24 -0
  41. package/src/common/card/stories/NsHeroCardLevel1.stories.tsx +45 -0
  42. package/src/common/card/stories/NsHeroCardLevel2.stories.tsx +50 -0
  43. package/src/common/card/stories/NsIconText.stories.tsx +36 -0
  44. package/src/common/card/stories/NsLargeCard.stories.tsx +32 -0
  45. package/src/common/card/stories/NsMediumCard.stories.tsx +29 -0
  46. package/src/common/card/stories/NsPost.stories.tsx +39 -0
  47. package/src/common/card/stories/NsSmallFullCard.stories.tsx +29 -0
  48. package/src/common/card/stories/NsXLargeCard.stories.tsx +29 -0
  49. package/src/common/carousal/RenderBrand.tsx +3 -2
  50. package/src/common/checkbox/NsCheckbox.stories.tsx +1 -1
  51. package/src/common/checkbox/NsCheckbox.styled.tsx +3 -2
  52. package/src/common/email-simple/NsEmailSimple.spec.tsx +72 -102
  53. package/src/common/icon/icons/RoundedClose.tsx +10 -12
  54. package/src/common/input/NsInputField.tsx +7 -5
  55. package/src/common/input/types.d.ts +3 -2
  56. package/src/common/radiogroup/NsRadioGroup.tsx +5 -6
  57. package/src/common/validations/regex.ts +1 -2
  58. package/src/common/card/NsBrandProductCard.tsx +0 -47
  59. package/src/common/card/NsFfgCard.tsx +0 -24
  60. package/src/common/card/specs/NsBrandProductCard.spec.tsx +0 -32
  61. package/src/common/card/specs/NsFfgCard.spec.tsx +0 -33
  62. package/src/common/card/stories/NsBgCard.stories.tsx +0 -20
  63. package/src/common/card/stories/NsFfgCard.stories.tsx +0 -73
  64. package/src/common/card/styled/NsFfgStyled.tsx +0 -46
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nuskin/foundation-ui-components",
3
- "version": "1.6.1",
3
+ "version": "1.8.0-688-v1.1",
4
4
  "description": "It is a foundation library written in react, that provides common components to all UI pages",
5
5
  "main": "src/common/index.ts",
6
6
  "repository": {
@@ -42,62 +42,62 @@
42
42
  "dependencies": {
43
43
  "@emotion/react": "^11.11.1",
44
44
  "@emotion/styled": "^11.11.0",
45
- "@mui/icons-material": "^5.11.11",
46
- "@mui/material": "5.4.2",
47
- "@mui/utils": "^5.14.1",
48
- "@next/font": "13.2.4",
49
- "@nuskin/foundation-theme": "^1.0.1",
50
- "framer-motion": "^10.8.5",
51
- "next": "13.2.4",
45
+ "@mui/icons-material": "^5.14.14",
46
+ "@mui/material": "5.14.14",
47
+ "@mui/utils": "^5.14.13",
48
+ "@next/font": "13.5.5",
49
+ "@nuskin/foundation-theme": "1.2.0",
50
+ "@types/react": "^18.2.28",
51
+ "@types/react-dom": "^18.2.13",
52
+ "cliui": "^8.0.1",
53
+ "framer-motion": "^10.16.4",
54
+ "next": "13.5.5",
52
55
  "react": "18.2.0",
53
- "react-dom": "18.2.0",
56
+ "react-dom": "^18.2.0",
54
57
  "react-material-ui-carousel": "^3.4.2",
55
58
  "react-slick": "^0.29.0",
56
59
  "slick-carousel": "^1.8.1",
57
- "typescript": "4.9.5"
60
+ "typescript": "^5.2.2"
58
61
  },
59
62
  "devDependencies": {
60
- "@babel/core": "^7.21.0",
61
- "@babel/preset-env": "^7.20.2",
62
- "@babel/preset-react": "^7.18.6",
63
- "@babel/preset-typescript": "^7.21.0",
64
- "@emotion/jest": "^11.10.5",
63
+ "@babel/core": "^7.23.2",
64
+ "@babel/preset-env": "^7.23.2",
65
+ "@babel/preset-react": "^7.22.15",
66
+ "@babel/preset-typescript": "^7.23.2",
67
+ "@emotion/jest": "^11.11.0",
65
68
  "@nuskin/eslint-config": "^1.0.0-setup.1",
66
- "@storybook/addon-actions": "^7.0.7",
67
- "@storybook/addon-essentials": "^7.0.7",
68
- "@storybook/addon-interactions": "^7.0.7",
69
- "@storybook/addon-links": "^7.0.7",
70
- "@storybook/addon-mdx-gfm": "^7.0.7",
71
- "@storybook/jest": "^0.1.0",
72
- "@storybook/nextjs": "^7.0.7",
73
- "@storybook/react": "^7.0.24",
74
- "@storybook/test-runner": "^0.10.0",
75
- "@storybook/testing-library": "^0.1.0",
76
- "@testing-library/jest-dom": "^5.16.5",
69
+ "@storybook/addon-actions": "^7.5.0-alpha.6",
70
+ "@storybook/addon-essentials": "^7.5.0-alpha.6",
71
+ "@storybook/addon-interactions": "^7.5.0-alpha.6",
72
+ "@storybook/addon-links": "^7.5.0-alpha.6",
73
+ "@storybook/jest": "^0.2.3",
74
+ "@storybook/nextjs": "^7.5.0-alpha.6",
75
+ "@storybook/react": "^7.5.0-alpha.6",
76
+ "@storybook/test-runner": "^0.13.1-next.1",
77
+ "@storybook/testing-library": "^0.2.2",
78
+ "@testing-library/dom": "^9.3.3",
79
+ "@testing-library/jest-dom": "^6.1.4",
77
80
  "@testing-library/react": "^14.0.0",
78
81
  "@testing-library/react-hooks": "^8.0.1",
79
- "@types/jest": "^29.5.0",
80
- "@types/lodash": "^4.14.191",
81
- "@types/node": "18.15.0",
82
- "@types/ramda": "^0.29.3",
83
- "@types/react": "18.0.28",
84
- "@types/react-dom": "18.0.11",
82
+ "@types/jest": "^29.5.5",
83
+ "@types/lodash": "^4.14.199",
84
+ "@types/node": "^20.8.6",
85
+ "@types/ramda": "^0.29.6",
85
86
  "@types/react-slick": "^0.23.10",
86
- "@types/react-test-renderer": "^18.0.0",
87
- "@types/testing-library__jest-dom": "^5.14.5",
88
- "babel-jest": "^29.5.0",
89
- "babel-loader": "^9.1.2",
87
+ "@types/react-test-renderer": "^18.0.3",
88
+ "babel-jest": "^29.7.0",
89
+ "babel-loader": "^9.1.3",
90
90
  "babel-plugin-emotion": "^11.0.0",
91
- "chromatic": "^6.17.3",
92
- "eslint": "8.36.0",
93
- "eslint-config-next": "13.2.4",
94
- "eslint-config-prettier": "^8.7.0",
91
+ "chromatic": "^7.4.0",
92
+ "eslint": "^8.51.0",
93
+ "eslint-config-next": "^13.5.5",
94
+ "eslint-config-prettier": "^9.0.0",
95
95
  "eslint-plugin-json": "^3.1.0",
96
- "eslint-plugin-prettier": "^4.2.1",
97
- "eslint-plugin-storybook": "^0.6.11",
98
- "jest": "^29.5.0",
99
- "jest-environment-jsdom": "^29.5.0",
100
- "storybook": "^7.0.7"
96
+ "eslint-plugin-prettier": "^5.0.1",
97
+ "eslint-plugin-storybook": "^0.6.15",
98
+ "jest": "^29.7.0",
99
+ "jest-environment-jsdom": "^29.7.0",
100
+ "storybook": "^7.5.0-alpha.6"
101
101
  },
102
102
  "files": [
103
103
  "src/common"
@@ -1,62 +1,40 @@
1
- import React from 'react';
2
- import userEvent from '@testing-library/user-event';
3
- import { act } from 'react-dom/test-utils';
4
1
  import { render, screen, waitFor } from '@/test-utils/index';
5
- import { OptionUiComponent } from './mock/MockUI';
2
+ import userEvent from '@testing-library/user-event';
3
+ import React from 'react';
4
+
6
5
  import { AutocompleteMockList } from './mock/MockData';
6
+ import { OptionUiComponent } from './mock/MockUI';
7
7
  import NsAutocomplete from './NsAutocomplete';
8
8
 
9
+ const commonProps = {
10
+ value: '',
11
+ inputValue: '',
12
+ onInputChange: jest.fn(),
13
+ onChange: jest.fn(),
14
+ options: AutocompleteMockList,
15
+ placeholder: 'autocomplete-input',
16
+ OptionsUI: OptionUiComponent,
17
+ };
9
18
  describe('CustomAutocomplete', () => {
10
19
  it('1. should render autocomplete component', () => {
11
- render(
12
- <NsAutocomplete
13
- options={AutocompleteMockList}
14
- placeholder="autocomplete-input"
15
- OptionsUI={OptionUiComponent}
16
- inputValue=""
17
- value=""
18
- />
19
- );
20
+ render(<NsAutocomplete {...commonProps} />);
20
21
  const autocompleteInput = screen.getByPlaceholderText('autocomplete-input');
21
22
  expect(autocompleteInput).toBeInTheDocument();
22
23
  });
23
- it('2. check that onChange gets called', () => {
24
- const onSelectMock = jest.fn();
25
- const onChangeMock = jest.fn();
26
- render(
27
- <NsAutocomplete
28
- options={AutocompleteMockList}
29
- onSelect={onSelectMock}
30
- onChange={onChangeMock}
31
- placeholder="autocomplete-input"
32
- OptionsUI={OptionUiComponent}
33
- inputValue=""
34
- value=""
35
- />
36
- );
24
+ it('2. check that onInputChange gets called', async () => {
25
+ const onInputChangeMock = jest.fn();
26
+ render(<NsAutocomplete {...commonProps} onInputChange={onInputChangeMock} />);
37
27
  const autocompleteInput = screen.getByPlaceholderText('autocomplete-input');
38
28
  expect(autocompleteInput).toBeInTheDocument();
39
- act(() => {
40
- userEvent.type(autocompleteInput, 'GS Facial');
41
- });
42
- expect(onChangeMock).toHaveBeenCalled();
43
- });
29
+ await userEvent.type(autocompleteInput, 'GS Facial');
30
+ expect(onInputChangeMock).toHaveBeenCalled();
31
+ }, 10000);
44
32
 
45
33
  it('3. displays options when typing in the input', async () => {
46
- render(
47
- <NsAutocomplete
48
- options={AutocompleteMockList}
49
- onSelect={() => {}}
50
- OptionsUI={OptionUiComponent}
51
- placeholder="autocomplete-input"
52
- inputValue=""
53
- value=""
54
- />
55
- );
34
+ const onInputChangeMock = jest.fn();
35
+ render(<NsAutocomplete {...commonProps} onInputChange={onInputChangeMock} />);
56
36
  const autocompleteInput = screen.getByPlaceholderText('autocomplete-input');
57
- act(() => {
58
- userEvent.type(autocompleteInput, 'GS Facial');
59
- });
37
+ await userEvent.type(autocompleteInput, 'GS Facial');
60
38
  await waitFor(
61
39
  () => {
62
40
  const option1 = screen.getByText('GS Facial Gels 2pk Subscription');
@@ -67,75 +45,52 @@ describe('CustomAutocomplete', () => {
67
45
  }, 40000);
68
46
 
69
47
  it('4. selects an option when clicking on it', async () => {
70
- const onSelectMock = jest.fn();
71
- render(
72
- <NsAutocomplete
73
- onSelect={onSelectMock}
74
- options={AutocompleteMockList}
75
- OptionsUI={OptionUiComponent}
76
- placeholder="autocomplete-input"
77
- inputValue=""
78
- value=""
79
- />
80
- );
48
+ const onChangeMock = jest.fn();
49
+ render(<NsAutocomplete {...commonProps} onChange={onChangeMock} />);
81
50
  const autocompleteInput = screen.getByPlaceholderText('autocomplete-input');
82
- act(() => {
83
- userEvent.type(autocompleteInput, 'GS Facial');
84
- });
85
- await waitFor(() => {
51
+ await userEvent.type(autocompleteInput, 'GS Facial');
52
+ await waitFor(async () => {
86
53
  const optionLi = screen.getByText('GS Facial Spa');
87
- userEvent.click(optionLi);
54
+ await userEvent.click(optionLi);
88
55
  });
89
- expect(onSelectMock).toHaveBeenCalled();
56
+ expect(onChangeMock).toHaveBeenCalled();
90
57
  }, 40000);
91
58
 
92
59
  it('5. should load more options when clicking load more button', async () => {
93
60
  render(
94
61
  <NsAutocomplete
95
- options={AutocompleteMockList}
96
- OptionsUI={OptionUiComponent}
97
- placeholder="autocomplete-input"
98
62
  seeMore={{
99
63
  text: '',
100
64
  show: true,
101
65
  onSeeMore: () => ({}),
102
66
  }}
103
- inputValue=""
104
- value=""
67
+ {...commonProps}
105
68
  />
106
69
  );
107
70
  const autocompleteInput = screen.getByPlaceholderText('autocomplete-input');
108
- act(() => {
109
- userEvent.type(autocompleteInput, 'GS Facial');
110
- });
111
- await waitFor(() => {
71
+ await userEvent.type(autocompleteInput, 'GS Facial');
72
+ await waitFor(async () => {
112
73
  const loadMoreButton = screen.getByTestId('autocomplete-loadmore-id');
113
- userEvent.click(loadMoreButton);
74
+ await userEvent.click(loadMoreButton);
114
75
  });
115
76
  }, 40000);
116
77
 
117
78
  it('6. should clear options when clicking clear button', async () => {
118
79
  render(
119
80
  <NsAutocomplete
120
- options={AutocompleteMockList}
121
- OptionsUI={OptionUiComponent}
122
- placeholder="autocomplete-input"
123
81
  clear={{
124
82
  text: '',
125
83
  show: true,
126
84
  onClear: () => ({}),
127
85
  }}
128
- inputValue=""
129
- value=""
86
+ {...commonProps}
130
87
  />
131
88
  );
132
89
  const autocompleteInput = screen.getByPlaceholderText('autocomplete-input');
133
- act(() => {
134
- userEvent.type(autocompleteInput, 'GS Facial');
135
- });
136
- await waitFor(() => {
90
+ await userEvent.type(autocompleteInput, 'GS Facial');
91
+ await waitFor(async () => {
137
92
  const clearButton = screen.getByTestId('autocomplete-clear-id');
138
- userEvent.click(clearButton);
93
+ await userEvent.click(clearButton);
139
94
  });
140
95
  }, 40000);
141
96
  });
@@ -1,7 +1,9 @@
1
1
  import { styled } from '@nuskin/foundation-theme';
2
+
2
3
  import { NsInputField } from '../input';
3
4
 
4
5
  // TODO: why is .muiautocomplete-popupindicator added?
6
+ // TODO: ${({ theme }) => getGenomeColor(theme, 'N100')}; use forceMode light
5
7
  export const StyledTextField = styled(NsInputField)`
6
8
  .MuiAutocomplete-inputRoot {
7
9
  padding-right: 10px !important;
@@ -1,7 +1,8 @@
1
- import { Autocomplete, AutocompleteRenderInputParams, List } from '@mui/material';
2
- import React, { HTMLAttributes, PropsWithChildren, useCallback, useEffect, useRef, useState } from 'react';
1
+ import { Autocomplete, AutocompleteRenderInputParams } from '@mui/material';
2
+ import { noop } from 'lodash';
3
+ import React, { PropsWithChildren, useEffect, useRef, useState } from 'react';
3
4
 
4
- import { ClearButton } from './helper/ClearButton';
5
+ import { AutoCompleteButton } from './helper/AutoCompleteButton';
5
6
  import { renderGroupBy, renderGroupName, renderOptionLabel } from './helper/renderGroupName';
6
7
  import { SeeMoreButton } from './helper/SeeMoreButton';
7
8
  import { StyledTextField } from './NsAutocomplete.styled';
@@ -13,7 +14,7 @@ const NsAutocomplete = ({
13
14
  OptionsUI,
14
15
  loading,
15
16
  noOptionsText,
16
- onSelect,
17
+ onInputChange,
17
18
  onChange,
18
19
  clear,
19
20
  seeMore,
@@ -34,24 +35,6 @@ const NsAutocomplete = ({
34
35
  }
35
36
  }, [options, scrollTopPosition]);
36
37
 
37
- const handleSelect = useCallback(
38
- (event: React.SyntheticEvent, value: string | OptionsProps | null) => {
39
- if (typeof onSelect === 'function') {
40
- onSelect(value);
41
- }
42
- },
43
- [onSelect]
44
- );
45
-
46
- const onInputChange = useCallback(
47
- (event: React.SyntheticEvent, newInputValue: string) => {
48
- if (typeof onChange === 'function') {
49
- onChange(newInputValue);
50
- }
51
- },
52
- [onChange]
53
- );
54
-
55
38
  const renderInput = (params: AutocompleteRenderInputParams) => (
56
39
  <StyledTextField
57
40
  {...params}
@@ -71,47 +54,62 @@ const NsAutocomplete = ({
71
54
  </li>
72
55
  );
73
56
 
74
- const renderListBoxComponent = ({ children, ...otherProps }: ComponentBoxProps) => (
75
- <List {...otherProps} ref={listboxRef}>
76
- <ClearButton show={clear?.show} text={clear?.text} onClear={clear?.onClear} />
77
- {children}
78
- <SeeMoreButton
79
- onSeeMore={seeMore?.onSeeMore}
80
- show={seeMore?.show}
81
- text={seeMore?.text}
82
- options={options}
83
- setScrollTopPosition={setScrollTopPosition}
84
- listboxRef={listboxRef}
85
- />
86
- </List>
87
- );
57
+ const renderListBoxComponent = ({ children, ...rest }: ComponentBoxProps) => {
58
+ return (
59
+ <ul
60
+ aria-labelledby={rest['aria-labelledby']}
61
+ onMouseDown={rest.onMouseDown}
62
+ role={rest.role}
63
+ id={rest.id}
64
+ className={rest.className}
65
+ ref={listboxRef}
66
+ >
67
+ <AutoCompleteButton
68
+ show={clear?.show ?? false}
69
+ text={clear?.text ?? 'Clear All'}
70
+ onClick={clear?.onClear ?? noop}
71
+ testId="autocomplete-clear-id"
72
+ />
73
+ {children}
74
+ <SeeMoreButton
75
+ onSeeMore={seeMore?.onSeeMore}
76
+ show={seeMore?.show}
77
+ text={seeMore?.text}
78
+ options={options}
79
+ setScrollTopPosition={setScrollTopPosition}
80
+ listboxRef={listboxRef}
81
+ />
82
+ </ul>
83
+ );
84
+ };
88
85
 
89
86
  return (
90
- <Autocomplete
91
- id={id}
92
- disablePortal
93
- className={className}
94
- options={options}
95
- loading={loading}
96
- noOptionsText={noOptionsText}
97
- groupBy={renderGroupBy}
98
- getOptionLabel={renderOptionLabel}
99
- renderOption={renderOption}
100
- renderInput={renderInput}
101
- ListboxComponent={renderListBoxComponent}
102
- ListboxProps={{ scrollTopPosition } as HTMLAttributes<HTMLUListElement>} // Pass the current scroll position
103
- renderGroup={renderGroupName}
104
- onChange={handleSelect}
105
- onInputChange={onInputChange}
106
- value={value}
107
- inputValue={inputValue}
108
- filterOptions={
109
- isFilterEnabled
110
- ? undefined // Use default filtering behavior
111
- : (options) => options
112
- }
113
- freeSolo
114
- />
87
+ <>
88
+ <Autocomplete
89
+ id={id}
90
+ disablePortal
91
+ className={className}
92
+ options={options}
93
+ loading={loading}
94
+ noOptionsText={noOptionsText}
95
+ groupBy={renderGroupBy}
96
+ getOptionLabel={renderOptionLabel}
97
+ renderOption={renderOption}
98
+ renderInput={renderInput}
99
+ ListboxComponent={renderListBoxComponent}
100
+ renderGroup={renderGroupName}
101
+ onChange={onChange}
102
+ onInputChange={onInputChange}
103
+ value={value}
104
+ inputValue={inputValue}
105
+ filterOptions={
106
+ isFilterEnabled
107
+ ? undefined // Use default filtering behavior
108
+ : (options) => options
109
+ }
110
+ freeSolo
111
+ />
112
+ </>
115
113
  );
116
114
  };
117
115
 
@@ -1,18 +1,20 @@
1
1
  import { NsButton, NsTypography } from '../..';
2
2
 
3
- type ClearButtonProps = {
4
- text?: string;
5
- show?: boolean;
6
- onClear?(): void;
3
+ type AutoCompleteButtonProps = {
4
+ text: string;
5
+ show: boolean;
6
+ onClick(): void;
7
+ testId?: string;
7
8
  };
8
- export const ClearButton = (props: ClearButtonProps) => {
9
- const { show, onClear, text = 'Clear All' } = props ?? {};
9
+
10
+ export const AutoCompleteButton = (props: AutoCompleteButtonProps) => {
11
+ const { show, onClick, text, testId } = props;
10
12
  if (!show) {
11
13
  return null;
12
14
  }
13
15
  return (
14
16
  <li className="text-right p-3">
15
- <NsButton onClick={onClear} data-testid="autocomplete-clear-id">
17
+ <NsButton onClick={onClick} data-testid={testId}>
16
18
  <NsTypography variant="p-xs" weight="bold">
17
19
  {text}
18
20
  </NsTypography>
@@ -1,11 +1,13 @@
1
1
  import { Dispatch, MutableRefObject, SetStateAction, useCallback } from 'react';
2
- import { NsButton, NsTypography } from '../..';
2
+
3
+ import { OptionsProps } from '../..';
4
+ import { AutoCompleteButton } from './AutoCompleteButton';
3
5
 
4
6
  type SeeMoreButtonProps = {
5
7
  text?: string;
6
8
  show?: boolean;
7
9
  onSeeMore?(): void;
8
- options: any[];
10
+ options: OptionsProps[];
9
11
  setScrollTopPosition: Dispatch<SetStateAction<number>>;
10
12
  listboxRef: MutableRefObject<HTMLUListElement | null>;
11
13
  };
@@ -32,16 +34,5 @@ export const SeeMoreButton = (props: SeeMoreButtonProps) => {
32
34
  onSeeMore();
33
35
  }
34
36
  }, [listboxRef, onSeeMore, options?.length, setScrollTopPosition]);
35
- if (!show) {
36
- return null;
37
- }
38
- return (
39
- <li className="text-center p-3">
40
- <NsButton onClick={handleSeeMore} data-testid="autocomplete-loadmore-id">
41
- <NsTypography variant="p-xs" weight="bold">
42
- {text}
43
- </NsTypography>
44
- </NsButton>
45
- </li>
46
- );
37
+ return <AutoCompleteButton show={show} text={text} onClick={handleSeeMore} testId="autocomplete-loadmore-id" />;
47
38
  };
@@ -1,4 +1,5 @@
1
1
  import { AutocompleteRenderGroupParams } from '@mui/material';
2
+
2
3
  import { NsTypography, OptionsProps } from '../..';
3
4
 
4
5
  export const renderGroupName = ({ key, group, children }: AutocompleteRenderGroupParams) => (
@@ -12,6 +13,7 @@ export const renderGroupName = ({ key, group, children }: AutocompleteRenderGrou
12
13
  </li>
13
14
  );
14
15
 
15
- export const renderOptionLabel = (option: OptionsProps) => option.value;
16
+ export const renderOptionLabel = (option: string | OptionsProps) =>
17
+ typeof option === 'string' ? option : option?.value ?? '';
16
18
 
17
- export const renderGroupBy = (option: OptionsProps) => option.group as string;
19
+ export const renderGroupBy = (option: OptionsProps) => (option?.group ?? '') as string;
@@ -1,12 +1,12 @@
1
1
  import { NsAutocompleteProps, OptionsProps } from '../types';
2
- import React, { useState } from 'react';
2
+ import React, { useState, SyntheticEvent } from 'react';
3
3
 
4
4
  import { NsAutocomplete } from '..';
5
5
  import { OptionUiComponent } from '../mock/MockUI';
6
6
 
7
7
  const PAGE_SIZE = 6;
8
8
 
9
- export const ACWithoutClose = (args: NsAutocompleteProps) => {
9
+ export const NoCloseAutoComplete = (args: NsAutocompleteProps) => {
10
10
  const [selectedOption, setSelectedOption] = useState<string | OptionsProps | null>(null);
11
11
  const [searchTerms, setSearchTerms] = useState<string>('');
12
12
  const [pageNo, setPageNo] = useState(PAGE_SIZE);
@@ -23,12 +23,12 @@ export const ACWithoutClose = (args: NsAutocompleteProps) => {
23
23
  },
24
24
  } as NsAutocompleteProps;
25
25
 
26
- const onSelect = (value: string | OptionsProps | null) => {
26
+ const onChange = (event: SyntheticEvent<Element, Event>, value: string | OptionsProps | null) => {
27
27
  setSelectedOption(value);
28
28
  setSearchTerms((value = ''));
29
29
  };
30
30
 
31
- const handleInputChange = (newValue: string) => {
31
+ const onInputChange = (event: SyntheticEvent<Element, Event>, newValue: string) => {
32
32
  setSearchTerms(newValue);
33
33
  };
34
34
 
@@ -37,8 +37,8 @@ export const ACWithoutClose = (args: NsAutocompleteProps) => {
37
37
  <NsAutocomplete
38
38
  {...AutoCompleteProps}
39
39
  options={args.options.slice(0, pageNo)}
40
- onChange={handleInputChange}
41
- onSelect={onSelect}
40
+ onInputChange={onInputChange}
41
+ onChange={onChange}
42
42
  OptionsUI={OptionUiComponent}
43
43
  value={selectedOption}
44
44
  inputValue={searchTerms}
@@ -7,7 +7,7 @@ import { NsAutocomplete } from '..';
7
7
  import { AutocompleteMockList } from '../mock/MockData';
8
8
  import { NsIcon } from '../../icon';
9
9
  import { RenderAutoComplete } from './RenderAutoComplete';
10
- import { ACWithoutClose } from './ACWithoutClose';
10
+ import { NoCloseAutoComplete } from './NoCloseAutoComplete';
11
11
 
12
12
  type ComponentType = typeof NsAutocomplete;
13
13
  type Story = StoryObj<ComponentType>;
@@ -63,7 +63,7 @@ export default {
63
63
  },
64
64
  iconStart: <NsIcon name="search" />,
65
65
  iconEnd: <NsIcon name="roundedClose" size="small" colorOverride="#F5F5F5" />,
66
- placeholder: 'search',
66
+ placeholder: 'Search',
67
67
  },
68
68
  } as MetaStory;
69
69
 
@@ -72,5 +72,5 @@ export const Autocomplete: Story = {
72
72
  };
73
73
 
74
74
  export const WithoutClose: Story = {
75
- render: ACWithoutClose,
75
+ render: NoCloseAutoComplete,
76
76
  };
@@ -1,6 +1,6 @@
1
1
  import { NsAutocompleteProps, OptionsProps } from '../types';
2
2
  import { IconButton } from '@mui/material';
3
- import React, { useState } from 'react';
3
+ import React, { useState, SyntheticEvent } from 'react';
4
4
 
5
5
  import { NsAutocomplete } from '..';
6
6
  import { NsIcon } from '../../icon';
@@ -25,12 +25,12 @@ export const RenderAutoComplete = (args: NsAutocompleteProps) => {
25
25
  },
26
26
  } as NsAutocompleteProps;
27
27
 
28
- const onSelect = (value: string | OptionsProps | null) => {
28
+ const onChange = (event: SyntheticEvent<Element, Event>, value: string | OptionsProps | null) => {
29
29
  setSelectedOption(value);
30
30
  setSearchTerms((value = ''));
31
31
  };
32
32
 
33
- const handleInputChange = (newValue: string) => {
33
+ const onInputChange = (event: SyntheticEvent<Element, Event>, newValue: string) => {
34
34
  setSearchTerms(newValue);
35
35
  };
36
36
 
@@ -44,8 +44,8 @@ export const RenderAutoComplete = (args: NsAutocompleteProps) => {
44
44
  <NsAutocomplete
45
45
  {...AutoCompleteProps}
46
46
  options={args.options.slice(0, pageNo)}
47
- onChange={handleInputChange}
48
- onSelect={onSelect}
47
+ onInputChange={onInputChange}
48
+ onChange={onChange}
49
49
  OptionsUI={OptionUiComponent}
50
50
  iconEnd={
51
51
  <IconButton onClick={onInputClear}>