Skip to content

Commit ddc682a

Browse files
fix(select): get proper controlled props
1 parent 2bf4997 commit ddc682a

File tree

2 files changed

+26
-19
lines changed
  • apps/website/src/routes/docs/headless/select/examples
  • packages/kit-headless/src/components/select

2 files changed

+26
-19
lines changed

apps/website/src/routes/docs/headless/select/examples/controlled.tsx

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,26 +9,30 @@ import {
99
} from '@qwik-ui/headless';
1010
export default component$(() => {
1111
useStyles$(styles);
12-
const usersSig = useSignal<string[]>(['Tim', 'Ryan', 'Jim', 'Jessie', 'Abby']);
13-
const selectedVal = useSignal<string>('Ryan');
12+
const usersSig = ['Tim', 'Ryan', 'Jim', 'Jessie', 'Abby'];
13+
const selected = useSignal<string>('Ryan');
1414

1515
return (
1616
<>
17-
<Select bind:value={selectedVal} class="select">
17+
<Select
18+
onChange$={$((value: string) => {
19+
selected.value = value;
20+
})}
21+
bind:value={selected}
22+
class="select"
23+
>
1824
<SelectTrigger class="select-trigger">
1925
<SelectValue placeholder="Select an option" />
2026
</SelectTrigger>
2127
<SelectListbox class="select-listbox">
22-
{usersSig.value.map((user) => (
28+
{usersSig.map((user) => (
2329
<SelectOption class="select-option" key={user}>
2430
{user}
2531
</SelectOption>
2632
))}
2733
</SelectListbox>
2834
</Select>
29-
<button onClick$={$(() => (selectedVal.value = 'Jessie'))}>
30-
Click me to change val!
31-
</button>
35+
<p>Your favorite user is: {selected.value}</p>
3236
</>
3337
);
3438
});

packages/kit-headless/src/components/select/select.tsx

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import SelectContextId from './select-context';
1414
import { Opt } from './select-inline';
1515
import { isBrowser } from '@builder.io/qwik/build';
1616

17-
export type SelectProps = PropsOf<'div'> & {
17+
export type SelectProps = Omit<PropsOf<'div'>, 'onChange$'> & {
1818
value?: string;
1919
'bind:value'?: Signal<string>;
2020

@@ -24,7 +24,7 @@ export type SelectProps = PropsOf<'div'> & {
2424
// when a value is passed, we check if it's an actual option value, and get its index at pre-render time.
2525
_valuePropIndex?: number | null;
2626

27-
onChange$?: QRL<() => void>;
27+
onChange$?: QRL<(value: string) => void>;
2828
onOpenChange$?: QRL<() => void>;
2929

3030
scrollOptions?: ScrollIntoViewOptions;
@@ -80,7 +80,7 @@ export const SelectImpl = component$<SelectProps>((props) => {
8080
useTask$(async function onChangeTask({ track }) {
8181
track(() => selectedIndexSig.value);
8282
if (isBrowser) {
83-
await props.onChange$?.();
83+
await props.onChange$?.(optionsSig.value[selectedIndexSig.value!].value);
8484
}
8585
});
8686

@@ -108,14 +108,17 @@ export const SelectImpl = component$<SelectProps>((props) => {
108108
useContextProvider(SelectContextId, context);
109109

110110
return (
111-
<div
112-
role="combobox"
113-
ref={rootRef}
114-
data-open={context.isListboxOpenSig.value ? '' : undefined}
115-
data-closed={!context.isListboxOpenSig.value ? '' : undefined}
116-
{...props}
117-
>
118-
<Slot />
119-
</div>
111+
<>
112+
{/* @ts-expect-error Qwik expects onChange$ types */}
113+
<div
114+
role="combobox"
115+
ref={rootRef}
116+
data-open={context.isListboxOpenSig.value ? '' : undefined}
117+
data-closed={!context.isListboxOpenSig.value ? '' : undefined}
118+
{...props}
119+
>
120+
<Slot />
121+
</div>
122+
</>
120123
);
121124
});

0 commit comments

Comments
 (0)