|
| 1 | +import { Meta, Story } from '@storybook/addon-docs/blocks'; |
| 2 | +import AlertBannerStories, { |
| 3 | + Information, |
| 4 | + Error, |
| 5 | + Success, |
| 6 | + Warning, |
| 7 | + InformationWithIconAndCloseButton, |
| 8 | + CustomTheme, |
| 9 | + CssOverrides, |
| 10 | +} from './AlertBanner.stories'; |
| 11 | +import { |
| 12 | + SandboxReact, |
| 13 | + SandboxCss, |
| 14 | + SandboxJs, |
| 15 | +} from '../../util/storybook/sandbox/Sandbox'; |
| 16 | +import { |
| 17 | + componentName, |
| 18 | + componentCss, |
| 19 | + componentHtml, |
| 20 | + componentJs, |
| 21 | + componentTsx, |
| 22 | +} from './sandbox'; |
| 23 | + |
| 24 | +<Meta of={AlertBannerStories} /> |
| 25 | + |
| 26 | +# AlertBanner |
| 27 | + |
| 28 | +A full-width banner used to communicate high-priority status messages at page or section level. It supports four levels (`information`, `success`, `warning`, `error`), optional icon display, custom icons, and an optional dismiss action. |
| 29 | + |
| 30 | +## When to use |
| 31 | + |
| 32 | +- To show important status feedback that should be visible across the full container width |
| 33 | +- For success, warning, error, or informational messages tied to a page or workflow |
| 34 | +- When a message may need optional dismissal via a close button |
| 35 | + |
| 36 | +## Peer dependencies |
| 37 | + |
| 38 | +- `@emotion/react` |
| 39 | +- `react` |
| 40 | +- `react-dom` |
| 41 | +- `typescript` |
| 42 | + |
| 43 | +See the `peerDependencies` section of `package.json` for compatible versions. |
| 44 | + |
| 45 | +See [custom component build](#custom-component-build) for usage without React/Emotion. |
| 46 | + |
| 47 | +## Example usage |
| 48 | + |
| 49 | +<SandboxReact |
| 50 | + componentName={componentName} |
| 51 | + componentTsx={componentTsx} |
| 52 | + flowColumn |
| 53 | +/> |
| 54 | + |
| 55 | +```tsx |
| 56 | +import { AlertBanner } from '@guardian/stand/alert-banner'; |
| 57 | + |
| 58 | +/* types, if required */ |
| 59 | +import type { |
| 60 | + AlertBannerProps, |
| 61 | + AlertBannerTheme, |
| 62 | +} from '@guardian/stand/alert-banner'; |
| 63 | + |
| 64 | +<AlertBanner level="information"> |
| 65 | + You are working in the CODE Environment |
| 66 | +</AlertBanner>; |
| 67 | + |
| 68 | +<AlertBanner level="warning" showIcon> |
| 69 | + Your session will expire in 2 minutes. |
| 70 | +</AlertBanner>; |
| 71 | + |
| 72 | +<AlertBanner |
| 73 | + level="error" |
| 74 | + closeButtonProps={{ onPress: () => console.log('dismissed') }} |
| 75 | +> |
| 76 | + Unable to save changes. Try again. |
| 77 | +</AlertBanner>; |
| 78 | +``` |
| 79 | + |
| 80 | +## Props |
| 81 | + |
| 82 | +| Name | Type | Required | Default | Description | |
| 83 | +| ------------------ | ---------------------------------------------------- | -------- | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | |
| 84 | +| `level` | `'error' \| 'success' \| 'information' \| 'warning'` | Yes | N/A | Severity level of the banner. Controls the background treatment and the default icon choice when `showIcon` is enabled. | |
| 85 | +| `children` | `React.ReactNode` | No | N/A | Content rendered inside the banner. | |
| 86 | +| `showIcon` | `boolean` | No | `false` | When `true`, renders an icon before the message content. Uses a level-based default icon unless overridden by `icon`. | |
| 87 | +| `icon` | `IconProps['symbol'] \| SVGElement` | No | N/A | Optional custom icon. Accepts a Material Symbols name (`string`) or non-string icon element (for example an inline SVG). | |
| 88 | +| `closeButtonProps` | `Partial<IconButtonProps>` | No | N/A | Optional props for the close button. If provided, a close icon button is rendered and the props are forwarded to `IconButton` (with defaults for `variant`, `size`, `symbol`, and `ariaLabel`). | |
| 89 | +| `theme` | `Partial<AlertBannerTheme>` | No | N/A | Custom theme token overrides merged over the component defaults. | |
| 90 | +| `cssOverrides` | `SerializedStyles \| SerializedStyles[]` | No | N/A | Additional Emotion CSS styles applied to the root element. | |
| 91 | +| `className` | `string` | No | N/A | Additional class name(s) for the root element. | |
| 92 | + |
| 93 | +## Stories |
| 94 | + |
| 95 | +### Information |
| 96 | + |
| 97 | +<Story of={Information} /> |
| 98 | + |
| 99 | +### Success |
| 100 | + |
| 101 | +<Story of={Success} /> |
| 102 | + |
| 103 | +### Warning |
| 104 | + |
| 105 | +<Story of={Warning} /> |
| 106 | + |
| 107 | +### Error |
| 108 | + |
| 109 | +<Story of={Error} /> |
| 110 | + |
| 111 | +### Information with Icon and Close Button |
| 112 | + |
| 113 | +<Story of={InformationWithIconAndCloseButton} /> |
| 114 | + |
| 115 | +## Customisation |
| 116 | + |
| 117 | +We recommend using the AlertBanner component as provided, but it can be customised using the `theme` or `cssOverrides` props as required. |
| 118 | + |
| 119 | +### Custom theme |
| 120 | + |
| 121 | +The `theme` prop allows you to override specific design tokens for the AlertBanner component: |
| 122 | + |
| 123 | +<Story of={CustomTheme} /> |
| 124 | + |
| 125 | +```tsx |
| 126 | +import { baseColors } from '@guardian/stand'; |
| 127 | +import type { AlertBannerTheme } from '@guardian/stand/alert-banner'; |
| 128 | +import { AlertBanner } from '@guardian/stand/alert-banner'; |
| 129 | + |
| 130 | +const customTheme: Partial<AlertBannerTheme> = { |
| 131 | + error: { |
| 132 | + 'background-color': baseColors.red[100], |
| 133 | + }, |
| 134 | + shared: { |
| 135 | + content: { |
| 136 | + color: baseColors.red[700], |
| 137 | + }, |
| 138 | + }, |
| 139 | +}; |
| 140 | + |
| 141 | +const Component = () => ( |
| 142 | + <AlertBanner level="error" theme={customTheme}> |
| 143 | + Unable to save changes. |
| 144 | + </AlertBanner> |
| 145 | +); |
| 146 | +``` |
| 147 | + |
| 148 | +### CSS overrides |
| 149 | + |
| 150 | +The `cssOverrides` prop allows you to pass custom CSS to the AlertBanner component: |
| 151 | + |
| 152 | +<Story of={CssOverrides} /> |
| 153 | + |
| 154 | +```tsx |
| 155 | +import { AlertBanner } from '@guardian/stand/alert-banner'; |
| 156 | +import { css } from '@emotion/react'; |
| 157 | + |
| 158 | +const customStyles = css\` |
| 159 | + box-shadow: inset 0 -2px 0 currentColor; |
| 160 | + text-transform: uppercase; |
| 161 | + letter-spacing: 0.04em; |
| 162 | +\`; |
| 163 | +
|
| 164 | +const Component = () => ( |
| 165 | + <AlertBanner level="success" cssOverrides={customStyles}> |
| 166 | + Changes published successfully. |
| 167 | + </AlertBanner> |
| 168 | +); |
| 169 | +``` |
| 170 | + |
| 171 | +## Custom Component Build |
| 172 | + |
| 173 | +If you're not using React/Emotion, you can create a custom AlertBanner component using the styles defined in the `AlertBannerTheme` type. |
| 174 | + |
| 175 | +**`css`** |
| 176 | + |
| 177 | +You can import the AlertBanner styles as CSS from the package: |
| 178 | + |
| 179 | +<SandboxCss |
| 180 | + componentName={componentName} |
| 181 | + componentHtml={componentHtml} |
| 182 | + componentCss={componentCss} |
| 183 | +/> |
| 184 | + |
| 185 | +**TypeScript/JavaScript** |
| 186 | + |
| 187 | +Use the `componentAlertBanner` variable and the `ComponentAlertBanner` type: |
| 188 | + |
| 189 | +<SandboxJs componentName={componentName} componentJs={componentJs} /> |
0 commit comments