@justeattakeaway/pie-notification 0.6.1 → 0.7.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.
@@ -261,6 +261,15 @@
261
261
  "privacy": "public",
262
262
  "attribute": "hasStackedActions"
263
263
  },
264
+ {
265
+ "kind": "field",
266
+ "name": "aria",
267
+ "type": {
268
+ "text": "NotificationProps['aria']"
269
+ },
270
+ "privacy": "public",
271
+ "attribute": "aria"
272
+ },
264
273
  {
265
274
  "kind": "field",
266
275
  "name": "_iconSlot",
@@ -568,6 +577,13 @@
568
577
  {
569
578
  "name": "hasStackedActions",
570
579
  "fieldName": "hasStackedActions"
580
+ },
581
+ {
582
+ "name": "aria",
583
+ "type": {
584
+ "text": "NotificationProps['aria']"
585
+ },
586
+ "fieldName": "aria"
571
587
  }
572
588
  ],
573
589
  "superclass": {
package/dist/index.d.ts CHANGED
@@ -16,6 +16,11 @@ export declare type ActionProps = {
16
16
  ariaLabel?: string;
17
17
  };
18
18
 
19
+ export declare type AriaProps = {
20
+ close?: string;
21
+ label?: string;
22
+ };
23
+
19
24
  export declare const componentClass = "c-notification";
20
25
 
21
26
  export declare const componentSelector = "pie-notification";
@@ -71,6 +76,11 @@ export declare interface NotificationProps {
71
76
  * When true, the notification will stack the action buttons on narrow screens.
72
77
  */
73
78
  hasStackedActions?: boolean;
79
+ /**
80
+ * The ARIA labels used for various parts of the notification.
81
+ * Only pass label if there is no heading to ensure the region is announced with a title
82
+ */
83
+ aria?: AriaProps;
74
84
  }
75
85
 
76
86
  /**
@@ -120,6 +130,7 @@ export declare class PieNotification extends LitElement implements NotificationP
120
130
  leadingAction: NotificationProps['leadingAction'];
121
131
  supportingAction: NotificationProps['supportingAction'];
122
132
  hasStackedActions: boolean;
133
+ aria: NotificationProps['aria'];
123
134
  _iconSlot: Array<HTMLElement>;
124
135
  protected _hasExternalIcon: boolean;
125
136
  protected _hasIconClass: boolean;
package/dist/index.js CHANGED
@@ -1,7 +1,8 @@
1
- import { unsafeCSS as O, LitElement as x, nothing as c } from "lit";
2
- import { html as d, unsafeStatic as E } from "lit/static-html.js";
3
- import { validPropertyValues as v, defineCustomElement as k, dispatchCustomEvent as g } from "@justeattakeaway/pie-webc-core";
4
- import { property as l, queryAssignedElements as w, state as $ } from "lit/decorators.js";
1
+ import { unsafeCSS as E, LitElement as k, nothing as c } from "lit";
2
+ import { html as d, unsafeStatic as w } from "lit/static-html.js";
3
+ import { validPropertyValues as m, defineCustomElement as A, dispatchCustomEvent as v } from "@justeattakeaway/pie-webc-core";
4
+ import { property as r, queryAssignedElements as z, state as C } from "lit/decorators.js";
5
+ import { ifDefined as I } from "lit/directives/if-defined.js";
5
6
  import "@justeattakeaway/pie-button";
6
7
  import "@justeattakeaway/pie-icon-button";
7
8
  import "@justeattakeaway/pie-icons-webc/dist/IconAlertCircle.js";
@@ -9,7 +10,7 @@ import "@justeattakeaway/pie-icons-webc/dist/IconAlertTriangle.js";
9
10
  import "@justeattakeaway/pie-icons-webc/dist/IconCheckCircle.js";
10
11
  import "@justeattakeaway/pie-icons-webc/dist/IconClose.js";
11
12
  import "@justeattakeaway/pie-icons-webc/dist/IconInfoCircle.js";
12
- const A = ["neutral", "neutral-alternative", "info", "success", "warning", "error"], z = ["h2", "h3", "h4", "h5", "h6"], S = ["inline-content", "full-width"], o = "pie-notification", h = "c-notification", D = `${o}-close`, V = `${o}-open`, T = `${o}-leading-action-click`, B = `${o}-supporting-action-click`, r = {
13
+ const S = ["neutral", "neutral-alternative", "info", "success", "warning", "error"], D = ["h2", "h3", "h4", "h5", "h6"], V = ["inline-content", "full-width"], t = "pie-notification", h = "c-notification", T = `${t}-close`, B = `${t}-open`, L = `${t}-leading-action-click`, P = `${t}-supporting-action-click`, l = {
13
14
  isOpen: !0,
14
15
  variant: "neutral",
15
16
  position: "inline-content",
@@ -18,16 +19,16 @@ const A = ["neutral", "neutral-alternative", "info", "success", "warning", "erro
18
19
  headingLevel: "h2",
19
20
  hideIcon: !1,
20
21
  hasStackedActions: !1
21
- }, L = `*,*:after,*:before{box-sizing:inherit}.c-notification{--notification-border-radius: var(--dt-radius-rounded-c);--notification-background-color: var(--dt-color-container-subtle);--notification-direction: column;--notification-heading-font-size: calc(var(--dt-font-heading-s-size--narrow) * 1px);--notification-heading-line-height: calc(var(--dt-font-heading-s-line-height--narrow) * 1px);--notification-font-size: calc(var(--dt-font-body-l-size) * 1px);--notification-line-height: calc(var(--dt-font-body-l-line-height) * 1px);--notification-icon-fill: var(--dt-color-content-default);--notification-close-icon-offset: var(--dt-spacing-b);--notification-heading-icon-offset: 2px;padding:var(--dt-spacing-d);border-radius:var(--notification-border-radius);background-color:var(--notification-background-color);position:relative;display:flex;flex-direction:var(--notification-direction);gap:var(--dt-spacing-d);font-size:var(--notification-font-size);line-height:var(--notification-line-height)}.c-notification[isCompact]{--notification-direction: row}.c-notification[position=full-width]{--notification-border-radius: var(--dt-radius-rounded-none)}.c-notification[variant=neutral-alternative]{--notification-background-color: var(--dt-color-container-default)}.c-notification[variant=info]{--notification-background-color: var(--dt-color-support-info-02);--notification-icon-fill: var(--dt-color-blue)}.c-notification[variant=success]{--notification-background-color: var(--dt-color-support-positive-02)}.c-notification[variant=warning]{--notification-background-color: var(--dt-color-support-warning-02)}.c-notification[variant=error]{--notification-background-color: var(--dt-color-support-error-02);--notification-icon-fill: var(--dt-color-red)}.c-notification-heading{margin:0;margin-block-end:var(--dt-spacing-a);font-size:var(--notification-heading-font-size);line-height:var(--notification-heading-line-height)}@media (min-width: 768px){.c-notification-heading{--notification-heading-font-size: calc(var(--dt-font-heading-s-size--wide) * 1px);--notification-heading-line-height: calc(var(--dt-font-heading-s-line-height--wide) * 1px)}}.c-notification-content-section{display:flex;flex-direction:row}.c-notification-content-section .has-icon{display:block ruby;margin-inline-end:var(--dt-spacing-c)}.c-notification-content-section[isDismissible]{max-width:calc(100% - var(--notification-close-icon-offset) - 40px)}.c-notification-heading-icon{padding-block-start:var(--notification-heading-icon-offset);color:var(--notification-icon-fill)}.c-notification-icon-close{position:absolute;inset-block-start:var(--notification-close-icon-offset);inset-inline-end:var(--notification-close-icon-offset)}.c-notification-footer{display:flex;flex-direction:row;justify-content:flex-end;gap:var(--dt-spacing-d)}.c-notification-footer[isCompact]{align-self:flex-end}@media (max-width: 768px){.c-notification-footer[isStacked]{flex-direction:column-reverse}}
22
+ }, F = `*,*:after,*:before{box-sizing:inherit}.c-notification{--notification-border-radius: var(--dt-radius-rounded-c);--notification-background-color: var(--dt-color-container-subtle);--notification-direction: column;--notification-heading-font-size: calc(var(--dt-font-heading-s-size--narrow) * 1px);--notification-heading-line-height: calc(var(--dt-font-heading-s-line-height--narrow) * 1px);--notification-font-size: calc(var(--dt-font-body-l-size) * 1px);--notification-line-height: calc(var(--dt-font-body-l-line-height) * 1px);--notification-icon-fill: var(--dt-color-content-default);--notification-close-icon-offset: var(--dt-spacing-b);--notification-heading-icon-offset: 2px;padding:var(--dt-spacing-d);border-radius:var(--notification-border-radius);background-color:var(--notification-background-color);position:relative;display:flex;flex-direction:var(--notification-direction);gap:var(--dt-spacing-d);font-size:var(--notification-font-size);line-height:var(--notification-line-height)}.c-notification[isCompact]{--notification-direction: row}.c-notification[position=full-width]{--notification-border-radius: var(--dt-radius-rounded-none)}.c-notification[variant=neutral-alternative]{--notification-background-color: var(--dt-color-container-default)}.c-notification[variant=info]{--notification-background-color: var(--dt-color-support-info-02);--notification-icon-fill: var(--dt-color-blue)}.c-notification[variant=success]{--notification-background-color: var(--dt-color-support-positive-02)}.c-notification[variant=warning]{--notification-background-color: var(--dt-color-support-warning-02)}.c-notification[variant=error]{--notification-background-color: var(--dt-color-support-error-02);--notification-icon-fill: var(--dt-color-red)}.c-notification-heading{margin:0;margin-block-end:var(--dt-spacing-a);font-size:var(--notification-heading-font-size);line-height:var(--notification-heading-line-height)}@media (min-width: 768px){.c-notification-heading{--notification-heading-font-size: calc(var(--dt-font-heading-s-size--wide) * 1px);--notification-heading-line-height: calc(var(--dt-font-heading-s-line-height--wide) * 1px)}}.c-notification-content-section{display:flex;flex-direction:row}.c-notification-content-section .has-icon{display:block ruby;margin-inline-end:var(--dt-spacing-c)}.c-notification-content-section[isDismissible]{max-width:calc(100% - var(--notification-close-icon-offset) - 40px)}.c-notification-heading-icon{padding-block-start:var(--notification-heading-icon-offset);color:var(--notification-icon-fill)}.c-notification-icon-close{position:absolute;inset-block-start:var(--notification-close-icon-offset);inset-inline-end:var(--notification-close-icon-offset)}.c-notification-footer{display:flex;flex-direction:row;justify-content:flex-end;gap:var(--dt-spacing-d)}.c-notification-footer[isCompact]{align-self:flex-end}@media (max-width: 768px){.c-notification-footer[isStacked]{flex-direction:column-reverse}}
22
23
  `;
23
- var P = Object.defineProperty, F = Object.getOwnPropertyDescriptor, e = (u, i, t, a) => {
24
- for (var s = a > 1 ? void 0 : a ? F(i, t) : i, f = u.length - 1, p; f >= 0; f--)
25
- (p = u[f]) && (s = (a ? p(i, t, s) : p(s)) || s);
26
- return a && s && P(i, t, s), s;
24
+ var j = Object.defineProperty, H = Object.getOwnPropertyDescriptor, e = (u, i, o, a) => {
25
+ for (var s = a > 1 ? void 0 : a ? H(i, o) : i, f = u.length - 1, p; f >= 0; f--)
26
+ (p = u[f]) && (s = (a ? p(i, o, s) : p(s)) || s);
27
+ return a && s && j(i, o, s), s;
27
28
  };
28
- class n extends x {
29
+ class n extends k {
29
30
  constructor() {
30
- super(...arguments), this.isOpen = r.isOpen, this.variant = r.variant, this.position = r.position, this.isDismissible = r.isDismissible, this.isCompact = r.isCompact, this.headingLevel = r.headingLevel, this.hideIcon = r.hideIcon, this.hasStackedActions = r.hasStackedActions, this._hasExternalIcon = !1, this._hasIconClass = !1;
31
+ super(...arguments), this.isOpen = l.isOpen, this.variant = l.variant, this.position = l.position, this.isDismissible = l.isDismissible, this.isCompact = l.isCompact, this.headingLevel = l.headingLevel, this.hideIcon = l.hideIcon, this.hasStackedActions = l.hasStackedActions, this._hasExternalIcon = !1, this._hasIconClass = !1;
31
32
  }
32
33
  /**
33
34
  * Lifecycle method executed when component is about to update.
@@ -42,7 +43,7 @@ class n extends x {
42
43
  * It applies a gutter if there's no heading content in order to avoid the close button overlap the content.
43
44
  */
44
45
  updated(i) {
45
- i.has("isOpen") && this.isOpen && g(this, V, { targetNotification: this });
46
+ i.has("isOpen") && this.isOpen && v(this, B, { targetNotification: this });
46
47
  }
47
48
  /**
48
49
  * Method responsible to check if an external icon has been provided.
@@ -59,10 +60,10 @@ class n extends x {
59
60
  *
60
61
  * @private
61
62
  */
62
- renderFooter(i, t) {
63
+ renderFooter(i, o) {
63
64
  return d`
64
- <footer class="${h}-footer" data-test-id="${o}-footer" ?isCompact="${this.isCompact}" ?isStacked="${this.hasStackedActions && !this.isCompact}">
65
- ${t ? this.renderActionButton(t, "supporting") : c}
65
+ <footer class="${h}-footer" data-test-id="${t}-footer" ?isCompact="${this.isCompact}" ?isStacked="${this.hasStackedActions && !this.isCompact}">
66
+ ${o ? this.renderActionButton(o, "supporting") : c}
66
67
  ${i ? this.renderActionButton(i, "leading") : c}
67
68
  </footer>
68
69
  `;
@@ -76,8 +77,13 @@ class n extends x {
76
77
  *
77
78
  * @private
78
79
  */
79
- renderNotificationHeading(i, t) {
80
- return d`<${t} class="${h}-heading" data-test-id="${o}-heading">${i}</${t}>`;
80
+ renderNotificationHeading(i, o) {
81
+ return d`<${o}
82
+ id="${t}-heading"
83
+ class="${h}-heading"
84
+ data-test-id="${t}-heading">
85
+ ${i}
86
+ </${o}>`;
81
87
  }
82
88
  /**
83
89
  * Util method that returns a boolean if variant has a default icon.
@@ -99,13 +105,13 @@ class n extends x {
99
105
  getDefaultVariantIcon(i) {
100
106
  switch (i) {
101
107
  case "info":
102
- return d`<icon-info-circle size="m" data-test-id="${o}-heading-icon-info"></icon-info-circle>`;
108
+ return d`<icon-info-circle size="m" data-test-id="${t}-heading-icon-info"></icon-info-circle>`;
103
109
  case "success":
104
- return d`<icon-check-circle size="m" data-test-id="${o}-heading-icon-success"></icon-check-circle>`;
110
+ return d`<icon-check-circle size="m" data-test-id="${t}-heading-icon-success"></icon-check-circle>`;
105
111
  case "warning":
106
- return d`<icon-alert-triangle size="m" data-test-id="${o}-heading-icon-warning"></icon-alert-triangle>`;
112
+ return d`<icon-alert-triangle size="m" data-test-id="${t}-heading-icon-warning"></icon-alert-triangle>`;
107
113
  case "error":
108
- return d`<icon-alert-circle size="m" data-test-id="${o}-heading-icon-error"></icon-alert-circle>`;
114
+ return d`<icon-alert-circle size="m" data-test-id="${t}-heading-icon-error"></icon-alert-circle>`;
109
115
  default:
110
116
  return c;
111
117
  }
@@ -131,10 +137,10 @@ class n extends x {
131
137
  *
132
138
  * @private
133
139
  */
134
- renderIcon(i, t, a) {
140
+ renderIcon(i, o, a) {
135
141
  return d`
136
- <div data-test-id="${o}-icon-area" class="${a ? "has-icon " : ""}${h}-heading-icon">
137
- ${t ? c : this.renderIconVariant(i)}
142
+ <div data-test-id="${t}-icon-area" class="${a ? "has-icon " : ""}${h}-heading-icon">
143
+ ${o ? c : this.renderIconVariant(i)}
138
144
  <slot name="icon"></slot>
139
145
  </div>
140
146
  `;
@@ -146,13 +152,15 @@ class n extends x {
146
152
  * @private
147
153
  */
148
154
  renderCloseButton() {
155
+ var i;
149
156
  return d`
150
157
  <pie-icon-button
151
158
  variant="ghost-secondary"
152
159
  size="small"
153
160
  class="${h}-icon-close"
154
- data-test-id="${o}-icon-close"
161
+ data-test-id="${t}-icon-close"
155
162
  @click="${this.handleCloseButton}"
163
+ aria-label="${I((i = this.aria) == null ? void 0 : i.close)}"
156
164
  >
157
165
  <icon-close></icon-close>
158
166
  </pie-icon-button>`;
@@ -164,7 +172,7 @@ class n extends x {
164
172
  * @private
165
173
  */
166
174
  handleCloseButton() {
167
- this.closeNotificationComponent(), g(this, D, { targetNotification: this });
175
+ this.closeNotificationComponent(), v(this, T, { targetNotification: this });
168
176
  }
169
177
  /**
170
178
  * Util method responsible to close the component.
@@ -183,7 +191,7 @@ class n extends x {
183
191
  * @private
184
192
  */
185
193
  handleActionClick(i) {
186
- g(this, i === "leading" ? T : B, { targetNotification: this });
194
+ v(this, i === "leading" ? L : P, { targetNotification: this });
187
195
  }
188
196
  /**
189
197
  * Render the action button depending on action type and its action.
@@ -194,15 +202,15 @@ class n extends x {
194
202
  * @returns {TemplateResult | typeof nothing} - The rendered action button or nothing if the action text is not defined.
195
203
  * @private
196
204
  */
197
- renderActionButton(i, t) {
205
+ renderActionButton(i, o) {
198
206
  const { text: a, ariaLabel: s } = i;
199
207
  return a ? d`
200
208
  <pie-button
201
- variant="${t === "leading" ? "primary" : "ghost"}"
209
+ variant="${o === "leading" ? "primary" : "ghost"}"
202
210
  size="small-productive"
203
211
  aria-label="${s || c}"
204
- @click="${() => this.handleActionClick(t)}"
205
- data-test-id="${o}-${t}-action"
212
+ @click="${() => this.handleActionClick(o)}"
213
+ data-test-id="${t}-${o}-action"
206
214
  ?isFullWidth="${this.hasStackedActions}"
207
215
  type="button">
208
216
  ${a}
@@ -212,99 +220,107 @@ class n extends x {
212
220
  render() {
213
221
  const {
214
222
  variant: i,
215
- position: t,
223
+ position: o,
216
224
  heading: a,
217
225
  headingLevel: s,
218
226
  isDismissible: f,
219
227
  isCompact: p,
220
- _hasExternalIcon: I,
221
- hideIcon: C,
222
- _hasIconClass: y,
223
- leadingAction: m,
224
- supportingAction: _,
225
- isOpen: N
228
+ _hasExternalIcon: y,
229
+ hideIcon: _,
230
+ _hasIconClass: O,
231
+ leadingAction: b,
232
+ supportingAction: N,
233
+ isOpen: x,
234
+ aria: g
226
235
  } = this;
227
- if (!N)
236
+ if (!x)
228
237
  return c;
229
- const b = f && !p;
238
+ const $ = f && !p;
230
239
  return d`
231
240
  <div
232
- data-test-id="${o}"
241
+ data-test-id="${t}"
233
242
  class="${h}"
234
243
  variant="${i}"
235
- position="${t}"
236
- ?isCompact="${p}">
237
- ${b ? this.renderCloseButton() : c}
244
+ position="${o}"
245
+ ?isCompact="${p}"
246
+ role="region"
247
+ aria-live="${i === "error" ? "assertive" : "polite"}"
248
+ aria-labelledby="${a ? `${t}-heading` : c}"
249
+ aria-label="${!a && I(g == null ? void 0 : g.label)}">
250
+ ${$ ? this.renderCloseButton() : c}
238
251
 
239
- <section class="${h}-content-section" ?isDismissible="${b}">
240
- ${C ? c : this.renderIcon(i, I, y)}
252
+ <section class="${h}-content-section" ?isDismissible="${$}">
253
+ ${_ ? c : this.renderIcon(i, y, O)}
241
254
  <article>
242
- ${a ? this.renderNotificationHeading(a, E(s)) : c}
255
+ ${a ? this.renderNotificationHeading(a, w(s)) : c}
243
256
  <slot></slot>
244
257
  </article>
245
258
  </section>
246
259
 
247
- ${m ? this.renderFooter(m, _) : c}
260
+ ${b ? this.renderFooter(b, N) : c}
248
261
  </div>`;
249
262
  }
250
263
  }
251
- n.styles = O(L);
264
+ n.styles = E(F);
252
265
  e([
253
- l({ type: Boolean })
266
+ r({ type: Boolean })
254
267
  ], n.prototype, "isOpen", 2);
255
268
  e([
256
- l(),
257
- v(o, A, r.variant)
269
+ r(),
270
+ m(t, S, l.variant)
258
271
  ], n.prototype, "variant", 2);
259
272
  e([
260
- l(),
261
- v(o, S, r.position)
273
+ r(),
274
+ m(t, V, l.position)
262
275
  ], n.prototype, "position", 2);
263
276
  e([
264
- l({ type: Boolean })
277
+ r({ type: Boolean })
265
278
  ], n.prototype, "isDismissible", 2);
266
279
  e([
267
- l({ type: Boolean })
280
+ r({ type: Boolean })
268
281
  ], n.prototype, "isCompact", 2);
269
282
  e([
270
- l({ type: String })
283
+ r({ type: String })
271
284
  ], n.prototype, "heading", 2);
272
285
  e([
273
- l(),
274
- v(o, z, r.headingLevel)
286
+ r(),
287
+ m(t, D, l.headingLevel)
275
288
  ], n.prototype, "headingLevel", 2);
276
289
  e([
277
- l({ type: Boolean })
290
+ r({ type: Boolean })
278
291
  ], n.prototype, "hideIcon", 2);
279
292
  e([
280
- l({ type: Object })
293
+ r({ type: Object })
281
294
  ], n.prototype, "leadingAction", 2);
282
295
  e([
283
- l({ type: Object })
296
+ r({ type: Object })
284
297
  ], n.prototype, "supportingAction", 2);
285
298
  e([
286
- l({ type: Boolean })
299
+ r({ type: Boolean })
287
300
  ], n.prototype, "hasStackedActions", 2);
288
301
  e([
289
- w({ slot: "icon" })
302
+ r({ type: Object })
303
+ ], n.prototype, "aria", 2);
304
+ e([
305
+ z({ slot: "icon" })
290
306
  ], n.prototype, "_iconSlot", 2);
291
307
  e([
292
- $()
308
+ C()
293
309
  ], n.prototype, "_hasExternalIcon", 2);
294
310
  e([
295
- $()
311
+ C()
296
312
  ], n.prototype, "_hasIconClass", 2);
297
- k(o, n);
313
+ A(t, n);
298
314
  export {
299
- D as ON_NOTIFICATION_CLOSE_EVENT,
300
- T as ON_NOTIFICATION_LEADING_ACTION_CLICK_EVENT,
301
- V as ON_NOTIFICATION_OPEN_EVENT,
302
- B as ON_NOTIFICATION_SUPPORTING_ACTION_CLICK_EVENT,
315
+ T as ON_NOTIFICATION_CLOSE_EVENT,
316
+ L as ON_NOTIFICATION_LEADING_ACTION_CLICK_EVENT,
317
+ B as ON_NOTIFICATION_OPEN_EVENT,
318
+ P as ON_NOTIFICATION_SUPPORTING_ACTION_CLICK_EVENT,
303
319
  n as PieNotification,
304
320
  h as componentClass,
305
- o as componentSelector,
306
- r as defaultProps,
307
- z as headingLevels,
308
- S as positions,
309
- A as variants
321
+ t as componentSelector,
322
+ l as defaultProps,
323
+ D as headingLevels,
324
+ V as positions,
325
+ S as variants
310
326
  };
package/dist/react.d.ts CHANGED
@@ -17,6 +17,11 @@ export declare type ActionProps = {
17
17
  ariaLabel?: string;
18
18
  };
19
19
 
20
+ export declare type AriaProps = {
21
+ close?: string;
22
+ label?: string;
23
+ };
24
+
20
25
  export declare const componentClass = "c-notification";
21
26
 
22
27
  export declare const componentSelector = "pie-notification";
@@ -72,6 +77,11 @@ export declare interface NotificationProps {
72
77
  * When true, the notification will stack the action buttons on narrow screens.
73
78
  */
74
79
  hasStackedActions?: boolean;
80
+ /**
81
+ * The ARIA labels used for various parts of the notification.
82
+ * Only pass label if there is no heading to ensure the region is announced with a title
83
+ */
84
+ aria?: AriaProps;
75
85
  }
76
86
 
77
87
  /**
@@ -123,6 +133,7 @@ declare class PieNotification_2 extends LitElement implements NotificationProps
123
133
  leadingAction: NotificationProps['leadingAction'];
124
134
  supportingAction: NotificationProps['supportingAction'];
125
135
  hasStackedActions: boolean;
136
+ aria: NotificationProps['aria'];
126
137
  _iconSlot: Array<HTMLElement>;
127
138
  protected _hasExternalIcon: boolean;
128
139
  protected _hasIconClass: boolean;
package/dist/react.js CHANGED
@@ -1,11 +1,12 @@
1
1
  import * as i from "react";
2
2
  import { createComponent as o } from "@lit/react";
3
3
  import { PieNotification as t } from "./index.js";
4
- import { ON_NOTIFICATION_CLOSE_EVENT as E, ON_NOTIFICATION_LEADING_ACTION_CLICK_EVENT as A, ON_NOTIFICATION_OPEN_EVENT as g, ON_NOTIFICATION_SUPPORTING_ACTION_CLICK_EVENT as L, componentClass as d, componentSelector as k, defaultProps as F, headingLevels as S, positions as V, variants as u } from "./index.js";
4
+ import { ON_NOTIFICATION_CLOSE_EVENT as A, ON_NOTIFICATION_LEADING_ACTION_CLICK_EVENT as g, ON_NOTIFICATION_OPEN_EVENT as L, ON_NOTIFICATION_SUPPORTING_ACTION_CLICK_EVENT as d, componentClass as k, componentSelector as F, defaultProps as S, headingLevels as V, positions as u, variants as v } from "./index.js";
5
5
  import "lit";
6
6
  import "lit/static-html.js";
7
7
  import "@justeattakeaway/pie-webc-core";
8
8
  import "lit/decorators.js";
9
+ import "lit/directives/if-defined.js";
9
10
  import "@justeattakeaway/pie-button";
10
11
  import "@justeattakeaway/pie-icon-button";
11
12
  import "@justeattakeaway/pie-icons-webc/dist/IconAlertCircle.js";
@@ -28,17 +29,17 @@ const n = o({
28
29
  onPieNotificationOpen: "pie-notification-open"
29
30
  // When the notification is opened.
30
31
  }
31
- }), T = n;
32
+ }), l = n;
32
33
  export {
33
- E as ON_NOTIFICATION_CLOSE_EVENT,
34
- A as ON_NOTIFICATION_LEADING_ACTION_CLICK_EVENT,
35
- g as ON_NOTIFICATION_OPEN_EVENT,
36
- L as ON_NOTIFICATION_SUPPORTING_ACTION_CLICK_EVENT,
37
- T as PieNotification,
38
- d as componentClass,
39
- k as componentSelector,
40
- F as defaultProps,
41
- S as headingLevels,
42
- V as positions,
43
- u as variants
34
+ A as ON_NOTIFICATION_CLOSE_EVENT,
35
+ g as ON_NOTIFICATION_LEADING_ACTION_CLICK_EVENT,
36
+ L as ON_NOTIFICATION_OPEN_EVENT,
37
+ d as ON_NOTIFICATION_SUPPORTING_ACTION_CLICK_EVENT,
38
+ l as PieNotification,
39
+ k as componentClass,
40
+ F as componentSelector,
41
+ S as defaultProps,
42
+ V as headingLevels,
43
+ u as positions,
44
+ v as variants
44
45
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@justeattakeaway/pie-notification",
3
3
  "description": "PIE Design System Notification built using Web Components",
4
- "version": "0.6.1",
4
+ "version": "0.7.0",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.js",
package/src/defs.ts CHANGED
@@ -4,6 +4,11 @@ export const variants = ['neutral', 'neutral-alternative', 'info', 'success', 'w
4
4
  export const headingLevels = ['h2', 'h3', 'h4', 'h5', 'h6'] as const;
5
5
  export const positions = ['inline-content', 'full-width'] as const;
6
6
 
7
+ export type AriaProps = {
8
+ close?: string;
9
+ label?: string;
10
+ };
11
+
7
12
  export type ActionProps = {
8
13
  /**
9
14
  * The text to display inside the button.
@@ -71,6 +76,12 @@ export interface NotificationProps {
71
76
  * When true, the notification will stack the action buttons on narrow screens.
72
77
  */
73
78
  hasStackedActions?: boolean;
79
+
80
+ /**
81
+ * The ARIA labels used for various parts of the notification.
82
+ * Only pass label if there is no heading to ensure the region is announced with a title
83
+ */
84
+ aria?: AriaProps;
74
85
  }
75
86
 
76
87
  export const componentSelector = 'pie-notification';
package/src/index.ts CHANGED
@@ -8,6 +8,7 @@ import {
8
8
  import { type StaticValue, html, unsafeStatic } from 'lit/static-html.js';
9
9
  import { defineCustomElement, validPropertyValues, dispatchCustomEvent } from '@justeattakeaway/pie-webc-core';
10
10
  import { property, queryAssignedElements, state } from 'lit/decorators.js';
11
+ import { ifDefined } from 'lit/directives/if-defined.js';
11
12
  import {
12
13
  type NotificationProps,
13
14
  type ActionProps,
@@ -79,6 +80,9 @@ export class PieNotification extends LitElement implements NotificationProps {
79
80
  @property({ type: Boolean })
80
81
  public hasStackedActions = defaultProps.hasStackedActions;
81
82
 
83
+ @property({ type: Object })
84
+ public aria: NotificationProps['aria'];
85
+
82
86
  @queryAssignedElements({ slot: 'icon' }) _iconSlot!: Array<HTMLElement>;
83
87
 
84
88
  @state()
@@ -147,7 +151,12 @@ export class PieNotification extends LitElement implements NotificationProps {
147
151
  * @private
148
152
  */
149
153
  private renderNotificationHeading (heading: NotificationProps['heading'], headingTag: StaticValue): TemplateResult {
150
- return html`<${headingTag} class="${componentClass}-heading" data-test-id="${componentSelector}-heading">${heading}</${headingTag}>`;
154
+ return html`<${headingTag}
155
+ id="${componentSelector}-heading"
156
+ class="${componentClass}-heading"
157
+ data-test-id="${componentSelector}-heading">
158
+ ${heading}
159
+ </${headingTag}>`;
151
160
  }
152
161
 
153
162
  /**
@@ -234,6 +243,7 @@ export class PieNotification extends LitElement implements NotificationProps {
234
243
  class="${componentClass}-icon-close"
235
244
  data-test-id="${componentSelector}-icon-close"
236
245
  @click="${this.handleCloseButton}"
246
+ aria-label="${ifDefined(this.aria?.close)}"
237
247
  >
238
248
  <icon-close></icon-close>
239
249
  </pie-icon-button>`;
@@ -319,6 +329,7 @@ export class PieNotification extends LitElement implements NotificationProps {
319
329
  leadingAction,
320
330
  supportingAction,
321
331
  isOpen,
332
+ aria,
322
333
  } = this;
323
334
 
324
335
  if (!isOpen) {
@@ -333,7 +344,11 @@ export class PieNotification extends LitElement implements NotificationProps {
333
344
  class="${componentClass}"
334
345
  variant="${variant}"
335
346
  position="${position}"
336
- ?isCompact="${isCompact}">
347
+ ?isCompact="${isCompact}"
348
+ role="region"
349
+ aria-live="${variant === 'error' ? 'assertive' : 'polite'}"
350
+ aria-labelledby="${heading ? `${componentSelector}-heading` : nothing}"
351
+ aria-label="${!heading && ifDefined(aria?.label)}">
337
352
  ${showCloseButton ? this.renderCloseButton() : nothing}
338
353
 
339
354
  <section class="${componentClass}-content-section" ?isDismissible="${showCloseButton}">