primitives
primitives copied to clipboard
[Select] Not inheriting `disabled` from parent fieldset
Bug report
Hi,
I just noticed a small, but important issue with Select Primitive.
If you wrap it with a <fieldset disabled></fieldset> it'll not inherit the disabled attribute. This works like this with every other "form" primitive (radio group, switch, checkbox etc) so I'd also think it should be the same for Select.
Current Behavior
This works:
<Select.Root disabled>
(...)
</Select.Root>
This doesn't:
<fieldset disabled>
<Select.Root>
(...)
</Select.Root>
</fieldset>
Expected behavior
A select root to inherit disabled attribute from parent fieldset.
I should also add, that the underlying element gets marked as disabled properly, but you still can open the dialog and select values.
You can use css to remove the pointer events when the object is disabled, im using tailwindcss but you can do it with vanilla as well
<RadixSelect.Trigger className='disabled:pointer-events-none'>
You can use css to remove the pointer events when the object is disabled, im using tailwindcss but you can do it with vanilla as well
<RadixSelect.Trigger className='disabled:pointer-events-none'>
- The field is still keyboard accessible
cursor: not-alloweddoesn't work
I'm also running into this issue. I'm using Shadcn, which uses Radix's select implementation. One workaround is to keep track of whether the select is within a disabled fieldset or not. The disabled attribute can then be added to the button element, which will then behave as being properly disabled.
const ref = useRef<HTMLButtonElement>(null);
const isInDisabledFieldset = Boolean(ref.current?.closest("fieldset:disabled"));
return (
<Select.Root>
<Select.Trigger ref={ref} disabled={isInDisabledFieldset}>
</Select.Trigger>
</Select.Root>
);
I used @BrendanC23's great idea, but had to put the disabled prop on the Select.Root, still with the ref on the Select.Trigger, in order to make it work.
const ref = useRef<HTMLButtonElement>(null);
const isInDisabledFieldset = Boolean(ref.current?.closest("fieldset:disabled"));
return (
<Select.Root disabled={isInDisabledFieldset}>
<Select.Trigger ref={ref}>
</Select.Trigger>
</Select.Root>
);
#3174
I opened the PR for solving this issue! Check it out!
This doesn't seem to be limited to just Selects. A disabled fieldset should disable all descendant form controls, which includes <button>s in general:
<fieldset disabled>
<button onClick={...}>Btn</button> {/* ✅ Native behavior: Can't be interacted with */}
</fieldset>
But e.g. DropdownMenuTriggers aren't properly disabled (just like SelectTrigger):
<fieldset disabled>
<DropdownMenu.Root>
<DropdownMenu.Trigger asChild>
<button>Trigger</button> {/* ❌ Can be clicked to open the dropdown */}
</DropdownMenu.Trigger>
<DropdownMenu.Portal>
<DropdownMenu.Content>...</DropdownMenu.Content>
</DropdownMenu.Portal>
</DropdownMenu.Root>
</fieldset>
But CollapsibleTriggers are disabled for some reason:
<fieldset disabled>
<Collapsible.Root>
<Collapsible.Trigger asChild>
<button>Trigger</button> {/* ✅ Can't be interacted with */}
</Collapsible.Trigger>
<Collapsible.Content>...</Collapsible.Content>
</Collapsible.Root>
</fieldset>
I haven't checked other trigger components, I just noticed the disparity between these two.