# Linked heading

A heading with a button that copies a link to it, for long pages that people share by section, such as documentation. For other headings, use [Heading](/components/heading.md).

```tsx
// demo.tsx
import {LinkedHeading} from '@earendil-works/elanor-react';

export default function LinkedHeadingDemo() {
  return (
    <LinkedHeading level={2} size={4} id="billing" linkLabel="Copy link to Billing">
      Billing
    </LinkedHeading>
  );
}
```

## Usage

```tsx
import {LinkedHeading} from '@earendil-works/elanor-react';

<LinkedHeading level={2} id="billing" linkLabel="Copy link to Billing">
  Billing
</LinkedHeading>;
```

Linked heading takes Heading's props plus a required `id` and `linkLabel`. The button follows the heading's last word, `semantic.dimension.space.gap.small` away. Pressing it copies the heading's absolute URL and moves the page to the heading, so the address bar shows the link too.

The button shows on hover, on keyboard focus, after a tap or click on the heading, and while it confirms a copy, on every device; the heading takes focus without joining the tab order (`tabIndex={-1}`). On touch screens the button is a 48px target.

## In long-form content

Inside [Prose](/components/prose.md), a linked heading gets the same space as a plain heading of its level.

```tsx
// prose.tsx
import {LinkedHeading, Prose, Text} from '@earendil-works/elanor-react';

export default function LinkedHeadingProse() {
  return (
    <Prose>
      <Text>Invoices go to the billing contact on the first day of each month.</Text>
      <LinkedHeading
        level={3}
        size={3}
        id="payment-methods"
        linkLabel="Copy link to Payment methods"
      >
        Payment methods
      </LinkedHeading>
      <Text>Add a card or pay by bank transfer. Cards are charged when the invoice is issued.</Text>
    </Prose>
  );
}
```

## Static rendering

On pages rendered on the server without React in the browser, the same component works with two behaviors: the copy button's, which copies the heading's absolute URL, and the linked heading's, which moves the page to the heading.

```ts
import {createCopyButton, createLinkedHeading, enhance} from '@earendil-works/elanor-react';

enhance({'copy-button': createCopyButton, 'linked-heading': createLinkedHeading});
```

## API

### `LinkedHeading`

A heading followed by a button that copies the heading's link and moves the page to it. The button shows on hover, on keyboard focus, after a tap or click on the heading, and while it confirms a copy. `ref` and the heading props go to the heading; `className` goes to the wrapper.

| Prop | Type | Default | Description |
| --- | --- | --- | --- |
| `variant` | `'app'` | - | Heading style: `app` for interfaces, `marketing` for promotional pages. |
| `size` | `1 \| … \| 6` | - | Visual size, from `1` (largest) to `6`, one per `semantic.typography.heading.app` style. |
| `level` (required) | `1 \| … \| 6` | - | Heading level. Follow the page outline; `level` doesn't change the size. |
| `id` (required) | `string` | - | The heading's id, the target of its link. |
| `linkLabel` (required) | `string` | - | Accessible name of the link button, such as "Copy link to Billing". |
| `copiedLabel` | `string` | `'Link copied.'` | Announced after the link is copied. |
| `data-elanor` | `string` | - | The page's own behaviors for the wrapper, attached after the linked heading's. |

Renders `<div>`. Also accepts its HTML attributes and `ref`.
