Checkbox
A yes or no that takes effect when the form is saved.
Preview
tsx
import { state } from '@kerf-js/core'import { Checkbox } from '@kerf-js/veneer'export function Basic() { const on = state(true) return ( <Checkbox checked={on.value} onChange={( e: Event & { currentTarget: HTMLInputElement }, ) => (on.value = e.currentTarget.checked)} > Deploy on push </Checkbox> )}Installation
npm install @kerf-js/veneerTry it
Change the controls: the preview and its code update together. The address keeps what you set, so you can link to it.
Live preview
Controls
Codeupdates as you change the controls
import { Checkbox } from '@kerf-js/veneer'<Checkbox checked>Deploy on push</Checkbox>Usage
tsx
import { Checkbox } from '@kerf-js/veneer'<Checkbox>Deploy on push</Checkbox>With a hint
A checkbox's hint is a quieter second line under its label.
tsx
import { state } from '@kerf-js/core'import { Checkbox } from '@kerf-js/veneer'export function Hint() { const on = state(false) return ( <Checkbox checked={on.value} hint="Failed checks stop the deploy." onChange={( e: Event & { currentTarget: HTMLInputElement }, ) => (on.value = e.currentTarget.checked)} > Require checks to pass </Checkbox> )}States
A checkbox can be checked, indeterminate or disabled, and can show a hint or an error.
tsx
import { Checkbox, Grid } from '@kerf-js/veneer'import { Stack, Text } from '@kerf-js/veneer'export function States() { return ( <Grid cols={3} gap="group" > <Cell name="Off"> <Checkbox>Deploy on push</Checkbox> </Cell> <Cell name="On"> <Checkbox checked>Deploy on push</Checkbox> </Cell> <Cell name="Part of a set"> <Checkbox indeterminate>Deploy on push</Checkbox> </Cell> <Cell name="Hint"> <Checkbox hint="Every push to main goes live."> Deploy on push </Checkbox> </Cell> <Cell name="Invalid"> <Checkbox error="Accept this to carry on."> Deploy on push </Checkbox> </Cell> <Cell name="Disabled"> <Checkbox checked disabled > Deploy on push </Checkbox> </Cell> </Grid> )}const Cell = ({ name, children,}: { name: string children?: unknown}) => ( <Stack gap="tight"> <Text role="caption" subtle > {name} </Text> {children} </Stack>)Select all
The parent shows a dash while only some are on.
tsx
import { derived, state } from '@kerf-js/core'import { Checkbox, Stack } from '@kerf-js/veneer'export function SelectAll() { const on = state(['Deploy failed', 'Uptime drops']) const flip = (name: string) => (on.value = on.value.includes(name) ? on.value.filter((n) => n !== name) : [...on.value, name]) const all = derived( () => on.value.length === EVENTS.length, ) return ( <Stack gap="tight"> <Checkbox checked={all.value} indeterminate={on.value.length > 0 && !all.value} onChange={() => (on.value = all.value ? [] : EVENTS) } > Email me about </Checkbox> <Stack gap="tight" style={ 'padding-inline-start:' + 'var(--veneer-space-group)' } > {EVENTS.map((name) => ( <Checkbox key={name} checked={on.value.includes(name)} onChange={() => flip(name)} > {name} </Checkbox> ))} </Stack> </Stack> )}const EVENTS = [ 'Deploy failed', 'Deploy finished', 'Uptime drops', 'Budget reached',]Confirm before deleting
Press Delete without ticking it.
tsx
import { state } from '@kerf-js/core'import { Button, Checkbox, Row, Stack, Text} from '@kerf-js/veneer'export function Confirm() { const sure = state(false) const tried = state(false) const gone = state(false) const remove = () => { tried.value = true if (sure.value) gone.value = true } return ( <Stack gap="group"> <Text> {gone.value ? 'reports was deleted.' : 'Deleting reports removes its 41 deploys ' + 'and all its logs.'} </Text> <Checkbox checked={sure.value} error={ tried.value && !sure.value ? 'Tick this first.' : undefined } onChange={( e: Event & { currentTarget: HTMLInputElement }, ) => (sure.value = e.currentTarget.checked)} > I understand this can't be undone </Checkbox> <Row justify="end"> <Button tone="critical" onClick={remove} > Delete project </Button> </Row> </Stack> )}When to use
Use it for
- An option inside a form with a Save button
- Picking any number from a list
Reach for something else
- Switch, when it applies straight away
- RadioGroup, when exactly one can be chosen
Accessibility
- Space
- Toggles
- It is a real checkbox, and the whole label can be pressed.
indeterminatesets the real property, so it is announced as mixed.
API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
checked | boolean | false | Whether it is on. You own this value. |
indeterminate | boolean | false | Shows a dash: some of a set are on. |
hint | unknown | — | A short line under the label. |
error | unknown | — | Replaces the hint and marks it invalid. |
children | unknown | — | What it contains. |
Parts
Every element carries a stable name, so you can style it from your own CSS: [data-scope="checkbox"] [data-part="control"]
controlmarklabelhint
RelatedSwitchRadio groupChip