Guidelines
Composition
How to compose Stance components: compound parts, the asChild prop for router links, controlled and uncontrolled state, and extending styles safely.
Stance favours small parts that compose over large components with many props.
Compound components
Complex components are families of parts: Dialog, DialogTrigger, DialogContent, DialogTitle… The parent holds state and the parts render markup. You can reorder, omit or wrap parts without new props.
<Tabs defaultValue="templates">
<TabsList aria-label="Signature workspace">
<TabsTrigger value="templates">Templates</TabsTrigger>
<TabsTrigger value="users">Organisation users</TabsTrigger>
</TabsList>
<TabsContent value="templates">…</TabsContent>
<TabsContent value="users">…</TabsContent>
</Tabs>asChild
Triggers and actions accept asChild to render your element, such as a router link, with Stance behaviour and styling merged onto it. Props, handlers, refs and class names merge.
<Button asChild variant="outline">
<Link href="/dashboard/templates">View templates</Link>
</Button>Controlled and uncontrolled
Stateful components work both ways. Pass defaultValue/defaultOpen and let Stance manage state, or pass value/open with an on…Change handler to own it.
Extending
- Every component forwards its ref and spreads native attributes onto its root element.
classNamemerges with Stance classes. Style with tokens:var(--st-…).- Variants and state are
data-*attributes, so they are stable selectors for product-specific CSS. - Build product patterns by composing Stance parts inside your app; promote them to Stance when a second product needs them.