99-reference/component-vocabulary.md
Component vocabulary
Component vocabulary
This file defines the global public vocabulary for Vroq v02 components.
Use this file as the source of truth when creating, refactoring, or documenting components.
The goal is to make component APIs easy to remember, easy to validate, and easy for LLMs to generate correctly.
Main rule
All public component APIs should start with a props object.
Allowed public call shapes:
Component({ ...props })
Component({ ...props }, ...children)
Do not introduce new public positional signatures such as:
Component(text, props)
Component(label, onClick, props)
Component(binding, props)
Those older patterns are harder to document and easier for LLMs to misuse.
Shared public prop categories
These categories define the common vocabulary that components should reuse whenever possible.
- common props
- content props
- interaction props
- visual props
- state props
- layout props
- accessibility props
- composition props
Not every component needs every category.
The rule is: prefer an existing vocabulary word before inventing a new prop name.
1. Common props
Use these across most components when relevant:
classclassNamestyleasidtitle
Rules
classandclassNameare accepted aliases when class-based styling is neededstyleis the escape hatch for local one-off stylingaschanges the rendered element when the component supports itidis allowed for DOM identity and labelingtitleshould only be used for semantic titles or the DOM title attribute when that meaning is clear
2. Content props
Use these names for visible content.
text— generic text content for text-like primitiveslabel— action label or form control labeltitle— semantic title of a card, modal, section, or compound widgetsubtitle— supporting title textmessage— body message for alerts, dialogs, and feedbackplaceholder— input placeholder texthelper— helper text for an input or fielderror— error message content for a field or feedback componentsuccess— success message content for a field or feedback componenticon— icon content or icon node
Rules
- use
textfor generic display text primitives such asText - use
labelfor clickable or interactive labels such asButton,Checkbox, and menu-like items - use
titleandsubtitleonly when the component has meaningful title structure - do not invent near-synonyms like
captionText,btnText, orheadingTextunless the component truly needs a distinct semantic role
3. Interaction props
Use these names for controlled behavior and callbacks.
onClickonChangeonOpenChangeonCloseonFocusonBluronInputonSelectonSubmit
Controlled value rules
Prefer these names:
value+onChangechecked+onChangeopen+onOpenChange
Rules
- use
valuefor controlled selection or text-like state - use
checkedfor boolean input state - use
openfor overlays and disclosure state - prefer
onChangeover custom callback names when the action is fundamentally a value update - use
onClickfor button-like immediate actions
4. Visual props
These define the shared design-system vocabulary.
tonevariantsizeemphasissurfaceshapeshadowborder
Recommended meanings
tone— semantic intent such asneutral,primary,success,warning,danger,infovariant— presentation mode such assolid,soft,outline,ghost,plainsize— scale such asxs,sm,md,lg,xlemphasis— relative visual weight when a family uses itsurface— surface style such asbase,raised,sunken,overlayshape— corner or silhouette style such assquare,rounded,pillshadow— shadow preset name or boolean enablementborder— border preset name or boolean enablement
Rules
- prefer these words across all families when possible
- do not create family-local synonyms unless truly necessary
- if a component needs a new visual prop, it must be justified and documented
5. State props
Use these words when a component exposes a visible or interactive state.
disabledloadingreadOnlyselectedactiveinvalidrequiredstate
Rules
- prefer booleans like
disabled,loading,readOnly,selected, andactivewhen the state is binary - use
stateonly when the family truly needs a named multi-state value such asdefault,error,success - do not mix
state="disabled"withdisabled={true}in the same family unless there is a strong reason
6. Layout props
Use these for container-like and layout-aware components.
gappadalignjustifywrapblockgrowinline
Rules
gapcontrols spacing between childrenpadcontrols internal padding when a component family uses named padding sizesalignandjustifyshould follow flex-style meaningswrapcontrols flex wrapping behaviorblockmeans the component should take full available row width when that concept appliesgrowmeans the component should expand in flexible layouts when that concept appliesinlinemeans inline rendering where relevant
7. Accessibility props
These are not Vroq-specific, but components should preserve them clearly.
aria-labelaria-labelledbyaria-describedbyrole
Rules
- do not hide or rename standard accessibility props
- icon-only interactive components should usually require an accessible label
8. Composition rules
Container components
Container and layout components may take positional children after the props object:
Card({ pad: "md" }, childA, childB)
VStack({ gap: "lg" }, childA, childB)
Non-container components
Leaf and widget components should use named content props instead of positional content.
Good:
Text({ text: "Hello" })
Button({ label: "Save", onClick })
Checkbox({ checked, onChange, label: "Done" })
Avoid:
Text("Hello")
Button("Save", onClick)
Checkbox(binding, { label: "Done" })
9. Family guidance
Typography family
Prefer:
texttonesizeweightaligntruncatelines
Action family
Prefer:
labelicononClicktonevariantsizedisabledloading
Input family
Prefer:
valueorcheckedonChangelabelplaceholderhelpererrorsuccessdisabledreadOnlyrequiredsizevariantstate
Surface and container family
Prefer:
titlesubtitletonevariantsurfacepadshadowborder
10. Migration rule for v02
When refactoring existing v02 components:
- keep behavior stable where practical
- move public APIs toward object-first props
- keep positional children only for container-like components
- update demo app examples to use the canonical API
- update docs to show only the canonical API
Final rule
When naming a prop, ask:
1. does an existing vocabulary word already fit? 2. is this prop name semantically clear? 3. will a fresh LLM guess this name correctly? 4. will this make docs shorter instead of longer?
If not, choose a better vocabulary word or simplify the API.