Checkbox (Two-State)
Allows users to visually select an option by checking it.
I have read the README
import { component$, useSignal } from '@builder.io/qwik';
import { Checkbox } from '@qwik-ui/headless';
export default component$(() => {
const isCheckedSig = useSignal(false);
return (
<Checkbox.Root
bind:checked={isCheckedSig}
id="test"
class="flex items-center gap-3 border-2 border-black p-2"
>
<div class="flex h-[25px] w-[25px] items-center justify-center bg-slate-600">
<Checkbox.Indicator>✅</Checkbox.Indicator>
</div>
<p> I have read the README</p>
</Checkbox.Root>
);
});
Anatomy
Component | Description |
Checkbox.Root | Defines the component boundary and exposes its internal logic AND must wrap over all other parts |
Checkbox.Indicator | Wrapper that automatically shows its children when true and hides them when false |
Examples
Controlled Checkbox
To add reactive state, use the bind:checked
prop on the <Checkbox.Root />
component.
import { component$, useSignal } from '@builder.io/qwik';
import { Checkbox } from '@qwik-ui/headless';
export default component$(() => {
const initialVal1 = false;
const controlledSig1 = useSignal(initialVal1);
return (
<>
<div class="flex gap-8">
<div class="flex flex-col gap-3">
<Checkbox.Root
bind:checked={controlledSig1}
id="test"
class="flex items-center gap-3 border-2 border-black p-2 "
>
<Checkbox.Indicator class="flex h-[25px] w-[25px] items-center justify-center bg-slate-600">
✅
</Checkbox.Indicator>
Toggle Value
</Checkbox.Root>
</div>
</div>
</>
);
});
In the example below, the left checkbox starts as false, while the right checkbox starts as true.
The initial value was: false
The current value is: false
The initial value was: true
The current value is: true
import { component$, useSignal } from '@builder.io/qwik';
import { Checkbox } from '@qwik-ui/headless';
export default component$(() => {
const initialVal1 = false;
const controlledSig1 = useSignal(initialVal1);
const initialVal2 = true;
const controlledSig2 = useSignal(initialVal2);
return (
<>
<div class="flex gap-8">
<div class="flex flex-col gap-3">
<Checkbox.Root
bind:checked={controlledSig1}
id="test"
class="flex items-center gap-3 border-2 border-black p-2 "
>
<Checkbox.Indicator class="flex h-[25px] w-[25px] items-center justify-center bg-slate-600">
✅
</Checkbox.Indicator>
Toggle Value
</Checkbox.Root>
<p>The initial value was: {`${initialVal1}`}</p>
<p>The current value is: {`${controlledSig1.value}`}</p>
</div>
<div class="flex flex-col gap-3">
<Checkbox.Root
bind:checked={controlledSig2}
id="test"
class="flex items-center gap-3 border-2 border-black p-2 "
>
<Checkbox.Indicator class="flex h-[25px] w-[25px] items-center justify-center bg-slate-600">
✅
</Checkbox.Indicator>
Toggle Value
</Checkbox.Root>
<p>The initial value was: {`${initialVal2}`}</p>
<p>The current value is: {`${controlledSig2.value}`}</p>
</div>
</div>
</>
);
});
- Select All
- item 0
- item 1
import { component$ } from '@builder.io/qwik';
import { Checklist } from '@qwik-ui/headless';
export default component$(() => {
return (
<Checklist.Root initialStates={[false, false, false]}>
<Checklist.SelectAll class="flex items-center justify-center border-2 p-2">
<div class="flex items-center justify-center border-2 p-2">
<Checklist.ItemIndicator>✅</Checklist.ItemIndicator>
</div>{' '}
Select All
</Checklist.SelectAll>
{Array.from({ length: 2 }, (_, index) => {
const uniqueKey = `cl-${index}-${Date.now()}`;
return (
<Checklist.Item key={uniqueKey} _index={index}>
<div class="flex items-center justify-center border-2 p-2">
<Checklist.ItemIndicator>✅</Checklist.ItemIndicator>
</div>
{`item ${index}`}
</Checklist.Item>
);
})}
</Checklist.Root>
);
});
Customization & Caveats
You can apply CSS classes to any part of the component. Any valid HTML can be used as an icon, but children of the Checkbox Indicator are removed from the accessibility tree to prevent them from being added to the Checkbox Label.
Automatic Labeling
The Checkbox element is a div with the role of checkbox, so any text inside the Checkbox Root is interpreted as the checkbox label.
Text tags lose their semantic meaning. For example, an h1 tag is treated the same as a p tag. See this MDN section for more details.
API
Checkbox.Root
Component | Description |
bind:checked | Two-way data binding of the checkbox value to a user-defined signal |
checklist | When true, treats the checkbox as a tri-state and binds its value to all other checkboxes in the checklist |