diff --git a/.changeset/purple-games-ring.md b/.changeset/purple-games-ring.md new file mode 100644 index 000000000..6b78a9dd9 --- /dev/null +++ b/.changeset/purple-games-ring.md @@ -0,0 +1,5 @@ +--- +'@qwik-ui/headless': patch +--- + +fix: select can now be reactively disabled diff --git a/apps/website/src/routes/docs/headless/select/snippets/select.css b/apps/website/src/routes/docs/headless/select/snippets/select.css index cadcd66d9..e5e125acd 100644 --- a/apps/website/src/routes/docs/headless/select/snippets/select.css +++ b/apps/website/src/routes/docs/headless/select/snippets/select.css @@ -10,7 +10,6 @@ width: 100%; height: 100%; border: 2px dotted hsla(var(--primary) / 1); - border-radius: calc(var (--border-radius) / 2); min-height: 44px; max-width: var(--select-width); padding-block: 0.5rem; @@ -39,7 +38,6 @@ background-color: hsl(var(--background)); padding: 0.5rem; border: 2px dotted hsla(var(--foreground) / 0.6); - border-radius: calc(var(--border-radius) / 2); max-width: var(--select-width); color: hsl(var(--foreground)); } @@ -93,7 +91,6 @@ [data-highlighted] { background-color: hsla(var(--primary) / 0.08); outline: 2px dotted hsla(var(--primary) / 1); - border-radius: calc(var(--border-radius) / 2); } [data-disabled] { diff --git a/packages/kit-headless/src/components/select/hidden-select.tsx b/packages/kit-headless/src/components/select/hidden-select.tsx index e82b2e81b..c6336facb 100644 --- a/packages/kit-headless/src/components/select/hidden-select.tsx +++ b/packages/kit-headless/src/components/select/hidden-select.tsx @@ -44,7 +44,7 @@ export const HHiddenNativeSelect = component$( multiple={context.multiple} tabIndex={-1} autocomplete={autoComplete} - disabled={context.disabled} + disabled={context.isDisabledSig.value ? true : undefined} required={context.required} name={context.name} // height is determined by its children diff --git a/packages/kit-headless/src/components/select/select-context.ts b/packages/kit-headless/src/components/select/select-context.ts index 3893d7f73..a17c659cb 100644 --- a/packages/kit-headless/src/components/select/select-context.ts +++ b/packages/kit-headless/src/components/select/select-context.ts @@ -22,6 +22,7 @@ export type SelectContext = { highlightedIndexSig: Signal; currDisplayValueSig: Signal; isListboxOpenSig: Signal; + isDisabledSig: Signal; localId: string; // user configurable @@ -38,11 +39,6 @@ export type SelectContext = { * Specifies that the user must select a value before submitting the form. See [MDN](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/select#required). */ required?: boolean; - - /** - * If `true`, prevents the user from interacting with the select. - */ - disabled?: boolean; }; export const groupContextId = createContextId('Select-Group'); diff --git a/packages/kit-headless/src/components/select/select-description.tsx b/packages/kit-headless/src/components/select/select-description.tsx index 490d1165d..c125a0a6c 100644 --- a/packages/kit-headless/src/components/select/select-description.tsx +++ b/packages/kit-headless/src/components/select/select-description.tsx @@ -8,7 +8,11 @@ export const HSelectDescription = component$((props: SelectDescriptionProps) => const descriptionId = `${context.localId}-description`; return ( -
+
); diff --git a/packages/kit-headless/src/components/select/select-label.tsx b/packages/kit-headless/src/components/select/select-label.tsx index 05f419746..103de50fa 100644 --- a/packages/kit-headless/src/components/select/select-label.tsx +++ b/packages/kit-headless/src/components/select/select-label.tsx @@ -6,7 +6,7 @@ export const HSelectLabel = component$((props: PropsOf<'div'>) => { const labelId = `${context.localId}-label`; const handleClick$ = $(() => { - if (context.disabled) return; + if (context.isDisabledSig.value) return; context.triggerRef.value?.focus(); }); @@ -17,7 +17,7 @@ export const HSelectLabel = component$((props: PropsOf<'div'>) => { return (
& InternalSelectProps const initialLoadSig = useSignal(true); const highlightedItemRef = useSignal(); + const isDisabledSig = useSignal(disabled ?? false); const context: SelectContext = { itemsMapSig, @@ -181,7 +182,7 @@ export const HSelectImpl = component$ & InternalSelectProps multiple, name, required, - disabled, + isDisabledSig, }; useContextProvider(SelectContextId, context); @@ -281,7 +282,7 @@ export const HSelectImpl = component$ & InternalSelectProps }); useTask$(({ track }) => { - context.disabled = track(() => disabled); + isDisabledSig.value = track(() => disabled ?? false); }); return ( @@ -290,7 +291,7 @@ export const HSelectImpl = component$ & InternalSelectProps ref={rootRef} data-open={context.isListboxOpenSig.value ? '' : undefined} data-closed={!context.isListboxOpenSig.value ? '' : undefined} - data-disabled={context.disabled ? '' : undefined} + data-disabled={isDisabledSig.value ? '' : undefined} aria-controls={listboxId} aria-expanded={context.isListboxOpenSig.value} aria-haspopup="listbox" diff --git a/packages/kit-headless/src/components/select/select-trigger.tsx b/packages/kit-headless/src/components/select/select-trigger.tsx index 294dce161..dd8267022 100644 --- a/packages/kit-headless/src/components/select/select-trigger.tsx +++ b/packages/kit-headless/src/components/select/select-trigger.tsx @@ -118,11 +118,11 @@ export const HSelectTrigger = component$((props) => { onKeyDown$={[handleKeyDownSync$, handleKeyDown$, props.onKeyDown$]} data-open={context.isListboxOpenSig.value ? '' : undefined} data-closed={!context.isListboxOpenSig.value ? '' : undefined} - data-disabled={context.disabled ? '' : undefined} + data-disabled={context.isDisabledSig.value ? '' : undefined} aria-expanded={context.isListboxOpenSig.value} aria-labelledby={labelId} aria-describedby={descriptionId} - disabled={context.disabled} + disabled={context.isDisabledSig.value ? true : undefined} preventdefault:blur >