ControlField

ControlField combines a label, description, and a control (Switch, Checkbox, or Radio) into a single pressable row.

Basics

A controlled switch row — the whole row is a single tap target.

Loading demo…

import { useState } from 'react'; import { ControlField } from '@plocks/ui'; export function Demo() { const [enabled, setEnabled] = useState(true); return ( <ControlField label="Push notifications" description="Get notified when something happens" checked={enabled} onChange={setEnabled} /> ); }

Checkbox with validation

A consent row using the checkbox variant. When left unchecked the field shows an error message below the row.

Loading demo…

import { useState } from 'react'; import { ControlField } from '@plocks/ui'; export function Demo() { const [agreed, setAgreed] = useState(false); return ( <ControlField variant="checkbox" indicatorPosition="left" label="I agree to the Terms of Service" description="You must accept before continuing" required checked={agreed} onChange={setAgreed} error={!agreed ? 'This field is required' : undefined} /> ); }

Variants

Compare the switch, checkbox, and radio indicators inside the same pressable field row.

Loading demo…

import { Column, ControlField } from '@plocks/ui'; const variants = ['switch', 'checkbox', 'radio'] as const; export function Demo() { return ( <Column gap="sm" fullWidth> {variants.map(variant => ( <ControlField key={variant} variant={variant} label={`${variant} control`} description="Tap the row to change its value" defaultChecked={variant === 'switch'} /> ))} </Column> ); }

Custom control

Compose the row explicitly with ControlField.Indicator to drop in a custom control — here a warning-colored checkbox.

Loading demo…

import { useState } from 'react'; import { Block, Checkbox, ControlField } from '@plocks/ui'; export function Demo() { const [subscribed, setSubscribed] = useState(false); return ( <ControlField checked={subscribed} onChange={setSubscribed}> <Block style={{ flex: 1 }} fullWidth={false}> <ControlField.Label>Subscribe to newsletter</ControlField.Label> <ControlField.Description> One email a week, unsubscribe anytime </ControlField.Description> </Block> <ControlField.Indicator> <Checkbox color="warning" /> </ControlField.Indicator> </ControlField> ); }

Grouped surface

Wrap rows in ControlField.Group to get an iOS-style settings surface — a rounded, filled background with hairline dividers between rows. The group can carry an optional title and footer, and sets a shared size for its children.

Loading demo…

import { useState } from 'react'; import { ControlField } from '@plocks/ui'; export function Demo() { const [wifi, setWifi] = useState(true); const [bluetooth, setBluetooth] = useState(false); const [airplane, setAirplane] = useState(false); return ( <ControlField.Group variant="bordered" title="Connectivity" footer="Airplane mode disables all wireless radios." > <ControlField label="Wi-Fi" checked={wifi} onChange={setWifi} /> <ControlField label="Bluetooth" checked={bluetooth} onChange={setBluetooth} /> <ControlField label="Airplane mode" description="Turn off all connections" checked={airplane} onChange={setAirplane} /> </ControlField.Group> ); }
Scan to open this page on your phoneplocks.dev/ui/ControlField