Typography

A collection of styled text components for headings, body text, and inline elements.

Docs

Heading 1

Heading 2

Heading 3

Heading 4

Lead text — A larger, muted paragraph for introductions.

Regular paragraph with default styling. This text demonstrates how a standard paragraph looks with the typography system.

Large text — slightly bigger and bold.
Small text — fine print or captions.

Muted text — less prominent, for secondary info.

You can also use InlineCode for inline code snippets.

"A blockquote for quoting content or emphasizing a statement."
  • Unordered list item one
  • Unordered list item two
  • Unordered list item three
import {
  H1,
  H2,
  H3,
  H4,
  P,
  Lead,
  Large,
  Small,
  Muted,
  InlineCode,
  Blockquote,
  List,
} from "~/components/typography";

export default function TypographyBasicDemo() {
  return (
    <div class="space-y-4">
      <div>
        <H1>Heading 1</H1>
        <H2>Heading 2</H2>
        <H3>Heading 3</H3>
        <H4>Heading 4</H4>
      </div>
      <div>
        <Lead>Lead text — A larger, muted paragraph for introductions.</Lead>
      </div>
      <div>
        <P>
          Regular paragraph with default styling. This text demonstrates how a standard paragraph
          looks with the typography system.
        </P>
      </div>
      <div>
        <Large>Large text — slightly bigger and bold.</Large>
      </div>
      <div>
        <Small>Small text — fine print or captions.</Small>
      </div>
      <div>
        <Muted>Muted text — less prominent, for secondary info.</Muted>
      </div>
      <div>
        <P>
          You can also use <InlineCode>InlineCode</InlineCode> for inline code snippets.
        </P>
      </div>
      <Blockquote>"A blockquote for quoting content or emphasizing a statement."</Blockquote>
      <List>
        <li>Unordered list item one</li>
        <li>Unordered list item two</li>
        <li>Unordered list item three</li>
      </List>
    </div>
  );
}

Installation

CLI

Run the following command to add the component to your project:

npx @ark-preset/cli@latest add typography

Manual

Create the recipe file at src/components/recipes/typography.ts:

import { tv, type VariantProps } from "tailwind-variants";

export const typographyVariants = tv({
  slots: {
    h1: "scroll-m-20 text-4xl font-extrabold tracking-tight lg:text-5xl",
    h2: "scroll-m-20 pb-2 text-3xl font-semibold tracking-tight transition-colors first:mt-0",
    h3: "scroll-m-20 text-2xl font-semibold tracking-tight",
    h4: "scroll-m-20 text-xl font-semibold tracking-tight",
    p: "leading-7",
    lead: "text-xl text-muted-foreground",
    large: "text-lg font-semibold",
    small: "text-sm font-medium leading-none",
    muted: "text-sm text-muted-foreground",
    code: "relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm font-semibold",
    blockquote: "mt-6 border-l-2 border-border pl-6 italic text-muted-foreground",
    list: "my-6 ml-6 list-disc [&>li]:mt-2",
  },
});

export type TypographyVariants = VariantProps<typeof typographyVariants>;

Create the component file at src/components/typography/index.tsx:

import { splitProps, type Component } from "solid-js";
import { typographyVariants } from "../recipes/typography";
import { ark, type HTMLArkProps } from "@ark-ui/solid/factory";

const styles = typographyVariants();

type H1Props = HTMLArkProps<"h1">;
type H2Props = HTMLArkProps<"h2">;
type H3Props = HTMLArkProps<"h3">;
type H4Props = HTMLArkProps<"h4">;
type PProps = HTMLArkProps<"p">;
type LeadProps = HTMLArkProps<"p">;
type LargeProps = HTMLArkProps<"div">;
type SmallProps = HTMLArkProps<"small">;
type MutedProps = HTMLArkProps<"p">;
type InlineCodeProps = HTMLArkProps<"code">;
type BlockquoteProps = HTMLArkProps<"blockquote">;
type ListProps = HTMLArkProps<"ul">;

const H1: Component<H1Props> = (props) => {
  const [local, others] = splitProps(props, ["class"]);
  return <ark.h1 class={styles.h1({ class: local.class })} {...others} />;
};

const H2: Component<H2Props> = (props) => {
  const [local, others] = splitProps(props, ["class"]);
  return <ark.h2 class={styles.h2({ class: local.class })} {...others} />;
};

const H3: Component<H3Props> = (props) => {
  const [local, others] = splitProps(props, ["class"]);
  return <ark.h3 class={styles.h3({ class: local.class })} {...others} />;
};

const H4: Component<H4Props> = (props) => {
  const [local, others] = splitProps(props, ["class"]);
  return <ark.h4 class={styles.h4({ class: local.class })} {...others} />;
};

const P: Component<PProps> = (props) => {
  const [local, others] = splitProps(props, ["class"]);
  return <ark.p class={styles.p({ class: local.class })} {...others} />;
};

const Lead: Component<LeadProps> = (props) => {
  const [local, others] = splitProps(props, ["class"]);
  return <ark.p class={styles.lead({ class: local.class })} {...others} />;
};

const Large: Component<LargeProps> = (props) => {
  const [local, others] = splitProps(props, ["class"]);
  return <ark.div class={styles.large({ class: local.class })} {...others} />;
};

const Small: Component<SmallProps> = (props) => {
  const [local, others] = splitProps(props, ["class"]);
  return <ark.small class={styles.small({ class: local.class })} {...others} />;
};

const Muted: Component<MutedProps> = (props) => {
  const [local, others] = splitProps(props, ["class"]);
  return <ark.p class={styles.muted({ class: local.class })} {...others} />;
};

const InlineCode: Component<InlineCodeProps> = (props) => {
  const [local, others] = splitProps(props, ["class"]);
  return <ark.code class={styles.code({ class: local.class })} {...others} />;
};

const Blockquote: Component<BlockquoteProps> = (props) => {
  const [local, others] = splitProps(props, ["class"]);
  return <ark.blockquote class={styles.blockquote({ class: local.class })} {...others} />;
};

const List: Component<ListProps> = (props) => {
  const [local, others] = splitProps(props, ["class"]);
  return <ark.ul class={styles.list({ class: local.class })} {...others} />;
};

export {
  H1,
  H2,
  H3,
  H4,
  P,
  Lead,
  Large,
  Small,
  Muted,
  InlineCode,
  Blockquote,
  List,
  typographyVariants,
};

Note: Make sure your project has the Tailwind CSS theme variables set up (--background, --foreground, --ring, --border, etc.) or override the utility classes to match your design system.

Usage

Headings

Heading components from H1 through H4 for structured document titles.

The Quick Brown Fox

The Quick Brown Fox

The Quick Brown Fox

The Quick Brown Fox

import { H1, H2, H3, H4 } from "~/components/typography";

export default function TypographyHeadingsDemo() {
  return (
    <div class="space-y-4">
      <H1>The Quick Brown Fox</H1>
      <H2>The Quick Brown Fox</H2>
      <H3>The Quick Brown Fox</H3>
      <H4>The Quick Brown Fox</H4>
    </div>
  );
}

Body Text

Components for paragraphs, lead text, large, small, and muted copy.

Regular paragraph text with standard styling.

Lead paragraph for introducing content.

Large styled text.
Small styled text.

Muted secondary text.

import { P, Lead, Large, Small, Muted } from "~/components/typography";

export default function TypographyBodyDemo() {
  return (
    <div class="space-y-4">
      <P>Regular paragraph text with standard styling.</P>
      <Lead>Lead paragraph for introducing content.</Lead>
      <Large>Large styled text.</Large>
      <Small>Small styled text.</Small>
      <Muted>Muted secondary text.</Muted>
    </div>
  );
}

Inline Elements

Use the InlineCode component for displaying inline snippets of code.

Use InlineCode for inline code snippets.

import { P, InlineCode } from "~/components/typography";

export default function TypographyInlineCodeDemo() {
  return (
    <P>
      Use <InlineCode>InlineCode</InlineCode> for inline code snippets.
    </P>
  );
}

Blockquote

Use the Blockquote component for quoted text callouts.

"A quote for emphasis."
import { Blockquote } from "~/components/typography";

export default function TypographyBlockquoteDemo() {
  return <Blockquote>"A quote for emphasis."</Blockquote>;
}

List

Use the List component for formatted bulleted lists.

  • First item
  • Second item
import { List } from "~/components/typography";

export default function TypographyListDemo() {
  return (
    <List>
      <li>First item</li>
      <li>Second item</li>
    </List>
  );
}

API Reference

ComponentRenders AsDescription
H1<h1>Top-level heading
H2<h2>Section heading
H3<h3>Sub-section heading
H4<h4>Group heading
P<p>Paragraph text
Lead<p>Lead/introductory text
Large<div>Large body text
Small<small>Small/fine print text
Muted<p>Muted/secondary text
InlineCode<code>Inline code snippet
Blockquote<blockquote>Quoted content
List<ul>Unordered list container
classstringAll components accept class