@utilitywarehouse/hearth-react-native 0.27.3 → 0.28.0

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 (118) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/.turbo/turbo-lint.log +18 -19
  3. package/CHANGELOG.md +110 -0
  4. package/build/components/Combobox/Combobox.context.d.ts +13 -0
  5. package/build/components/Combobox/Combobox.context.js +9 -0
  6. package/build/components/Combobox/Combobox.d.ts +6 -0
  7. package/build/components/Combobox/Combobox.js +246 -0
  8. package/build/components/Combobox/Combobox.props.d.ts +180 -0
  9. package/build/components/Combobox/Combobox.props.js +1 -0
  10. package/build/components/Combobox/ComboboxOption.d.ts +6 -0
  11. package/build/components/Combobox/ComboboxOption.js +56 -0
  12. package/build/components/Combobox/index.d.ts +4 -0
  13. package/build/components/Combobox/index.js +3 -0
  14. package/build/components/Modal/Modal.js +26 -42
  15. package/build/components/Modal/Modal.web.js +3 -3
  16. package/build/components/Pagination/Pagination.d.ts +6 -0
  17. package/build/components/Pagination/Pagination.js +125 -0
  18. package/build/components/Pagination/Pagination.props.d.ts +26 -0
  19. package/build/components/Pagination/Pagination.props.js +1 -0
  20. package/build/components/Pagination/Pagination.utils.d.ts +2 -0
  21. package/build/components/Pagination/Pagination.utils.js +20 -0
  22. package/build/components/Pagination/Pagination.utils.test.d.ts +1 -0
  23. package/build/components/Pagination/Pagination.utils.test.js +16 -0
  24. package/build/components/Pagination/index.d.ts +2 -0
  25. package/build/components/Pagination/index.js +1 -0
  26. package/build/components/SafeAreaView/SafeAreaView.d.ts +5 -0
  27. package/build/components/SafeAreaView/SafeAreaView.js +117 -0
  28. package/build/components/SafeAreaView/SafeAreaView.props.d.ts +17 -0
  29. package/build/components/SafeAreaView/SafeAreaView.props.js +1 -0
  30. package/build/components/SafeAreaView/index.d.ts +2 -0
  31. package/build/components/SafeAreaView/index.js +1 -0
  32. package/build/components/Select/Select.js +3 -2
  33. package/build/components/Table/Table.context.d.ts +12 -0
  34. package/build/components/Table/Table.context.js +9 -0
  35. package/build/components/Table/Table.d.ts +6 -0
  36. package/build/components/Table/Table.js +71 -0
  37. package/build/components/Table/Table.props.d.ts +56 -0
  38. package/build/components/Table/Table.props.js +1 -0
  39. package/build/components/Table/Table.utils.d.ts +5 -0
  40. package/build/components/Table/Table.utils.js +48 -0
  41. package/build/components/Table/Table.utils.test.d.ts +1 -0
  42. package/build/components/Table/Table.utils.test.js +71 -0
  43. package/build/components/Table/TableBody.d.ts +6 -0
  44. package/build/components/Table/TableBody.js +16 -0
  45. package/build/components/Table/TableCell.d.ts +10 -0
  46. package/build/components/Table/TableCell.js +44 -0
  47. package/build/components/Table/TableHeader.d.ts +6 -0
  48. package/build/components/Table/TableHeader.js +24 -0
  49. package/build/components/Table/TableHeaderCell.d.ts +10 -0
  50. package/build/components/Table/TableHeaderCell.js +97 -0
  51. package/build/components/Table/TablePagination.d.ts +6 -0
  52. package/build/components/Table/TablePagination.js +7 -0
  53. package/build/components/Table/TableRow.d.ts +8 -0
  54. package/build/components/Table/TableRow.js +25 -0
  55. package/build/components/Table/index.d.ts +8 -0
  56. package/build/components/Table/index.js +7 -0
  57. package/build/components/Timeline/Timeline.d.ts +6 -0
  58. package/build/components/Timeline/Timeline.js +34 -0
  59. package/build/components/Timeline/Timeline.props.d.ts +47 -0
  60. package/build/components/Timeline/Timeline.props.js +1 -0
  61. package/build/components/Timeline/TimelineItem.d.ts +6 -0
  62. package/build/components/Timeline/TimelineItem.js +235 -0
  63. package/build/components/Timeline/index.d.ts +3 -0
  64. package/build/components/Timeline/index.js +2 -0
  65. package/build/components/index.d.ts +5 -0
  66. package/build/components/index.js +5 -0
  67. package/build/tokens/components/dark/timeline.d.ts +2 -2
  68. package/build/tokens/components/dark/timeline.js +2 -2
  69. package/docs/components/AllComponents.web.tsx +106 -23
  70. package/docs/llm-docs/unistyles-llms-full.txt +1132 -534
  71. package/docs/llm-docs/unistyles-llms-small.txt +37 -37
  72. package/package.json +2 -2
  73. package/src/components/Combobox/Combobox.context.ts +26 -0
  74. package/src/components/Combobox/Combobox.docs.mdx +277 -0
  75. package/src/components/Combobox/Combobox.figma.tsx +60 -0
  76. package/src/components/Combobox/Combobox.props.ts +187 -0
  77. package/src/components/Combobox/Combobox.stories.tsx +233 -0
  78. package/src/components/Combobox/Combobox.tsx +446 -0
  79. package/src/components/Combobox/ComboboxOption.tsx +100 -0
  80. package/src/components/Combobox/index.ts +9 -0
  81. package/src/components/Modal/Modal.tsx +52 -74
  82. package/src/components/Modal/Modal.web.tsx +3 -3
  83. package/src/components/Pagination/Pagination.docs.mdx +99 -0
  84. package/src/components/Pagination/Pagination.figma.tsx +20 -0
  85. package/src/components/Pagination/Pagination.props.ts +28 -0
  86. package/src/components/Pagination/Pagination.stories.tsx +88 -0
  87. package/src/components/Pagination/Pagination.tsx +248 -0
  88. package/src/components/Pagination/Pagination.utils.test.ts +20 -0
  89. package/src/components/Pagination/Pagination.utils.ts +37 -0
  90. package/src/components/Pagination/index.ts +2 -0
  91. package/src/components/SafeAreaView/SafeAreaView.props.ts +20 -0
  92. package/src/components/SafeAreaView/SafeAreaView.tsx +173 -0
  93. package/src/components/SafeAreaView/index.ts +2 -0
  94. package/src/components/Select/Select.tsx +30 -27
  95. package/src/components/Table/Table.context.tsx +23 -0
  96. package/src/components/Table/Table.docs.mdx +239 -0
  97. package/src/components/Table/Table.figma.tsx +65 -0
  98. package/src/components/Table/Table.props.ts +65 -0
  99. package/src/components/Table/Table.stories.tsx +399 -0
  100. package/src/components/Table/Table.tsx +127 -0
  101. package/src/components/Table/Table.utils.test.ts +82 -0
  102. package/src/components/Table/Table.utils.ts +72 -0
  103. package/src/components/Table/TableBody.tsx +25 -0
  104. package/src/components/Table/TableCell.tsx +67 -0
  105. package/src/components/Table/TableHeader.tsx +41 -0
  106. package/src/components/Table/TableHeaderCell.tsx +136 -0
  107. package/src/components/Table/TablePagination.tsx +10 -0
  108. package/src/components/Table/TableRow.tsx +42 -0
  109. package/src/components/Table/index.ts +16 -0
  110. package/src/components/Timeline/Timeline.docs.mdx +177 -0
  111. package/src/components/Timeline/Timeline.figma.tsx +89 -0
  112. package/src/components/Timeline/Timeline.props.ts +51 -0
  113. package/src/components/Timeline/Timeline.stories.tsx +102 -0
  114. package/src/components/Timeline/Timeline.tsx +48 -0
  115. package/src/components/Timeline/TimelineItem.tsx +293 -0
  116. package/src/components/Timeline/index.ts +9 -0
  117. package/src/components/index.ts +5 -0
  118. package/src/tokens/components/dark/timeline.ts +2 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@utilitywarehouse/hearth-react-native",
3
- "version": "0.27.3",
3
+ "version": "0.28.0",
4
4
  "description": "Utility Warehouse React Native UI library",
5
5
  "main": "build/index.js",
6
6
  "types": "build/index.d.ts",
@@ -58,8 +58,8 @@
58
58
  "vitest": "^3.2.4",
59
59
  "@utilitywarehouse/hearth-fonts": "^0.0.4",
60
60
  "@utilitywarehouse/hearth-react-icons": "^0.8.0",
61
- "@utilitywarehouse/hearth-react-native-icons": "^0.8.0",
62
61
  "@utilitywarehouse/hearth-svg-assets": "^0.5.0",
62
+ "@utilitywarehouse/hearth-react-native-icons": "^0.8.0",
63
63
  "@utilitywarehouse/hearth-tokens": "^0.2.4"
64
64
  },
65
65
  "peerDependencies": {
@@ -0,0 +1,26 @@
1
+ import { createContext, useContext } from 'react';
2
+
3
+ export interface ComboboxSelection {
4
+ label: string;
5
+ value: string;
6
+ }
7
+
8
+ export interface ComboboxContextValue {
9
+ close: () => void;
10
+ search: string;
11
+ selectedValue?: string | null;
12
+ selectOption: (option: ComboboxSelection) => void;
13
+ setSearch: (value: string) => void;
14
+ }
15
+
16
+ export const ComboboxContext = createContext<ComboboxContextValue | undefined>(undefined);
17
+
18
+ export const useComboboxContext = () => {
19
+ const context = useContext(ComboboxContext);
20
+
21
+ if (!context) {
22
+ throw new Error('useComboboxContext must be used within a Combobox');
23
+ }
24
+
25
+ return context;
26
+ };
@@ -0,0 +1,277 @@
1
+ import { Canvas, Controls, Meta } from '@storybook/addon-docs/blocks';
2
+ import { BottomSheetFlatList, Box, Center, Combobox, ComboboxOption } from '../../';
3
+ import { BackToTopButton, UsageWrap, ViewFigmaButton } from '../../../docs/components';
4
+ import * as Stories from './Combobox.stories';
5
+
6
+ <Meta title="Forms / Combobox" />
7
+
8
+ <BackToTopButton />
9
+
10
+ <ViewFigmaButton url="https://www.figma.com/design/6NKZXZhFSExXrcbBgc6zTR/Hearth-Components---Tokens?node-id=9359-2923&t=c7xg5X0N2EL0t87h-4" />
11
+
12
+ # Combobox
13
+
14
+ The `Combobox` component lets people search and select from a list inside a bottom sheet. It keeps the trigger text and the bottom sheet search input in sync, and can render either the built-in options list or fully custom sheet content.
15
+
16
+ - [Playground](#playground)
17
+ - [Usage](#usage)
18
+ - [Props](#props)
19
+ - [Examples](#examples)
20
+ - [Accessibility](#accessibility)
21
+
22
+ ## Playground
23
+
24
+ <Canvas of={Stories.Playground} />
25
+
26
+ <Controls of={Stories.Playground} />
27
+
28
+ ## Usage
29
+
30
+ <UsageWrap>
31
+ <Center>
32
+ <Combobox
33
+ label="Country"
34
+ placeholder="Search for a country"
35
+ searchPlaceholder="Search for a country"
36
+ options={[
37
+ { label: 'United Kingdom', value: 'uk' },
38
+ { label: 'United States', value: 'us' },
39
+ { label: 'Canada', value: 'ca' },
40
+ ]}
41
+ value="uk"
42
+ />
43
+ </Center>
44
+ </UsageWrap>
45
+
46
+ ```tsx
47
+ import { Combobox } from '@utilitywarehouse/hearth-react-native';
48
+ import { useState } from 'react';
49
+
50
+ const countries = [
51
+ { label: 'United Kingdom', value: 'uk' },
52
+ { label: 'United States', value: 'us' },
53
+ { label: 'Canada', value: 'ca' },
54
+ ];
55
+
56
+ const MyComponent = () => {
57
+ const [value, setValue] = useState<string | null>(null);
58
+
59
+ return (
60
+ <Combobox
61
+ label="Country"
62
+ placeholder="Search for a country"
63
+ searchPlaceholder="Search for a country"
64
+ options={countries}
65
+ value={value}
66
+ onValueChange={setValue}
67
+ />
68
+ );
69
+ };
70
+ ```
71
+
72
+ ## Props
73
+
74
+ The `Combobox` component inherits all of the React Native [`View` props](https://reactnative.dev/docs/view).
75
+
76
+ | Prop | Type | Default | Description |
77
+ | -------------------- | ----------------------------------- | -------------------- | ---------------------------------------------------------------------------- |
78
+ | `options` | `ComboboxOptionItemProps[]` | `[]` | Array of options for the built-in bottom sheet list. |
79
+ | `value` | `string \| null` | `-` | Currently selected value. |
80
+ | `onValueChange` | `(value: string \| null) => void` | `-` | Callback when the selected value changes. |
81
+ | `inputValue` | `string` | `-` | Controlled search value for the trigger and bottom sheet input. |
82
+ | `onInputValueChange` | `(value: string) => void` | `-` | Callback when the search value changes. |
83
+ | `placeholder` | `string` | `'Search'` | Placeholder shown in the trigger when empty. |
84
+ | `searchPlaceholder` | `string` | `'Search'` | Placeholder shown in the bottom sheet search input. |
85
+ | `menuHeading` | `string` | `-` | Optional heading shown at the top of the bottom sheet. |
86
+ | `children` | `ReactNode \| (props) => ReactNode` | `-` | Custom bottom sheet content, or a render function for custom list rendering. |
87
+ | `loading` | `boolean` | `false` | Displays a loading spinner in the trigger and sheet input. |
88
+ | `noOptionsFoundText` | `string` | `'No options found'` | Empty state text for the built-in options list. |
89
+ | `getValueLabel` | `(value) => string` | `-` | Resolve a label for selected values that are not present in `options`. |
90
+ | `filterOption` | `(option, search) => boolean` | `-` | Override the default label and keyword filtering logic. |
91
+
92
+ ## Examples
93
+
94
+ ### Static Searchable List
95
+
96
+ <Canvas of={Stories.StaticSearchableList} />
97
+
98
+ ```tsx
99
+ import { Combobox } from '@utilitywarehouse/hearth-react-native';
100
+ import { useState } from 'react';
101
+
102
+ const countries = [
103
+ { label: 'United Kingdom', value: 'uk', keywords: ['britain', 'england'] },
104
+ { label: 'United States', value: 'us', keywords: ['america', 'usa'] },
105
+ { label: 'Canada', value: 'ca' },
106
+ { label: 'Australia', value: 'au' },
107
+ { label: 'France', value: 'fr' },
108
+ ];
109
+
110
+ const MyComponent = () => {
111
+ const [value, setValue] = useState<string | null>(null);
112
+
113
+ return (
114
+ <Combobox
115
+ label="Country"
116
+ helperText="Search a fixed list of countries"
117
+ placeholder="Search for a country"
118
+ searchPlaceholder="Search for a country"
119
+ menuHeading="Choose a country"
120
+ options={countries}
121
+ value={value}
122
+ onValueChange={setValue}
123
+ />
124
+ );
125
+ };
126
+ ```
127
+
128
+ ### Dynamic Items
129
+
130
+ <Canvas of={Stories.DynamicItems} />
131
+
132
+ ```tsx
133
+ import { Combobox } from '@utilitywarehouse/hearth-react-native';
134
+ import { useEffect, useState } from 'react';
135
+
136
+ const allProducts = [
137
+ { label: 'Broadband', value: 'broadband' },
138
+ { label: 'Energy', value: 'energy' },
139
+ { label: 'Mobile', value: 'mobile' },
140
+ ];
141
+
142
+ const MyComponent = () => {
143
+ const [value, setValue] = useState<string | null>(null);
144
+ const [inputValue, setInputValue] = useState('');
145
+ const [loading, setLoading] = useState(false);
146
+ const [options, setOptions] = useState(allProducts);
147
+
148
+ useEffect(() => {
149
+ setLoading(true);
150
+
151
+ const timeout = setTimeout(() => {
152
+ const query = inputValue.trim().toLowerCase();
153
+ setOptions(allProducts.filter(option => option.label.toLowerCase().includes(query)));
154
+ setLoading(false);
155
+ }, 300);
156
+
157
+ return () => clearTimeout(timeout);
158
+ }, [inputValue]);
159
+
160
+ return (
161
+ <Combobox
162
+ label="Products"
163
+ options={options}
164
+ value={value}
165
+ onValueChange={setValue}
166
+ inputValue={inputValue}
167
+ onInputValueChange={setInputValue}
168
+ loading={loading}
169
+ getValueLabel={selectedValue =>
170
+ allProducts.find(option => option.value === selectedValue)?.label ?? ''
171
+ }
172
+ />
173
+ );
174
+ };
175
+ ```
176
+
177
+ ### Custom Bottom Sheet Flat List
178
+
179
+ <Canvas of={Stories.CustomFlatList} />
180
+
181
+ ```tsx
182
+ import {
183
+ BottomSheetFlatList,
184
+ Combobox,
185
+ ComboboxOption,
186
+ } from '@utilitywarehouse/hearth-react-native';
187
+
188
+ const cities = [
189
+ { label: 'London', value: 'london' },
190
+ { label: 'Liverpool', value: 'liverpool' },
191
+ { label: 'Leeds', value: 'leeds' },
192
+ ];
193
+
194
+ const MyComponent = () => {
195
+ return (
196
+ <Combobox label="Cities" placeholder="Search a city">
197
+ {({ search }) => {
198
+ const query = search.trim().toLowerCase();
199
+ const filteredCities = cities.filter(option => option.label.toLowerCase().includes(query));
200
+
201
+ return (
202
+ <BottomSheetFlatList
203
+ data={filteredCities}
204
+ keyExtractor={item => item.value}
205
+ renderItem={({ item }) => <ComboboxOption label={item.label} value={item.value} />}
206
+ />
207
+ );
208
+ }}
209
+ </Combobox>
210
+ );
211
+ };
212
+ ```
213
+
214
+ ### Inline Custom Content
215
+
216
+ <UsageWrap>
217
+ <Center>
218
+ <Combobox label="Inline options" placeholder="Search for a country">
219
+ <Box>
220
+ <ComboboxOption label="United Kingdom" value="uk" />
221
+ <ComboboxOption label="United States" value="us" />
222
+ <ComboboxOption label="Canada" value="ca" />
223
+ </Box>
224
+ </Combobox>
225
+ </Center>
226
+ </UsageWrap>
227
+
228
+ ```tsx
229
+ import { Box, Combobox, ComboboxOption } from '@utilitywarehouse/hearth-react-native';
230
+ import { useState } from 'react';
231
+
232
+ const countries = [
233
+ { label: 'United Kingdom', value: 'uk' },
234
+ { label: 'United States', value: 'us' },
235
+ { label: 'Canada', value: 'ca' },
236
+ ];
237
+
238
+ const MyComponent = () => {
239
+ const [value, setValue] = useState<string | null>(null);
240
+
241
+ return (
242
+ <Combobox
243
+ label="Inline options"
244
+ helperText="Compose your own sheet content using ComboboxOption"
245
+ placeholder="Search a country"
246
+ searchPlaceholder="Search a country"
247
+ value={value}
248
+ onValueChange={setValue}
249
+ >
250
+ <Box>
251
+ {countries.map(option => (
252
+ <ComboboxOption key={option.value} label={option.label} value={option.value} />
253
+ ))}
254
+ </Box>
255
+ </Combobox>
256
+ );
257
+ };
258
+ ```
259
+
260
+ ## Accessibility
261
+
262
+ The `Combobox` is implemented as a button that opens a bottom sheet. By default:
263
+
264
+ - The trigger uses an accessible label derived from the `label` prop (and, where appropriate, the current value or `placeholder`) and is exposed with `accessibilityRole="button"`.
265
+ - When the bottom sheet is open, the trigger reflects its state via `accessibilityState={{ expanded: true }}`; when the sheet is closed, it reports `expanded: false`. Screen readers should announce this state change as “expanded” / “collapsed”.
266
+ - The clear control (shown when a value is selected and clearing is allowed) is exposed as a separate button with an accessibility label such as “Clear selection”, so that screen reader users understand its purpose.
267
+
268
+ When you rely on the built‑in options list via the `options` prop, each option is rendered with appropriate roles and labels so that it can be discovered and activated with assistive technology.
269
+
270
+ When you provide fully custom sheet content instead of using `ComboboxOption`:
271
+
272
+ - Make sure interactive elements inside the sheet have the correct `accessibilityRole` (for example, `button` or `checkbox`) and meaningful `accessibilityLabel`s.
273
+ - Ensure that the primary search field inside the sheet remains focusable and clearly labelled with `searchPlaceholder` or a custom accessible label.
274
+ - Provide clear labelling or headings for grouped content, and ensure focus order inside the sheet is logical.
275
+ - Keep a visible and accessible way to dismiss the sheet (for example, a close button with an appropriate accessibility label).
276
+
277
+ These practices help ensure that the combobox remains understandable and operable for screen reader and keyboard users, regardless of whether you use the built‑in options list or custom content.
@@ -0,0 +1,60 @@
1
+ import figma from '@figma/code-connect';
2
+ import { useState } from 'react';
3
+ import { Combobox } from '../';
4
+
5
+ figma.connect(
6
+ Combobox,
7
+ 'https://www.figma.com/design/6NKZXZhFSExXrcbBgc6zTR/Hearth-Components---Tokens?node-id=9359%3A2923',
8
+ {
9
+ props: {
10
+ label: figma.string('Label'),
11
+ placeholder: figma.enum('Value type', {
12
+ Empty: figma.string('Value'),
13
+ }),
14
+ disabled: figma.enum('Variant', {
15
+ Disabled: true,
16
+ }),
17
+ validationStatus: figma.enum('Variant', {
18
+ Invalid: 'invalid',
19
+ }),
20
+ invalidText: figma.enum('Variant', {
21
+ Invalid: figma.string('Validation'),
22
+ }),
23
+ helperText: figma.boolean('Helper text?', {
24
+ true: figma.string('Helper text'),
25
+ }),
26
+ required: figma.boolean('Optional?', {
27
+ true: false,
28
+ }),
29
+ loading: figma.enum('Variant', {
30
+ Loading: true,
31
+ }),
32
+ value: figma.enum('Value type', {
33
+ Filled: figma.string('Value'),
34
+ }),
35
+ },
36
+ example: props => {
37
+ const [value, setValue] = useState<string | null>(props.value ? '1' : null);
38
+
39
+ return (
40
+ <Combobox
41
+ label={props.label}
42
+ placeholder={props.placeholder}
43
+ disabled={props.disabled}
44
+ validationStatus={props.validationStatus}
45
+ invalidText={props.invalidText}
46
+ helperText={props.helperText}
47
+ required={props.required}
48
+ loading={props.loading}
49
+ options={[
50
+ { label: 'Option 1', value: '1' },
51
+ { label: 'Option 2', value: '2' },
52
+ { label: 'Option 3', value: '3' },
53
+ ]}
54
+ value={value}
55
+ onValueChange={setValue}
56
+ />
57
+ );
58
+ },
59
+ }
60
+ );
@@ -0,0 +1,187 @@
1
+ import { BottomSheetFlatListProps } from '@gorhom/bottom-sheet/lib/typescript/components/bottomSheetScrollable/types';
2
+ import { ComponentType, ReactNode } from 'react';
3
+ import { ViewProps } from 'react-native';
4
+ import { BottomSheetProps } from '../BottomSheet';
5
+ import { ComboboxSelection } from './Combobox.context';
6
+
7
+ type ValidationStatus = 'initial' | 'valid' | 'invalid';
8
+
9
+ export interface ComboboxOptionItemProps {
10
+ /**
11
+ * Label shown for this option.
12
+ */
13
+ label: string;
14
+ /**
15
+ * Value returned when this option is selected.
16
+ */
17
+ value: string;
18
+ /**
19
+ * Optional icon shown before the option label.
20
+ */
21
+ leadingIcon?: ComponentType;
22
+ /**
23
+ * Optional icon shown after the option label.
24
+ */
25
+ trailingIcon?: ComponentType;
26
+ /**
27
+ * Additional searchable terms for this option.
28
+ */
29
+ keywords?: string[];
30
+ /**
31
+ * Whether this option is disabled.
32
+ */
33
+ disabled?: boolean;
34
+ }
35
+
36
+ export interface ComboboxRenderContentProps {
37
+ /**
38
+ * Current search value used by both the trigger and bottom sheet input.
39
+ */
40
+ search: string;
41
+ /**
42
+ * Update the search value.
43
+ */
44
+ setSearch: (value: string) => void;
45
+ /**
46
+ * Close the bottom sheet.
47
+ */
48
+ close: () => void;
49
+ /**
50
+ * Select an option, update the trigger text and close the bottom sheet.
51
+ */
52
+ selectOption: (option: ComboboxSelection) => void;
53
+ /**
54
+ * Currently selected value.
55
+ */
56
+ selectedValue?: string | null;
57
+ }
58
+
59
+ export interface ComboboxOptionProps extends ComboboxOptionItemProps {
60
+ /**
61
+ * Whether this option is selected.
62
+ */
63
+ selected?: boolean;
64
+ /**
65
+ * Custom press handler for this option.
66
+ */
67
+ onPress?: (value: string) => void;
68
+ }
69
+
70
+ type ComboboxChildren = ReactNode | ((props: ComboboxRenderContentProps) => ReactNode);
71
+
72
+ interface ComboboxProps extends Omit<ViewProps, 'children'> {
73
+ /**
74
+ * Array of options to render using the default bottom sheet list.
75
+ */
76
+ options?: ComboboxOptionItemProps[];
77
+ /**
78
+ * Currently selected value.
79
+ */
80
+ value?: string | null;
81
+ /**
82
+ * Callback fired when the selected value changes.
83
+ */
84
+ onValueChange?: (value: string | null) => void;
85
+ /**
86
+ * Controlled search value used by the trigger and bottom sheet input.
87
+ */
88
+ inputValue?: string;
89
+ /**
90
+ * Callback fired when the search value changes.
91
+ */
92
+ onInputValueChange?: (value: string) => void;
93
+ /**
94
+ * Label shown above the combobox.
95
+ */
96
+ label?: string;
97
+ /**
98
+ * The variant of the label text.
99
+ *
100
+ * @default 'body'
101
+ */
102
+ labelVariant?: 'heading' | 'body';
103
+ /**
104
+ * Helper text shown below the label.
105
+ */
106
+ helperText?: string;
107
+ /**
108
+ * Optional helper icon.
109
+ */
110
+ helperIcon?: ComponentType;
111
+ /**
112
+ * Text shown for invalid state.
113
+ */
114
+ invalidText?: string;
115
+ /**
116
+ * Text shown for valid state.
117
+ */
118
+ validText?: string;
119
+ /**
120
+ * Placeholder shown when the combobox is empty.
121
+ *
122
+ * @default 'Search'
123
+ */
124
+ placeholder?: string;
125
+ /**
126
+ * Placeholder shown in the bottom sheet search input.
127
+ *
128
+ * @default 'Search'
129
+ */
130
+ searchPlaceholder?: string;
131
+ /**
132
+ * Whether the combobox is disabled.
133
+ */
134
+ disabled?: boolean;
135
+ /**
136
+ * Validation status for the combobox.
137
+ *
138
+ * @default 'initial'
139
+ */
140
+ validationStatus?: ValidationStatus;
141
+ /**
142
+ * Whether the combobox is required.
143
+ *
144
+ * @default true
145
+ */
146
+ required?: boolean;
147
+ /**
148
+ * Heading displayed above the bottom sheet search input.
149
+ */
150
+ menuHeading?: string;
151
+ /**
152
+ * Custom bottom sheet content, or a render function for fully custom list rendering.
153
+ */
154
+ children?: ComboboxChildren;
155
+ /**
156
+ * Props passed to the BottomSheetModal.
157
+ */
158
+ bottomSheetProps?: Partial<BottomSheetProps>;
159
+ /**
160
+ * Text shown when no options match the current search.
161
+ *
162
+ * @default 'No options found'
163
+ */
164
+ noOptionsFoundText?: string;
165
+ /**
166
+ * Props passed to the default BottomSheetFlatList renderer.
167
+ */
168
+ listProps?: Partial<BottomSheetFlatListProps<ComboboxOptionItemProps>>;
169
+ /**
170
+ * Whether the combobox should show a loading spinner.
171
+ */
172
+ loading?: boolean;
173
+ /**
174
+ * Whether the combobox is readonly.
175
+ */
176
+ readonly?: boolean;
177
+ /**
178
+ * Resolve a label for a selected value when the current options array does not contain it.
179
+ */
180
+ getValueLabel?: (value: string | null | undefined) => string;
181
+ /**
182
+ * Override the default filtering behaviour for the default options list.
183
+ */
184
+ filterOption?: (option: ComboboxOptionItemProps, search: string) => boolean;
185
+ }
186
+
187
+ export default ComboboxProps;