Skip to content

Basic controls

The Common subpath provides native basic controls for ordinary React state and browser forms. They expose real element refs, standard native attributes, semantic value callbacks, stable parts, and canonical state attributes without an Arc command binding.

import {
Button,
Checkbox,
IconButton,
Radio,
Surface,
Switch,
TextArea,
TextInput,
} from '@cratis/components/Common';
<Surface as='section' aria-label='Preferences'>
<TextInput
name='displayName'
aria-label='Display name'
defaultValue='Sample User'
onChange={(value) => console.log(value)}
/>
<TextArea name='notes' aria-label='Notes' />
<Checkbox name='updates' value='email' label='Email updates' />
<Radio name='frequency' value='daily' label='Daily' />
<Switch name='notifications' value='enabled' label='Enable notifications' />
<IconButton icon={<span aria-hidden='true'>+</span>} aria-label='Add preference' />
<Button label='Save preferences' type='submit' />
</Surface>
ComponentNative element and refSemantic valueStable partsCanonical states
Buttonbutton / HTMLButtonElementNative click and form actionroot, spinner, icon, labeldisabled, loading, variant, tone, shape, size on root
IconButtonbutton / HTMLButtonElementUses Button click semanticsroot, spinner, icon, labeldisabled, loading on root
TextInputinput / HTMLInputElementstringrootdisabled, invalid, readonly
TextAreatextarea / HTMLTextAreaElementstringrootdisabled, invalid, readonly
Checkboxinput[type=checkbox] / HTMLInputElementbooleanroot, input, box, indicator, labelselected, disabled, invalid, readonly
Radioone input[type=radio] / HTMLInputElementboolean when checkedroot, input, box, indicator, labelselected, disabled, invalid, readonly
Switchinput[type=checkbox][role=switch] / HTMLInputElementbooleanroot, input, control, handle, labelselected, disabled, invalid, readonly
Surfacediv, section, or article / HTMLElementnonerootnone

IconButton requires aria-label and delegates to Button; it does not add another button or interaction layer. It accepts the same semantic variant, tone, shape, size, loading, and disabled props as Button.

TextInput accepts the native text-like types text, email, password, search, tel, and url. TextInput and TextArea preserve native controlled (value) and uncontrolled (defaultValue) behavior.

Radio represents exactly one native option. Give related options the same name; the browser owns grouping. Components does not add radio-group state or keyboard orchestration.

Each value control uses ChangeHandler<T>:

onChange?: (value: T, meta?: ChangeMeta) => void;

A user change supplies { source: 'user', nativeEvent }, where nativeEvent is the real browser Event. The optional second argument keeps a one-argument callback, including a React state setter, directly assignable.

The controls preserve name, value, form, checked, defaultChecked, value, and defaultValue on the real native element. Uncontrolled controls therefore submit and reset through browser form behavior.

HTML does not define native read-only behavior for checkboxes and radios. Checkbox, Radio, and Switch keep a read-only selected control enabled so its name and value still submit, expose the canonical data-readonly state, and prevent user toggling. Checkbox and Switch additionally expose supported aria-readonly semantics; native radio does not allow that ARIA attribute. Use disabled instead when the control must be excluded from submission.

For progress UI, use ProgressBar and its existing ProgressBarProps contract from @cratis/components/Display; Common does not define a second progress component.