AloeUI
Components

Paragraph

A foundational typography component optimized for legibility and rhythmic flow. It streamlines body text management by providing a standardized scale for sizes and line-heights, ensuring your content remains perfectly readable across all screen sizes while adhering to the Shadcn/ui design principles.

API

Author's Note

While headlines grab attention, paragraphs carry the message. This component is built to prioritize readability. By offering pre-defined scale sizes and refined line-heights (leading), the Paragraph component ensures that long-form content remains legible and aesthetically consistent with the rest of the AloeUI design system, effectively eliminating the visual "noise" of inconsistent body text.

import type * as React from "react";
 
import { Paragraph } from "@/components/ui/paragraph";
 
export function ParagraphDemo(): React.ReactElement {
  return (
    <div className="flex flex-col gap-4">
      <Paragraph size="xs">Extra small body text.</Paragraph>
      <Paragraph size="sm">Small body text.</Paragraph>
      <Paragraph size="base">Base body text.</Paragraph>
      <Paragraph size="lg">Large body text.</Paragraph>
      <Paragraph size="xl">Extra large body text.</Paragraph>
      <Paragraph size="2xl">2XL body text.</Paragraph>
      <Paragraph size="3xl">3XL body text.</Paragraph>
    </div>
  );
}

Installation

CLI

npx shadcn@latest add @aloeui/paragraph

Manual

Install the following dependencies:

npm install @radix-ui/react-slot class-variance-authority

Copy and paste the following code into your project.

import { Slot } from "@radix-ui/react-slot";
import { cva, type VariantProps } from "class-variance-authority";
import * as React from "react";
 
import { cn } from "@/lib/utils";
 
const paragraphVariants = cva("", {
  variants: {
    size: {
      xs: "text-xs",
      sm: "text-sm",
      base: "text-base",
      lg: "text-lg",
      xl: "text-xl",
      "2xl": "text-2xl",
      "3xl": "text-3xl",
    },
    weight: {
      normal: "font-normal",
      medium: "font-medium",
      semibold: "font-semibold",
    },
    muted: {
      false: "text-foreground",
      true: "text-muted-foreground",
    },
    leading: {
      snug: "leading-snug",
      normal: "leading-normal",
      relaxed: "leading-relaxed",
    },
    truncate: {
      true: "truncate",
      false: "",
    },
  },
  defaultVariants: {
    size: "base",
    weight: "normal",
    muted: false,
    leading: "normal",
    truncate: false,
  },
});
 
const Paragraph = React.forwardRef<
  HTMLParagraphElement,
  React.ComponentPropsWithoutRef<"p"> &
    VariantProps<typeof paragraphVariants> & { asChild?: boolean }
>(
  (
    {
      className,
      size = "base",
      weight,
      muted,
      leading,
      truncate,
      asChild = false,
      ...props
    },
    ref,
  ) => {
    const Comp = asChild ? Slot : "p";
 
    return (
      <Comp
        data-slot="paragraph"
        ref={ref}
        className={cn(
          paragraphVariants({
            size,
            weight,
            muted,
            leading,
            truncate,
            className,
          }),
        )}
        {...props}
      />
    );
  },
);
 
Paragraph.displayName = "Paragraph";
 
export { Paragraph, paragraphVariants };

Examples

Size

Choose the appropriate size (xs, sm, base, lg, xl, 2xl, 3xl).

import type * as React from "react";
 
import { Paragraph } from "@/components/ui/paragraph";
 
export function ParagraphSizeDemo(): React.ReactElement {
  return (
    <div className="flex flex-col gap-2">
      <Paragraph size="xs">Paragraph</Paragraph>
      <Paragraph size="sm">Paragraph</Paragraph>
      <Paragraph size="base">Paragraph</Paragraph>
      <Paragraph size="lg">Paragraph</Paragraph>
      <Paragraph size="xl">Paragraph</Paragraph>
      <Paragraph size="2xl">Paragraph</Paragraph>
      <Paragraph size="3xl">Paragraph</Paragraph>
    </div>
  );
}

Weight

Control font weight with the weight prop.

Paragraph

Paragraph

Paragraph

import type * as React from "react";
 
import { Paragraph } from "@/components/ui/paragraph";
 
export function ParagraphWeightDemo(): React.ReactElement {
  return (
    <div className="flex flex-col gap-2">
      <Paragraph size="base" weight="normal">
        Paragraph
      </Paragraph>
      <Paragraph size="base" weight="medium">
        Paragraph
      </Paragraph>
      <Paragraph size="base" weight="semibold">
        Paragraph
      </Paragraph>
    </div>
  );
}

Muted

Use muted for secondary text.

Paragraph

Paragraph

import type * as React from "react";
 
import { Paragraph } from "@/components/ui/paragraph";
 
export function ParagraphMutedDemo(): React.ReactElement {
  return (
    <div className="flex flex-col gap-2">
      <Paragraph size="base">Paragraph</Paragraph>
      <Paragraph size="base" muted>
        Paragraph
      </Paragraph>
    </div>
  );
}

Leading

Adjust line height for body text.

import type * as React from "react";
 
import { Paragraph } from "@/components/ui/paragraph";
 
export function ParagraphLeadingDemo(): React.ReactElement {
  return (
    <div className="flex flex-col gap-4 max-w-md">
      <div>
        <span className="text-muted-foreground mb-1 block text-sm">
          leading=&quot;snug&quot;
        </span>
        <Paragraph size="base" leading="snug">
          The quick brown fox jumps over the lazy dog. Lorem ipsum dolor sit
          amet, consectetur adipiscing elit.
        </Paragraph>
      </div>
      <div>
        <span className="text-muted-foreground mb-1 block text-sm">
          leading=&quot;normal&quot;
        </span>
        <Paragraph size="base" leading="normal">
          The quick brown fox jumps over the lazy dog. Lorem ipsum dolor sit
          amet, consectetur adipiscing elit.
        </Paragraph>
      </div>
      <div>
        <span className="text-muted-foreground mb-1 block text-sm">
          leading=&quot;relaxed&quot;
        </span>
        <Paragraph size="base" leading="relaxed">
          The quick brown fox jumps over the lazy dog. Lorem ipsum dolor sit
          amet, consectetur adipiscing elit.
        </Paragraph>
      </div>
    </div>
  );
}

Truncate

Truncate with ellipsis when overflow.

This paragraph will truncate with an ellipsis when it overflows.

import type * as React from "react";
 
import { Paragraph } from "@/components/ui/paragraph";
 
export function ParagraphTruncateDemo(): React.ReactElement {
  return (
    <div className="w-48">
      <Paragraph size="base" truncate>
        This paragraph will truncate with an ellipsis when it overflows.
      </Paragraph>
    </div>
  );
}

asChild

Use asChild to merge props with your child element (e.g. Link).

Paragraph as Link

Use asChild to merge props with your child element.

import type * as React from "react";
 
import { Paragraph } from "@/components/ui/paragraph";
 
export function ParagraphAsChildDemo(): React.ReactElement {
  return (
    <div className="flex flex-col gap-2">
      <Paragraph asChild size="base">
        <a href="#">Paragraph as Link</a>
      </Paragraph>
      <p className="text-muted-foreground text-sm">
        Use <code>asChild</code> to merge props with your child element.
      </p>
    </div>
  );
}

API Reference

Paragraph

Prop

Type

On this page