Text

Body-text primitive with token-driven sans family and a size/tone/weight scale; polymorphic via `as`. Install Text from the VLLNT UI registry with the shadcn CLI.

Report a bug

Body-text primitive with token-driven sans family and a size/tone/weight scale; polymorphic via as. Part of the core family in VLLNT UI, it ships as a machine-readable registry entry — copy the source directly into your app with the shadcn CLI and own it, no runtime dependency on a component library.

Preview

Switch between light and dark to inspect the embedded Storybook preview.

Installation

Add Text to your project with the shadcn CLI. The source lands in your codebase, ready to adapt:

pnpm dlx shadcn@latest add https://ui.vllnt.ai/r/text.json

Source

import { createElement } from "react"; import { cva, type VariantProps } from "class-variance-authority"; import { cn } from "../../lib/utils"; /** * Body-text scale for the {@link Text} primitive. Exposed so consumers can * compose the same token-driven styles onto bespoke elements. */ export const textVariants = cva( "font-[family-name:var(--font-sans)] text-foreground", { defaultVariants: { size: "base", tone: "default", weight: "normal", }, variants: { size: { base: "text-[length:var(--font-size-body)] leading-[var(--line-height-body)]", caption: "text-[length:var(--font-size-caption)] leading-[var(--line-height-caption)]", lead: "text-[length:var(--font-size-body-lg)] leading-[var(--line-height-body-lg)]", small: "text-[length:var(--font-size-body-sm)] leading-[var(--line-height-body-sm)]", }, tone: { default: "", muted: "text-muted-foreground", }, weight: { medium: "font-medium", normal: "font-normal", semibold: "font-semibold", }, }, }, ); /** HTML element the {@link Text} primitive renders as. */ export type TextElement = "div" | "label" | "p" | "span"; /** Props for {@link Text}. */ export type TextProps = React.HTMLAttributes<HTMLElement> & VariantProps<typeof textVariants> & { as?: TextElement; ref?: React.Ref<HTMLElement>; }; /** * Body text whose family, scale, and weight come from theme-overridable tokens * (`--font-sans`, `--font-size-body*`). Polymorphic via `as`. Forwards `ref` to * the rendered element. * * Use `tone="muted"` on the default `background`; on `muted`/`card` surfaces the * muted foreground can fall below WCAG AA contrast for body text. * * @example * <Text size="lead" tone="muted">Intro copy</Text> */ const Text = ({ as = "p", className, ref, size, tone, weight, ...props }: TextProps) => createElement(as, { className: cn(textVariants({ size, tone, weight }), className), ref, ...props, }); Text.displayName = "Text"; export { Text };

Stories

Explore every variant and state in the interactive Storybook:

Preview

Switch between light and dark to inspect the embedded Storybook preview.

Dependencies

  • @vllnt/ui@^0.3.0
  • class-variance-authority