# Text (/docs/text)





## API Reference [#api-reference]

`Text` is a moduix typography primitive. Base UI does not provide a matching text primitive,
so the public API stays focused on semantic element choice, visual variants, and root
`className` composition.

## Basic [#basic]

<Preview cssProperties="textPlaygroundCssProperties">
  <TextExample />

  <Preview.Code>
    {`
          import { Text } from "moduix";

          export function TextDemo() {
            return (
              <Text>
                Use text to describe interface state and supporting details.
              </Text>
            );
          }
        `}
  </Preview.Code>

  <Preview.CSSProperties>
    {(context) => <TextCssPropertiesPanel {...context} />}
  </Preview.CSSProperties>

  <Preview.CSSPlayground>
    {(context) => <TextCssPlaygroundPanel {...context} />}
  </Preview.CSSPlayground>
</Preview>

## Anatomy [#anatomy]

`Text` is composed as a single typography root that renders the chosen semantic element.
Visual style is controlled through size, weight, tone, alignment, and CSS variables.

```text
Text
└─ text or inline content
```

```tsx
<Text as="small" size="sm" tone="muted">
  Last updated just now
</Text>
```

| Part   | Role                                                                |
| ------ | ------------------------------------------------------------------- |
| `Text` | Semantic text root with design-system typography, tone, and sizing. |

`Text` does not use portal-like service layers such as `portal`, `backdrop`, or `viewport`.
In most cases, keep the default root styling and use props for semantic element, size,
weight, tone, and alignment. Use `className` when a specific block needs local CSS variables
or project styles.

## Composition [#composition]

Use `as` for the semantic element and `size` for the visual scale when semantics and
appearance should differ. Built-in defaults keep `strong` semibold and `small` at `sm`, while
other elements and custom components default to regular `md` text.

Style the root with `className` and component CSS variables. `Text` has no hidden service
slots, so it does not use `classNames` or slot props.

## Examples [#examples]

### Elements [#elements]

Use `as` to choose the semantic element without leaving the typography scale.

<Preview>
  <TextElementsExample />

  <Preview.Code>
    {`
          import { Text } from "moduix";

          export function TextElementsDemo() {
            return (
              <div className={styles.stack}>
                <Text as="p">Paragraph text rendered as p.</Text>
                <Text as="span">Inline text rendered as span.</Text>
                <Text as="small">Small supporting text rendered as small.</Text>
                <Text as="strong">Important text rendered as strong.</Text>
                <Text as="em">Emphasized text rendered as em.</Text>
                <Text as="div">Block text rendered as div.</Text>
              </div>
            );
          }
        `}
  </Preview.Code>

  <Preview.CSS>
    {`
          .stack {
            display: flex;
            width: min(34rem, calc(100vw - var(--spacing-8)));
            flex-direction: column;
            gap: var(--spacing-3);
          }
        `}
  </Preview.CSS>
</Preview>

### Custom Element [#custom-element]

Pass any React element or component to `as` when routing, analytics, or app-level primitives own
the rendered element.

<Preview>
  <TextCustomElementExample />

  <Preview.Code>
    {`
          import { Text } from "moduix";
          import type { ComponentPropsWithoutRef } from "react";

          type InlineLinkProps = ComponentPropsWithoutRef<"a">;

          function InlineLink(props: InlineLinkProps) {
            return <a {...props} />;
          }

          export function TextCustomElementDemo() {
            return (
              <Text as={InlineLink} href="/docs" tone="primary" weight="medium">
                Read the documentation
              </Text>
            );
          }
        `}
  </Preview.Code>
</Preview>

### Sizes [#sizes]

Use `size` for visual sizing. Override size-specific CSS variables in your project for responsive typography.

<Preview>
  <TextSizesExample />

  <Preview.Code>
    {`
          import { Text } from "moduix";

          export function TextSizesDemo() {
            return (
              <div className={styles.stack}>
                <Text size="xl">Extra-large text</Text>
                <Text size="lg">Large text</Text>
                <Text size="md">Medium text</Text>
                <Text size="sm">Small text</Text>
                <Text size="xs">Extra-small text</Text>
              </div>
            );
          }
        `}
  </Preview.Code>

  <Preview.CSS>
    {`
          .stack {
            display: flex;
            width: min(34rem, calc(100vw - var(--spacing-8)));
            flex-direction: column;
            gap: var(--spacing-3);
          }
        `}
  </Preview.CSS>
</Preview>

### Tones [#tones]

Use `tone` to match the role of the copy without introducing local color classes.

<Preview>
  <TextTonesExample />

  <Preview.Code>
    {`
          import { Text } from "moduix";

          export function TextTonesDemo() {
            return (
              <div className={styles.stack}>
                <Text tone="default">Default tone</Text>
                <Text tone="muted">Muted tone</Text>
                <Text tone="subtle">Subtle tone</Text>
                <Text tone="primary">Primary tone</Text>
                <Text tone="destructive">Destructive tone</Text>
              </div>
            );
          }
        `}
  </Preview.Code>

  <Preview.CSS>
    {`
          .stack {
            display: flex;
            width: min(34rem, calc(100vw - var(--spacing-8)));
            flex-direction: column;
            gap: var(--spacing-3);
          }
        `}
  </Preview.CSS>
</Preview>

### Weights [#weights]

Use `weight` for emphasis. `strong` defaults to semibold while other elements default to regular.

<Preview>
  <TextWeightsExample />

  <Preview.Code>
    {`
          import { Text } from "moduix";

          export function TextWeightsDemo() {
            return (
              <div className={styles.stack}>
                <Text weight="regular">Regular weight</Text>
                <Text weight="medium">Medium weight</Text>
                <Text weight="semibold">Semibold weight</Text>
                <Text weight="bold">Bold weight</Text>
              </div>
            );
          }
        `}
  </Preview.Code>

  <Preview.CSS>
    {`
          .stack {
            display: flex;
            width: min(34rem, calc(100vw - var(--spacing-8)));
            flex-direction: column;
            gap: var(--spacing-3);
          }
        `}
  </Preview.CSS>
</Preview>

### Alignment [#alignment]

Use `align` when text alignment belongs to the typography primitive instead of the surrounding layout.

<Preview>
  <TextAlignExample />

  <Preview.Code>
    {`
          import { Text } from "moduix";

          export function TextAlignDemo() {
            return (
              <div className={styles.aligned}>
                <Text align="left">Left aligned text.</Text>
                <Text align="center">Center aligned text.</Text>
                <Text align="right">Right aligned text.</Text>
              </div>
            );
          }
        `}
  </Preview.Code>

  <Preview.CSS>
    {`
          .aligned {
            display: flex;
            width: min(34rem, calc(100vw - var(--spacing-8)));
            flex-direction: column;
            gap: var(--spacing-4);
          }
        `}
  </Preview.CSS>
</Preview>

### Class Names [#class-names]

Pass `className` when styling the root with CSS Modules, Tailwind CSS, or CSS-in-JS.

<Preview>
  <TextClassNameExample />

  <Preview.Code>
    {`
          import { Text } from "moduix";

          export function TextClassNameDemo() {
            return (
              <Text as="p" className={styles.customText}>
                Customized body copy with local CSS variables.
              </Text>
            );
          }
        `}
  </Preview.Code>

  <Preview.CSS>
    {`
          .customText {
            --text-default-color: var(--color-primary);
            --text-font-size-md: var(--text-lg);
            --text-line-height-md: var(--line-height-text-lg);
            --text-font-weight-regular: var(--weight-medium);
          }
        `}
  </Preview.CSS>
</Preview>
