@rentnerkev/select 1.0.1 → 3.0.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.
- package/README.md +193 -83
- package/dist/Components/SelectView.d.ts +12 -0
- package/dist/Components/SelectView.d.ts.map +1 -0
- package/dist/Components/SelectView.js +90 -0
- package/dist/Components/SelectView.js.map +1 -0
- package/dist/Hooks/useSelect.logic.d.ts +69 -0
- package/dist/Hooks/useSelect.logic.d.ts.map +1 -0
- package/dist/Hooks/useSelect.logic.js +197 -0
- package/dist/Hooks/useSelect.logic.js.map +1 -0
- package/dist/Select.d.ts +6 -2
- package/dist/Select.d.ts.map +1 -1
- package/dist/Select.js +34 -154
- package/dist/Select.js.map +1 -1
- package/dist/i18n.d.ts +13 -0
- package/dist/i18n.d.ts.map +1 -0
- package/dist/i18n.js +29 -0
- package/dist/i18n.js.map +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/selectValue.d.ts +4 -0
- package/dist/selectValue.d.ts.map +1 -0
- package/dist/selectValue.js +14 -0
- package/dist/selectValue.js.map +1 -0
- package/dist/types.d.ts +28 -8
- package/dist/types.d.ts.map +1 -1
- package/package.json +34 -12
- package/tailwind.css +14 -0
- package/dist/Internal/Tooltip.d.ts +0 -16
- package/dist/Internal/Tooltip.d.ts.map +0 -1
- package/dist/Internal/Tooltip.js +0 -13
- package/dist/Internal/Tooltip.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,150 +1,257 @@
|
|
|
1
1
|
# @rentnerkev/select
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
An accessible, searchable React select for typed single and multiple selection, native form integration, validation, localization, and Tailwind CSS styling.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
Install the package with npm:
|
|
8
8
|
|
|
9
9
|
```bash
|
|
10
10
|
npm install @rentnerkev/select
|
|
11
11
|
```
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
Or with Bun:
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
```bash
|
|
16
|
+
bun add @rentnerkev/select
|
|
17
|
+
```
|
|
16
18
|
|
|
17
|
-
|
|
19
|
+
## Quick start
|
|
20
|
+
|
|
21
|
+
`CustomSelect<TValue>` infers its value type from `value` and `options`, so the change handler remains typed without casts.
|
|
18
22
|
|
|
19
23
|
```tsx
|
|
20
|
-
import { CustomSelect } from '@rentnerkev/select'
|
|
24
|
+
import { CustomSelect, type Option } from '@rentnerkev/select'
|
|
21
25
|
import { useState } from 'react'
|
|
22
|
-
import { User } from 'lucide-react'
|
|
23
26
|
|
|
24
|
-
|
|
25
|
-
|
|
27
|
+
const contactOptions = [
|
|
28
|
+
{
|
|
29
|
+
value: 'alex-morgan',
|
|
30
|
+
label: 'Alex Morgan',
|
|
31
|
+
subOption: 'Customer success',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
value: 'sam-rivera',
|
|
35
|
+
label: 'Sam Rivera',
|
|
36
|
+
subOption: 'Technical support',
|
|
37
|
+
},
|
|
38
|
+
] satisfies ReadonlyArray<Option<string>>
|
|
26
39
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
value: 'max-mustermann',
|
|
30
|
-
label: 'Max - Mustermann',
|
|
31
|
-
subOption: 'Musterstraße 12, 10115 Berlin',
|
|
32
|
-
},
|
|
33
|
-
{
|
|
34
|
-
value: 'erika-musterfrau',
|
|
35
|
-
label: 'Erika - Musterfrau',
|
|
36
|
-
subOption: 'Hafenweg 4, 20457 Hamburg',
|
|
37
|
-
},
|
|
38
|
-
{
|
|
39
|
-
value: 'tim-schneider',
|
|
40
|
-
label: 'Tim - Schneider',
|
|
41
|
-
subOption: 'Königsallee 22, 40212 Düsseldorf',
|
|
42
|
-
},
|
|
43
|
-
]
|
|
40
|
+
export function ContactSelect() {
|
|
41
|
+
const [contact, setContact] = useState('')
|
|
44
42
|
|
|
45
43
|
return (
|
|
46
|
-
<
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
44
|
+
<CustomSelect
|
|
45
|
+
id="contact"
|
|
46
|
+
name="contact"
|
|
47
|
+
label="Contact"
|
|
48
|
+
value={contact}
|
|
49
|
+
onValueChange={setContact}
|
|
50
|
+
options={contactOptions}
|
|
51
|
+
placeholder="Choose a contact"
|
|
52
|
+
required
|
|
53
|
+
/>
|
|
54
|
+
)
|
|
55
|
+
}
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
## Generic values
|
|
59
|
+
|
|
60
|
+
Strings, numbers, booleans, and objects are supported. Use `isOptionEqualToValue` to define equality for object values and `getFormValue` to serialize values for native form submission. Without `getFormValue`, the component uses `String(value)`.
|
|
61
|
+
|
|
62
|
+
```tsx
|
|
63
|
+
import { CustomSelect, type Option } from '@rentnerkev/select'
|
|
64
|
+
import { useState } from 'react'
|
|
65
|
+
|
|
66
|
+
const statuses = ['todo', 'done'] as const
|
|
67
|
+
type Status = (typeof statuses)[number]
|
|
68
|
+
|
|
69
|
+
const statusOptions = statuses.map((status) => ({
|
|
70
|
+
value: status,
|
|
71
|
+
label: status === 'todo' ? 'To do' : 'Done',
|
|
72
|
+
})) satisfies ReadonlyArray<Option<Status>>
|
|
73
|
+
|
|
74
|
+
export function StatusSelect() {
|
|
75
|
+
const [status, setStatus] = useState<Status>('todo')
|
|
76
|
+
|
|
77
|
+
return (
|
|
78
|
+
<CustomSelect
|
|
79
|
+
value={status}
|
|
80
|
+
onValueChange={setStatus}
|
|
81
|
+
options={statusOptions}
|
|
82
|
+
/>
|
|
83
|
+
)
|
|
84
|
+
}
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
## Multiple selection
|
|
88
|
+
|
|
89
|
+
The current multiple-selection API uses an array, preserving values that contain commas:
|
|
90
|
+
|
|
91
|
+
```tsx
|
|
92
|
+
import { CustomSelect } from '@rentnerkev/select'
|
|
93
|
+
import { useState } from 'react'
|
|
94
|
+
|
|
95
|
+
export function RegionSelect() {
|
|
96
|
+
const [regions, setRegions] = useState<Array<string>>([])
|
|
97
|
+
|
|
98
|
+
return (
|
|
99
|
+
<CustomSelect
|
|
100
|
+
name="regions"
|
|
101
|
+
multiple
|
|
102
|
+
value={regions}
|
|
103
|
+
onValueChange={setRegions}
|
|
104
|
+
options={[
|
|
105
|
+
{ value: 'north,west', label: 'North West' },
|
|
106
|
+
{ value: 'south', label: 'South' },
|
|
107
|
+
]}
|
|
108
|
+
minSelection={1}
|
|
109
|
+
maxSelection={2}
|
|
110
|
+
/>
|
|
60
111
|
)
|
|
61
112
|
}
|
|
62
113
|
```
|
|
63
114
|
|
|
64
|
-
|
|
115
|
+
When `name` is set, each selected array item is submitted under the same field name. Read all values with `new FormData(form).getAll('regions')`.
|
|
116
|
+
|
|
117
|
+
Multiple selection uses a typed array value and submits one native form entry per selected option. Values containing commas remain unambiguous.
|
|
65
118
|
|
|
66
|
-
|
|
119
|
+
## Forms and accessibility
|
|
120
|
+
|
|
121
|
+
The visible trigger supports labels, descriptions, external errors, native validation, and forwarded `aria-*` attributes. Set `required` to participate in form validation. `disabled` removes the field from interaction and validation; `readOnly` prevents changes while retaining the submitted value.
|
|
67
122
|
|
|
68
123
|
```tsx
|
|
69
124
|
import { CustomSelect } from '@rentnerkev/select'
|
|
70
|
-
import { BriefcaseBusiness } from 'lucide-react'
|
|
71
125
|
import { useState } from 'react'
|
|
72
126
|
|
|
73
|
-
function
|
|
127
|
+
export function DepartmentForm() {
|
|
74
128
|
const [department, setDepartment] = useState('')
|
|
75
129
|
|
|
76
130
|
return (
|
|
77
|
-
<form
|
|
78
|
-
onSubmit={(event) => {
|
|
79
|
-
event.preventDefault()
|
|
80
|
-
event.currentTarget.reportValidity()
|
|
81
|
-
}}
|
|
82
|
-
>
|
|
131
|
+
<form>
|
|
83
132
|
<CustomSelect
|
|
84
133
|
id="department"
|
|
85
134
|
name="department"
|
|
135
|
+
label="Department"
|
|
136
|
+
description="Choose the team that owns this request."
|
|
86
137
|
value={department}
|
|
87
138
|
onValueChange={setDepartment}
|
|
88
139
|
options={[
|
|
89
|
-
{ value: '
|
|
140
|
+
{ value: 'consulting', label: 'Consulting' },
|
|
90
141
|
{ value: 'support', label: 'Support' },
|
|
91
|
-
{ value: '
|
|
142
|
+
{ value: 'sales', label: 'Sales' },
|
|
92
143
|
]}
|
|
93
|
-
placeholder="
|
|
144
|
+
placeholder="Choose a department"
|
|
94
145
|
required
|
|
95
|
-
|
|
146
|
+
locale="en"
|
|
96
147
|
/>
|
|
97
148
|
|
|
98
|
-
<button type="submit">
|
|
149
|
+
<button type="submit">Submit</button>
|
|
99
150
|
</form>
|
|
100
151
|
)
|
|
101
152
|
}
|
|
102
153
|
```
|
|
103
154
|
|
|
104
|
-
##
|
|
155
|
+
## Localization
|
|
105
156
|
|
|
106
|
-
|
|
157
|
+
German messages remain the default for backward compatibility. Set `locale="en"` for the complete English catalog, or override individual messages with a typed `Partial<SelectMessages>`. The catalog and resolver are available as `selectMessageCatalog` and `resolveSelectMessages`.
|
|
107
158
|
|
|
108
|
-
|
|
159
|
+
```tsx
|
|
160
|
+
import { CustomSelect, type SelectMessages } from '@rentnerkev/select'
|
|
161
|
+
import { useState } from 'react'
|
|
109
162
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
| `onValueChange` | `(value: string) => void` | Callback-Funktion, die bei Änderung aufgerufen wird. |
|
|
116
|
-
| `options` | `Option[]` | Ein Array von Optionen (siehe unten). |
|
|
117
|
-
| `required` | `boolean` | (Optional) Aktiviert Pflichtfeld-Validierung. Default ist `false`. |
|
|
118
|
-
| `className` | `string` | (Optional) Überträgt classes an die Select-Komponente. |
|
|
119
|
-
| `placeholder` | `string` | (Optional) Text, der angezeigt wird, wenn nichts ausgewählt ist. |
|
|
120
|
-
| `icon` | `React.ReactNode` | (Optional) Ein Icon, das links im Select angezeigt wird. |
|
|
121
|
-
| `fallbackOption` | `string` | (Optional) Text, der angezeigt wird, wenn keine Optionen vorhanden sind. |
|
|
122
|
-
| `multiple` | `boolean` | (Optional) Aktiviert die Mehrfachauswahl. Default ist false. |
|
|
123
|
-
| `minSelection` | `number` | (Optional) Bestimmt die Mindestanzahl an auszuwählenden Optionen. |
|
|
124
|
-
| `maxSelection` | `number` | (Optional) Bestimmt die maximale Anzahl an auszuwählenden Optionen. |
|
|
163
|
+
const messages: Partial<SelectMessages> = {
|
|
164
|
+
searchPlaceholder: 'Find an option',
|
|
165
|
+
noResults: 'Nothing found',
|
|
166
|
+
minSelection: (count) => `Choose at least ${count}`,
|
|
167
|
+
}
|
|
125
168
|
|
|
126
|
-
|
|
169
|
+
export function LocalizedSelect() {
|
|
170
|
+
const [selectedValue, setSelectedValue] = useState('')
|
|
171
|
+
|
|
172
|
+
return (
|
|
173
|
+
<CustomSelect
|
|
174
|
+
value={selectedValue}
|
|
175
|
+
onValueChange={setSelectedValue}
|
|
176
|
+
options={[{ value: 'priority', label: 'Priority' }]}
|
|
177
|
+
locale="en"
|
|
178
|
+
messages={messages}
|
|
179
|
+
/>
|
|
180
|
+
)
|
|
181
|
+
}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
## API
|
|
185
|
+
|
|
186
|
+
### `CustomSelect` props
|
|
187
|
+
|
|
188
|
+
| Prop | Type | Description |
|
|
189
|
+
| ---------------------- | -------------------------------------------------------- | ---------------------------------------------------------------------- |
|
|
190
|
+
| `id` | `string` | ID for the visible trigger and associated labels. |
|
|
191
|
+
| `name` | `string` | Native form field name. |
|
|
192
|
+
| `value` | `TValue \| null \| undefined` or `ReadonlyArray<TValue>` | Controlled single or multiple value. |
|
|
193
|
+
| `onValueChange` | `(value: TValue) => void` or `(value: TValue[]) => void` | Typed callback for the selected mode. |
|
|
194
|
+
| `options` | `ReadonlyArray<Option<TValue>>` | Available options. |
|
|
195
|
+
| `required` | `boolean` | Enables required-field validation. Defaults to `false`. |
|
|
196
|
+
| `label` | `ReactNode` | Visible label linked to the trigger. |
|
|
197
|
+
| `description` | `ReactNode` | Supporting text linked through `aria-describedby`. |
|
|
198
|
+
| `error` | `string \| null` | External validation message; `null` clears external and native errors. |
|
|
199
|
+
| `disabled` | `boolean` | Disables interaction and validation. |
|
|
200
|
+
| `readOnly` | `boolean` | Prevents changes while retaining the form value. |
|
|
201
|
+
| `className` | `string` | Additional Tailwind classes for the visible trigger. |
|
|
202
|
+
| `placeholder` | `string` | Text shown while no value is selected. |
|
|
203
|
+
| `icon` | `ReactNode` | Icon rendered at the start of the trigger. |
|
|
204
|
+
| `fallbackOption` | `string` | Message shown when no options are available. |
|
|
205
|
+
| `multiple` | `true` | Enables array-based multiple selection. |
|
|
206
|
+
| `minSelection` | `number` | Minimum number of selected options. |
|
|
207
|
+
| `maxSelection` | `number` | Maximum number of selected options. |
|
|
208
|
+
| `isOptionEqualToValue` | `(optionValue, value) => boolean` | Compares option and selected values. |
|
|
209
|
+
| `getFormValue` | `(value: TValue) => string` | Serializes a value for native form submission. |
|
|
210
|
+
| `locale` | `'de' \| 'en'` | Selects the default message catalog. Defaults to `'de'`. |
|
|
211
|
+
| `messages` | `Partial<SelectMessages>` | Overrides individual messages and ARIA text. |
|
|
212
|
+
| `aria-label` | `string` | Accessible name for the visible trigger. |
|
|
213
|
+
| `aria-labelledby` | `string` | External accessible-label IDs. |
|
|
214
|
+
| `aria-describedby` | `string` | External description IDs combined with internal text. |
|
|
215
|
+
| `triggerRef` | `Ref<HTMLButtonElement>` | Ref for the visible, focusable trigger. |
|
|
216
|
+
|
|
217
|
+
Additional React `aria-*` attributes are forwarded to the visible trigger.
|
|
218
|
+
|
|
219
|
+
### `Option<TValue>`
|
|
127
220
|
|
|
128
221
|
```ts
|
|
129
|
-
interface Option {
|
|
130
|
-
value:
|
|
222
|
+
interface Option<TValue = string> {
|
|
223
|
+
value: TValue
|
|
131
224
|
label: string
|
|
132
225
|
subOption?: string
|
|
133
226
|
}
|
|
134
227
|
```
|
|
135
228
|
|
|
136
|
-
`subOption`
|
|
229
|
+
`subOption` adds secondary information below the label in both the open list and the closed trigger.
|
|
137
230
|
|
|
138
|
-
## CSS
|
|
231
|
+
## Tailwind CSS
|
|
139
232
|
|
|
140
|
-
|
|
233
|
+
Import the package entry after Tailwind CSS in your application stylesheet:
|
|
141
234
|
|
|
142
235
|
```css
|
|
143
236
|
@import 'tailwindcss';
|
|
144
|
-
@
|
|
237
|
+
@import '@rentnerkev/select/tailwind.css';
|
|
145
238
|
```
|
|
146
239
|
|
|
147
|
-
|
|
240
|
+
The package entry scans only the published JavaScript under `dist` and provides the shared theme tokens `primary`, `primary-hover`, `background-dark`, `surface-dark`, `input-dark`, `border-dark`, `secondary-text`, and `muted-foreground`. Override them with a later `@theme` block when needed.
|
|
241
|
+
|
|
242
|
+
## Public entry points
|
|
243
|
+
|
|
244
|
+
| Entry point | Purpose |
|
|
245
|
+
| --------------------------------- | -------------------------------------------- |
|
|
246
|
+
| `@rentnerkev/select` | Component, messages, and public types. |
|
|
247
|
+
| `@rentnerkev/select/select` | `CustomSelect` component module. |
|
|
248
|
+
| `@rentnerkev/select/value` | Value comparison and toggle helpers. |
|
|
249
|
+
| `@rentnerkev/select/messages` | Locale catalog, resolver, and message types. |
|
|
250
|
+
| `@rentnerkev/select/types` | Component and option types. |
|
|
251
|
+
| `@rentnerkev/select/tailwind.css` | Tailwind source and shared theme tokens. |
|
|
252
|
+
| `@rentnerkev/select/package.json` | Package metadata. |
|
|
253
|
+
|
|
254
|
+
## Development
|
|
148
255
|
|
|
149
256
|
```bash
|
|
150
257
|
bun install
|
|
@@ -152,5 +259,8 @@ bun run verify
|
|
|
152
259
|
bun run playground:dev
|
|
153
260
|
```
|
|
154
261
|
|
|
155
|
-
`bun run verify`
|
|
156
|
-
|
|
262
|
+
`bun run verify` checks types, lint, formatting, tests, the package build, and the published package contents.
|
|
263
|
+
|
|
264
|
+
## License
|
|
265
|
+
|
|
266
|
+
MIT
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { SingleSelectProps } from '../types.js';
|
|
2
|
+
export type SelectViewProps<TValue> = Omit<SingleSelectProps<TValue>, 'value' | 'onValueChange' | 'multiple' | 'getFormValue'> & {
|
|
3
|
+
selectedValues: ReadonlyArray<TValue>;
|
|
4
|
+
formEntries: ReadonlyArray<{
|
|
5
|
+
key: string;
|
|
6
|
+
value: string;
|
|
7
|
+
}>;
|
|
8
|
+
multiple: boolean;
|
|
9
|
+
onSelectValue: (value: TValue) => void;
|
|
10
|
+
};
|
|
11
|
+
export default function SelectView<TValue>({ id, name, options, selectedValues, formEntries, onSelectValue, required, label, description, error: externalError, disabled, readOnly, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, 'aria-describedby': ariaDescribedBy, triggerRef, icon, placeholder, className, fallbackOption, multiple, minSelection, maxSelection, locale, messages: providedMessages, isOptionEqualToValue: isOptionEqualToValueProp, ...ariaProps }: SelectViewProps<TValue>): import("react").JSX.Element;
|
|
12
|
+
//# sourceMappingURL=SelectView.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SelectView.d.ts","sourceRoot":"","sources":["../../src/Components/SelectView.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AAEpD,MAAM,MAAM,eAAe,CAAC,MAAM,IAAI,IAAI,CACtC,iBAAiB,CAAC,MAAM,CAAC,EACzB,OAAO,GAAG,eAAe,GAAG,UAAU,GAAG,cAAc,CAC1D,GAAG;IACA,cAAc,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IACrC,WAAW,EAAE,aAAa,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAC1D,QAAQ,EAAE,OAAO,CAAA;IACjB,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;CACzC,CAAA;AAUD,MAAM,CAAC,OAAO,UAAU,UAAU,CAAC,MAAM,EAAE,EACvC,EAAE,EACF,IAAI,EACJ,OAAO,EACP,cAAc,EACd,WAAW,EACX,aAAa,EACb,QAAgB,EAChB,KAAK,EACL,WAAW,EACX,KAAK,EAAE,aAAa,EACpB,QAAgB,EAChB,QAAgB,EAChB,YAAY,EAAE,SAAS,EACvB,iBAAiB,EAAE,cAAc,EACjC,kBAAkB,EAAE,eAAe,EACnC,UAAU,EACV,IAAI,EACJ,WAAW,EACX,SAAS,EACT,cAAc,EACd,QAAgB,EAChB,YAAY,EACZ,YAAY,EACZ,MAAa,EACb,QAAQ,EAAE,gBAAgB,EAC1B,oBAAoB,EAAE,wBAAwB,EAC9C,GAAG,SAAS,EACf,EAAE,eAAe,CAAC,MAAM,CAAC,+BA0TzB"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import * as SelectPrimitive from '@radix-ui/react-select';
|
|
3
|
+
import { CustomTooltip } from '@rentnerkev/tooltips';
|
|
4
|
+
import { AlertCircle, Check, ChevronDown } from 'lucide-react';
|
|
5
|
+
import useSelectLogic from '../Hooks/useSelect.logic.js';
|
|
6
|
+
function mergeAriaIds(...values) {
|
|
7
|
+
const ids = values.flatMap((value) => value?.split(/\s+/).filter(Boolean) ?? []);
|
|
8
|
+
return [...new Set(ids)].join(' ') || undefined;
|
|
9
|
+
}
|
|
10
|
+
export default function SelectView({ id, name, options, selectedValues, formEntries, onSelectValue, required = false, label, description, error: externalError, disabled = false, readOnly = false, 'aria-label': ariaLabel, 'aria-labelledby': ariaLabelledBy, 'aria-describedby': ariaDescribedBy, triggerRef, icon, placeholder, className, fallbackOption, multiple = false, minSelection, maxSelection, locale = 'de', messages: providedMessages, isOptionEqualToValue: isOptionEqualToValueProp, ...ariaProps }) {
|
|
11
|
+
const logic = useSelectLogic({
|
|
12
|
+
id,
|
|
13
|
+
options,
|
|
14
|
+
selectedValues,
|
|
15
|
+
multiple,
|
|
16
|
+
required,
|
|
17
|
+
externalError,
|
|
18
|
+
disabled,
|
|
19
|
+
readOnly,
|
|
20
|
+
triggerRef,
|
|
21
|
+
minSelection,
|
|
22
|
+
maxSelection,
|
|
23
|
+
locale,
|
|
24
|
+
messages: providedMessages,
|
|
25
|
+
isOptionEqualToValue: isOptionEqualToValueProp,
|
|
26
|
+
onSelectValue,
|
|
27
|
+
});
|
|
28
|
+
const { triggerId, labelId, descriptionId, errorId, messages, open, searchValue, filteredOptions, selectedEntries, selectedRadixValue, hasError, resolvedError, isOptionEqualToValue, } = logic.state;
|
|
29
|
+
const { trigger, validationInput, searchInput } = logic.ref;
|
|
30
|
+
const { handleInvalid, handleValueChange, handleOpenChange, handleContentKeyDownCapture, setSearchValue, } = logic.handler;
|
|
31
|
+
const { shouldKeepOpen } = logic.setter;
|
|
32
|
+
const hasLeftIcon = Boolean(icon || hasError);
|
|
33
|
+
const describedBy = mergeAriaIds(ariaDescribedBy, description !== undefined && description !== null
|
|
34
|
+
? descriptionId
|
|
35
|
+
: undefined, hasError ? errorId : undefined);
|
|
36
|
+
const labelledBy = mergeAriaIds(ariaLabelledBy, label !== undefined && label !== null ? labelId : undefined);
|
|
37
|
+
return (_jsxs(SelectPrimitive.Root, { open: open, onOpenChange: handleOpenChange, value: selectedRadixValue, onValueChange: handleValueChange, children: [_jsxs("div", { className: "group relative", children: [label !== undefined && label !== null && (_jsx("label", { id: labelId, htmlFor: triggerId, className: "mb-1 block text-sm font-medium text-gray-300", children: label })), _jsx("input", { ref: validationInput, name: name, value: formEntries[0]?.value ?? '', onChange: () => undefined, onInvalid: handleInvalid, required: required &&
|
|
38
|
+
selectedValues.length === 0 &&
|
|
39
|
+
!disabled &&
|
|
40
|
+
externalError === undefined, disabled: disabled, readOnly: readOnly, tabIndex: -1, "aria-hidden": "true", className: "pointer-events-none absolute left-0 top-1/2 h-px w-px -translate-y-1/2 opacity-0" }), multiple &&
|
|
41
|
+
formEntries
|
|
42
|
+
.slice(1)
|
|
43
|
+
.map((formEntry) => (_jsx("input", { type: "hidden", name: name, value: formEntry.value, disabled: disabled, readOnly: readOnly }, formEntry.key))), hasLeftIcon && (_jsx("div", { className: "absolute left-2.5 top-1/2 z-10 -translate-y-1/2 text-gray-500", children: hasError ? (_jsx(CustomTooltip, { content: resolvedError || '', side: "bottom", children: _jsx(AlertCircle, { className: "h-4 w-4 text-red-500" }) })) : (_jsx("span", { className: "pointer-events-none flex items-center transition-colors group-focus-within:text-primary [&>svg]:h-4 [&>svg]:w-4", children: icon })) })), _jsxs(SelectPrimitive.Trigger, { ref: trigger, id: triggerId, disabled: disabled, ...ariaProps, "aria-invalid": hasError || ariaProps['aria-invalid'] || undefined, "aria-required": disabled
|
|
44
|
+
? undefined
|
|
45
|
+
: externalError === undefined
|
|
46
|
+
? required ||
|
|
47
|
+
ariaProps['aria-required'] ||
|
|
48
|
+
undefined
|
|
49
|
+
: ariaProps['aria-required'], "aria-label": ariaLabel, "aria-labelledby": labelledBy, "aria-describedby": describedBy, "aria-errormessage": hasError ? errorId : ariaProps['aria-errormessage'], "aria-readonly": readOnly || ariaProps['aria-readonly'] || undefined, "aria-disabled": disabled || ariaProps['aria-disabled'] || undefined, onPointerDown: (event) => {
|
|
50
|
+
if (readOnly) {
|
|
51
|
+
event.preventDefault();
|
|
52
|
+
event.currentTarget.focus();
|
|
53
|
+
}
|
|
54
|
+
}, onKeyDown: (event) => {
|
|
55
|
+
if (readOnly &&
|
|
56
|
+
(event.key === 'Enter' ||
|
|
57
|
+
event.key === ' ' ||
|
|
58
|
+
event.key === 'ArrowDown' ||
|
|
59
|
+
event.key === 'ArrowUp')) {
|
|
60
|
+
event.preventDefault();
|
|
61
|
+
}
|
|
62
|
+
}, className: `bg-input-dark border text-[11px] text-gray-300 rounded-lg ${hasLeftIcon ? 'pl-8' : 'pl-3'} pr-8 py-2 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/50 w-full uppercase font-bold tracking-wider cursor-pointer flex items-center justify-between transition-colors min-w-45 disabled:cursor-not-allowed disabled:opacity-50 ${hasError
|
|
63
|
+
? 'border-red-500 focus:ring-2 focus:ring-red-500/50 data-[state=open]:border-red-500'
|
|
64
|
+
: 'border-border-dark focus:border-primary data-[state=open]:border-primary'} ${className || ''}`, children: [_jsx("span", { className: "min-w-0 flex-1 text-left", children: selectedEntries.length > 0 ? (_jsxs("span", { className: "flex min-w-0 flex-col gap-0.5", children: [_jsx("span", { className: "truncate leading-4", children: selectedEntries
|
|
65
|
+
.map(({ option }) => option.label)
|
|
66
|
+
.join(', ') }), selectedEntries.length === 1 &&
|
|
67
|
+
selectedEntries[0].option.subOption && (_jsx("span", { className: "truncate text-[10px] font-semibold leading-3 tracking-normal text-gray-400 normal-case", children: selectedEntries[0].option
|
|
68
|
+
.subOption }))] })) : (_jsx(SelectPrimitive.Value, { placeholder: placeholder })) }), _jsx(SelectPrimitive.Icon, { asChild: true, children: _jsx(ChevronDown, { className: "absolute right-2.5 top-1/2 h-4 w-4 -translate-y-1/2 opacity-50" }) })] })] }), description !== undefined && description !== null && (_jsx("div", { id: descriptionId, className: "mt-1 text-xs text-gray-400", children: description })), hasError && (_jsx("span", { id: errorId, className: "sr-only", "aria-live": "polite", children: resolvedError })), _jsx(SelectPrimitive.Portal, { children: _jsxs(SelectPrimitive.Content, { position: "popper", sideOffset: 4, onKeyDownCapture: handleContentKeyDownCapture, className: "z-9998 w-(--radix-select-trigger-width) min-w-45 overflow-hidden rounded-lg border border-border-dark bg-surface-dark shadow-xl motion-safe:animate-in motion-safe:fade-in motion-safe:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2", children: [_jsx("div", { className: "border-b border-border-dark p-1", children: _jsx("input", { ref: searchInput, "aria-label": messages.searchOptions, value: searchValue, onChange: (event) => setSearchValue(event.target.value), onPointerDownCapture: (event) => event.stopPropagation(), onKeyDownCapture: (event) => {
|
|
69
|
+
if (event.key !== 'Escape') {
|
|
70
|
+
event.stopPropagation();
|
|
71
|
+
}
|
|
72
|
+
}, onKeyDown: (event) => {
|
|
73
|
+
if (event.key !== 'Escape') {
|
|
74
|
+
event.stopPropagation();
|
|
75
|
+
}
|
|
76
|
+
}, placeholder: messages.searchPlaceholder, className: "h-8 w-full rounded-md border border-border-dark bg-input-dark px-2 text-[11px] font-bold uppercase tracking-wider text-gray-300 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/50 placeholder:text-gray-500 focus:border-primary" }) }), _jsx("div", { className: "rentnerselect-scrollbar max-h-[min(var(--radix-select-content-available-height),16rem)] overflow-y-scroll scrollbar-gutter-stable", children: _jsx(SelectPrimitive.Viewport, { className: "p-1", children: filteredOptions.length > 0 ? (filteredOptions.map(({ option, radixValue }) => (_jsxs(SelectPrimitive.Item, { value: radixValue, onPointerDown: () => {
|
|
77
|
+
if (multiple) {
|
|
78
|
+
shouldKeepOpen.current = true;
|
|
79
|
+
}
|
|
80
|
+
}, onKeyDown: (event) => {
|
|
81
|
+
if (multiple &&
|
|
82
|
+
(event.key === 'Enter' ||
|
|
83
|
+
event.key === ' ')) {
|
|
84
|
+
shouldKeepOpen.current = true;
|
|
85
|
+
}
|
|
86
|
+
}, className: "relative flex w-full cursor-pointer select-none items-center rounded-md py-2 pl-8 pr-2 text-[11px] font-bold uppercase tracking-wider text-gray-300 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary/50 focus:bg-primary/20 focus:text-primary transition-colors data-disabled:opacity-50", children: [_jsx("span", { className: "absolute left-2 flex h-3.5 w-3.5 items-center justify-center", children: multiple ? (selectedValues.some((value) => isOptionEqualToValue(option.value, value)) && (_jsx(Check, { className: "h-4 w-4" }))) : (_jsx(SelectPrimitive.ItemIndicator, { children: _jsx(Check, { className: "h-4 w-4" }) })) }), _jsx(SelectPrimitive.ItemText, { children: _jsxs("span", { className: "flex min-w-0 flex-col gap-0.5", children: [_jsx("span", { className: "truncate leading-4", children: option.label }), option.subOption && (_jsx("span", { className: "truncate text-[10px] font-semibold leading-3 tracking-normal text-gray-400 normal-case", children: option.subOption }))] }) })] }, radixValue)))) : (_jsx("div", { className: "relative flex w-full select-none items-center rounded-md py-2 pl-8 pr-2 text-[11px] font-bold uppercase tracking-wider text-gray-400 opacity-60 outline-none italic cursor-not-allowed", children: searchValue.trim()
|
|
87
|
+
? messages.noResults
|
|
88
|
+
: fallbackOption || messages.noOptions })) }) })] }) })] }));
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=SelectView.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SelectView.js","sourceRoot":"","sources":["../../src/Components/SelectView.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,eAAe,MAAM,wBAAwB,CAAA;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAA;AACpD,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAA;AAC9D,OAAO,cAAc,MAAM,6BAA6B,CAAA;AAaxD,SAAS,YAAY,CAAC,GAAG,MAAiC;IACtD,MAAM,GAAG,GAAG,MAAM,CAAC,OAAO,CACtB,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE,CACvD,CAAA;IAED,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,SAAS,CAAA;AACnD,CAAC;AAED,MAAM,CAAC,OAAO,UAAU,UAAU,CAAS,EACvC,EAAE,EACF,IAAI,EACJ,OAAO,EACP,cAAc,EACd,WAAW,EACX,aAAa,EACb,QAAQ,GAAG,KAAK,EAChB,KAAK,EACL,WAAW,EACX,KAAK,EAAE,aAAa,EACpB,QAAQ,GAAG,KAAK,EAChB,QAAQ,GAAG,KAAK,EAChB,YAAY,EAAE,SAAS,EACvB,iBAAiB,EAAE,cAAc,EACjC,kBAAkB,EAAE,eAAe,EACnC,UAAU,EACV,IAAI,EACJ,WAAW,EACX,SAAS,EACT,cAAc,EACd,QAAQ,GAAG,KAAK,EAChB,YAAY,EACZ,YAAY,EACZ,MAAM,GAAG,IAAI,EACb,QAAQ,EAAE,gBAAgB,EAC1B,oBAAoB,EAAE,wBAAwB,EAC9C,GAAG,SAAS,EACU;IACtB,MAAM,KAAK,GAAG,cAAc,CAAC;QACzB,EAAE;QACF,OAAO;QACP,cAAc;QACd,QAAQ;QACR,QAAQ;QACR,aAAa;QACb,QAAQ;QACR,QAAQ;QACR,UAAU;QACV,YAAY;QACZ,YAAY;QACZ,MAAM;QACN,QAAQ,EAAE,gBAAgB;QAC1B,oBAAoB,EAAE,wBAAwB;QAC9C,aAAa;KAChB,CAAC,CAAA;IACF,MAAM,EACF,SAAS,EACT,OAAO,EACP,aAAa,EACb,OAAO,EACP,QAAQ,EACR,IAAI,EACJ,WAAW,EACX,eAAe,EACf,eAAe,EACf,kBAAkB,EAClB,QAAQ,EACR,aAAa,EACb,oBAAoB,GACvB,GAAG,KAAK,CAAC,KAAK,CAAA;IACf,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,GAAG,KAAK,CAAC,GAAG,CAAA;IAC3D,MAAM,EACF,aAAa,EACb,iBAAiB,EACjB,gBAAgB,EAChB,2BAA2B,EAC3B,cAAc,GACjB,GAAG,KAAK,CAAC,OAAO,CAAA;IACjB,MAAM,EAAE,cAAc,EAAE,GAAG,KAAK,CAAC,MAAM,CAAA;IACvC,MAAM,WAAW,GAAG,OAAO,CAAC,IAAI,IAAI,QAAQ,CAAC,CAAA;IAC7C,MAAM,WAAW,GAAG,YAAY,CAC5B,eAAe,EACf,WAAW,KAAK,SAAS,IAAI,WAAW,KAAK,IAAI;QAC7C,CAAC,CAAC,aAAa;QACf,CAAC,CAAC,SAAS,EACf,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CACjC,CAAA;IACD,MAAM,UAAU,GAAG,YAAY,CAC3B,cAAc,EACd,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAC9D,CAAA;IAED,OAAO,CACH,MAAC,eAAe,CAAC,IAAI,IACjB,IAAI,EAAE,IAAI,EACV,YAAY,EAAE,gBAAgB,EAC9B,KAAK,EAAE,kBAAkB,EACzB,aAAa,EAAE,iBAAiB,aAEhC,eAAK,SAAS,EAAC,gBAAgB,aAC1B,KAAK,KAAK,SAAS,IAAI,KAAK,KAAK,IAAI,IAAI,CACtC,gBACI,EAAE,EAAE,OAAO,EACX,OAAO,EAAE,SAAS,EAClB,SAAS,EAAC,8CAA8C,YAEvD,KAAK,GACF,CACX,EACD,gBACI,GAAG,EAAE,eAAe,EACpB,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,EAAE,EAClC,QAAQ,EAAE,GAAG,EAAE,CAAC,SAAS,EACzB,SAAS,EAAE,aAAa,EACxB,QAAQ,EACJ,QAAQ;4BACR,cAAc,CAAC,MAAM,KAAK,CAAC;4BAC3B,CAAC,QAAQ;4BACT,aAAa,KAAK,SAAS,EAE/B,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,CAAC,CAAC,iBACA,MAAM,EAClB,SAAS,EAAC,kFAAkF,GAC9F,EACD,QAAQ;wBACL,WAAW;6BACN,KAAK,CAAC,CAAC,CAAC;6BACR,GAAG,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,CAChB,gBAEI,IAAI,EAAC,QAAQ,EACb,IAAI,EAAE,IAAI,EACV,KAAK,EAAE,SAAS,CAAC,KAAK,EACtB,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,QAAQ,IALb,SAAS,CAAC,GAAG,CAMpB,CACL,CAAC,EACT,WAAW,IAAI,CACZ,cAAK,SAAS,EAAC,+DAA+D,YACzE,QAAQ,CAAC,CAAC,CAAC,CACR,KAAC,aAAa,IACV,OAAO,EAAE,aAAa,IAAI,EAAE,EAC5B,IAAI,EAAC,QAAQ,YAEb,KAAC,WAAW,IAAC,SAAS,EAAC,sBAAsB,GAAG,GACpC,CACnB,CAAC,CAAC,CAAC,CACA,eAAM,SAAS,EAAC,iHAAiH,YAC5H,IAAI,GACF,CACV,GACC,CACT,EACD,MAAC,eAAe,CAAC,OAAO,IACpB,GAAG,EAAE,OAAO,EACZ,EAAE,EAAE,SAAS,EACb,QAAQ,EAAE,QAAQ,KACd,SAAS,kBAET,QAAQ,IAAI,SAAS,CAAC,cAAc,CAAC,IAAI,SAAS,mBAGlD,QAAQ;4BACJ,CAAC,CAAC,SAAS;4BACX,CAAC,CAAC,aAAa,KAAK,SAAS;gCAC3B,CAAC,CAAC,QAAQ;oCACR,SAAS,CAAC,eAAe,CAAC;oCAC1B,SAAS;gCACX,CAAC,CAAC,SAAS,CAAC,eAAe,CAAC,gBAE1B,SAAS,qBACJ,UAAU,sBACT,WAAW,uBAEzB,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,mBAAmB,CAAC,mBAGnD,QAAQ,IAAI,SAAS,CAAC,eAAe,CAAC,IAAI,SAAS,mBAGnD,QAAQ,IAAI,SAAS,CAAC,eAAe,CAAC,IAAI,SAAS,EAEvD,aAAa,EAAE,CAAC,KAAK,EAAE,EAAE;4BACrB,IAAI,QAAQ,EAAE,CAAC;gCACX,KAAK,CAAC,cAAc,EAAE,CAAA;gCACtB,KAAK,CAAC,aAAa,CAAC,KAAK,EAAE,CAAA;4BAC/B,CAAC;wBACL,CAAC,EACD,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE;4BACjB,IACI,QAAQ;gCACR,CAAC,KAAK,CAAC,GAAG,KAAK,OAAO;oCAClB,KAAK,CAAC,GAAG,KAAK,GAAG;oCACjB,KAAK,CAAC,GAAG,KAAK,WAAW;oCACzB,KAAK,CAAC,GAAG,KAAK,SAAS,CAAC,EAC9B,CAAC;gCACC,KAAK,CAAC,cAAc,EAAE,CAAA;4BAC1B,CAAC;wBACL,CAAC,EACD,SAAS,EAAE,6DACP,WAAW,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAC3B,kQACI,QAAQ;4BACJ,CAAC,CAAC,oFAAoF;4BACtF,CAAC,CAAC,0EACV,IAAI,SAAS,IAAI,EAAE,EAAE,aAErB,eAAM,SAAS,EAAC,0BAA0B,YACrC,eAAe,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAC1B,gBAAM,SAAS,EAAC,+BAA+B,aAC3C,eAAM,SAAS,EAAC,oBAAoB,YAC/B,eAAe;iDACX,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC;iDACjC,IAAI,CAAC,IAAI,CAAC,GACZ,EACN,eAAe,CAAC,MAAM,KAAK,CAAC;4CACzB,eAAe,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,SAAS,IAAI,CACnC,eAAM,SAAS,EAAC,wFAAwF,YAEhG,eAAe,CAAC,CAAC,CAAC,CAAC,MAAM;iDACpB,SAAS,GAEf,CACV,IACF,CACV,CAAC,CAAC,CAAC,CACA,KAAC,eAAe,CAAC,KAAK,IAAC,WAAW,EAAE,WAAW,GAAI,CACtD,GACE,EACP,KAAC,eAAe,CAAC,IAAI,IAAC,OAAO,kBACzB,KAAC,WAAW,IAAC,SAAS,EAAC,gEAAgE,GAAG,GACvE,IACD,IACxB,EAEL,WAAW,KAAK,SAAS,IAAI,WAAW,KAAK,IAAI,IAAI,CAClD,cAAK,EAAE,EAAE,aAAa,EAAE,SAAS,EAAC,4BAA4B,YACzD,WAAW,GACV,CACT,EAEA,QAAQ,IAAI,CACT,eAAM,EAAE,EAAE,OAAO,EAAE,SAAS,EAAC,SAAS,eAAW,QAAQ,YACpD,aAAa,GACX,CACV,EAED,KAAC,eAAe,CAAC,MAAM,cACnB,MAAC,eAAe,CAAC,OAAO,IACpB,QAAQ,EAAC,QAAQ,EACjB,UAAU,EAAE,CAAC,EACb,gBAAgB,EAAE,2BAA2B,EAC7C,SAAS,EAAC,+VAA+V,aAEzW,cAAK,SAAS,EAAC,iCAAiC,YAC5C,gBACI,GAAG,EAAE,WAAW,gBACJ,QAAQ,CAAC,aAAa,EAClC,KAAK,EAAE,WAAW,EAClB,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAChB,cAAc,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,EAEtC,oBAAoB,EAAE,CAAC,KAAK,EAAE,EAAE,CAC5B,KAAK,CAAC,eAAe,EAAE,EAE3B,gBAAgB,EAAE,CAAC,KAAK,EAAE,EAAE;oCACxB,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;wCACzB,KAAK,CAAC,eAAe,EAAE,CAAA;oCAC3B,CAAC;gCACL,CAAC,EACD,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE;oCACjB,IAAI,KAAK,CAAC,GAAG,KAAK,QAAQ,EAAE,CAAC;wCACzB,KAAK,CAAC,eAAe,EAAE,CAAA;oCAC3B,CAAC;gCACL,CAAC,EACD,WAAW,EAAE,QAAQ,CAAC,iBAAiB,EACvC,SAAS,EAAC,8PAA8P,GAC1Q,GACA,EACN,cAAK,SAAS,EAAC,mIAAmI,YAC9I,KAAC,eAAe,CAAC,QAAQ,IAAC,SAAS,EAAC,KAAK,YACpC,eAAe,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAC1B,eAAe,CAAC,GAAG,CACf,CAAC,EAAE,MAAM,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CACxB,MAAC,eAAe,CAAC,IAAI,IAEjB,KAAK,EAAE,UAAU,EACjB,aAAa,EAAE,GAAG,EAAE;wCAChB,IAAI,QAAQ,EAAE,CAAC;4CACX,cAAc,CAAC,OAAO,GAAG,IAAI,CAAA;wCACjC,CAAC;oCACL,CAAC,EACD,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE;wCACjB,IACI,QAAQ;4CACR,CAAC,KAAK,CAAC,GAAG,KAAK,OAAO;gDAClB,KAAK,CAAC,GAAG,KAAK,GAAG,CAAC,EACxB,CAAC;4CACC,cAAc,CAAC,OAAO,GAAG,IAAI,CAAA;wCACjC,CAAC;oCACL,CAAC,EACD,SAAS,EAAC,qTAAqT,aAE/T,eAAM,SAAS,EAAC,8DAA8D,YACzE,QAAQ,CAAC,CAAC,CAAC,CACR,cAAc,CAAC,IAAI,CACf,CAAC,KAAK,EAAE,EAAE,CACN,oBAAoB,CAChB,MAAM,CAAC,KAAK,EACZ,KAAK,CACR,CACR,IAAI,CACD,KAAC,KAAK,IAAC,SAAS,EAAC,SAAS,GAAG,CAChC,CACJ,CAAC,CAAC,CAAC,CACA,KAAC,eAAe,CAAC,aAAa,cAC1B,KAAC,KAAK,IAAC,SAAS,EAAC,SAAS,GAAG,GACD,CACnC,GACE,EACP,KAAC,eAAe,CAAC,QAAQ,cACrB,gBAAM,SAAS,EAAC,+BAA+B,aAC3C,eAAM,SAAS,EAAC,oBAAoB,YAC/B,MAAM,CAAC,KAAK,GACV,EACN,MAAM,CAAC,SAAS,IAAI,CACjB,eAAM,SAAS,EAAC,wFAAwF,YACnG,MAAM,CAAC,SAAS,GACd,CACV,IACE,GACgB,KA9CtB,UAAU,CA+CI,CAC1B,CACJ,CACJ,CAAC,CAAC,CAAC,CACA,cAAK,SAAS,EAAC,wLAAwL,YAClM,WAAW,CAAC,IAAI,EAAE;wCACf,CAAC,CAAC,QAAQ,CAAC,SAAS;wCACpB,CAAC,CAAC,cAAc,IAAI,QAAQ,CAAC,SAAS,GACxC,CACT,GACsB,GACzB,IACgB,GACL,IACN,CAC1B,CAAA;AACL,CAAC"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import type { InvalidEvent, KeyboardEvent, Ref } from 'react';
|
|
2
|
+
import { type SelectLocale, type SelectMessages } from '../i18n.js';
|
|
3
|
+
import type { Option } from '../types.js';
|
|
4
|
+
export interface UseSelectLogicOptions<TValue> {
|
|
5
|
+
id?: string;
|
|
6
|
+
name?: string;
|
|
7
|
+
options: ReadonlyArray<Option<TValue>>;
|
|
8
|
+
selectedValues: ReadonlyArray<TValue>;
|
|
9
|
+
multiple: boolean;
|
|
10
|
+
required?: boolean;
|
|
11
|
+
externalError?: string | null;
|
|
12
|
+
disabled?: boolean;
|
|
13
|
+
readOnly?: boolean;
|
|
14
|
+
triggerRef?: Ref<HTMLButtonElement>;
|
|
15
|
+
minSelection?: number;
|
|
16
|
+
maxSelection?: number;
|
|
17
|
+
locale?: SelectLocale;
|
|
18
|
+
messages?: Partial<SelectMessages>;
|
|
19
|
+
isOptionEqualToValue?: (optionValue: TValue, value: TValue) => boolean;
|
|
20
|
+
onSelectValue: (value: TValue) => void;
|
|
21
|
+
}
|
|
22
|
+
export default function useSelectLogic<TValue>({ id, options, selectedValues, multiple, required, externalError, disabled, readOnly, triggerRef, minSelection, maxSelection, locale, messages: providedMessages, isOptionEqualToValue: isOptionEqualToValueProp, onSelectValue, }: UseSelectLogicOptions<TValue>): {
|
|
23
|
+
ref: {
|
|
24
|
+
trigger: (node: HTMLButtonElement | null) => void;
|
|
25
|
+
searchInput: import("react").RefObject<HTMLInputElement | null>;
|
|
26
|
+
validationInput: import("react").RefObject<HTMLInputElement | null>;
|
|
27
|
+
};
|
|
28
|
+
state: {
|
|
29
|
+
messages: SelectMessages;
|
|
30
|
+
triggerId: string;
|
|
31
|
+
labelId: string;
|
|
32
|
+
descriptionId: string;
|
|
33
|
+
errorId: string;
|
|
34
|
+
open: boolean;
|
|
35
|
+
searchValue: string;
|
|
36
|
+
optionEntries: {
|
|
37
|
+
option: Option<TValue>;
|
|
38
|
+
radixValue: string;
|
|
39
|
+
}[];
|
|
40
|
+
filteredOptions: {
|
|
41
|
+
option: Option<TValue>;
|
|
42
|
+
radixValue: string;
|
|
43
|
+
}[];
|
|
44
|
+
selectedEntries: {
|
|
45
|
+
option: Option<TValue>;
|
|
46
|
+
radixValue: string;
|
|
47
|
+
}[];
|
|
48
|
+
selectedRadixValue: string;
|
|
49
|
+
hasError: boolean;
|
|
50
|
+
resolvedError: string | null;
|
|
51
|
+
hasLeftIcon: boolean;
|
|
52
|
+
isOptionEqualToValue: (value1: any, value2: any) => boolean;
|
|
53
|
+
};
|
|
54
|
+
handler: {
|
|
55
|
+
handleInvalid: (event: InvalidEvent<HTMLInputElement>) => void;
|
|
56
|
+
handleValueChange: (nextRadixValue: string) => void;
|
|
57
|
+
handleOpenChange: (nextOpen: boolean) => void;
|
|
58
|
+
handleContentKeyDownCapture: (event: KeyboardEvent<HTMLDivElement>) => void;
|
|
59
|
+
setSearchValue: import("react").Dispatch<import("react").SetStateAction<string>>;
|
|
60
|
+
};
|
|
61
|
+
setter: {
|
|
62
|
+
setOpen: import("react").Dispatch<import("react").SetStateAction<boolean>>;
|
|
63
|
+
setSearchValue: import("react").Dispatch<import("react").SetStateAction<string>>;
|
|
64
|
+
setIsTouched: import("react").Dispatch<import("react").SetStateAction<boolean>>;
|
|
65
|
+
shouldKeepOpen: import("react").RefObject<boolean>;
|
|
66
|
+
};
|
|
67
|
+
};
|
|
68
|
+
export type SelectLogic = ReturnType<typeof useSelectLogic>;
|
|
69
|
+
//# sourceMappingURL=useSelect.logic.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useSelect.logic.d.ts","sourceRoot":"","sources":["../../src/Hooks/useSelect.logic.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,GAAG,EAAE,MAAM,OAAO,CAAA;AAC7D,OAAO,EAEH,KAAK,YAAY,EACjB,KAAK,cAAc,EACtB,MAAM,YAAY,CAAA;AACnB,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAA;AAEzC,MAAM,WAAW,qBAAqB,CAAC,MAAM;IACzC,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,aAAa,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAA;IACtC,cAAc,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IACrC,QAAQ,EAAE,OAAO,CAAA;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC7B,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,UAAU,CAAC,EAAE,GAAG,CAAC,iBAAiB,CAAC,CAAA;IACnC,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,MAAM,CAAC,EAAE,YAAY,CAAA;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC,cAAc,CAAC,CAAA;IAClC,oBAAoB,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,OAAO,CAAA;IACtE,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;CACzC;AAED,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,MAAM,EAAE,EAC3C,EAAE,EACF,OAAO,EACP,cAAc,EACd,QAAQ,EACR,QAAgB,EAChB,aAAa,EACb,QAAgB,EAChB,QAAgB,EAChB,UAAU,EACV,YAAY,EACZ,YAAY,EACZ,MAAa,EACb,QAAQ,EAAE,gBAAgB,EAC1B,oBAAoB,EAAE,wBAAwB,EAC9C,aAAa,GAChB,EAAE,qBAAqB,CAAC,MAAM,CAAC;;QA8MpB,OAAO,SArHJ,iBAAiB,GAAG,IAAI;QAsH3B,WAAW;QACX,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;+BAtEO,YAAY,CAAC,gBAAgB,CAAC;4CAMjB,MAAM;qCAUb,OAAO;6CAcC,aAAa,CAAC,cAAc,CAAC;;;;;;;;;EAyE5E;AAED,MAAM,MAAM,WAAW,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAA"}
|