# Heading

Heading titles a page, a section or a card and sets its level in the page outline.

Heading renders an `h1` to `h6` element at a step of the type scale. It names the content that follows it, and screen reader users move through a page by its headings. Copy that only needs to look larger, such as a price or a lead sentence, is [Text](/docs/text).


## Usage

```tsx
import { Button, Card, Flex, Heading, Text } from '@kushagradhawan/kookie-ui';

export function BillingCard() {
  return (
    <Card size="2">
      <Flex direction="column" gap="2" align="start">
        <Heading size="4">
          Billing
        </Heading>
        <Text as="p" size="2" emphasis="medium">
          Your next invoice is on 1 March.
        </Text>
        <Button size="2">Manage plan</Button>
      </Flex>
    </Card>
  );
}
```

## Best practices

**Set `as="h1"` on the page title.** Heading renders an `h2` by default, which fits a section. A page has one `h1`, and a heading inside a section needs `as="h3"`.

**Choose the level for the outline and the size for the look.** `as` and `size` are separate. A card title can be an `h3` at size 4 in one place and an `h2` at size 6 in another. Don't skip levels to get a smaller heading.

**Write the heading as a label for what follows.** "Billing" or "Team members" tells people what the section holds. A full sentence or a question is harder to scan in a list of headings.

**Rank headings with emphasis, not with gray.** Use `emphasis="medium"` for a heading that sits below a stronger one, such as a group label in a sidebar. Leave `color` for a heading that carries a meaning.

**Don't use Heading for text that only needs weight.** A bold label in a table row or a form is [Text](/docs/text) with `weight="medium"`. Every Heading adds an entry to the page outline.

## Size

`size` picks a step from 1 to 9: 12, 14, 16, 18, 20, 24, 32, 44 and 64 pixels at the default scale. Size 6 is the default. The theme can adjust heading sizes and spacing with its own heading tokens.

| Size | Use it for |
| --- | --- |
| `7` to `9` | A page title or a marketing hero |
| `5` and `6` | A section title |
| `3` and `4` | A card, dialog or panel title |
| `1` and `2` | A small group label |

`size` accepts a responsive object, such as `{ initial: '6', md: '7' }`.

## Emphasis

`emphasis` sets how strongly a heading reads. With no `color` set, `loud`, `medium` and `quiet` step down the neutral ink. With a `color` set, the heading reads that colour's strong ink, and `medium` and `quiet` fade it. With no `color` and no `emphasis`, a heading inherits its colour.

## Examples

### Page and section titles

Give the page one `h1` and its sections `h2`. Sizes can step down further than the levels.

```tsx
<Flex direction="column" gap="5">
  <Heading as="h1" size="7">
    Settings
  </Heading>
  <Heading as="h2" size="5">
    Profile
  </Heading>
</Flex>
```

### Centred title over a few lines

`wrap="balance"` evens out the line lengths, so a centred title doesn't leave one word on the last line.

```tsx
<Heading
  as="h1"
  size="8"
  align="center"
  wrap="balance"
>
  Plan, build and ship your next release
</Heading>
```

### Title on one line

`truncate` keeps a long title, such as a file name in a panel header, on one line and ends it with an ellipsis.

```tsx
<Heading as="h2" size="3" truncate>
  Quarterly report, final version, approved by finance
</Heading>
```

### Title flush with a card edge

`trim="start"` removes the space above the first line, so the title lines up with the top of the card's padding.

## Props

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `as` | `'h1' \| 'h2' \| 'h3' \| 'h4' \| 'h5' \| 'h6'` | `'h2'` | The heading level |
| `size` | `'1'` to `'9'`, responsive | `'6'` | The type step |
| `weight` | `'regular' \| 'medium' \| 'semibold'`, responsive | Theme heading weight | The font weight |
| `font` | `'sans' \| 'mono' \| 'serif'` | Theme heading font | The font family |
| `color` | `AccentColor` | | The colour. Inherits when unset |
| `emphasis` | `'loud' \| 'medium' \| 'quiet'` | | How strongly the heading reads |
| `align` | `'left' \| 'center' \| 'right'`, responsive | | The text alignment |
| `trim` | `'normal' \| 'start' \| 'end' \| 'both'`, responsive | | Removes the space above or below the text |
| `truncate` | `boolean` | | Keeps one line and ends it with an ellipsis |
| `wrap` | `'wrap' \| 'nowrap' \| 'pretty' \| 'balance'`, responsive | | How lines break |
| `asChild` | `boolean` | `false` | Renders the child element with the heading's styles |

Heading also accepts every attribute of the HTML heading element set by `as`.

## Accessibility

- **Level:** A screen reader announces the level, such as "heading level 2". People use the levels to jump between sections, so keep them in order without gaps.
- **One page title:** Use one `h1` for each page, set with `as="h1"`. Other headings default to `h2`.
- **Name:** A Heading's text names a section. To name a region, point `aria-labelledby` on the `section` at the heading's `id`.
- **Truncation:** A screen reader reads a truncated heading in full. A pointer user can't see the rest, so add a `title` when the hidden part matters.
