# Notification Block
> A Notification Block explains a problem that prevents the user from using a page, such as a missing permission or an unexpected error, and offers a way forward.

## Import

```jsx
import { NotificationBlock } from '@volue/wave-react';
```

Notification Block is a compound component made up of several parts:

- `NotificationBlock.Root`: The wrapper that contains all the parts of a notification block.
- `NotificationBlock.Title`: The title, with an error icon before it. Renders an `h2` by default.
- `NotificationBlock.Description`: The supporting text that explains the problem.
- `NotificationBlock.Details`: The wrapper for optional, collapsible technical details.
- `NotificationBlock.DetailsTrigger`: The button that toggles the technical details.
- `NotificationBlock.DetailsPanel`: The collapsible content with the technical details.
- `NotificationBlock.Actions`: The container for the actions that offer a way forward.

## When to use

Use a Notification Block when a problem blocks the whole page, for example when the user is missing a permission or the app hits an unexpected error. It replaces the page content, explains what happened, and offers a way forward.

For problems that don't block the whole page, use one of the other [notification components](https://next.wave-design-system.pages.dev/UX-patterns/system-feedback/notification.md) instead.

Render it in [`AppFrame.Main`](https://next.wave-design-system.pages.dev/components/app-frame.md#with-centred-content) with `centerContent`, so it replaces the page content and sits in the middle of the main area. See [In App Frame](#in-app-frame).

## Examples

### Basic

A title, a description, and the actions that let the user move on.

```jsx
<Box padding="spacingS">
  <NotificationBlock.Root>
    <NotificationBlock.Title>{'Error title message'}</NotificationBlock.Title>
    <NotificationBlock.Description>
      {
        'Error description. This should help the user to understand what the problem is and how they might fix it.'
      }
    </NotificationBlock.Description>
    <NotificationBlock.Actions>
      <Button variant="outline" size="small">
        {'Return to the front page'}
      </Button>
      <Button variant="strong" size="small">
        {'Log out'}
      </Button>
    </NotificationBlock.Actions>
  </NotificationBlock.Root>
</Box>
```

### In App Frame

Show the block in place of the page content: put it in `AppFrame.Main` with `centerContent`.

```jsx
<AppFrame.Root background="neutralSubtle" css={{ height: 480 }}>
  <AppFrame.AppHeader>
    <AppHeader.Root size="small">
      <AppHeader.Logo />
      <AppHeader.Title>{'Product Name'}</AppHeader.Title>
    </AppHeader.Root>
  </AppFrame.AppHeader>
  <AppFrame.Main centerContent padding="spacingL">
    <NotificationBlock.Root>
      <NotificationBlock.Title>
        {'You do not have permission'}
      </NotificationBlock.Title>
      <NotificationBlock.Description>
        {
          'Your account does not have access to this application. Contact your administrator to request access.'
        }
      </NotificationBlock.Description>
      <NotificationBlock.Actions>
        <Button size="small">{'Log out'}</Button>
      </NotificationBlock.Actions>
    </NotificationBlock.Root>
  </AppFrame.Main>
</AppFrame.Root>
```

> **Tip**
>
> See the [system feedback demo in Storybook](https://next--63ac6ba300bd3c91074bc891.chromatic.com/?path=/story/demos-applayouts-systemfeedback--system-feedback) for a complete flow with loading and tenant switching.

### Alternative actions

When actions are alternatives to each other, such as switching to another tenant or logging out, separate them with muted text such as "or".

```jsx
() => {
  const [tenant, setTenant] = React.useState('power-trading');

  return (
    <AppFrame.Root background="neutralSubtle" css={{ height: 480 }}>
      <AppFrame.AppHeader>
        <AppHeader.Root size="small">
          <AppHeader.Logo />
          <AppHeader.Title>{'Product Name'}</AppHeader.Title>
        </AppHeader.Root>
      </AppFrame.AppHeader>
      <AppFrame.Main centerContent padding="spacingL">
        <NotificationBlock.Root>
          <NotificationBlock.Title>
            {'You do not have permission'}
          </NotificationBlock.Title>
          <NotificationBlock.Description>
            {
              'Your account does not have access to this application in this tenant. Switch to another tenant or contact your administrator.'
            }
          </NotificationBlock.Description>
          <NotificationBlock.Actions>
            <FlexItem flex="1" shrinkPastContentSize>
              <SingleSelectMenu.Root
                size="small"
                value={tenant}
                onValueChange={setTenant}
              >
                <SingleSelectMenu.Trigger
                  aria-label="Tenant"
                  renderValue={({ getSelectedItem }) => (
                    <Flex gap="spacingXs">
                      <Text color="foregroundNeutralSubtle">{'Tenant:'}</Text>
                      <Text overflowStrategy="truncate">
                        {getSelectedItem()?.textValue}
                      </Text>
                    </Flex>
                  )}
                />
                <SingleSelectMenu.Content>
                  <SingleSelectMenu.Item value="power-trading">
                    {'Power Trading'}
                  </SingleSelectMenu.Item>
                  <SingleSelectMenu.Item value="nordic-hydro">
                    {'Nordic Hydro'}
                  </SingleSelectMenu.Item>
                </SingleSelectMenu.Content>
              </SingleSelectMenu.Root>
            </FlexItem>
            <Text color="foregroundNeutralModerate">{'or'}</Text>
            <FlexItem flex="1" shrinkPastContentSize>
              <Button
                variant="strong"
                size="small"
                css={{ width: '100%', textAlign: 'center' }}
              >
                {'Log out'}
              </Button>
            </FlexItem>
          </NotificationBlock.Actions>
        </NotificationBlock.Root>
      </AppFrame.Main>
    </AppFrame.Root>
  );
};
```

### Technical details

Tuck technical information, such as the failed request or an error ID, behind `NotificationBlock.Details`. Put a `NotificationBlock.DetailsTrigger` and a `NotificationBlock.DetailsPanel` inside it. Inline `<code>` elements in the panel are highlighted.

The trigger has no default text, so pass a translated label. `NotificationBlock.Details` accepts the same state props as [Collapsible](https://next.wave-design-system.pages.dev/components/collapsible.md).

```jsx
<AppFrame.Root background="neutralSubtle" css={{ height: 480 }}>
  <AppFrame.AppHeader>
    <AppHeader.Root size="small">
      <AppHeader.Logo />
      <AppHeader.Title>{'Product Name'}</AppHeader.Title>
    </AppHeader.Root>
  </AppFrame.AppHeader>
  <AppFrame.Main centerContent padding="spacingL">
    <NotificationBlock.Root>
      <NotificationBlock.Title>
        {'You do not have permission'}
      </NotificationBlock.Title>
      <NotificationBlock.Description>
        {
          'Your account does not have access to this application. Contact your administrator to request access.'
        }
      </NotificationBlock.Description>
      <NotificationBlock.Details>
        <NotificationBlock.DetailsTrigger>
          {'Details'}
        </NotificationBlock.DetailsTrigger>
        <NotificationBlock.DetailsPanel>
          {'Request forbidden. '}
          <code>{'GET /api/v2/me'}</code>
          {
            ' The access token is valid, but it grants no role for this application. The application requires at least the reader role. Status: 403. Error ID: 9f3c2a71-0b64-4e0e-a2d8-77c1e5b0f3d2.'
          }
        </NotificationBlock.DetailsPanel>
      </NotificationBlock.Details>
      <NotificationBlock.Actions>
        <Button variant="strong" size="small">
          {'Log out'}
        </Button>
      </NotificationBlock.Actions>
    </NotificationBlock.Root>
  </AppFrame.Main>
</AppFrame.Root>
```

## Accessibility

- When the block appears because of the user's action, such as a navigation or a tenant switch, set `focusOnMount` on `NotificationBlock.Title`, so screen reader and keyboard users land on it. Don't use it on a full page load, or for failures the user didn't trigger.
- `NotificationBlock.Title` renders an `h2` by default. Use the `as` prop to fit it into your page's heading order.
- `NotificationBlock.DetailsTrigger` exposes `aria-expanded` and `aria-controls`, so assistive technologies know the state of the details and which content they control.

## API reference

### NotificationBlock.Root

| Name  | Type                                                      | Default | Description                                                                                                                                                                                                                                                                                                                              | Required |
| ----- | --------------------------------------------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `as`  | `keyof JSX.IntrinsicElements \| React.ComponentType<any>` | `div`   | Change the component to a different HTML tag or custom component. This will merge the original component props with the props of the supplied element/component and change the underlying DOM node.   For more details, read our [Composition](https://next.wave-design-system.pages.dev/get-started/composition.md#polymorphism) guide. |          |
| `css` | `StitchesCss`                                             |         | Apply styles directly to a component in a similar way how you would define inline styles. Wave uses [Stitches](https://stitches.dev/) under the hood with a fully-typed API and support for features like tokens, media queries or variants.                                                                                             |          |

### NotificationBlock.Title

> **Tip**
>
> In addition to the props below, you can pass [Heading props](https://next.wave-design-system.pages.dev/components/typography/heading.md#api-reference), except `variant`.

| Name           | Type                                                      | Default | Description                                                                                                                                                                                                                                                                                                                              | Required |
| -------------- | --------------------------------------------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `as`           | `keyof JSX.IntrinsicElements \| React.ComponentType<any>` | `h2`    | Change the component to a different HTML tag or custom component. This will merge the original component props with the props of the supplied element/component and change the underlying DOM node.   For more details, read our [Composition](https://next.wave-design-system.pages.dev/get-started/composition.md#polymorphism) guide. |          |
| `css`          | `StitchesCss`                                             |         | Apply styles directly to a component in a similar way how you would define inline styles. Wave uses [Stitches](https://stitches.dev/) under the hood with a fully-typed API and support for features like tokens, media queries or variants.                                                                                             |          |
| `focusOnMount` | `boolean`                                                 | `false` | Moves focus to the title when it mounts. See [Accessibility](#accessibility) for when to use it.                                                                                                                                                                                                                                         |          |

### NotificationBlock.Description

> **Tip**
>
> In addition to the props below, you can pass [Text props](https://next.wave-design-system.pages.dev/components/typography/text.md#api-reference).

| Name  | Type                                                      | Default | Description                                                                                                                                                                                                                                                                                                                              | Required |
| ----- | --------------------------------------------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `as`  | `keyof JSX.IntrinsicElements \| React.ComponentType<any>` | `p`     | Change the component to a different HTML tag or custom component. This will merge the original component props with the props of the supplied element/component and change the underlying DOM node.   For more details, read our [Composition](https://next.wave-design-system.pages.dev/get-started/composition.md#polymorphism) guide. |          |
| `css` | `StitchesCss`                                             |         | Apply styles directly to a component in a similar way how you would define inline styles. Wave uses [Stitches](https://stitches.dev/) under the hood with a fully-typed API and support for features like tokens, media queries or variants.                                                                                             |          |

### NotificationBlock.Details

| Name             | Type                        | Default | Description                                                                                                                                                                                                                                  | Required |
| ---------------- | --------------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `css`            | `StitchesCss`               |         | Apply styles directly to a component in a similar way how you would define inline styles. Wave uses [Stitches](https://stitches.dev/) under the hood with a fully-typed API and support for features like tokens, media queries or variants. |          |
| `isOpen`         | `boolean`                   | `false` | The controlled open state of the details. Use in conjunction with `onIsOpenChange`.                                                                                                                                                          |          |
| `defaultIsOpen`  | `boolean`                   |         | The open state of the details when it's first rendered. Use when you do not need to control open state.                                                                                                                                      |          |
| `onIsOpenChange` | `(isOpen: boolean) => void` |         | Event handler called when the open state of the details changes.                                                                                                                                                                             |          |

### NotificationBlock.DetailsTrigger

> **Tip**
>
> In addition to the props below, you can pass native `button` props.

| Name  | Type          | Default | Description                                                                                                                                                                                                                                  | Required |
| ----- | ------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `css` | `StitchesCss` |         | Apply styles directly to a component in a similar way how you would define inline styles. Wave uses [Stitches](https://stitches.dev/) under the hood with a fully-typed API and support for features like tokens, media queries or variants. |          |

### NotificationBlock.DetailsPanel

> **Tip**
>
> In addition to the props below, you can pass [Collapsible.Panel props](https://next.wave-design-system.pages.dev/components/collapsible.md#api-reference).

| Name             | Type               | Default | Description                                                                                                                                                                                                                                  | Required |
| ---------------- | ------------------ | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `css`            | `StitchesCss`      |         | Apply styles directly to a component in a similar way how you would define inline styles. Wave uses [Stitches](https://stitches.dev/) under the hood with a fully-typed API and support for features like tokens, media queries or variants. |          |
| `unmountOnExit`  | `boolean`          | `false` | When `true`, panel's children will unmount when exit animation is done.                                                                                                                                                                      |          |
| `startingHeight` | `string \| number` |         | The height of the panel in its collapsed state. You cannot use `startingHeight` in conjunction with `unmountOnExit` set to `true`.                                                                                                           |          |

### NotificationBlock.Actions

| Name  | Type                                                      | Default | Description                                                                                                                                                                                                                                                                                                                              | Required |
| ----- | --------------------------------------------------------- | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| `as`  | `keyof JSX.IntrinsicElements \| React.ComponentType<any>` | `div`   | Change the component to a different HTML tag or custom component. This will merge the original component props with the props of the supplied element/component and change the underlying DOM node.   For more details, read our [Composition](https://next.wave-design-system.pages.dev/get-started/composition.md#polymorphism) guide. |          |
| `css` | `StitchesCss`                                             |         | Apply styles directly to a component in a similar way how you would define inline styles. Wave uses [Stitches](https://stitches.dev/) under the hood with a fully-typed API and support for features like tokens, media queries or variants.                                                                                             |          |
