# Typography

> Text in one of the library's text styles, with a heading, paragraph or span element to match.

Source: /docs/components/typography

```tsx
import { Typography, typography } from '@aksornproject/aksara-ui'
```

## Variants

`variant` names a text style by group and weight, such as `h2-semi-bold` or `label-medium`. The default is `body-regular`. The groups are `display-1` to `display-3`, `h1` to `h6`, `large`, `body`, `label`, `code` and `supporting`. The [Typography foundations](/docs/foundations/typography) page lists every style with its size and line height.

```tsx
import { Typography } from '@aksornproject/aksara-ui'

export default function TypographyVariants() {
  return (
    <div className="flex flex-col gap-spacing-8">
      <Typography variant="display-1-semi-bold">Display 1</Typography>
      <Typography variant="h1-semi-bold" render={<p />}>
        Heading 1
      </Typography>
      <Typography variant="h3-semi-bold" render={<p />}>
        Heading 3
      </Typography>
      <Typography variant="large-medium">Large medium</Typography>
      <Typography>Body regular, the default</Typography>
      <Typography variant="label-medium">Label medium</Typography>
      <Typography variant="code-regular">code-regular</Typography>
      <Typography variant="supporting-regular">Supporting regular</Typography>
    </div>
  )
}
```

## Weights

Every group comes in `regular`, `medium`, `semi-bold` and `bold`. `supporting` has only `regular` and `bold`.

```tsx
import { Typography } from '@aksornproject/aksara-ui'

export default function TypographyWeights() {
  return (
    <div className="flex flex-col gap-spacing-4">
      <Typography variant="body-regular">Body regular</Typography>
      <Typography variant="body-medium">Body medium</Typography>
      <Typography variant="body-semi-bold">Body semi-bold</Typography>
      <Typography variant="body-bold">Body bold</Typography>
      <Typography variant="supporting-regular">Supporting regular</Typography>
      <Typography variant="supporting-bold">Supporting bold</Typography>
    </div>
  )
}
```

## Elements

Headings render `h1` to `h6`. Display, large and body render `p`, so two body blocks stack. Label, code and supporting render `span`. `render` swaps the element and keeps the style, so a section title can look like an `h2` and still be an `h3` in the page outline.

```tsx
import { Typography } from '@aksornproject/aksara-ui'

export default function TypographyElements() {
  return (
    <article className="flex flex-col gap-spacing-8">
      <Typography variant="h2-semi-bold" render={<h3 />}>
        Term report
      </Typography>
      <Typography variant="supporting-regular" render={<p />}>
        Updated 2 November
      </Typography>
      <Typography>
        Reading and writing improved across the class this term.
      </Typography>
    </article>
  )
}
```

## Class name

`typography(variant)` returns the class for an element you render without Typography, such as a native `textarea`. It takes the same variant names.

```tsx
import { Typography, typography } from '@aksornproject/aksara-ui'

export default function TypographyClassName() {
  return (
    <div className="flex flex-col gap-spacing-4">
      <Typography variant="label-medium" render={<label htmlFor="notes" />}>
        Notes
      </Typography>
      <textarea
        id="notes"
        rows={3}
        defaultValue="Bring a lunch for the field trip."
        className={`${typography('body-regular')} w-full max-w-[320px] rounded-radius-radius-8 border border-color-border p-spacing-8`}
      />
    </div>
  )
}
```

## Overrides

`className` merges last. Add colour, alignment or truncation there. To change the style, pick another `variant`. A later style class in `className` also replaces the variant.

Font size and line height follow `data-fontsize` and `data-fontlineheight` on an ancestor, so Thai text gets the taller Thai line heights. See [Theming](/docs/theming).

## Accessibility

- The element carries the meaning, the variant only sets the look. Keep headings in page order with `render`.
- Give text that is not a heading `render={<p />}` or `render={<span />}` when it uses a heading style.

## API

### Typography

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `render` | `ComponentRenderFn<HTMLProps, {}> \| React.ReactElement<unknown, string \| React.JSXElementConstructor<any>>` |  | Allows you to replace the component's HTML element with a different tag, or compose it with another component. Accepts a `ReactElement` or a function that returns the element to render. |
| `variant` | `TypographyVariant` | `'body-regular'` | The text style, named by group and weight. Headings render `h1` to `h6`, display, large and body render `p`, and label, code and supporting render `span`. Defaults to `'body-regular'`. |
| `className` | `string` |  | Merged last with `cn()`, so these classes win. |

### typography

`typography(variant: TypographyVariant): string` returns the class for one style.