UNPKG

alouette

Version:

A modern, customizable design system built on top of NativeWind v5 with configurable defaults

186 lines (131 loc) 5.63 kB
--- name: alouette-typography description: > Style alouette Text and Paragraph entirely via className: combined font family+weight utilities (font-body, font-body-bold, font-body-extrabold, font-heading*, font-mono*), Tailwind text-* sizes, and semantic color tokens (text-sharp, text-muted, text-accent, text-on-accent). No variant props. Load when rendering any text; avoids font-bold and raw color classes. type: core library: alouette requires: - alouette-theming sources: - "christophehurpeau/alouette:packages/alouette/src/ui/primitives/Text.tsx" - "christophehurpeau/alouette:packages/alouette/src/ui/primitives/Text.stories.tsx" - "christophehurpeau/alouette:CLAUDE.md" --- This skill builds on alouette-theming. Read it first for the color token model. # alouette — Typography `Text` and `Paragraph` have no variant props — style them entirely with `className`. `Text` defaults to `font-body` + `text-sharp`, so plain body text needs no family or color class. `Paragraph` is `Text` with `role="paragraph"` (renders a `<p>` on web) and selectable text — a block of prose, not a generic text wrapper (see "Text vs Paragraph"). ## Setup ```tsx import { Text, Paragraph } from "alouette"; <Text className="font-heading-extrabold text-4xl">Title</Text> <Paragraph className="text-base">Body copy.</Paragraph> ``` ## Core Patterns ### Text vs Paragraph `Paragraph` means "this is prose": one or more sentences, in a `<p>`, selectable so the reader can copy them. Everything else is `Text` — a label, a heading, a stat, a table cell, a single value — even when it stands alone on its own line. A value with its own component keeps that component: a code fragment is `Code`, a code listing `CodeBlock`, a link `ExternalLinkText` / `LinkText`, a quotation `Blockquote` (which already wraps its text in a `Paragraph`). A `<p>` takes no block content, so a `Paragraph`'s children are inline only — `Text`, `Code`, `ExternalLinkText`. Nesting a `Paragraph`, a `View` or a `Surface` inside one is invalid DOM on web. ```tsx <Paragraph> Point the client at <Code>{endpointUrl}</Code>, then{" "} <ExternalLinkText size="sm" href={docsUrl} text="read the guide" />. </Paragraph> <Text className="text-sm text-muted">{endpointUrl}</Text> ``` ### Family + weight (one combined utility) Family and weight are a single utility — never a standalone `font-bold`: - `font-body`, `font-body-bold`, `font-body-extrabold` - `font-heading`, `font-heading-bold`, `font-heading-extrabold` - `font-mono`, `font-mono-bold`, `font-mono-extrabold` ```tsx <Text className="font-body-bold">Bold body</Text> <Text className="font-heading-extrabold text-2xl">Heading</Text> <Text className="font-mono text-sm text-muted">code()</Text> ``` ### Size (standard Tailwind, font-size only) `text-xs` 12 · `text-sm` 14 · `text-base` 16 · `text-lg` 18 · `text-xl` 24 · `text-2xl` 32 · `text-3xl` 40 · `text-4xl` 48 · `text-5xl` 64 · `text-6xl` 80. Pair `font-heading*` with `text-xl` (24px) or larger — the heading family is tuned for display sizes. For smaller emphasis, use `font-body-bold`. ### Color (semantic tokens) `text-sharp` (default) · `text-muted` · `text-accent` · `text-on-accent` (+ `-muted` variants). Accent color follows the nearest accent scope: ```tsx <Text accent="brand" className="text-accent"> Brand-colored </Text> ``` ## Common Mistakes ### MEDIUM Using Paragraph as a generic text wrapper A URL, a label, a stat or a heading is not prose: `role="paragraph"` announces a paragraph to a screen reader and emits a `<p>` that cannot legally hold the `View`/`Surface` such a value usually sits next to. Keep `Paragraph` for sentences; a value with its own component (`Code`, `CodeBlock`, `ExternalLinkText`) keeps that component. Source: packages/alouette/src/ui/primitives/Text.tsx ### HIGH Using font-bold instead of font-body-bold Wrong: ```tsx <Text className="font-bold text-base">Title</Text> ``` Correct: ```tsx <Text className="font-body-bold text-base">Title</Text> ``` On native, bold/extrabold are separate font files baked into the family utility. A standalone `font-bold` / `font-extrabold` / `font-normal` has no effect and is overridden — it only appears to work on web. Source: CLAUDE.md (Text styling); src/ui/primitives/Text.stories.tsx (Invalid) ### HIGH Using react-native Text instead of alouette Text Wrong: ```tsx import { Text } from "react-native"; <Text className="text-muted">Hi</Text>; ``` Correct: ```tsx import { Text } from "alouette"; <Text className="text-muted">Hi</Text>; ``` react-native's `Text` has no `font-body` default, no semantic color, and no `accent` prop, so it doesn't participate in theming. alouette's `Text` applies `font-body` + `text-sharp` and re-themes via `accent`. Source: packages/alouette/src/ui/primitives/Text.tsx ### MEDIUM Using a heading font below text-xl Wrong: ```tsx <Text className="font-heading-bold text-base">Section</Text> ``` Correct: ```tsx <Text className="font-heading-bold text-xl">Section</Text> ``` The heading family is tuned for display sizes (`text-xl` / 24px and up). Below that it looks off — use `font-body-bold` for small emphasized text instead. Source: scripts/build-css.ts (type scale); src/ui/primitives/Text.stories.tsx ### MEDIUM Coloring text with the raw Tailwind palette Wrong: ```tsx <Text className="text-black">Body</Text> ``` Correct: ```tsx <Text className="text-sharp">Body</Text> ``` `text-black` / `text-gray-500` ignore the theme and break dark mode; semantic tokens resolve per mode and accent. Source: CLAUDE.md (Color tokens)