Documentation
Atoms

Text

The typography primitive other components wear through `render`, so a dialog title, a field label and a menu label never grow their own class.

npx shadcn@latest add @fragiola/text
Text
Gallery

What Text is for

A component part that needs a heading does not declare one — it wears Text.Heading through render, keeping the behaviour library's a11y wiring (the ids for aria-labelledby / aria-describedby) while taking Text's typography:

<DialogPrimitive.Title render={<Text.Heading as="h2" />} {...props} />

Dialog.Title, Field.Label and Menu.Label all resolve to a Text member this way. If any of them grows its own typography class, the composition rule has been broken. Seventeen title classes is exactly the duplication this project exists to remove.

Secondary text

The most-used token in the shadcn baseline (muted-foreground, 44 occurrences) maps to a role Fragiola deliberately lacks. The settled value is text-palette-accent/85. The architecture initially proposed accent/70, but OKLCH→WCAG measurement showed 70% fails AA (4.5:1) even on neutral surfaces. At 85%, accent clears AA on every neutral surface (surface + raised, base + soft) in both themes — worst case 4.71:1. Secondary text realistically appears only on neutral backgrounds; chromatic palettes use contrast for their text, not a muted variant.

Text.Clickable vs Clickable.Button

Text.Clickable is a textual link rendered as a button — inline, underlined on hover, no fill. Clickable.Button is a filled affordance with a fill strategy, a measure and a form. They are different jobs; do not merge them.

Parts

PartRenders
Heading<h1|h2|h3>, text-palette-contrast
Paragraph<p>, text-palette-contrast
Linkplain <a> — stitch a router link through render
Label<label>, block, semibold
Error<span> + palette-danger
Strong / Small / Highlight<strong> / <small> / <span>
Clickable<button>, inline textual link