Controls and states
Choose a complete sm, md, or lg control recipe, align components across a task, and preserve every interaction state.
Choose sm, md, or lg
Use md for the default compact operational screen and lg when touch comfort or task emphasis needs a larger target. Use sm for dense application chrome such as a title bar or a toolbar, where the control sits beside window furniture rather than inside the task. Do not mix sizes in one action row merely to express visual hierarchy; use intent and appearance for that.
Apply the complete size recipe
A size changes height, inline padding, gap, font size, and line height together.
| Size | Height | Padding | Gap | Type | Line height |
|---|---|---|---|---|---|
sm | 1.75rem | 0.5rem | 0.25rem | xs | 1rem |
md | 2rem | 0.75rem | 0.375rem | sm | 1.25rem |
lg | 2.5rem | 1rem | 0.5rem | sm | 1.25rem |
Align components across a task
Set the same uiSize on adjacent components. Field-based controls take it on TRField.Root, where the field recipe can coordinate label, description, error, and control.
Preserve interaction states
- Hover previews an available action; it is never the only cue.
- Pressed gives immediate input feedback. Selected persists a choice after input ends.
- Disabled removes an unavailable action from interaction and needs a visible explanation when the reason is not obvious.
- Focus remains visible for keyboard navigation and must not be clipped.
Use component props and state attributes rather than reproducing these states with unrelated colors.
Keep touch targets usable
Choose lg for touch-first tasks when the larger recipe fits. The sm recipe is below a comfortable touch target, so reserve it for pointer-driven chrome. If a compact visual is required elsewhere, add layout space around the control without shrinking its interactive box or placing targets too close together.
Implementation
Add the foundation tokens and component styles to your global stylesheet so the button and field share the same scale.
@import "@tinyrack/ui/core.css";
@import "@tinyrack/ui/components/button.css";
@import "@tinyrack/ui/components/field.css";
Then render the components.
import { TRButton } from '@tinyrack/ui/components/button';
import { TRField } from '@tinyrack/ui/components/field';
<TRField.Root uiSize="md"><TRField.Label>Rack name</TRField.Label><TRField.Control /></TRField.Root>
<TRButton appearance="solid" intent="primary" uiSize="md">Save rack</TRButton>
Override global --tinyrack-control-* metrics only for a product-wide density decision. Use documented component --tr-* variables for deliberate local exceptions; do not override height alone.