@justeattakeaway/pie-notification 0.6.0 → 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.
@@ -75,6 +75,14 @@
75
75
  "name": "ON_NOTIFICATION_SUPPORTING_ACTION_CLICK_EVENT",
76
76
  "default": "`${componentSelector}-supporting-action-click`",
77
77
  "description": "Event name for when the notification supporting action is clicked."
78
+ },
79
+ {
80
+ "kind": "variable",
81
+ "name": "defaultProps",
82
+ "type": {
83
+ "text": "DefaultProps"
84
+ },
85
+ "default": "{\n isOpen: true,\n variant: 'neutral',\n position: 'inline-content',\n isDismissible: true,\n isCompact: false,\n headingLevel: 'h2',\n hideIcon: false,\n hasStackedActions: false,\n}"
78
86
  }
79
87
  ],
80
88
  "exports": [
@@ -149,6 +157,14 @@
149
157
  "name": "ON_NOTIFICATION_SUPPORTING_ACTION_CLICK_EVENT",
150
158
  "module": "src/defs.js"
151
159
  }
160
+ },
161
+ {
162
+ "kind": "js",
163
+ "name": "defaultProps",
164
+ "declaration": {
165
+ "name": "defaultProps",
166
+ "module": "src/defs.js"
167
+ }
152
168
  }
153
169
  ]
154
170
  },
@@ -164,11 +180,7 @@
164
180
  {
165
181
  "kind": "field",
166
182
  "name": "isOpen",
167
- "type": {
168
- "text": "boolean"
169
- },
170
183
  "privacy": "public",
171
- "default": "true",
172
184
  "attribute": "isOpen"
173
185
  },
174
186
  {
@@ -178,7 +190,6 @@
178
190
  "text": "NonNullable<NotificationProps['variant']>"
179
191
  },
180
192
  "privacy": "public",
181
- "default": "'neutral'",
182
193
  "attribute": "variant"
183
194
  },
184
195
  {
@@ -188,27 +199,18 @@
188
199
  "text": "NonNullable<NotificationProps['position']>"
189
200
  },
190
201
  "privacy": "public",
191
- "default": "'inline-content'",
192
202
  "attribute": "position"
193
203
  },
194
204
  {
195
205
  "kind": "field",
196
206
  "name": "isDismissible",
197
- "type": {
198
- "text": "boolean"
199
- },
200
207
  "privacy": "public",
201
- "default": "true",
202
208
  "attribute": "isDismissible"
203
209
  },
204
210
  {
205
211
  "kind": "field",
206
212
  "name": "isCompact",
207
- "type": {
208
- "text": "boolean"
209
- },
210
213
  "privacy": "public",
211
- "default": "false",
212
214
  "attribute": "isCompact"
213
215
  },
214
216
  {
@@ -227,17 +229,12 @@
227
229
  "text": "NonNullable<NotificationProps['headingLevel']>"
228
230
  },
229
231
  "privacy": "public",
230
- "default": "'h2'",
231
232
  "attribute": "headingLevel"
232
233
  },
233
234
  {
234
235
  "kind": "field",
235
236
  "name": "hideIcon",
236
- "type": {
237
- "text": "boolean"
238
- },
239
237
  "privacy": "public",
240
- "default": "false",
241
238
  "attribute": "hideIcon"
242
239
  },
243
240
  {
@@ -261,12 +258,17 @@
261
258
  {
262
259
  "kind": "field",
263
260
  "name": "hasStackedActions",
261
+ "privacy": "public",
262
+ "attribute": "hasStackedActions"
263
+ },
264
+ {
265
+ "kind": "field",
266
+ "name": "aria",
264
267
  "type": {
265
- "text": "boolean"
268
+ "text": "NotificationProps['aria']"
266
269
  },
267
270
  "privacy": "public",
268
- "default": "false",
269
- "attribute": "hasStackedActions"
271
+ "attribute": "aria"
270
272
  },
271
273
  {
272
274
  "kind": "field",
@@ -516,10 +518,6 @@
516
518
  "attributes": [
517
519
  {
518
520
  "name": "isOpen",
519
- "type": {
520
- "text": "boolean"
521
- },
522
- "default": "true",
523
521
  "fieldName": "isOpen"
524
522
  },
525
523
  {
@@ -527,7 +525,6 @@
527
525
  "type": {
528
526
  "text": "NonNullable<NotificationProps['variant']>"
529
527
  },
530
- "default": "'neutral'",
531
528
  "fieldName": "variant"
532
529
  },
533
530
  {
@@ -535,23 +532,14 @@
535
532
  "type": {
536
533
  "text": "NonNullable<NotificationProps['position']>"
537
534
  },
538
- "default": "'inline-content'",
539
535
  "fieldName": "position"
540
536
  },
541
537
  {
542
538
  "name": "isDismissible",
543
- "type": {
544
- "text": "boolean"
545
- },
546
- "default": "true",
547
539
  "fieldName": "isDismissible"
548
540
  },
549
541
  {
550
542
  "name": "isCompact",
551
- "type": {
552
- "text": "boolean"
553
- },
554
- "default": "false",
555
543
  "fieldName": "isCompact"
556
544
  },
557
545
  {
@@ -566,15 +554,10 @@
566
554
  "type": {
567
555
  "text": "NonNullable<NotificationProps['headingLevel']>"
568
556
  },
569
- "default": "'h2'",
570
557
  "fieldName": "headingLevel"
571
558
  },
572
559
  {
573
560
  "name": "hideIcon",
574
- "type": {
575
- "text": "boolean"
576
- },
577
- "default": "false",
578
561
  "fieldName": "hideIcon"
579
562
  },
580
563
  {
@@ -593,11 +576,14 @@
593
576
  },
594
577
  {
595
578
  "name": "hasStackedActions",
579
+ "fieldName": "hasStackedActions"
580
+ },
581
+ {
582
+ "name": "aria",
596
583
  "type": {
597
- "text": "boolean"
584
+ "text": "NotificationProps['aria']"
598
585
  },
599
- "default": "false",
600
- "fieldName": "hasStackedActions"
586
+ "fieldName": "aria"
601
587
  }
602
588
  ],
603
589
  "superclass": {
package/dist/index.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { ComponentDefaultPropsGeneric } from '@justeattakeaway/pie-webc-core';
1
2
  import type { CSSResult } from 'lit';
2
3
  import type { LitElement } from 'lit';
3
4
  import type { nothing } from 'lit';
@@ -15,10 +16,19 @@ export declare type ActionProps = {
15
16
  ariaLabel?: string;
16
17
  };
17
18
 
19
+ export declare type AriaProps = {
20
+ close?: string;
21
+ label?: string;
22
+ };
23
+
18
24
  export declare const componentClass = "c-notification";
19
25
 
20
26
  export declare const componentSelector = "pie-notification";
21
27
 
28
+ export declare type DefaultProps = ComponentDefaultPropsGeneric<NotificationProps, 'isOpen' | 'variant' | 'position' | 'isDismissible' | 'isCompact' | 'headingLevel' | 'hideIcon' | 'hasStackedActions'>;
29
+
30
+ export declare const defaultProps: DefaultProps;
31
+
22
32
  export declare const headingLevels: readonly ["h2", "h3", "h4", "h5", "h6"];
23
33
 
24
34
  export declare interface NotificationProps {
@@ -66,6 +76,11 @@ export declare interface NotificationProps {
66
76
  * When true, the notification will stack the action buttons on narrow screens.
67
77
  */
68
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;
69
84
  }
70
85
 
71
86
  /**
@@ -115,6 +130,7 @@ export declare class PieNotification extends LitElement implements NotificationP
115
130
  leadingAction: NotificationProps['leadingAction'];
116
131
  supportingAction: NotificationProps['supportingAction'];
117
132
  hasStackedActions: boolean;
133
+ aria: NotificationProps['aria'];
118
134
  _iconSlot: Array<HTMLElement>;
119
135
  protected _hasExternalIcon: boolean;
120
136
  protected _hasIconClass: boolean;
package/dist/index.js CHANGED
@@ -1,7 +1,8 @@
1
- import { unsafeCSS as N, LitElement as x, nothing as c } from "lit";
2
- import { html as l, unsafeStatic as O } from "lit/static-html.js";
3
- import { validPropertyValues as g, defineCustomElement as E, dispatchCustomEvent as u } from "@justeattakeaway/pie-webc-core";
4
- import { property as s, 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,16 +10,25 @@ 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 k = ["neutral", "neutral-alternative", "info", "success", "warning", "error"], A = ["h2", "h3", "h4", "h5", "h6"], z = ["inline-content", "full-width"], o = "pie-notification", h = "c-notification", S = `${o}-close`, V = `${o}-open`, T = `${o}-leading-action-click`, B = `${o}-supporting-action-click`, D = `*,*: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}}
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 = {
14
+ isOpen: !0,
15
+ variant: "neutral",
16
+ position: "inline-content",
17
+ isDismissible: !0,
18
+ isCompact: !1,
19
+ headingLevel: "h2",
20
+ hideIcon: !1,
21
+ hasStackedActions: !1
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}}
13
23
  `;
14
- var P = Object.defineProperty, L = Object.getOwnPropertyDescriptor, e = (p, i, t, a) => {
15
- for (var r = a > 1 ? void 0 : a ? L(i, t) : i, d = p.length - 1, f; d >= 0; d--)
16
- (f = p[d]) && (r = (a ? f(i, t, r) : f(r)) || r);
17
- return a && r && P(i, t, r), r;
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;
18
28
  };
19
- class n extends x {
29
+ class n extends k {
20
30
  constructor() {
21
- super(...arguments), this.isOpen = !0, this.variant = "neutral", this.position = "inline-content", this.isDismissible = !0, this.isCompact = !1, this.headingLevel = "h2", this.hideIcon = !1, this.hasStackedActions = !1, 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;
22
32
  }
23
33
  /**
24
34
  * Lifecycle method executed when component is about to update.
@@ -33,7 +43,7 @@ class n extends x {
33
43
  * It applies a gutter if there's no heading content in order to avoid the close button overlap the content.
34
44
  */
35
45
  updated(i) {
36
- i.has("isOpen") && this.isOpen && u(this, V, { targetNotification: this });
46
+ i.has("isOpen") && this.isOpen && v(this, B, { targetNotification: this });
37
47
  }
38
48
  /**
39
49
  * Method responsible to check if an external icon has been provided.
@@ -50,10 +60,10 @@ class n extends x {
50
60
  *
51
61
  * @private
52
62
  */
53
- renderFooter(i, t) {
54
- return l`
55
- <footer class="${h}-footer" data-test-id="${o}-footer" ?isCompact="${this.isCompact}" ?isStacked="${this.hasStackedActions && !this.isCompact}">
56
- ${t ? this.renderActionButton(t, "supporting") : c}
63
+ renderFooter(i, o) {
64
+ return d`
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}
57
67
  ${i ? this.renderActionButton(i, "leading") : c}
58
68
  </footer>
59
69
  `;
@@ -67,8 +77,13 @@ class n extends x {
67
77
  *
68
78
  * @private
69
79
  */
70
- renderNotificationHeading(i, t) {
71
- return l`<${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}>`;
72
87
  }
73
88
  /**
74
89
  * Util method that returns a boolean if variant has a default icon.
@@ -90,13 +105,13 @@ class n extends x {
90
105
  getDefaultVariantIcon(i) {
91
106
  switch (i) {
92
107
  case "info":
93
- return l`<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>`;
94
109
  case "success":
95
- return l`<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>`;
96
111
  case "warning":
97
- return l`<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>`;
98
113
  case "error":
99
- return l`<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>`;
100
115
  default:
101
116
  return c;
102
117
  }
@@ -122,10 +137,10 @@ class n extends x {
122
137
  *
123
138
  * @private
124
139
  */
125
- renderIcon(i, t, a) {
126
- return l`
127
- <div data-test-id="${o}-icon-area" class="${a ? "has-icon " : ""}${h}-heading-icon">
128
- ${t ? c : this.renderIconVariant(i)}
140
+ renderIcon(i, o, a) {
141
+ return d`
142
+ <div data-test-id="${t}-icon-area" class="${a ? "has-icon " : ""}${h}-heading-icon">
143
+ ${o ? c : this.renderIconVariant(i)}
129
144
  <slot name="icon"></slot>
130
145
  </div>
131
146
  `;
@@ -137,13 +152,15 @@ class n extends x {
137
152
  * @private
138
153
  */
139
154
  renderCloseButton() {
140
- return l`
155
+ var i;
156
+ return d`
141
157
  <pie-icon-button
142
158
  variant="ghost-secondary"
143
159
  size="small"
144
160
  class="${h}-icon-close"
145
- data-test-id="${o}-icon-close"
161
+ data-test-id="${t}-icon-close"
146
162
  @click="${this.handleCloseButton}"
163
+ aria-label="${I((i = this.aria) == null ? void 0 : i.close)}"
147
164
  >
148
165
  <icon-close></icon-close>
149
166
  </pie-icon-button>`;
@@ -155,7 +172,7 @@ class n extends x {
155
172
  * @private
156
173
  */
157
174
  handleCloseButton() {
158
- this.closeNotificationComponent(), u(this, S, { targetNotification: this });
175
+ this.closeNotificationComponent(), v(this, T, { targetNotification: this });
159
176
  }
160
177
  /**
161
178
  * Util method responsible to close the component.
@@ -174,7 +191,7 @@ class n extends x {
174
191
  * @private
175
192
  */
176
193
  handleActionClick(i) {
177
- u(this, i === "leading" ? T : B, { targetNotification: this });
194
+ v(this, i === "leading" ? L : P, { targetNotification: this });
178
195
  }
179
196
  /**
180
197
  * Render the action button depending on action type and its action.
@@ -185,15 +202,15 @@ class n extends x {
185
202
  * @returns {TemplateResult | typeof nothing} - The rendered action button or nothing if the action text is not defined.
186
203
  * @private
187
204
  */
188
- renderActionButton(i, t) {
189
- const { text: a, ariaLabel: r } = i;
190
- return a ? l`
205
+ renderActionButton(i, o) {
206
+ const { text: a, ariaLabel: s } = i;
207
+ return a ? d`
191
208
  <pie-button
192
- variant="${t === "leading" ? "primary" : "ghost"}"
209
+ variant="${o === "leading" ? "primary" : "ghost"}"
193
210
  size="small-productive"
194
- aria-label="${r || c}"
195
- @click="${() => this.handleActionClick(t)}"
196
- data-test-id="${o}-${t}-action"
211
+ aria-label="${s || c}"
212
+ @click="${() => this.handleActionClick(o)}"
213
+ data-test-id="${t}-${o}-action"
197
214
  ?isFullWidth="${this.hasStackedActions}"
198
215
  type="button">
199
216
  ${a}
@@ -203,98 +220,107 @@ class n extends x {
203
220
  render() {
204
221
  const {
205
222
  variant: i,
206
- position: t,
223
+ position: o,
207
224
  heading: a,
208
- headingLevel: r,
209
- isDismissible: d,
210
- isCompact: f,
211
- _hasExternalIcon: b,
212
- hideIcon: I,
213
- _hasIconClass: C,
214
- leadingAction: v,
215
- supportingAction: y,
216
- isOpen: _
225
+ headingLevel: s,
226
+ isDismissible: f,
227
+ isCompact: p,
228
+ _hasExternalIcon: y,
229
+ hideIcon: _,
230
+ _hasIconClass: O,
231
+ leadingAction: b,
232
+ supportingAction: N,
233
+ isOpen: x,
234
+ aria: g
217
235
  } = this;
218
- if (!_)
236
+ if (!x)
219
237
  return c;
220
- const m = d && !f;
221
- return l`
222
- <div
223
- data-test-id="${o}"
224
- class="${h}"
225
- variant="${i}"
226
- position="${t}"
227
- ?isCompact="${f}">
228
- ${m ? this.renderCloseButton() : c}
238
+ const $ = f && !p;
239
+ return d`
240
+ <div
241
+ data-test-id="${t}"
242
+ class="${h}"
243
+ variant="${i}"
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}
229
251
 
230
- <section class="${h}-content-section" ?isDismissible="${m}">
231
- ${I ? c : this.renderIcon(i, b, C)}
252
+ <section class="${h}-content-section" ?isDismissible="${$}">
253
+ ${_ ? c : this.renderIcon(i, y, O)}
232
254
  <article>
233
- ${a ? this.renderNotificationHeading(a, O(r)) : c}
255
+ ${a ? this.renderNotificationHeading(a, w(s)) : c}
234
256
  <slot></slot>
235
257
  </article>
236
258
  </section>
237
259
 
238
- ${v ? this.renderFooter(v, y) : c}
260
+ ${b ? this.renderFooter(b, N) : c}
239
261
  </div>`;
240
262
  }
241
263
  }
242
- n.styles = N(D);
264
+ n.styles = E(F);
243
265
  e([
244
- s({ type: Boolean })
266
+ r({ type: Boolean })
245
267
  ], n.prototype, "isOpen", 2);
246
268
  e([
247
- s(),
248
- g(o, k, "neutral")
269
+ r(),
270
+ m(t, S, l.variant)
249
271
  ], n.prototype, "variant", 2);
250
272
  e([
251
- s(),
252
- g(o, z, "inline-content")
273
+ r(),
274
+ m(t, V, l.position)
253
275
  ], n.prototype, "position", 2);
254
276
  e([
255
- s({ type: Boolean })
277
+ r({ type: Boolean })
256
278
  ], n.prototype, "isDismissible", 2);
257
279
  e([
258
- s({ type: Boolean })
280
+ r({ type: Boolean })
259
281
  ], n.prototype, "isCompact", 2);
260
282
  e([
261
- s({ type: String })
283
+ r({ type: String })
262
284
  ], n.prototype, "heading", 2);
263
285
  e([
264
- s(),
265
- g(o, A, "h2")
286
+ r(),
287
+ m(t, D, l.headingLevel)
266
288
  ], n.prototype, "headingLevel", 2);
267
289
  e([
268
- s({ type: Boolean })
290
+ r({ type: Boolean })
269
291
  ], n.prototype, "hideIcon", 2);
270
292
  e([
271
- s({ type: Object })
293
+ r({ type: Object })
272
294
  ], n.prototype, "leadingAction", 2);
273
295
  e([
274
- s({ type: Object })
296
+ r({ type: Object })
275
297
  ], n.prototype, "supportingAction", 2);
276
298
  e([
277
- s({ type: Boolean })
299
+ r({ type: Boolean })
278
300
  ], n.prototype, "hasStackedActions", 2);
279
301
  e([
280
- w({ slot: "icon" })
302
+ r({ type: Object })
303
+ ], n.prototype, "aria", 2);
304
+ e([
305
+ z({ slot: "icon" })
281
306
  ], n.prototype, "_iconSlot", 2);
282
307
  e([
283
- $()
308
+ C()
284
309
  ], n.prototype, "_hasExternalIcon", 2);
285
310
  e([
286
- $()
311
+ C()
287
312
  ], n.prototype, "_hasIconClass", 2);
288
- E(o, n);
313
+ A(t, n);
289
314
  export {
290
- S as ON_NOTIFICATION_CLOSE_EVENT,
291
- T as ON_NOTIFICATION_LEADING_ACTION_CLICK_EVENT,
292
- V as ON_NOTIFICATION_OPEN_EVENT,
293
- 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,
294
319
  n as PieNotification,
295
320
  h as componentClass,
296
- o as componentSelector,
297
- A as headingLevels,
298
- z as positions,
299
- k as variants
321
+ t as componentSelector,
322
+ l as defaultProps,
323
+ D as headingLevels,
324
+ V as positions,
325
+ S as variants
300
326
  };
package/dist/react.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { ComponentDefaultPropsGeneric } from '@justeattakeaway/pie-webc-core';
1
2
  import type { CSSResult } from 'lit';
2
3
  import type { LitElement } from 'lit';
3
4
  import type { nothing } from 'lit';
@@ -16,10 +17,19 @@ export declare type ActionProps = {
16
17
  ariaLabel?: string;
17
18
  };
18
19
 
20
+ export declare type AriaProps = {
21
+ close?: string;
22
+ label?: string;
23
+ };
24
+
19
25
  export declare const componentClass = "c-notification";
20
26
 
21
27
  export declare const componentSelector = "pie-notification";
22
28
 
29
+ export declare type DefaultProps = ComponentDefaultPropsGeneric<NotificationProps, 'isOpen' | 'variant' | 'position' | 'isDismissible' | 'isCompact' | 'headingLevel' | 'hideIcon' | 'hasStackedActions'>;
30
+
31
+ export declare const defaultProps: DefaultProps;
32
+
23
33
  export declare const headingLevels: readonly ["h2", "h3", "h4", "h5", "h6"];
24
34
 
25
35
  export declare interface NotificationProps {
@@ -67,6 +77,11 @@ export declare interface NotificationProps {
67
77
  * When true, the notification will stack the action buttons on narrow screens.
68
78
  */
69
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;
70
85
  }
71
86
 
72
87
  /**
@@ -118,6 +133,7 @@ declare class PieNotification_2 extends LitElement implements NotificationProps
118
133
  leadingAction: NotificationProps['leadingAction'];
119
134
  supportingAction: NotificationProps['supportingAction'];
120
135
  hasStackedActions: boolean;
136
+ aria: NotificationProps['aria'];
121
137
  _iconSlot: Array<HTMLElement>;
122
138
  protected _hasExternalIcon: boolean;
123
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, headingLevels as F, positions as S, variants as V } 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,16 +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 headingLevels,
41
- S as positions,
42
- V 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
43
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.0",
4
+ "version": "0.7.0",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.js",
@@ -41,9 +41,9 @@
41
41
  "cem-plugin-module-file-extensions": "0.0.5"
42
42
  },
43
43
  "dependencies": {
44
- "@justeattakeaway/pie-icon-button": "0.28.5",
45
- "@justeattakeaway/pie-icons-webc": "0.23.1",
46
- "@justeattakeaway/pie-webc-core": "0.22.0"
44
+ "@justeattakeaway/pie-icon-button": "0.28.6",
45
+ "@justeattakeaway/pie-icons-webc": "0.24.0",
46
+ "@justeattakeaway/pie-webc-core": "0.23.0"
47
47
  },
48
48
  "volta": {
49
49
  "extends": "../../../package.json"
package/src/defs.ts CHANGED
@@ -1,7 +1,14 @@
1
+ import { type ComponentDefaultPropsGeneric } from '@justeattakeaway/pie-webc-core';
2
+
1
3
  export const variants = ['neutral', 'neutral-alternative', 'info', 'success', 'warning', 'error'] as const;
2
4
  export const headingLevels = ['h2', 'h3', 'h4', 'h5', 'h6'] as const;
3
5
  export const positions = ['inline-content', 'full-width'] as const;
4
6
 
7
+ export type AriaProps = {
8
+ close?: string;
9
+ label?: string;
10
+ };
11
+
5
12
  export type ActionProps = {
6
13
  /**
7
14
  * The text to display inside the button.
@@ -69,6 +76,12 @@ export interface NotificationProps {
69
76
  * When true, the notification will stack the action buttons on narrow screens.
70
77
  */
71
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;
72
85
  }
73
86
 
74
87
  export const componentSelector = 'pie-notification';
@@ -101,3 +114,16 @@ export const ON_NOTIFICATION_LEADING_ACTION_CLICK_EVENT = `${componentSelector}-
101
114
  * @constant
102
115
  */
103
116
  export const ON_NOTIFICATION_SUPPORTING_ACTION_CLICK_EVENT = `${componentSelector}-supporting-action-click`;
117
+
118
+ export type DefaultProps = ComponentDefaultPropsGeneric<NotificationProps, 'isOpen' | 'variant' | 'position' | 'isDismissible' | 'isCompact' | 'headingLevel' | 'hideIcon' | 'hasStackedActions'>;
119
+
120
+ export const defaultProps: DefaultProps = {
121
+ isOpen: true,
122
+ variant: 'neutral',
123
+ position: 'inline-content',
124
+ isDismissible: true,
125
+ isCompact: false,
126
+ headingLevel: 'h2',
127
+ hideIcon: false,
128
+ hasStackedActions: false,
129
+ };
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,
@@ -20,6 +21,7 @@ import {
20
21
  ON_NOTIFICATION_OPEN_EVENT,
21
22
  ON_NOTIFICATION_LEADING_ACTION_CLICK_EVENT,
22
23
  ON_NOTIFICATION_SUPPORTING_ACTION_CLICK_EVENT,
24
+ defaultProps,
23
25
  } from './defs';
24
26
  import styles from './notification.scss?inline';
25
27
 
@@ -43,31 +45,31 @@ export * from './defs';
43
45
  */
44
46
  export class PieNotification extends LitElement implements NotificationProps {
45
47
  @property({ type: Boolean })
46
- public isOpen = true;
48
+ public isOpen = defaultProps.isOpen;
47
49
 
48
50
  @property()
49
- @validPropertyValues(componentSelector, variants, 'neutral')
50
- public variant: NonNullable<NotificationProps['variant']> = 'neutral';
51
+ @validPropertyValues(componentSelector, variants, defaultProps.variant)
52
+ public variant: NonNullable<NotificationProps['variant']> = defaultProps.variant;
51
53
 
52
54
  @property()
53
- @validPropertyValues(componentSelector, positions, 'inline-content')
54
- public position: NonNullable<NotificationProps['position']> = 'inline-content';
55
+ @validPropertyValues(componentSelector, positions, defaultProps.position)
56
+ public position: NonNullable<NotificationProps['position']> = defaultProps.position;
55
57
 
56
58
  @property({ type: Boolean })
57
- public isDismissible = true;
59
+ public isDismissible = defaultProps.isDismissible;
58
60
 
59
61
  @property({ type: Boolean })
60
- public isCompact = false;
62
+ public isCompact = defaultProps.isCompact;
61
63
 
62
64
  @property({ type: String })
63
65
  public heading!: string;
64
66
 
65
67
  @property()
66
- @validPropertyValues(componentSelector, headingLevels, 'h2')
67
- public headingLevel: NonNullable<NotificationProps['headingLevel']> = 'h2';
68
+ @validPropertyValues(componentSelector, headingLevels, defaultProps.headingLevel)
69
+ public headingLevel: NonNullable<NotificationProps['headingLevel']> = defaultProps.headingLevel;
68
70
 
69
71
  @property({ type: Boolean })
70
- public hideIcon = false;
72
+ public hideIcon = defaultProps.hideIcon;
71
73
 
72
74
  @property({ type: Object })
73
75
  public leadingAction!: NotificationProps['leadingAction'];
@@ -76,7 +78,10 @@ export class PieNotification extends LitElement implements NotificationProps {
76
78
  public supportingAction!: NotificationProps['supportingAction'];
77
79
 
78
80
  @property({ type: Boolean })
79
- public hasStackedActions = false;
81
+ public hasStackedActions = defaultProps.hasStackedActions;
82
+
83
+ @property({ type: Object })
84
+ public aria: NotificationProps['aria'];
80
85
 
81
86
  @queryAssignedElements({ slot: 'icon' }) _iconSlot!: Array<HTMLElement>;
82
87
 
@@ -146,7 +151,12 @@ export class PieNotification extends LitElement implements NotificationProps {
146
151
  * @private
147
152
  */
148
153
  private renderNotificationHeading (heading: NotificationProps['heading'], headingTag: StaticValue): TemplateResult {
149
- 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}>`;
150
160
  }
151
161
 
152
162
  /**
@@ -233,6 +243,7 @@ export class PieNotification extends LitElement implements NotificationProps {
233
243
  class="${componentClass}-icon-close"
234
244
  data-test-id="${componentSelector}-icon-close"
235
245
  @click="${this.handleCloseButton}"
246
+ aria-label="${ifDefined(this.aria?.close)}"
236
247
  >
237
248
  <icon-close></icon-close>
238
249
  </pie-icon-button>`;
@@ -318,6 +329,7 @@ export class PieNotification extends LitElement implements NotificationProps {
318
329
  leadingAction,
319
330
  supportingAction,
320
331
  isOpen,
332
+ aria,
321
333
  } = this;
322
334
 
323
335
  if (!isOpen) {
@@ -327,12 +339,16 @@ export class PieNotification extends LitElement implements NotificationProps {
327
339
  const showCloseButton = isDismissible && !isCompact;
328
340
 
329
341
  return html`
330
- <div
331
- data-test-id="${componentSelector}"
332
- class="${componentClass}"
333
- variant="${variant}"
342
+ <div
343
+ data-test-id="${componentSelector}"
344
+ class="${componentClass}"
345
+ variant="${variant}"
334
346
  position="${position}"
335
- ?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)}">
336
352
  ${showCloseButton ? this.renderCloseButton() : nothing}
337
353
 
338
354
  <section class="${componentClass}-content-section" ?isDismissible="${showCloseButton}">