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,
NumberInput,
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' />
<NumberInput value={12.5} onChange={(value) => console.log(value)} aria-label='Amount' />
<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
NumberInputowned spinbutton compositionnumber | nullroot, group, input, prefix, suffix, step, description, errordisabled, invalid, readonly, focused where documented
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.

NumberInput keeps locale-aware numeric edit text behind a controlled number | null boundary. Its public contract does not expose a formatter, renderer, or native event type.

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.

Wrap one focusable control with Tooltip to show supplementary, non-interactive content on hover or keyboard focus:

import { Tooltip } from '@cratis/components/Common';
<Tooltip content={<span>Save the current changes</span>} position='right'>
<button type='button'>Save</button>
</Tooltip>

content accepts a React node, including text, elements, and the number 0. undefined, null, either boolean (true or false), and an empty string disable the tooltip. Keep tooltip content non-interactive: an ARIA tooltip is not focusable, so links and buttons inside it cannot be used reliably. Put interactive content in a Dialog or an inline region instead. Button and IconButton retain their text-only tooltip prop.

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, 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.