@axinom/mosaic-ui 0.55.0-rc.1 → 0.55.0-rc.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/dist/components/DynamicDataList/helpers/useColumnDefs.d.ts +1 -1
  2. package/dist/components/DynamicDataList/helpers/useColumnDefs.d.ts.map +1 -1
  3. package/dist/components/FormElements/Select/Select.d.ts +15 -11
  4. package/dist/components/FormElements/Select/Select.d.ts.map +1 -1
  5. package/dist/components/FormElements/Select/SelectField.d.ts.map +1 -1
  6. package/dist/components/FormElements/SingleLineText/SingleLineText.d.ts.map +1 -1
  7. package/dist/components/FormElements/Tags/Tags.d.ts +2 -2
  8. package/dist/components/FormElements/Tags/Tags.d.ts.map +1 -1
  9. package/dist/components/FormElements/Tags/TagsField.d.ts +1 -1
  10. package/dist/components/FormElements/Tags/TagsField.d.ts.map +1 -1
  11. package/dist/index.es.js +4 -4
  12. package/dist/index.es.js.map +1 -1
  13. package/dist/index.js +4 -4
  14. package/dist/index.js.map +1 -1
  15. package/package.json +4 -3
  16. package/src/components/DynamicDataList/DynamicDataList.spec.tsx +1 -5
  17. package/src/components/DynamicDataList/DynamicDataList.tsx +1 -1
  18. package/src/components/DynamicDataList/DynamicListDataEntry/Renderers/createSelectRenderer/createSelectRenderer.spec.tsx +9 -4
  19. package/src/components/DynamicDataList/DynamicListDataEntry/Renderers/createSelectRenderer/createSelectRenderer.tsx +2 -2
  20. package/src/components/DynamicDataList/helpers/useColumnDefs.ts +4 -2
  21. package/src/components/FormElements/FileUploadControl/FileUploadControl.scss +2 -3
  22. package/src/components/FormElements/FileUploadControl/FileUploadControl.stories.tsx +0 -1
  23. package/src/components/FormElements/FileUploadControl/FileUploadControl.tsx +2 -2
  24. package/src/components/FormElements/Select/Select.scss +108 -59
  25. package/src/components/FormElements/Select/Select.spec.tsx +52 -43
  26. package/src/components/FormElements/Select/Select.stories.tsx +8 -10
  27. package/src/components/FormElements/Select/Select.tsx +138 -52
  28. package/src/components/FormElements/Select/SelectField.tsx +1 -0
  29. package/src/components/FormElements/SingleLineText/SingleLineText.tsx +23 -7
  30. package/src/components/FormElements/Tags/Tags.scss +16 -76
  31. package/src/components/FormElements/Tags/Tags.spec.tsx +69 -80
  32. package/src/components/FormElements/Tags/Tags.tsx +54 -62
  33. package/src/components/FormElements/Tags/TagsField.tsx +3 -13
  34. package/src/styles/variables.scss +8 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@axinom/mosaic-ui",
3
- "version": "0.55.0-rc.1",
3
+ "version": "0.55.0-rc.11",
4
4
  "description": "UI components for building Axinom Mosaic applications",
5
5
  "author": "Axinom",
6
6
  "license": "PROPRIETARY",
@@ -32,9 +32,10 @@
32
32
  "build-storybook": "storybook build"
33
33
  },
34
34
  "dependencies": {
35
- "@axinom/mosaic-core": "^0.4.28-rc.1",
35
+ "@axinom/mosaic-core": "^0.4.28-rc.11",
36
36
  "@faker-js/faker": "^7.4.0",
37
37
  "@geoffcox/react-splitter": "^2.1.2",
38
+ "@mui/base": "5.0.0-beta.40",
38
39
  "@popperjs/core": "^2.11.8",
39
40
  "clsx": "^1.1.0",
40
41
  "lodash": "^4.17.21",
@@ -106,5 +107,5 @@
106
107
  "publishConfig": {
107
108
  "access": "public"
108
109
  },
109
- "gitHead": "9a3fc4c143a12aaabedd95667504fd5757ddc2b2"
110
+ "gitHead": "45f7a689961673ef06813544d1f2af49f7e352ee"
110
111
  }
@@ -177,22 +177,18 @@ describe('DynamicDataList', () => {
177
177
  const wrapper = shallow(<DynamicDataList {...defaultProps} />);
178
178
 
179
179
  const header = wrapper.find(DynamicListHeader);
180
- const container = wrapper.find('.container');
181
180
 
182
181
  expect(header.exists()).toBe(true);
183
- expect(container.hasClass('noHeader')).toBe(false);
184
182
  });
185
183
 
186
- it(`hides header row if 'showHeader' is false and adds the 'noHeader' css class`, () => {
184
+ it(`hides header row if 'showHeader' is false`, () => {
187
185
  const wrapper = shallow(
188
186
  <DynamicDataList {...defaultProps} showHeader={false} />,
189
187
  );
190
188
 
191
189
  const header = wrapper.find(DynamicListHeader);
192
- const container = wrapper.find('.container');
193
190
 
194
191
  expect(header.exists()).toBe(false);
195
- expect(container.hasClass('noHeader')).toBe(true);
196
192
  });
197
193
 
198
194
  it(`sets 'positionKey' prop for DynamicListRow`, () => {
@@ -145,6 +145,7 @@ export const DynamicDataList = <T extends Data>({
145
145
  columns,
146
146
  allowReordering,
147
147
  allowNewData,
148
+ allowEditing,
148
149
  allowRowDragging,
149
150
  positionPropertyName,
150
151
  !!inlineMenuActions,
@@ -298,7 +299,6 @@ export const DynamicDataList = <T extends Data>({
298
299
  <div
299
300
  className={clsx(
300
301
  classes.container,
301
- { [classes.noHeader]: !showHeader },
302
302
  'dynamic-data-list-container',
303
303
  className,
304
304
  )}
@@ -44,12 +44,17 @@ describe('createSelectRenderer', () => {
44
44
  });
45
45
 
46
46
  it(`sets 'select' value to current value`, () => {
47
- const mockValue = 'test-value';
48
- const wrapper = mount(<RendererWrapper currentValue={mockValue} />);
47
+ const mockOptions = [{ value: 'test-value', label: 'Test Value' }];
48
+ const wrapper = mount(
49
+ <RendererWrapper
50
+ currentValue={mockOptions[0].value}
51
+ options={mockOptions}
52
+ />,
53
+ );
49
54
 
50
- const select = wrapper.find('select');
55
+ const input = wrapper.find('[role="combobox"]');
51
56
 
52
- expect(select.prop('value')).toBe(mockValue);
57
+ expect(input.prop('value')).toBe(mockOptions[0].label);
53
58
  });
54
59
 
55
60
  it(`emits 'onValueChange' with the new value when a new option has been selected`, () => {
@@ -1,4 +1,4 @@
1
- import React, { FormEvent } from 'react';
1
+ import React, { ChangeEvent } from 'react';
2
2
  import { DynamicListDataEntryRenderer } from '../../../../DynamicDataList/DynamicDataList.model';
3
3
  import { Select } from '../../../../FormElements';
4
4
  import { CreateSelectRendererConfig } from '../renderers.model';
@@ -33,7 +33,7 @@ export const createSelectRenderer = ({
33
33
  onValueChange(defaultValue);
34
34
  }
35
35
 
36
- const onChangeHandler = (e: FormEvent<HTMLSelectElement>): void => {
36
+ const onChangeHandler = (e: ChangeEvent<HTMLInputElement>): void => {
37
37
  onValueChange(transform(e.currentTarget.value)); // emit onChange with transformed value
38
38
  };
39
39
 
@@ -12,6 +12,7 @@ export const useColumnDefs = function <T extends Data>(
12
12
  columns: DynamicListColumn<T>[],
13
13
  allowReordering: boolean,
14
14
  allowNewData: boolean,
15
+ allowEditing: boolean,
15
16
  allowRowDragging: boolean,
16
17
  positionKey?: keyof T,
17
18
  showInlineMenu?: boolean,
@@ -30,7 +31,7 @@ export const useColumnDefs = function <T extends Data>(
30
31
  allowReordering,
31
32
  allowRowDragging,
32
33
  positionKey,
33
- allowNewData || showInlineMenu,
34
+ allowNewData || showInlineMenu || allowEditing,
34
35
  ),
35
36
  );
36
37
 
@@ -43,13 +44,14 @@ export const useColumnDefs = function <T extends Data>(
43
44
  allowReordering,
44
45
  allowRowDragging,
45
46
  positionKey,
46
- allowNewData || showInlineMenu,
47
+ allowNewData || showInlineMenu || allowEditing,
47
48
  ),
48
49
  );
49
50
  if (!isResized) {
50
51
  setColumnSizes(orgColumnSizes);
51
52
  }
52
53
  }, [
54
+ allowEditing,
53
55
  allowNewData,
54
56
  allowReordering,
55
57
  allowRowDragging,
@@ -53,7 +53,7 @@
53
53
  display: grid;
54
54
  align-content: center;
55
55
  color: var(--input-disabled-font-color, $input-disabled-font-color);
56
- border: 1px solid var(--file-upload-input, $file-upload-input);
56
+ border: 1px dashed var(--file-upload-input, $file-upload-input);
57
57
  background-color: var(
58
58
  --read-only-text-background-color,
59
59
  $read-only-text-background-color
@@ -80,13 +80,12 @@
80
80
  display: grid;
81
81
  align-content: center;
82
82
  text-align: center;
83
- border: 1px dashed var(--input-border-color, $input-border-color);
83
+ border: 1px dashed var(--file-upload-input, $file-upload-input);
84
84
  grid-column: 1 / span 2;
85
85
  height: 100px;
86
86
  width: 650px;
87
87
  z-index: 9999;
88
88
 
89
- background-color: white;
90
89
  transition: box-shadow 0.15s ease-in-out 0s;
91
90
 
92
91
  &:hover {
@@ -32,7 +32,6 @@ export const Default: StoryObj<typeof FileUploadControl> = {
32
32
  args: {
33
33
  name: 'fileUpload',
34
34
  label: 'Ingest File',
35
- placeholder: 'Select File...',
36
35
  tooltipContent: faker.lorem.paragraph(2),
37
36
  },
38
37
  render: (args) =>
@@ -34,7 +34,7 @@ export const FileUploadControl: React.FC<FileUploadProps> = ({
34
34
  onFileSelected,
35
35
  error,
36
36
  id = 'file',
37
- placeholder,
37
+ placeholder = 'Browse or drag your file here',
38
38
  value,
39
39
  accept,
40
40
  className = '',
@@ -138,7 +138,7 @@ export const FileUploadControl: React.FC<FileUploadProps> = ({
138
138
  <div className={clsx(classes.content)}>
139
139
  {dragging && !disabled ? (
140
140
  <div className={clsx(classes.dropTarget)} onDrop={handleDrop}>
141
- DROP YOUR FILE HERE!
141
+ Drag & Drop your file here
142
142
  </div>
143
143
  ) : (
144
144
  <>
@@ -1,79 +1,128 @@
1
1
  @import '../../../styles/common.scss';
2
2
 
3
- @function svg-arrow-glyph($color) {
4
- @return url('data:image/svg+xml;utf8,<svg stroke="' + $color + '" version="1.1" xmlns="http://www.w3.org/2000/svg" width="40px" height="20px" viewBox="0 0 40 40"><path vector-effect="non-scaling-stroke" fill="none" stroke-width="2" d="M38.5,9.5L20,30.5L1.5,9.5" /></svg>');
5
- }
6
-
7
3
  .container {
8
- select {
9
- -moz-appearance: none;
10
- -webkit-appearance: none;
11
- appearance: none;
12
- cursor: pointer;
13
- color: var(--input-color, $input-color);
14
- border: 1px solid var(--input-border-color, $input-border-color);
15
- width: max-content;
16
- outline: none;
17
- font-size: var(--label-font-size, $label-font-size);
18
- max-width: $select-max-width;
4
+ .inputWrapper {
5
+ position: relative;
6
+ max-width: var(--input-max-width, $input-max-width);
19
7
 
20
- // CSS variables will not work inside the background-image url - we still pass it in there for consistency reasons.
21
- background-image: svg-arrow-glyph(
22
- var(--select-arrow-color, encodecolor($select-arrow-color))
23
- );
24
- background-repeat: no-repeat;
25
- background-position-y: center;
26
- background-position-x: 100%;
8
+ .button {
9
+ position: absolute;
10
+ right: 0;
11
+ top: 0;
27
12
 
28
- background-color: var(--select-background-color, $select-background-color);
13
+ svg {
14
+ height: 50%;
15
+ * {
16
+ stroke: var(
17
+ --popper-trigger-button-color,
18
+ $popper-trigger-button-color
19
+ );
20
+ }
21
+ }
29
22
 
30
- height: 50px;
23
+ &:disabled {
24
+ svg * {
25
+ stroke: var(--select-arrow-color, $select-disabled-arrow-color);
26
+ }
27
+ }
28
+ }
31
29
 
32
- padding: 0 40px 0 12px;
30
+ input {
31
+ color: var(--input-color, $input-color);
32
+ border: 1px solid var(--input-border-color, $input-border-color);
33
+ padding: 0 48px 0 12px;
34
+ display: inline-block;
35
+ font-size: var(--label-font-size, $label-font-size);
36
+ outline: none;
37
+ height: 50px;
38
+ width: 100%;
39
+ transition: box-shadow 0.15s ease-in-out 0s;
33
40
 
34
- transition: box-shadow 0.15s ease-in-out 0s;
41
+ &::placeholder {
42
+ color: var(--input-placeholder-color, $input-placeholder-color);
43
+ }
35
44
 
36
- &.hasError {
37
- border: 1px solid
38
- var(--input-invalid-border-color, $input-invalid-border-color);
39
- }
45
+ &.hasError {
46
+ border: 1px solid
47
+ var(--input-invalid-border-color, $input-invalid-border-color);
48
+ }
40
49
 
41
- &:disabled {
42
- border-color: var(
43
- --input-disabled-border-color,
44
- $input-disabled-border-color
45
- );
50
+ &:disabled {
51
+ background-color: var(
52
+ --input-disabled-background-color,
53
+ $input-disabled-background-color
54
+ );
55
+ color: var(--input-disabled-font-color, $input-disabled-font-color);
56
+ border-color: var(
57
+ --input-disabled-border-color,
58
+ $input-disabled-border-color
59
+ );
60
+ }
46
61
 
47
- cursor: default;
62
+ &:hover:enabled,
63
+ &:focus {
64
+ border-color: var(--input-hover-color, $input-hover-color);
65
+ box-shadow: 0 0 0 2px var(--input-hover-color, $input-hover-color);
48
66
 
49
- background-image: svg-arrow-glyph(
50
- var(--select-arrow-color, encodecolor($select-disabled-arrow-color))
51
- );
52
- background-color: var(
53
- --input-disabled-background-color,
54
- $input-disabled-background-color
55
- );
67
+ &.hasError {
68
+ border-color: var(
69
+ --input-invalid-border-color,
70
+ $input-invalid-border-color
71
+ );
72
+ box-shadow: 0 0 0 2px
73
+ var(--input-invalid-hover-color, $input-invalid-hover-color);
74
+ }
75
+
76
+ &:disabled {
77
+ border-color: var(
78
+ --input-disabled-border-color,
79
+ $input-disabled-border-color
80
+ );
81
+ box-shadow: none;
82
+ }
83
+ }
56
84
  }
57
85
  }
86
+ }
58
87
 
59
- select,
60
- option {
61
- width: 325px;
62
- overflow: hidden;
63
- white-space: nowrap;
64
- text-overflow: ellipsis;
65
- }
88
+ .popperContent {
89
+ ul {
90
+ display: grid;
91
+ row-gap: 1px;
92
+ background-color: var(--popper-background-color, $popper-background-color);
93
+ padding: 0px;
94
+ margin-top: 1px;
95
+ margin-bottom: 1px;
96
+ border: 1px solid var(--popper-border-color, $popper-border-color);
97
+ overflow-y: auto;
98
+ max-height: 509px;
99
+
100
+ li {
101
+ display: grid;
102
+ place-items: center left;
103
+ height: 50px;
104
+ font-size: var(--popper-item-font-size, $popper-item-font-size);
105
+ color: var(--popper-text-color, $popper-text-color);
106
+ background-color: white;
107
+ padding: 0 12px;
108
+ list-style: none;
109
+ cursor: default;
66
110
 
67
- select:hover:enabled,
68
- select:focus:enabled {
69
- border: 1px solid var(--input-hover-color, $input-hover-color);
70
- box-shadow: 0 0 0 2px var(--input-hover-color, $input-hover-color);
111
+ &:hover {
112
+ cursor: pointer;
113
+ background-color: var(
114
+ --popper-background-selected-color,
115
+ $popper-background-selected-color
116
+ );
117
+ }
71
118
 
72
- &.hasError {
73
- border: 1px solid
74
- var(--input-invalid-border-color, $input-invalid-border-color);
75
- box-shadow: 0 0 0 2px
76
- var(--input-invalid-hover-color, $input-invalid-hover-color);
119
+ &[aria-selected='true'],
120
+ &[class='Mui-focused Mui-focusVisible'] {
121
+ background-color: var(
122
+ --popper-background-selected-color,
123
+ $popper-background-selected-color
124
+ );
125
+ }
77
126
  }
78
127
  }
79
128
  }
@@ -1,95 +1,104 @@
1
- import { shallow } from 'enzyme';
1
+ import { mount, shallow } from 'enzyme';
2
2
  import React from 'react';
3
3
  import { Select } from './Select';
4
4
 
5
+ const mockLabel = 'mockLabel';
6
+
7
+ const mockOptions = [
8
+ {
9
+ value: '1',
10
+ label: 'One',
11
+ },
12
+ {
13
+ value: '2',
14
+ label: 'Two',
15
+ },
16
+ {
17
+ value: '3',
18
+ label: 'Three',
19
+ },
20
+ ];
21
+
5
22
  describe('Select', () => {
23
+ afterEach(() => {
24
+ document.body.innerHTML = '';
25
+ });
26
+
6
27
  it('renders the component without crashing', () => {
7
- const wrapper = shallow(<Select name={'test-name'} />);
28
+ const wrapper = shallow(<Select name="test-name" options={[]} />);
8
29
 
9
30
  expect(wrapper).toBeTruthy();
10
31
  });
11
32
 
12
33
  it('displays a label', () => {
13
- const mockLabel = 'mockLabel';
14
- const wrapper = shallow(<Select name={'test-name'} label={mockLabel} />);
34
+ const wrapper = shallow(
35
+ <Select name="test-name" label={mockLabel} options={[]} />,
36
+ );
15
37
 
16
- const label = wrapper.dive().find('label');
38
+ const label = wrapper.dive().find('[data-test-id="form-field-label"]');
17
39
 
18
40
  expect(label.text()).toBe(mockLabel);
19
41
  });
20
42
 
21
- it('uses optional props when passed in', () => {
22
- const mockProps = {
23
- autoFocus: true,
24
- className: '',
25
- disabled: true,
26
- id: 'test-id',
27
- name: 'test-name',
28
- onBlur: () => null,
29
- onChange: () => null,
30
- onFocus: () => null,
31
- } as Record<string, unknown>;
32
-
33
- const wrapper = shallow(<Select name="test-name" {...mockProps} />);
43
+ it('the given value must be filled in input', () => {
44
+ const wrapper = mount(
45
+ <Select name={'test-name'} options={mockOptions} value="2" />,
46
+ );
34
47
 
35
- const select = wrapper.find('select');
48
+ const input = wrapper.find('[role="combobox"]');
36
49
 
37
- expect(select.props()).toEqual(expect.objectContaining(mockProps));
50
+ expect(input.prop('value')).toEqual(mockOptions[1].label);
38
51
  });
39
52
 
40
- it('sets select field using the value prop and emits updated values', () => {
41
- const spy = jest.fn();
42
- const mockValue = 'test-value';
43
- const mockValueUpdated = 'updated-test-value';
44
- const wrapper = shallow(
45
- <Select name="test-name" value={mockValue} onChange={spy} />,
53
+ it('the popper must be rendered on input click', () => {
54
+ const wrapper = mount(
55
+ <Select name={'test-name'} options={mockOptions} value="2" />,
46
56
  );
57
+ const input = wrapper.find('[role="combobox"]');
58
+ input.simulate('mousedown');
47
59
 
48
- const select = wrapper.find('select');
49
-
50
- expect(select.prop('value')).toEqual(mockValue);
51
-
52
- select.simulate('change', { target: { value: mockValueUpdated } });
53
-
54
- expect(spy).toHaveBeenCalledTimes(1);
55
- expect(spy).toHaveBeenCalledWith({ target: { value: mockValueUpdated } });
60
+ const popper = document.querySelector('[role="tooltip"]');
61
+ expect(popper).not.toBeNull();
56
62
  });
57
63
 
58
64
  it('raises change, blur, and focus events', () => {
59
65
  const changeSpy = jest.fn();
60
66
  const blurSpy = jest.fn();
61
67
  const focusSpy = jest.fn();
62
- const wrapper = shallow(
68
+ const wrapper = mount(
63
69
  <Select
64
70
  name={'test-name'}
65
71
  onChange={changeSpy}
66
72
  onBlur={blurSpy}
67
73
  onFocus={focusSpy}
74
+ options={mockOptions}
68
75
  />,
69
76
  );
70
77
 
71
- const select = wrapper.find('select');
78
+ const input = wrapper.find('[role="combobox"]');
79
+ input.simulate('mousedown');
80
+ const firstOption = document.querySelector('[role="option"]');
81
+ firstOption?.dispatchEvent(new Event('click', { bubbles: true }));
72
82
 
73
- select.simulate('change');
74
83
  expect(changeSpy).toHaveBeenCalledTimes(1);
75
84
 
76
- select.simulate('blur');
85
+ input.simulate('blur');
77
86
  expect(blurSpy).toHaveBeenCalledTimes(1);
78
87
 
79
- select.simulate('focus');
88
+ input.simulate('focus');
80
89
  expect(focusSpy).toHaveBeenCalledTimes(1);
81
90
  });
82
91
 
83
92
  it('applies error styling and renders error message when an error is passed', () => {
84
93
  const mockErrorMessage = 'test-error-message';
85
94
  const wrapper = shallow(
86
- <Select name={'test-name'} error={mockErrorMessage} />,
95
+ <Select name={'test-name'} error={mockErrorMessage} options={[]} />,
87
96
  );
88
97
 
89
- const errorMsg = wrapper.dive().find('small');
90
- const errorStyling = wrapper.find('select');
98
+ const errorMsg = wrapper.dive().find('[data-test-id="form-field-error"]');
99
+ const input = wrapper.find('[role="combobox"]');
91
100
 
92
101
  expect(errorMsg.text()).toBe(mockErrorMessage);
93
- expect(errorStyling.hasClass('hasError')).toBe(true);
102
+ expect(input.hasClass('hasError')).toBe(true);
94
103
  });
95
104
  });
@@ -6,14 +6,7 @@ import { createGroups } from '../../../helpers/storybook';
6
6
  import { Select } from './Select';
7
7
 
8
8
  const groups = createGroups({
9
- Behavior: [
10
- 'autoFocus',
11
- 'disabled',
12
- 'inlineMode',
13
- 'name',
14
- 'id',
15
- 'addEmptyOption',
16
- ],
9
+ Behavior: ['autoFocus', 'disabled', 'inlineMode', 'name', 'id'],
17
10
  Content: ['label', 'options', 'error', 'tooltipContent', 'value'],
18
11
  Styling: ['className'],
19
12
  Events: ['onChange', 'onBlur', 'onFocus'],
@@ -26,6 +19,7 @@ const meta: Meta<typeof Select> = {
26
19
  ...groups,
27
20
  },
28
21
  };
22
+
29
23
  export default meta;
30
24
 
31
25
  export const Main: StoryObj<typeof Select> = {
@@ -37,14 +31,18 @@ export const Main: StoryObj<typeof Select> = {
37
31
  { value: '2', label: 'Two' },
38
32
  { value: '3', label: 'Three' },
39
33
  { value: '4', label: 'Four' },
34
+ { value: '5', label: 'Five' },
35
+ { value: '6', label: 'Six' },
36
+ { value: '7', label: 'Seven' },
37
+ { value: '8', label: 'Eight' },
38
+ { value: '9', label: 'Nine' },
39
+ { value: '10', label: 'Ten' },
40
40
  ],
41
41
  tooltipContent: faker.lorem.paragraph(2),
42
- addEmptyOption: false,
43
42
  },
44
43
  render: (args) =>
45
44
  React.createElement(() => {
46
45
  const [value, setValue] = useState(args.value);
47
-
48
46
  return (
49
47
  <Select
50
48
  {...args}