@bspk/ui 1.3.2 → 1.3.3

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 (58) hide show
  1. package/dist/components/DateInput/DateInput.js +1 -0
  2. package/dist/components/DateInput/DateInput.js.map +1 -1
  3. package/dist/components/ListItem/ListItem.d.ts +2 -2
  4. package/dist/components/ListItem/ListItem.js +11 -7
  5. package/dist/components/ListItem/ListItem.js.map +1 -1
  6. package/dist/components/ListItem/ListItemExample.d.ts +1 -1
  7. package/dist/components/ListItem/ListItemExample.js +72 -3
  8. package/dist/components/ListItem/ListItemExample.js.map +1 -1
  9. package/dist/components/ListItem/list-item.css +8 -6
  10. package/dist/components/ListItem/list-item.css.js +8 -6
  11. package/dist/components/ListItemMenu/ListItemMenu.d.ts +1 -1
  12. package/dist/components/ListItemMenu/ListItemMenu.js.map +1 -1
  13. package/dist/components/NumberInput/NumberInput.d.ts +2 -2
  14. package/dist/components/NumberInput/NumberInput.js +7 -20
  15. package/dist/components/NumberInput/NumberInput.js.map +1 -1
  16. package/dist/components/Popover/Popover.js +1 -0
  17. package/dist/components/Popover/Popover.js.map +1 -1
  18. package/dist/components/ProgressionStepper/ProgressionStepper.d.ts +3 -7
  19. package/dist/components/ProgressionStepper/ProgressionStepper.js +9 -5
  20. package/dist/components/ProgressionStepper/ProgressionStepper.js.map +1 -1
  21. package/dist/components/ProgressionStepper/ProgressionStepperExample.js +20 -4
  22. package/dist/components/ProgressionStepper/ProgressionStepperExample.js.map +1 -1
  23. package/dist/components/SearchBar/SearchBar.d.ts +36 -35
  24. package/dist/components/SearchBar/SearchBar.js +100 -49
  25. package/dist/components/SearchBar/SearchBar.js.map +1 -1
  26. package/dist/components/SearchBar/SearchBarExample.js +2 -1
  27. package/dist/components/SearchBar/SearchBarExample.js.map +1 -1
  28. package/dist/components/Select/Select.d.ts +2 -2
  29. package/dist/components/Select/Select.js +3 -5
  30. package/dist/components/Select/Select.js.map +1 -1
  31. package/dist/components/TabList/TabList.js +2 -1
  32. package/dist/components/TabList/TabList.js.map +1 -1
  33. package/dist/components/TabList/tab-list.css +6 -0
  34. package/dist/components/TabList/tab-list.css.js +6 -0
  35. package/dist/hooks/useArrowNavigation.js +6 -1
  36. package/dist/hooks/useArrowNavigation.js.map +1 -1
  37. package/dist/hooks/useOutsideClick.d.ts +4 -3
  38. package/dist/hooks/useOutsideClick.js +13 -2
  39. package/dist/hooks/useOutsideClick.js.map +1 -1
  40. package/package.json +1 -1
  41. package/src/components/DateInput/DateInput.tsx +1 -0
  42. package/src/components/ListItem/ListItem.rtl.test.tsx +4 -1
  43. package/src/components/ListItem/ListItem.tsx +19 -12
  44. package/src/components/ListItem/ListItemExample.tsx +74 -4
  45. package/src/components/ListItem/list-item.scss +21 -17
  46. package/src/components/ListItemMenu/ListItemMenu.tsx +4 -3
  47. package/src/components/NumberInput/NumberInput.tsx +14 -27
  48. package/src/components/Popover/Popover.tsx +1 -0
  49. package/src/components/ProgressionStepper/ProgressionStepper.tsx +24 -15
  50. package/src/components/ProgressionStepper/ProgressionStepperExample.tsx +20 -4
  51. package/src/components/SearchBar/SearchBar.rtl.test.tsx +0 -1
  52. package/src/components/SearchBar/SearchBar.tsx +192 -115
  53. package/src/components/SearchBar/SearchBarExample.tsx +2 -1
  54. package/src/components/Select/Select.tsx +6 -12
  55. package/src/components/TabList/TabList.tsx +2 -1
  56. package/src/components/TabList/tab-list.scss +12 -0
  57. package/src/hooks/useArrowNavigation.ts +6 -1
  58. package/src/hooks/useOutsideClick.ts +16 -3
@@ -13,9 +13,7 @@ import { Truncated } from '-/components/Truncated';
13
13
  import { useId } from '-/hooks/useId';
14
14
  import { CommonProps, ElementProps, SetRef } from '-/types/common';
15
15
 
16
- export type ListItemProps<As extends ElementType = ElementType> = CommonProps<
17
- 'active' | 'disabled' | 'owner' | 'readOnly'
18
- > &
16
+ export type ListItemProps<As extends ElementType = ElementType> = CommonProps<'active' | 'owner'> &
19
17
  Pick<AriaAttributes, 'aria-label'> & {
20
18
  /**
21
19
  * The element type to render as.
@@ -123,14 +121,12 @@ export type ListItemProps<As extends ElementType = ElementType> = CommonProps<
123
121
  * @name ListItem
124
122
  * @phase UXReview
125
123
  */
126
- function ListItem<As extends ElementType = ElementType>({
124
+ function ListItem<As extends ElementType = 'div'>({
127
125
  active,
128
126
  as,
129
- disabled,
130
127
  innerRef,
131
128
  label,
132
129
  leading,
133
- readOnly,
134
130
  owner,
135
131
  role: roleProp,
136
132
  subText,
@@ -138,6 +134,8 @@ function ListItem<As extends ElementType = ElementType>({
138
134
  id: idProp,
139
135
  'aria-label': ariaLabel,
140
136
  'aria-selected': ariaSelected,
137
+ 'aria-disabled': ariaDisabled,
138
+ 'aria-readonly': ariaReadonly,
141
139
  hideAriaLabel,
142
140
  ...props
143
141
  }: ElementProps<ListItemProps<As>, As>) {
@@ -146,24 +144,30 @@ function ListItem<As extends ElementType = ElementType>({
146
144
  if (!label) return null;
147
145
 
148
146
  const As = asLogic(as, props);
149
- const role = roleLogic(roleProp, { as: As, props });
150
- const actionable = (props.href || props.onClick) && !props.disabled && !props.readOnly;
147
+
148
+ const isReadOnly = Boolean(props.readOnly || ariaReadonly);
149
+ const isDisabled = Boolean(props.disabled || ariaDisabled);
150
+
151
+ const actionable = !!(props.href || props.onClick || as === 'button') && !isReadOnly && !isDisabled;
152
+
153
+ const role = roleLogic(roleProp, { as: As, props, actionable });
151
154
 
152
155
  return (
153
156
  <As
154
157
  {...props}
155
- aria-disabled={disabled || undefined}
156
158
  aria-label={ariaLabel || undefined}
157
159
  aria-selected={ariaSelected}
158
160
  data-action={actionable || undefined}
159
161
  data-active={active || undefined}
160
162
  data-bspk="list-item"
161
163
  data-bspk-owner={owner || undefined}
162
- data-readonly={readOnly || undefined}
164
+ data-disabled={isDisabled || undefined}
165
+ data-readonly={isReadOnly || undefined}
163
166
  id={id}
167
+ onClick={isReadOnly || isDisabled ? undefined : props.onClick}
164
168
  ref={innerRef}
165
169
  role={role}
166
- tabIndex={props.tabIndex || (actionable ? 0 : undefined)}
170
+ tabIndex={props.tabIndex || (actionable ? 0 : -1)}
167
171
  >
168
172
  {leading && (
169
173
  <span aria-hidden data-leading>
@@ -190,18 +194,21 @@ function asLogic<As extends ElementType>(as: As | undefined, props: Partial<List
190
194
  }
191
195
 
192
196
  function roleLogic(
197
+ /** User provided role prop */
193
198
  existingRole: AriaRole | undefined,
194
199
  {
195
200
  as: As,
196
201
  props,
202
+ actionable,
197
203
  }: {
198
204
  as: ElementType;
199
205
  props: Partial<ListItemProps>;
206
+ actionable?: boolean;
200
207
  },
201
208
  ): HTMLAttributes<HTMLElement>['role'] | undefined {
202
209
  if (existingRole) return existingRole;
203
210
 
204
- if (props.href) return As !== 'a' ? 'link' : undefined;
211
+ if (!actionable) return undefined;
205
212
 
206
213
  if (props.onClick && As !== 'button' && As !== 'label') return 'button';
207
214
 
@@ -1,22 +1,90 @@
1
1
  import { ElementType } from 'react';
2
2
  import { ListItem, ListItemProps } from './ListItem';
3
+ import { ElementProps } from '-/types/common';
3
4
  import { createExampleChildElement } from '-/utils/createExampleChildElement';
4
5
  import { ComponentExampleFn, Preset } from '-/utils/demo';
5
6
 
6
- export const presets: Preset<ListItemProps>[] = [
7
+ export const presets = (action: (param: string) => void): Preset<ListItemProps>[] => [
7
8
  {
8
9
  label: 'Long Label',
9
10
  propState: {
10
11
  label: 'This is a really long label that should be truncated if it exceeds the width of the ListItem',
12
+ as: undefined,
11
13
  subText: 'See below for other leading and trailing examples',
12
14
  trailing: 'Checkbox',
13
15
  leading: 'Avatar',
14
- },
16
+ disabled: undefined,
17
+ readOnly: undefined,
18
+ 'aria-disabled': undefined,
19
+ 'aria-readonly': undefined,
20
+ } as ElementProps<ListItemProps<'div'>, 'div'>,
21
+ },
22
+ {
23
+ label: 'As Role Button',
24
+ propState: {
25
+ as: undefined,
26
+ label: 'as="button"',
27
+ role: 'button',
28
+ subText: 'Button example',
29
+ trailing: undefined,
30
+ leading: undefined,
31
+ 'aria-disabled': true,
32
+ disabled: undefined,
33
+ readOnly: undefined,
34
+ 'aria-readonly': undefined,
35
+ onClick: () => action('This is aria disabled and should not show'),
36
+ } as ElementProps<ListItemProps<'div'>, 'div'>,
37
+ },
38
+ {
39
+ label: 'As Button',
40
+ propState: {
41
+ label: 'as="button"',
42
+ as: 'button',
43
+ subText: 'Button example',
44
+ trailing: undefined,
45
+ leading: undefined,
46
+ disabled: undefined,
47
+ readOnly: undefined,
48
+ 'aria-disabled': undefined,
49
+ 'aria-readonly': undefined,
50
+ onClick: () => action('This is not disabled or readonly and should show'),
51
+ } as ElementProps<ListItemProps<'button'>, 'button'>,
52
+ },
53
+ {
54
+ label: 'As Button Disabled',
55
+ propState: {
56
+ label: 'as="button"',
57
+ as: 'button',
58
+ subText: 'Disabled button example',
59
+ trailing: undefined,
60
+ leading: undefined,
61
+ disabled: true,
62
+ readOnly: false,
63
+ 'aria-disabled': undefined,
64
+ 'aria-readonly': undefined,
65
+ onClick: () => action('This is disabled and should not show'),
66
+ } as ElementProps<ListItemProps<'button'>, 'button'>,
67
+ },
68
+ {
69
+ label: 'As Button Read Only',
70
+ propState: {
71
+ label: 'as="button"',
72
+ as: 'button',
73
+ subText: 'Read only button example',
74
+ trailing: undefined,
75
+ leading: undefined,
76
+ readOnly: true,
77
+ disabled: undefined,
78
+ 'aria-disabled': undefined,
79
+ 'aria-readonly': undefined,
80
+ onClick: () => action('This is readonly and should not show'),
81
+ } as ElementProps<ListItemProps<'button'>, 'button'>,
15
82
  },
16
83
  ];
17
84
 
18
85
  export const ListItemExample: ComponentExampleFn<ListItemProps> = ({ action, setState }) => ({
19
- render: ({ props, id }) => {
86
+ presets: presets(action),
87
+ render: ({ props, id, preset }) => {
20
88
  const leading = createExampleChildElement({
21
89
  exampleState: props,
22
90
  name: 'leading',
@@ -34,9 +102,11 @@ export const ListItemExample: ComponentExampleFn<ListItemProps> = ({ action, set
34
102
 
35
103
  let as: ElementType = props.as || 'div';
36
104
 
105
+ if (!preset) return null;
106
+
37
107
  if (trailing.componentName && ['Checkbox', 'Radio', 'Switch'].includes(trailing.componentName)) as = 'label';
38
108
 
39
109
  return <ListItem {...props} as={as} leading={leading.element} trailing={trailing.element} />;
40
110
  },
41
- presets,
111
+ variants: false,
42
112
  });
@@ -25,18 +25,20 @@
25
25
  }
26
26
  }
27
27
 
28
- &[data-action],
29
- &:is(label) {
30
- &[data-active],
31
- [data-pseudo='hover'] &,
32
- &:hover {
33
- background-color: var(--interactions-neutral-hover-opacity);
34
- }
35
-
36
- [data-pseudo='active'] &,
28
+ &:not([data-disabled], [data-readonly]) {
29
+ &[data-action],
30
+ &:is(label) {
31
+ &[data-active],
32
+ [data-pseudo='hover'] &,
33
+ &:hover {
34
+ background-color: var(--interactions-neutral-hover-opacity);
35
+ }
36
+
37
+ [data-pseudo='active'] &,
37
38
  // pressed state
38
39
  &:active {
39
- background-color: var(--interactions-neutral-press-opacity);
40
+ background-color: var(--interactions-neutral-press-opacity);
41
+ }
40
42
  }
41
43
  }
42
44
 
@@ -78,13 +80,6 @@
78
80
  }
79
81
  }
80
82
 
81
- &[aria-disabled] {
82
- [data-text],
83
- [data-sub-text] {
84
- color: var(--foreground-neutral-disabled-on-surface);
85
- }
86
- }
87
-
88
83
  [data-trailing]:has(input) {
89
84
  pointer-events: none;
90
85
  }
@@ -105,6 +100,15 @@
105
100
  &[aria-selected='true'] {
106
101
  background-color: var(--surface-brand-primary-highlight);
107
102
  }
103
+
104
+ &[data-disabled],
105
+ &[data-readonly] {
106
+ [data-text],
107
+ [data-sub-text] {
108
+ color: var(--foreground-neutral-disabled-on-surface);
109
+ cursor: not-allowed;
110
+ }
111
+ }
108
112
  }
109
113
 
110
114
  /** Copyright 2025 Anywhere Real Estate - CC BY 4.0 */
@@ -20,9 +20,10 @@ import { CommonProps, SetRef } from '-/types/common';
20
20
  import { getElementById } from '-/utils/dom';
21
21
  import { handleKeyDown } from '-/utils/handleKeyDown';
22
22
 
23
- export type MenuListItem = Omit<ListItemProps, 'id'> & {
24
- id: string;
25
- };
23
+ export type MenuListItem = CommonProps<'disabled'> &
24
+ Omit<ListItemProps, 'id'> & {
25
+ id: string;
26
+ };
26
27
 
27
28
  export type ListItemMenuRole = keyof typeof LIST_ITEM_ROLES;
28
29
 
@@ -1,5 +1,5 @@
1
1
  import './number-input.scss';
2
- import { useCallback, useState } from 'react';
2
+ import { useMemo } from 'react';
3
3
  import { IncrementButton } from './IncrementButton';
4
4
  import { useId } from '-/hooks/useId';
5
5
  import { CommonProps, FormFieldControlProps } from '-/types/common';
@@ -16,7 +16,7 @@ export type NumberInputProps = CommonProps<
16
16
  > &
17
17
  FormFieldControlProps & {
18
18
  /** The value of the control. */
19
- value?: number | string;
19
+ value?: number;
20
20
  /**
21
21
  * Callback when the value changes.
22
22
  *
@@ -75,7 +75,7 @@ export type NumberInputProps = CommonProps<
75
75
  * @phase Utility
76
76
  */
77
77
  export function NumberInput({
78
- value,
78
+ value: valueProp,
79
79
  onChange,
80
80
  align = 'center',
81
81
  size = 'medium',
@@ -95,27 +95,12 @@ export function NumberInput({
95
95
  const max = typeof maxProp === 'number' && maxProp >= min ? maxProp : Number.MAX_SAFE_INTEGER;
96
96
  const centered = align !== 'left';
97
97
  const inputId = useId(inputIdProp);
98
- const valueNumber = isNumber(value) || 0;
99
-
100
- const [inputElement, setInputElement] = useState<HTMLInputElement | null>(null);
98
+ const value = useMemo(() => isNumber(valueProp) || 0, [valueProp]);
101
99
 
102
100
  const handleIncrement = (increment: -1 | 1) => {
103
- if (!inputElement) return;
104
- const nextValue = (isNumber(inputElement.value) || 0) + increment * step;
105
- handleUpdate(nextValue);
101
+ onChange(value + increment * step);
106
102
  };
107
103
 
108
- const handleUpdate = useCallback(
109
- (nextValue: number | undefined) => {
110
- if (!inputElement) return;
111
- let nextVal = isNumber(nextValue);
112
- if (nextVal !== undefined) nextVal = Math.min(Math.max(nextVal, min), max);
113
- onChange(nextVal);
114
- inputElement.value = nextVal?.toString() || '';
115
- },
116
- [inputElement, min, max, onChange],
117
- );
118
-
119
104
  return (
120
105
  <div
121
106
  data-bspk="number-input"
@@ -128,7 +113,7 @@ export function NumberInput({
128
113
  >
129
114
  {!!centered && (
130
115
  <IncrementButton
131
- disabled={disabled ? true : valueNumber + -1 < min}
116
+ disabled={disabled ? true : value + -1 < min}
132
117
  increment={-1}
133
118
  inputId={inputId}
134
119
  onIncrement={handleIncrement}
@@ -141,25 +126,27 @@ export function NumberInput({
141
126
  aria-invalid={invalid}
142
127
  aria-label={ariaLabel}
143
128
  autoComplete="off"
144
- defaultValue={String(valueNumber)}
129
+ data-input
130
+ data-stepper-input-element
145
131
  disabled={disabled}
146
132
  id={inputId}
133
+ inputMode="numeric"
147
134
  max={max}
148
135
  min={min}
149
136
  name={name}
150
- onBlur={() => {
151
- handleUpdate(isNumber(inputElement?.value));
137
+ onChange={(e) => {
138
+ onChange(isNumber(e.target.value));
152
139
  }}
153
140
  readOnly={readOnly}
154
- ref={(node) => node && setInputElement(node)}
155
141
  step={step}
156
142
  type="number"
143
+ value={value}
157
144
  />
158
145
  {!centered && (
159
146
  <>
160
147
  <div aria-hidden data-divider />
161
148
  <IncrementButton
162
- disabled={disabled ? true : valueNumber + -1 < min}
149
+ disabled={!!disabled || value + -1 < min}
163
150
  increment={-1}
164
151
  inputId={inputId}
165
152
  onIncrement={handleIncrement}
@@ -167,7 +154,7 @@ export function NumberInput({
167
154
  </>
168
155
  )}
169
156
  <IncrementButton
170
- disabled={disabled ? true : valueNumber + 1 > max}
157
+ disabled={!!disabled || value + 1 > max}
171
158
  increment={1}
172
159
  inputId={inputId}
173
160
  onIncrement={handleIncrement}
@@ -111,6 +111,7 @@ export function Popover({
111
111
  useOutsideClick({
112
112
  elements: [elements.floating],
113
113
  callback: () => setShow(false),
114
+ disabled: !show,
114
115
  });
115
116
 
116
117
  const basicArrowX = middlewareData?.arrow?.x ? `${middlewareData.arrow.x}px` : '0px';
@@ -37,16 +37,12 @@ export type ProgressionStepperProps = {
37
37
  */
38
38
  steps: ProgressionStepperItem[];
39
39
  /**
40
- * The current step in the progress bar.
41
- *
42
- * If the current step is greater than the number of steps, all steps with be completed.
43
- *
44
- * If the current step is less than 1, all steps will be incomplete.
40
+ * The last completed step in the progress bar. This is only applicable for the 'widget' variant.
45
41
  *
46
42
  * @default 0
47
43
  * @minimum 0
48
44
  */
49
- currentStep?: number;
45
+ completedStep?: number;
50
46
  /**
51
47
  * The variant of the progress bar. Can be either horizontal, vertical, or widget.
52
48
  *
@@ -72,22 +68,35 @@ export type ProgressionStepperProps = {
72
68
  */
73
69
  export function ProgressionStepper({
74
70
  steps = [],
75
- currentStep: currentStepProp = 0,
71
+ completedStep: completedStepProp = 0,
76
72
  variant = 'horizontal',
77
73
  ...containerProps
78
74
  }: ElementProps<ProgressionStepperProps, 'div'>) {
79
- const currentStep = Math.max(0, Math.min(currentStepProp, steps.length + 1));
80
- return !steps?.length ? null : (
75
+ const completedStepNumber = Math.max(0, Math.min(completedStepProp, steps.length));
76
+
77
+ const currentStepNumber = Math.min(completedStepNumber + 1, steps.length);
78
+
79
+ const currentStep = steps[currentStepNumber - 1];
80
+
81
+ if (!steps?.length) return null;
82
+
83
+ return (
81
84
  <div {...containerProps} data-bspk="progression-stepper" data-variant={variant}>
82
85
  {variant === 'widget' && (
83
86
  <label>
84
- <span data-title>{steps[Math.max(0, Math.min(currentStep - 1, steps.length - 1))].name}</span>
87
+ <span data-title>{currentStep.name}</span>
85
88
  <span data-subtitle>
86
- {currentStep > steps.length ? (
87
- 'Completed'
89
+ {currentStep.subtext ? (
90
+ currentStep.subtext
88
91
  ) : (
89
92
  <>
90
- Step {currentStep} of {steps.length}
93
+ {completedStepNumber === steps.length ? (
94
+ 'Completed'
95
+ ) : (
96
+ <>
97
+ Step {currentStepNumber} of {steps.length}
98
+ </>
99
+ )}
91
100
  </>
92
101
  )}
93
102
  </span>
@@ -97,8 +106,8 @@ export function ProgressionStepper({
97
106
  {steps.map(({ name, subtext }, index) => {
98
107
  const stepNum = index + 1;
99
108
  let status: 'complete' | 'current' | 'incomplete' = 'incomplete';
100
- if (currentStep > stepNum) status = 'complete';
101
- else if (currentStep === stepNum) status = 'current';
109
+ if (completedStepNumber >= stepNum) status = 'complete';
110
+ else if (completedStepNumber + 1 === stepNum) status = 'current';
102
111
 
103
112
  return (
104
113
  <li
@@ -6,7 +6,7 @@ export const presets: Preset<ProgressionStepperProps>[] = [
6
6
  label: 'Horizontal',
7
7
  propState: {
8
8
  variant: 'horizontal',
9
- currentStep: 2,
9
+ completedStep: 2,
10
10
  steps: [{ name: 'Name of step 1' }, { name: 'Name of step 2' }, { name: 'Name of step 3' }],
11
11
  },
12
12
  },
@@ -14,7 +14,7 @@ export const presets: Preset<ProgressionStepperProps>[] = [
14
14
  label: 'Vertical',
15
15
  propState: {
16
16
  variant: 'vertical',
17
- currentStep: 2,
17
+ completedStep: 2,
18
18
  steps: [
19
19
  {
20
20
  name: 'Name of step 1',
@@ -35,7 +35,7 @@ export const presets: Preset<ProgressionStepperProps>[] = [
35
35
  label: 'Widget',
36
36
  propState: {
37
37
  variant: 'widget',
38
- currentStep: 3,
38
+ completedStep: 3,
39
39
  steps: [
40
40
  { name: 'Name of step 1' },
41
41
  { name: 'Name of step 2' },
@@ -43,7 +43,23 @@ export const presets: Preset<ProgressionStepperProps>[] = [
43
43
  { name: 'Name of step 4' },
44
44
  { name: 'Name of step 5' },
45
45
  { name: 'Name of step 6' },
46
- { name: 'Name of step 7' },
46
+ { name: 'Review' },
47
+ ],
48
+ },
49
+ },
50
+ {
51
+ label: 'Widget (w/ subtext)',
52
+ propState: {
53
+ variant: 'widget',
54
+ completedStep: 3,
55
+ steps: [
56
+ { name: 'Name of step 1' },
57
+ { name: 'Name of step 2' },
58
+ { name: 'Name of step 3' },
59
+ { name: 'Name of step 4' },
60
+ { name: 'Name of step 5' },
61
+ { name: 'Name of step 6' },
62
+ { name: 'Review', subtext: `Check your information...` },
47
63
  ],
48
64
  },
49
65
  },
@@ -23,7 +23,6 @@ const TestBed = () => {
23
23
  items={items}
24
24
  name="Example name"
25
25
  onChange={() => {}}
26
- onSelect={() => {}}
27
26
  placeholder="Search"
28
27
  value=""
29
28
  />