@neo4j-ndl/react 4.23.5 → 4.24.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/cjs/announcement-banner/AnnouncementBanner.js +198 -0
- package/lib/cjs/announcement-banner/AnnouncementBanner.js.map +1 -0
- package/lib/cjs/announcement-banner/index.js +38 -0
- package/lib/cjs/announcement-banner/index.js.map +1 -0
- package/lib/cjs/announcement-banner/stories/announcement-banner-closeable.story.js +30 -0
- package/lib/cjs/announcement-banner/stories/announcement-banner-closeable.story.js.map +1 -0
- package/lib/cjs/announcement-banner/stories/announcement-banner-custom-icons.story.js +31 -0
- package/lib/cjs/announcement-banner/stories/announcement-banner-custom-icons.story.js.map +1 -0
- package/lib/cjs/announcement-banner/stories/announcement-banner-default.story.js +30 -0
- package/lib/cjs/announcement-banner/stories/announcement-banner-default.story.js.map +1 -0
- package/lib/cjs/announcement-banner/stories/announcement-banner-injected-non-urgent.story.js +32 -0
- package/lib/cjs/announcement-banner/stories/announcement-banner-injected-non-urgent.story.js.map +1 -0
- package/lib/cjs/announcement-banner/stories/announcement-banner-injected-urgent.story.js +32 -0
- package/lib/cjs/announcement-banner/stories/announcement-banner-injected-urgent.story.js.map +1 -0
- package/lib/cjs/announcement-banner/stories/announcement-banner-present-at-page-render.story.js +30 -0
- package/lib/cjs/announcement-banner/stories/announcement-banner-present-at-page-render.story.js.map +1 -0
- package/lib/cjs/announcement-banner/stories/announcement-banner-variants.story.js +30 -0
- package/lib/cjs/announcement-banner/stories/announcement-banner-variants.story.js.map +1 -0
- package/lib/cjs/announcement-banner/stories/announcement-banner-with-actions.story.js +30 -0
- package/lib/cjs/announcement-banner/stories/announcement-banner-with-actions.story.js.map +1 -0
- package/lib/cjs/announcement-banner/stories/announcement-banner-with-page-content.story.js +32 -0
- package/lib/cjs/announcement-banner/stories/announcement-banner-with-page-content.story.js.map +1 -0
- package/lib/cjs/announcement-banner/stories/index.js +64 -0
- package/lib/cjs/announcement-banner/stories/index.js.map +1 -0
- package/lib/cjs/index.js +4 -2
- package/lib/cjs/index.js.map +1 -1
- package/lib/esm/announcement-banner/AnnouncementBanner.js +159 -0
- package/lib/esm/announcement-banner/AnnouncementBanner.js.map +1 -0
- package/lib/esm/announcement-banner/index.js +22 -0
- package/lib/esm/announcement-banner/index.js.map +1 -0
- package/lib/esm/announcement-banner/stories/announcement-banner-closeable.story.js +28 -0
- package/lib/esm/announcement-banner/stories/announcement-banner-closeable.story.js.map +1 -0
- package/lib/esm/announcement-banner/stories/announcement-banner-custom-icons.story.js +29 -0
- package/lib/esm/announcement-banner/stories/announcement-banner-custom-icons.story.js.map +1 -0
- package/lib/esm/announcement-banner/stories/announcement-banner-default.story.js +28 -0
- package/lib/esm/announcement-banner/stories/announcement-banner-default.story.js.map +1 -0
- package/lib/esm/announcement-banner/stories/announcement-banner-injected-non-urgent.story.js +30 -0
- package/lib/esm/announcement-banner/stories/announcement-banner-injected-non-urgent.story.js.map +1 -0
- package/lib/esm/announcement-banner/stories/announcement-banner-injected-urgent.story.js +30 -0
- package/lib/esm/announcement-banner/stories/announcement-banner-injected-urgent.story.js.map +1 -0
- package/lib/esm/announcement-banner/stories/announcement-banner-present-at-page-render.story.js +28 -0
- package/lib/esm/announcement-banner/stories/announcement-banner-present-at-page-render.story.js.map +1 -0
- package/lib/esm/announcement-banner/stories/announcement-banner-variants.story.js +28 -0
- package/lib/esm/announcement-banner/stories/announcement-banner-variants.story.js.map +1 -0
- package/lib/esm/announcement-banner/stories/announcement-banner-with-actions.story.js +28 -0
- package/lib/esm/announcement-banner/stories/announcement-banner-with-actions.story.js.map +1 -0
- package/lib/esm/announcement-banner/stories/announcement-banner-with-page-content.story.js +30 -0
- package/lib/esm/announcement-banner/stories/announcement-banner-with-page-content.story.js.map +1 -0
- package/lib/esm/announcement-banner/stories/index.js +49 -0
- package/lib/esm/announcement-banner/stories/index.js.map +1 -0
- package/lib/esm/index.js +1 -0
- package/lib/esm/index.js.map +1 -1
- package/lib/types/announcement-banner/AnnouncementBanner.d.ts +75 -0
- package/lib/types/announcement-banner/AnnouncementBanner.d.ts.map +1 -0
- package/lib/types/announcement-banner/index.d.ts +22 -0
- package/lib/types/announcement-banner/index.d.ts.map +1 -0
- package/lib/types/announcement-banner/stories/announcement-banner-closeable.story.d.ts +24 -0
- package/lib/types/announcement-banner/stories/announcement-banner-closeable.story.d.ts.map +1 -0
- package/lib/types/announcement-banner/stories/announcement-banner-custom-icons.story.d.ts +24 -0
- package/lib/types/announcement-banner/stories/announcement-banner-custom-icons.story.d.ts.map +1 -0
- package/lib/types/announcement-banner/stories/announcement-banner-default.story.d.ts +24 -0
- package/lib/types/announcement-banner/stories/announcement-banner-default.story.d.ts.map +1 -0
- package/lib/types/announcement-banner/stories/announcement-banner-injected-non-urgent.story.d.ts +24 -0
- package/lib/types/announcement-banner/stories/announcement-banner-injected-non-urgent.story.d.ts.map +1 -0
- package/lib/types/announcement-banner/stories/announcement-banner-injected-urgent.story.d.ts +24 -0
- package/lib/types/announcement-banner/stories/announcement-banner-injected-urgent.story.d.ts.map +1 -0
- package/lib/types/announcement-banner/stories/announcement-banner-present-at-page-render.story.d.ts +24 -0
- package/lib/types/announcement-banner/stories/announcement-banner-present-at-page-render.story.d.ts.map +1 -0
- package/lib/types/announcement-banner/stories/announcement-banner-variants.story.d.ts +24 -0
- package/lib/types/announcement-banner/stories/announcement-banner-variants.story.d.ts.map +1 -0
- package/lib/types/announcement-banner/stories/announcement-banner-with-actions.story.d.ts +24 -0
- package/lib/types/announcement-banner/stories/announcement-banner-with-actions.story.d.ts.map +1 -0
- package/lib/types/announcement-banner/stories/announcement-banner-with-page-content.story.d.ts +24 -0
- package/lib/types/announcement-banner/stories/announcement-banner-with-page-content.story.d.ts.map +1 -0
- package/lib/types/announcement-banner/stories/index.d.ts +39 -0
- package/lib/types/announcement-banner/stories/index.d.ts.map +1 -0
- package/lib/types/index.d.ts +1 -0
- package/lib/types/index.d.ts.map +1 -1
- package/package.json +7 -2
- package/skills/ndl-react/SKILL.md +3 -2
- package/skills/ndl-react/components/announcement-banner.md +468 -0
|
@@ -0,0 +1,468 @@
|
|
|
1
|
+
[//]: # (This file is auto-generated by the docs:generate-skills script, do not edit it manually)
|
|
2
|
+
|
|
3
|
+
# AnnouncementBanner
|
|
4
|
+
|
|
5
|
+
Import: `import { AnnouncementBanner } from '@neo4j-ndl/react'`
|
|
6
|
+
|
|
7
|
+
## Props
|
|
8
|
+
|
|
9
|
+
### AnnouncementBanner
|
|
10
|
+
|
|
11
|
+
| Prop | Type | Required | Default | Description |
|
|
12
|
+
|------|------|----------|---------|-------------|
|
|
13
|
+
| `as` | `ElementType<any, keyof IntrinsicElements>` | | | An override of the default HTML tag of the root of the component. Can also be another React component. |
|
|
14
|
+
| `children` | `ReactNode` | | | Content to be shown in the announcement banner. |
|
|
15
|
+
| `hasIcon` | `boolean` | | `false` | Shows a status icon. The icon is based on the value of the `variant` prop |
|
|
16
|
+
| `icon` | `ReactNode` | | | Decorative icon shown when `hasIcon` is true. Only used for `discovery` and `neutral`; those variants fall back to Sparkles and Bolt. `info`, `warning`, and `danger` always use their status icons. |
|
|
17
|
+
| `isCloseable` | `boolean` | | `false` | If the banner is closeable. Renders an icon button on the right |
|
|
18
|
+
| `liveRegion` | `'alert' \| 'status'` | | | Announces the header when the banner appears or its header changes. `status` announces politely, while `alert` interrupts the user. Leave this unset for banners that are present during the page's initial render. This is independent of the visual `variant`. |
|
|
19
|
+
| `onClose` | `((error?: MouseEvent<HTMLElement, MouseEvent> \| KeyboardEvent<HTMLElement>) => void)` | | | Event handler for when the close icon is clicked |
|
|
20
|
+
| `ref` | `any` | | | A ref to apply to the root element. |
|
|
21
|
+
| `variant` | `'danger' \| 'discovery' \| 'info' \| 'neutral' \| 'warning'` | | `info` | The variant of the announcement banner |
|
|
22
|
+
|
|
23
|
+
### AnnouncementBanner.Actions
|
|
24
|
+
|
|
25
|
+
| Prop | Type | Required | Default | Description |
|
|
26
|
+
|------|------|----------|---------|-------------|
|
|
27
|
+
| `children` | `ReactNode` | ✅ | | |
|
|
28
|
+
| `ref` | `Ref<HTMLDivElement>` | | | A ref to apply to the root element. |
|
|
29
|
+
|
|
30
|
+
### AnnouncementBanner.Header
|
|
31
|
+
|
|
32
|
+
| Prop | Type | Required | Default | Description |
|
|
33
|
+
|------|------|----------|---------|-------------|
|
|
34
|
+
| `children` | `ReactNode` | ✅ | | |
|
|
35
|
+
| `ref` | `Ref<HTMLSpanElement>` | | | A ref to apply to the root element. |
|
|
36
|
+
|
|
37
|
+
## Accessibility
|
|
38
|
+
|
|
39
|
+
## Implementation guidelines
|
|
40
|
+
|
|
41
|
+
Place `AnnouncementBanner` as the first child of its parent so content below is shifted down by the banner’s height. The banner stays in normal document flow (not sticky or fixed), so it does not overlay content underneath and does not obscure focused content (WCAG 2.2 SC 2.4.11 Focus Not Obscured).
|
|
42
|
+
|
|
43
|
+
### Content and meaning
|
|
44
|
+
|
|
45
|
+
- Put the announcement meaning in text. Status icons are decorative (`aria-hidden` on the icon wrapper) and reinforce the `variant` visually; do not rely on color or the icon alone to convey severity (WCAG 2.2 SC 1.4.1 Use of Color). Prefer wording such as “Warning: …” or “Error: …”.
|
|
46
|
+
- `info`, `warning`, and `danger` always use the built-in status icons. For `discovery` and `neutral`, pass `icon` to replace Sparkles or Bolt; custom icons stay decorative through the same wrapper.
|
|
47
|
+
|
|
48
|
+
### Live region semantics
|
|
49
|
+
|
|
50
|
+
The time at which a banner appears and its urgency are separate concerns:
|
|
51
|
+
|
|
52
|
+
- `variant` communicates visual meaning and never enables a live region.
|
|
53
|
+
- `liveRegion` controls whether a new or updated header is announced (WCAG 2.2 SC 4.1.3 Status Messages).
|
|
54
|
+
|
|
55
|
+
Use `liveRegion` only when a banner appears or changes after the page is ready and the user may already be interacting with it. Omit it for banners that are part of the initial page or shell render, including important `warning` and `danger` banners. Data that resolves as part of normal initial page loading does not necessarily make a banner a live update.
|
|
56
|
+
|
|
57
|
+
| `liveRegion` | Behavior | Use when |
|
|
58
|
+
| --- | --- | --- |
|
|
59
|
+
| `"status"` | Uses `role="status"` (`aria-live="polite"`) | New information is useful but can wait until the screen reader reaches a natural pause. |
|
|
60
|
+
| `"alert"` | Uses `role="alert"` (`aria-live="assertive"`) | New information is sufficiently urgent that interrupting the user is justified. |
|
|
61
|
+
| omitted | No live region | The banner is present during initial rendering, regardless of its visual severity. |
|
|
62
|
+
|
|
63
|
+
| Scenario | Recommended semantics |
|
|
64
|
+
| --- | --- |
|
|
65
|
+
| A deprecation, license, payment, or service warning is present during initial rendering | Omit `liveRegion`; choose an appropriate `variant` |
|
|
66
|
+
| A campaign or informational message appears later from polling or an event | `liveRegion="status"` |
|
|
67
|
+
| A connection loss, session expiry, or other urgent message appears later | `liveRegion="alert"` |
|
|
68
|
+
|
|
69
|
+
For reliable announcements across screen readers, the component mounts an empty, visually hidden live region before adding the message after a short delay. Only the text in `AnnouncementBanner.Header` is copied into that region; action and close controls remain available through normal keyboard and screen reader navigation without being duplicated in the announcement. `aria-atomic="true"` is set explicitly for interoperability. Do not add a redundant `aria-live` attribute, because combining it with `role="alert"` can cause duplicate announcements in VoiceOver on iOS.
|
|
70
|
+
|
|
71
|
+
### Interactive controls
|
|
72
|
+
|
|
73
|
+
- When `isCloseable` is `true`, the close control is a keyboard-operable button labeled “Close”.
|
|
74
|
+
- Action buttons passed into `AnnouncementBanner.Actions` must have accessible names (visible text or `aria-label`).
|
|
75
|
+
|
|
76
|
+
### Reflow and target size
|
|
77
|
+
|
|
78
|
+
- Narrow widths are supported without horizontal scrolling (WCAG 2.2 SC 1.4.10 Reflow): below `512px` of banner width the message and actions stack, and long or unbreakable strings (such as URLs) wrap, so the banner reflows down to a 320px viewport / 400% zoom without a horizontal scrollbar.
|
|
79
|
+
- Close and action controls meet the 24×24 CSS pixel minimum target size (WCAG 2.2 SC 2.5.8 Target Size Minimum).
|
|
80
|
+
|
|
81
|
+
## Examples
|
|
82
|
+
|
|
83
|
+
### Default
|
|
84
|
+
|
|
85
|
+
```tsx
|
|
86
|
+
import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';
|
|
87
|
+
|
|
88
|
+
import { AnnouncementBanner } from '@neo4j-ndl/react';
|
|
89
|
+
|
|
90
|
+
const Component = () => {
|
|
91
|
+
return (
|
|
92
|
+
<AnnouncementBanner variant="info" hasIcon={true}>
|
|
93
|
+
<AnnouncementBanner.Header>
|
|
94
|
+
Scheduled maintenance starts tonight at 22:00 UTC.
|
|
95
|
+
</AnnouncementBanner.Header>
|
|
96
|
+
</AnnouncementBanner>
|
|
97
|
+
);
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
export default Component;
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### Closeable
|
|
104
|
+
|
|
105
|
+
```tsx
|
|
106
|
+
import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';
|
|
107
|
+
|
|
108
|
+
import { AnnouncementBanner } from '@neo4j-ndl/react';
|
|
109
|
+
|
|
110
|
+
const Component = () => {
|
|
111
|
+
return (
|
|
112
|
+
<AnnouncementBanner
|
|
113
|
+
isCloseable={true}
|
|
114
|
+
onClose={() => alert('Announcement banner closed')}
|
|
115
|
+
>
|
|
116
|
+
<AnnouncementBanner.Header>
|
|
117
|
+
This announcement can be dismissed.
|
|
118
|
+
</AnnouncementBanner.Header>
|
|
119
|
+
</AnnouncementBanner>
|
|
120
|
+
);
|
|
121
|
+
};
|
|
122
|
+
|
|
123
|
+
export default Component;
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Custom Icons
|
|
127
|
+
|
|
128
|
+
```tsx
|
|
129
|
+
import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';
|
|
130
|
+
|
|
131
|
+
import { AnnouncementBanner } from '@neo4j-ndl/react';
|
|
132
|
+
import { GiftIconSolid, RocketLaunchIconSolid } from '@neo4j-ndl/react/icons';
|
|
133
|
+
|
|
134
|
+
const Component = () => {
|
|
135
|
+
return (
|
|
136
|
+
<div className="n-flex n-flex-col n-gap-token-8 n-w-full">
|
|
137
|
+
<AnnouncementBanner variant="discovery" hasIcon={true}>
|
|
138
|
+
<AnnouncementBanner.Header>
|
|
139
|
+
Discovery with the default Sparkles icon
|
|
140
|
+
</AnnouncementBanner.Header>
|
|
141
|
+
</AnnouncementBanner>
|
|
142
|
+
<AnnouncementBanner
|
|
143
|
+
variant="discovery"
|
|
144
|
+
hasIcon={true}
|
|
145
|
+
icon={<GiftIconSolid />}
|
|
146
|
+
>
|
|
147
|
+
<AnnouncementBanner.Header>
|
|
148
|
+
Discovery with a custom gift icon
|
|
149
|
+
</AnnouncementBanner.Header>
|
|
150
|
+
</AnnouncementBanner>
|
|
151
|
+
<AnnouncementBanner variant="neutral" hasIcon={true}>
|
|
152
|
+
<AnnouncementBanner.Header>
|
|
153
|
+
Neutral with the default Bolt icon
|
|
154
|
+
</AnnouncementBanner.Header>
|
|
155
|
+
</AnnouncementBanner>
|
|
156
|
+
<AnnouncementBanner
|
|
157
|
+
variant="neutral"
|
|
158
|
+
hasIcon={true}
|
|
159
|
+
icon={<RocketLaunchIconSolid />}
|
|
160
|
+
>
|
|
161
|
+
<AnnouncementBanner.Header>
|
|
162
|
+
Neutral with a custom rocket icon
|
|
163
|
+
</AnnouncementBanner.Header>
|
|
164
|
+
</AnnouncementBanner>
|
|
165
|
+
</div>
|
|
166
|
+
);
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
export default Component;
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
### Injected Non Urgent
|
|
173
|
+
|
|
174
|
+
```tsx
|
|
175
|
+
import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';
|
|
176
|
+
|
|
177
|
+
import {
|
|
178
|
+
AnnouncementBanner,
|
|
179
|
+
OutlinedButton,
|
|
180
|
+
Typography,
|
|
181
|
+
} from '@neo4j-ndl/react';
|
|
182
|
+
import { useState } from 'react';
|
|
183
|
+
|
|
184
|
+
const Component = () => {
|
|
185
|
+
const [isVisible, setIsVisible] = useState(false);
|
|
186
|
+
|
|
187
|
+
return (
|
|
188
|
+
<div className="n-flex n-flex-col n-w-full">
|
|
189
|
+
{isVisible && (
|
|
190
|
+
<AnnouncementBanner
|
|
191
|
+
variant="discovery"
|
|
192
|
+
hasIcon={true}
|
|
193
|
+
liveRegion="status"
|
|
194
|
+
isCloseable={true}
|
|
195
|
+
onClose={() => setIsVisible(false)}
|
|
196
|
+
>
|
|
197
|
+
<AnnouncementBanner.Header>
|
|
198
|
+
New Aura features are available for your organization.
|
|
199
|
+
</AnnouncementBanner.Header>
|
|
200
|
+
</AnnouncementBanner>
|
|
201
|
+
)}
|
|
202
|
+
<div className="n-flex n-flex-col n-gap-token-16 n-p-token-24 n-bg-neutral-bg-default">
|
|
203
|
+
<OutlinedButton onClick={() => setIsVisible((visible) => !visible)}>
|
|
204
|
+
{isVisible ? 'Hide announcement' : 'Show announcement'}
|
|
205
|
+
</OutlinedButton>
|
|
206
|
+
<Typography variant="body-medium">
|
|
207
|
+
The page is already loaded. Toggle the announcement in to simulate a
|
|
208
|
+
later campaign or poll. <code>liveRegion="status"</code>{' '}
|
|
209
|
+
announces politely without interrupting.
|
|
210
|
+
</Typography>
|
|
211
|
+
</div>
|
|
212
|
+
</div>
|
|
213
|
+
);
|
|
214
|
+
};
|
|
215
|
+
|
|
216
|
+
export default Component;
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
### Injected Urgent
|
|
220
|
+
|
|
221
|
+
```tsx
|
|
222
|
+
import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';
|
|
223
|
+
|
|
224
|
+
import {
|
|
225
|
+
AnnouncementBanner,
|
|
226
|
+
OutlinedButton,
|
|
227
|
+
Typography,
|
|
228
|
+
} from '@neo4j-ndl/react';
|
|
229
|
+
import { useState } from 'react';
|
|
230
|
+
|
|
231
|
+
const Component = () => {
|
|
232
|
+
const [isVisible, setIsVisible] = useState(false);
|
|
233
|
+
|
|
234
|
+
return (
|
|
235
|
+
<div className="n-flex n-flex-col n-w-full">
|
|
236
|
+
{isVisible && (
|
|
237
|
+
<AnnouncementBanner variant="danger" hasIcon={true} liveRegion="alert">
|
|
238
|
+
<AnnouncementBanner.Header>
|
|
239
|
+
Error: connection to the database was lost. Reconnecting…
|
|
240
|
+
</AnnouncementBanner.Header>
|
|
241
|
+
</AnnouncementBanner>
|
|
242
|
+
)}
|
|
243
|
+
<div className="n-flex n-flex-col n-gap-token-16 n-p-token-24 n-bg-neutral-bg-default">
|
|
244
|
+
<OutlinedButton onClick={() => setIsVisible((visible) => !visible)}>
|
|
245
|
+
{isVisible ? 'Hide announcement' : 'Show announcement'}
|
|
246
|
+
</OutlinedButton>
|
|
247
|
+
<Typography variant="body-medium">
|
|
248
|
+
The page is already loaded. Toggle the announcement in to simulate a
|
|
249
|
+
connection loss or session expiry.{' '}
|
|
250
|
+
<code>liveRegion="alert"</code> interrupts the screen reader
|
|
251
|
+
because the message is time-sensitive.
|
|
252
|
+
</Typography>
|
|
253
|
+
</div>
|
|
254
|
+
</div>
|
|
255
|
+
);
|
|
256
|
+
};
|
|
257
|
+
|
|
258
|
+
export default Component;
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
### Present At Page Render
|
|
262
|
+
|
|
263
|
+
```tsx
|
|
264
|
+
import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';
|
|
265
|
+
|
|
266
|
+
import { AnnouncementBanner, Typography } from '@neo4j-ndl/react';
|
|
267
|
+
|
|
268
|
+
const Component = () => {
|
|
269
|
+
return (
|
|
270
|
+
<div className="n-flex n-flex-col n-w-full">
|
|
271
|
+
<AnnouncementBanner variant="danger" hasIcon={true}>
|
|
272
|
+
<AnnouncementBanner.Header>
|
|
273
|
+
Warning: your marketplace subscription will be deprecated on September
|
|
274
|
+
19, 2026.
|
|
275
|
+
</AnnouncementBanner.Header>
|
|
276
|
+
</AnnouncementBanner>
|
|
277
|
+
<div className="n-p-token-24 n-bg-neutral-bg-default">
|
|
278
|
+
<Typography variant="body-medium">
|
|
279
|
+
This banner is part of the initial page render, so `liveRegion` is
|
|
280
|
+
omitted. Screen reader users hear it when they reach it in the page,
|
|
281
|
+
not as an interruption.
|
|
282
|
+
</Typography>
|
|
283
|
+
</div>
|
|
284
|
+
</div>
|
|
285
|
+
);
|
|
286
|
+
};
|
|
287
|
+
|
|
288
|
+
export default Component;
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
### Variants
|
|
292
|
+
|
|
293
|
+
```tsx
|
|
294
|
+
import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';
|
|
295
|
+
|
|
296
|
+
import { AnnouncementBanner } from '@neo4j-ndl/react';
|
|
297
|
+
|
|
298
|
+
const Component = () => {
|
|
299
|
+
return (
|
|
300
|
+
<div className="n-flex n-flex-col n-gap-token-8 n-w-full">
|
|
301
|
+
<AnnouncementBanner variant="info" hasIcon={true}>
|
|
302
|
+
<AnnouncementBanner.Header>Info announcement</AnnouncementBanner.Header>
|
|
303
|
+
</AnnouncementBanner>
|
|
304
|
+
<AnnouncementBanner variant="warning" hasIcon={true}>
|
|
305
|
+
<AnnouncementBanner.Header>
|
|
306
|
+
Warning announcement
|
|
307
|
+
</AnnouncementBanner.Header>
|
|
308
|
+
</AnnouncementBanner>
|
|
309
|
+
<AnnouncementBanner variant="danger" hasIcon={true}>
|
|
310
|
+
<AnnouncementBanner.Header>
|
|
311
|
+
Danger announcement
|
|
312
|
+
</AnnouncementBanner.Header>
|
|
313
|
+
</AnnouncementBanner>
|
|
314
|
+
<AnnouncementBanner variant="discovery" hasIcon={true}>
|
|
315
|
+
<AnnouncementBanner.Header>
|
|
316
|
+
Discovery announcement
|
|
317
|
+
</AnnouncementBanner.Header>
|
|
318
|
+
</AnnouncementBanner>
|
|
319
|
+
<AnnouncementBanner variant="neutral" hasIcon={true}>
|
|
320
|
+
<AnnouncementBanner.Header>
|
|
321
|
+
Neutral announcement
|
|
322
|
+
</AnnouncementBanner.Header>
|
|
323
|
+
</AnnouncementBanner>
|
|
324
|
+
</div>
|
|
325
|
+
);
|
|
326
|
+
};
|
|
327
|
+
|
|
328
|
+
export default Component;
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
### With Actions
|
|
332
|
+
|
|
333
|
+
```tsx
|
|
334
|
+
import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';
|
|
335
|
+
|
|
336
|
+
import {
|
|
337
|
+
AnnouncementBanner,
|
|
338
|
+
OutlinedButton,
|
|
339
|
+
TextButton,
|
|
340
|
+
} from '@neo4j-ndl/react';
|
|
341
|
+
|
|
342
|
+
const Component = () => {
|
|
343
|
+
return (
|
|
344
|
+
<AnnouncementBanner hasIcon={true} variant="warning">
|
|
345
|
+
<AnnouncementBanner.Header>
|
|
346
|
+
Your trial ends in 3 days.
|
|
347
|
+
</AnnouncementBanner.Header>
|
|
348
|
+
<AnnouncementBanner.Actions>
|
|
349
|
+
<OutlinedButton>Upgrade</OutlinedButton>
|
|
350
|
+
<TextButton>Learn more</TextButton>
|
|
351
|
+
</AnnouncementBanner.Actions>
|
|
352
|
+
</AnnouncementBanner>
|
|
353
|
+
);
|
|
354
|
+
};
|
|
355
|
+
|
|
356
|
+
export default Component;
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
### With Page Content
|
|
360
|
+
|
|
361
|
+
```tsx
|
|
362
|
+
import '@neo4j-ndl/base/lib/neo4j-ds-styles.css';
|
|
363
|
+
|
|
364
|
+
import {
|
|
365
|
+
AnnouncementBanner,
|
|
366
|
+
OutlinedButton,
|
|
367
|
+
TextButton,
|
|
368
|
+
Typography,
|
|
369
|
+
} from '@neo4j-ndl/react';
|
|
370
|
+
import { useState } from 'react';
|
|
371
|
+
|
|
372
|
+
const Component = () => {
|
|
373
|
+
const [isVisible, setIsVisible] = useState(true);
|
|
374
|
+
|
|
375
|
+
return (
|
|
376
|
+
<div className="n-flex n-flex-col n-max-w-[768px] n-h-52">
|
|
377
|
+
{isVisible && (
|
|
378
|
+
<AnnouncementBanner
|
|
379
|
+
variant="warning"
|
|
380
|
+
hasIcon={true}
|
|
381
|
+
isCloseable={true}
|
|
382
|
+
onClose={() => setIsVisible(false)}
|
|
383
|
+
>
|
|
384
|
+
<AnnouncementBanner.Header>
|
|
385
|
+
Scheduled maintenance starts tonight at 22:00 UTC.
|
|
386
|
+
</AnnouncementBanner.Header>
|
|
387
|
+
<AnnouncementBanner.Actions>
|
|
388
|
+
<OutlinedButton>Learn more</OutlinedButton>
|
|
389
|
+
</AnnouncementBanner.Actions>
|
|
390
|
+
</AnnouncementBanner>
|
|
391
|
+
)}
|
|
392
|
+
<div className="n-flex n-flex-col n-gap-token-16 n-p-token-24 n-bg-neutral-bg-default n-flex-1 n-min-h-0 n-overflow-y-auto">
|
|
393
|
+
{!isVisible && (
|
|
394
|
+
<div>
|
|
395
|
+
<TextButton onClick={() => setIsVisible(true)}>
|
|
396
|
+
Show announcement again
|
|
397
|
+
</TextButton>
|
|
398
|
+
</div>
|
|
399
|
+
)}
|
|
400
|
+
<Typography variant="title-2">Page title</Typography>
|
|
401
|
+
<OutlinedButton>Can focus</OutlinedButton>
|
|
402
|
+
<Typography variant="body-medium">
|
|
403
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque
|
|
404
|
+
tempus, quam non molestie faucibus, orci nibh bibendum urna, ut
|
|
405
|
+
lacinia orci dui a augue. Nullam at risus quam. Fusce pulvinar, metus
|
|
406
|
+
vitae finibus dapibus, nisi ipsum venenatis sapien, at facilisis eros
|
|
407
|
+
massa ac nunc. Aliquam sed odio orci. Vivamus condimentum sit amet
|
|
408
|
+
ipsum bibendum sollicitudin. Etiam eget vehicula urna, et ullamcorper
|
|
409
|
+
libero. Interdum et malesuada fames ac ante ipsum primis in faucibus.
|
|
410
|
+
Proin sodales euismod sem, posuere maximus libero interdum semper.
|
|
411
|
+
Nunc mollis posuere arcu non elementum. Vivamus sed laoreet mauris.
|
|
412
|
+
Etiam fringilla arcu convallis erat vehicula iaculis. Pellentesque
|
|
413
|
+
dictum aliquam cursus.
|
|
414
|
+
</Typography>
|
|
415
|
+
<Typography variant="body-medium">
|
|
416
|
+
Integer vehicula turpis quis risus aliquet congue. Vivamus
|
|
417
|
+
pellentesque nibh ac blandit varius. Fusce placerat lacus ut mauris
|
|
418
|
+
porta, nec facilisis risus pulvinar. Nullam elementum nulla ut laoreet
|
|
419
|
+
imperdiet. Maecenas eget erat erat. Phasellus in turpis placerat,
|
|
420
|
+
imperdiet ante nec, tincidunt nisl. Donec a lacus neque. Nullam
|
|
421
|
+
iaculis ante molestie ultrices semper. Sed non lorem ullamcorper
|
|
422
|
+
ligula elementum convallis. Aenean egestas risus quis tortor cursus
|
|
423
|
+
dapibus. Nulla hendrerit at orci ut scelerisque. Nullam vel bibendum
|
|
424
|
+
tellus. Praesent efficitur ultrices lectus at posuere. Maecenas
|
|
425
|
+
facilisis lacus ac turpis malesuada, sit amet imperdiet ipsum
|
|
426
|
+
condimentum. Donec et nibh eget justo luctus ornare. Maecenas suscipit
|
|
427
|
+
nulla at ullamcorper congue.
|
|
428
|
+
</Typography>
|
|
429
|
+
<Typography variant="body-medium">
|
|
430
|
+
Vestibulum vehicula nibh mi, ultrices condimentum massa venenatis sit
|
|
431
|
+
amet. Pellentesque accumsan mollis ex, id lobortis lacus venenatis id.
|
|
432
|
+
Proin sem dui, mollis id gravida ac, vulputate et lacus. In pharetra
|
|
433
|
+
nunc odio, in fermentum elit dignissim at. Nunc ut justo elit. Proin
|
|
434
|
+
ligula orci, faucibus vitae vehicula nec, faucibus sit amet erat.
|
|
435
|
+
Interdum et malesuada fames ac ante ipsum primis in faucibus. Quisque
|
|
436
|
+
pharetra venenatis rutrum. Sed pharetra turpis id arcu maximus,
|
|
437
|
+
interdum rhoncus eros mollis. Donec vitae sapien et odio interdum
|
|
438
|
+
bibendum. Quisque eleifend, sem ut ornare mollis, orci nunc dapibus
|
|
439
|
+
odio, aliquam fringilla augue nulla id magna. Phasellus consectetur,
|
|
440
|
+
velit egestas sodales ultricies, odio nunc facilisis libero, vel
|
|
441
|
+
vehicula nisi quam quis nisl. Proin vel massa libero.
|
|
442
|
+
</Typography>
|
|
443
|
+
<Typography variant="body-medium">
|
|
444
|
+
Sed mollis lacinia tincidunt. Curabitur blandit pellentesque
|
|
445
|
+
consequat. Maecenas mollis pharetra dolor in ornare. Cras vel nibh eu
|
|
446
|
+
nisi venenatis convallis id vel nisl. Curabitur et viverra nisl.
|
|
447
|
+
Phasellus et finibus turpis. Praesent scelerisque vel lectus at
|
|
448
|
+
imperdiet. Curabitur porta egestas magna ullamcorper hendrerit.
|
|
449
|
+
</Typography>
|
|
450
|
+
<Typography variant="body-medium">
|
|
451
|
+
Curabitur hendrerit egestas mi, ut venenatis turpis sagittis nec.
|
|
452
|
+
Proin consectetur, nisi et vehicula placerat, tellus augue luctus
|
|
453
|
+
odio, in commodo mauris urna nec libero. Maecenas eu placerat sapien,
|
|
454
|
+
in aliquam tellus. Sed pharetra nunc id urna iaculis tincidunt. In hac
|
|
455
|
+
habitasse platea dictumst. Donec tincidunt risus vitae congue congue.
|
|
456
|
+
Fusce consequat ut justo ut tristique. Nunc ut urna quis neque
|
|
457
|
+
consequat venenatis. Praesent nec feugiat orci. Vestibulum rutrum dui
|
|
458
|
+
lacus, sit amet vulputate dolor finibus ut. Donec placerat urna eu
|
|
459
|
+
fringilla convallis. Praesent sollicitudin felis at lacus semper, vel
|
|
460
|
+
convallis magna scelerisque.
|
|
461
|
+
</Typography>
|
|
462
|
+
</div>
|
|
463
|
+
</div>
|
|
464
|
+
);
|
|
465
|
+
};
|
|
466
|
+
|
|
467
|
+
export default Component;
|
|
468
|
+
```
|