Skip to content

Commit e30ae71

Browse files
feat: select improvements
1 parent 6d171ba commit e30ae71

File tree

2 files changed

+36
-28
lines changed

2 files changed

+36
-28
lines changed

app/components/ui/select.stories.tsx

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -111,12 +111,17 @@ export const AllowCustomValue = () => {
111111
const [bear, setBear] = useState<Bear | null>(null);
112112

113113
return (
114-
<Select
115-
allowCustomValue
116-
options={astrobears}
117-
value={bear}
118-
onChange={(v) => setBear(v)}
119-
/>
114+
<div className="flex flex-col gap-2">
115+
<Select
116+
allowCustomValue
117+
options={astrobears}
118+
value={bear}
119+
onChange={(v) => setBear(v)}
120+
/>
121+
<div className="text-sm">
122+
Selected value: <pre>{JSON.stringify(bear)}</pre>
123+
</div>
124+
</div>
120125
);
121126
};
122127

@@ -174,27 +179,16 @@ export const IsError = () => {
174179
return (
175180
<Select
176181
options={astrobears}
177-
invalid
182+
inputProps={{ 'aria-invalid': true }}
178183
value={bear}
179184
onChange={(v) => setBear(v)}
180185
/>
181186
);
182187
};
183188

184-
export const Creatable = () => {
189+
export const Customization = () => {
185190
const [bear, setBear] = useState<Bear | null>(null);
186191

187-
return (
188-
<Select
189-
options={astrobears}
190-
allowCustomValue
191-
value={bear}
192-
onChange={(v) => setBear(v)}
193-
/>
194-
);
195-
};
196-
197-
export const Customization = () => {
198192
return (
199193
<Select
200194
options={astrobears}
@@ -211,20 +205,26 @@ export const Customization = () => {
211205
),
212206
inputClassName: cn('data-[state=open]:bg-[#C0FFEE]'),
213207
}}
208+
value={bear}
209+
onChange={(v) => setBear(v)}
214210
renderEmpty={(search) => (
215-
<div className="bg-negative-100">
216-
This is empty and your search is {search}
211+
<div className="flex h-20 items-center justify-center text-sm text-muted-foreground">
212+
This is empty and your search is "{search}"
217213
</div>
218214
)}
219215
/>
220216
);
221217
};
222218

223-
const lotsOfOptions = Array.from({ length: 100_000 }, () => ({
219+
const lotsOfOptions = Array.from({ length: 1_000 }, () => ({
224220
label: `${faker.person.firstName()} ${faker.person.lastName()}`,
225221
id: window.crypto.randomUUID(),
226222
}));
227223

228224
export const LotsOfOptions = () => {
229-
return <Select options={lotsOfOptions} />;
225+
const [bear, setBear] = useState<Bear | null>(null);
226+
227+
return (
228+
<Select options={lotsOfOptions} value={bear} onChange={(v) => setBear(v)} />
229+
);
230230
};

app/components/ui/select.tsx

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export const Select = <TValue extends TValueBase>({
4141
withClearButton,
4242
inputProps,
4343
size,
44-
placeholder = 'Select...', // TODO Translation
44+
placeholder = 'Select...', // TODO)) Translation
4545
options,
4646
renderEmpty,
4747
renderOption,
@@ -69,6 +69,14 @@ export const Select = <TValue extends TValueBase>({
6969
onChange?.(value);
7070
};
7171

72+
/**
73+
* On close, reset the search and items so they are back to the original state
74+
*/
75+
const handleOnClose = () => {
76+
setSearch('');
77+
setItems(options);
78+
};
79+
7280
const ui = getUiState((set) => {
7381
if (items.length === 0 && allowCustomValue && search.length > 0) {
7482
return set('create-search', { search });
@@ -98,7 +106,7 @@ export const Select = <TValue extends TValueBase>({
98106
immediate
99107
value={value ?? null}
100108
onChange={(v) => handleOnValueChange(v)}
101-
onClose={() => setSearch('')}
109+
onClose={handleOnClose}
102110
{...props}
103111
>
104112
<div className="relative">
@@ -142,7 +150,7 @@ export const Select = <TValue extends TValueBase>({
142150
className="absolute z-10 mt-1 w-(--input-width) overflow-auto rounded-md bg-white p-1 shadow empty:invisible dark:bg-neutral-900"
143151
>
144152
{ui
145-
.match('empty', () => <div className="p-4">No results found</div>)
153+
.match('empty', () => <div className="p-4">No results found</div>) // TODO)) Translation
146154
.match('empty-override', ({ renderEmpty }) => renderEmpty(search))
147155
.match('create-search', ({ search }) => (
148156
<ComboboxOption value={{ id: search, label: search }}>
@@ -154,13 +162,13 @@ export const Select = <TValue extends TValueBase>({
154162
)
155163
.match('default', () =>
156164
items.map((item) => (
157-
<HeadlessComboboxOption
165+
<ComboboxOption
158166
key={item.id}
159167
value={item}
160168
disabled={item.disabled}
161169
>
162170
{item.label}
163-
</HeadlessComboboxOption>
171+
</ComboboxOption>
164172
))
165173
)
166174
.exhaustive()}

0 commit comments

Comments
 (0)