@justeattakeaway/pie-notification 0.5.5 → 0.6.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.
@@ -28,6 +28,14 @@
28
28
  },
29
29
  "default": "['h2', 'h3', 'h4', 'h5', 'h6']"
30
30
  },
31
+ {
32
+ "kind": "variable",
33
+ "name": "positions",
34
+ "type": {
35
+ "text": "['inline-content', 'full-width']"
36
+ },
37
+ "default": "['inline-content', 'full-width']"
38
+ },
31
39
  {
32
40
  "kind": "variable",
33
41
  "name": "componentSelector",
@@ -86,6 +94,14 @@
86
94
  "module": "src/defs.js"
87
95
  }
88
96
  },
97
+ {
98
+ "kind": "js",
99
+ "name": "positions",
100
+ "declaration": {
101
+ "name": "positions",
102
+ "module": "src/defs.js"
103
+ }
104
+ },
89
105
  {
90
106
  "kind": "js",
91
107
  "name": "componentSelector",
@@ -165,6 +181,16 @@
165
181
  "default": "'neutral'",
166
182
  "attribute": "variant"
167
183
  },
184
+ {
185
+ "kind": "field",
186
+ "name": "position",
187
+ "type": {
188
+ "text": "NonNullable<NotificationProps['position']>"
189
+ },
190
+ "privacy": "public",
191
+ "default": "'inline-content'",
192
+ "attribute": "position"
193
+ },
168
194
  {
169
195
  "kind": "field",
170
196
  "name": "isDismissible",
@@ -214,16 +240,6 @@
214
240
  "default": "false",
215
241
  "attribute": "hideIcon"
216
242
  },
217
- {
218
- "kind": "field",
219
- "name": "hideCloseIcon",
220
- "type": {
221
- "text": "boolean"
222
- },
223
- "privacy": "public",
224
- "default": "false",
225
- "attribute": "hideCloseIcon"
226
- },
227
243
  {
228
244
  "kind": "field",
229
245
  "name": "leadingAction",
@@ -277,15 +293,6 @@
277
293
  "privacy": "protected",
278
294
  "default": "false"
279
295
  },
280
- {
281
- "kind": "field",
282
- "name": "_hasContentGutter",
283
- "type": {
284
- "text": "boolean"
285
- },
286
- "privacy": "protected",
287
- "default": "false"
288
- },
289
296
  {
290
297
  "kind": "method",
291
298
  "name": "updateIconProperties",
@@ -523,6 +530,14 @@
523
530
  "default": "'neutral'",
524
531
  "fieldName": "variant"
525
532
  },
533
+ {
534
+ "name": "position",
535
+ "type": {
536
+ "text": "NonNullable<NotificationProps['position']>"
537
+ },
538
+ "default": "'inline-content'",
539
+ "fieldName": "position"
540
+ },
526
541
  {
527
542
  "name": "isDismissible",
528
543
  "type": {
@@ -562,14 +577,6 @@
562
577
  "default": "false",
563
578
  "fieldName": "hideIcon"
564
579
  },
565
- {
566
- "name": "hideCloseIcon",
567
- "type": {
568
- "text": "boolean"
569
- },
570
- "default": "false",
571
- "fieldName": "hideCloseIcon"
572
- },
573
580
  {
574
581
  "name": "leadingAction",
575
582
  "type": {
package/dist/index.d.ts CHANGED
@@ -26,6 +26,10 @@ export declare interface NotificationProps {
26
26
  * Set the variant of the notification.
27
27
  */
28
28
  variant?: typeof variants[number];
29
+ /**
30
+ * The position of the notification defining proper styles if the component appear within the content or at the top of the interface.
31
+ */
32
+ position?: typeof positions[number];
29
33
  /**
30
34
  * When true, allows dismissing the notification by clicking on the close button.
31
35
  */
@@ -102,24 +106,19 @@ export declare const ON_NOTIFICATION_SUPPORTING_ACTION_CLICK_EVENT: string;
102
106
  export declare class PieNotification extends LitElement implements NotificationProps {
103
107
  isOpen: boolean;
104
108
  variant: NonNullable<NotificationProps['variant']>;
109
+ position: NonNullable<NotificationProps['position']>;
105
110
  isDismissible: boolean;
106
111
  isCompact: boolean;
107
112
  heading: string;
108
113
  headingLevel: NonNullable<NotificationProps['headingLevel']>;
109
114
  hideIcon: boolean;
110
- hideCloseIcon: boolean;
111
115
  leadingAction: NotificationProps['leadingAction'];
112
116
  supportingAction: NotificationProps['supportingAction'];
113
117
  hasStackedActions: boolean;
114
118
  _iconSlot: Array<HTMLElement>;
115
119
  protected _hasExternalIcon: boolean;
116
120
  protected _hasIconClass: boolean;
117
- protected _hasContentGutter: boolean;
118
121
  static styles: CSSResult;
119
- /**
120
- * Lifecycle method executed after component renders.
121
- */
122
- protected firstUpdated(): void;
123
122
  /**
124
123
  * Lifecycle method executed when component is about to update.
125
124
  * It update icon properties if variant has changes.
@@ -233,6 +232,8 @@ export declare class PieNotification extends LitElement implements NotificationP
233
232
  render(): TemplateResult | typeof nothing;
234
233
  }
235
234
 
235
+ export declare const positions: readonly ["inline-content", "full-width"];
236
+
236
237
  export declare const variants: readonly ["neutral", "neutral-alternative", "info", "success", "warning", "error"];
237
238
 
238
239
  export { }
package/dist/index.js CHANGED
@@ -1,7 +1,7 @@
1
- import { unsafeCSS as _, LitElement as N, nothing as a } from "lit";
1
+ import { unsafeCSS as N, LitElement as x, nothing as c } from "lit";
2
2
  import { html as l, unsafeStatic as O } from "lit/static-html.js";
3
- import { validPropertyValues as m, defineCustomElement as x, dispatchCustomEvent as u } from "@justeattakeaway/pie-webc-core";
4
- import { property as s, queryAssignedElements as E, state as g } from "lit/decorators.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";
5
5
  import "@justeattakeaway/pie-button";
6
6
  import "@justeattakeaway/pie-icon-button";
7
7
  import "@justeattakeaway/pie-icons-webc/dist/IconAlertCircle.js";
@@ -9,37 +9,31 @@ import "@justeattakeaway/pie-icons-webc/dist/IconAlertTriangle.js";
9
9
  import "@justeattakeaway/pie-icons-webc/dist/IconCheckCircle.js";
10
10
  import "@justeattakeaway/pie-icons-webc/dist/IconClose.js";
11
11
  import "@justeattakeaway/pie-icons-webc/dist/IconInfoCircle.js";
12
- const k = ["neutral", "neutral-alternative", "info", "success", "warning", "error"], A = ["h2", "h3", "h4", "h5", "h6"], o = "pie-notification", h = "c-notification", z = `${o}-close`, S = `${o}-open`, V = `${o}-leading-action-click`, w = `${o}-supporting-action-click`, T = `*,*: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-icon-size-override: 22px;--notification-heading-font-size: calc(var(--dt-font-size-20) * 1px);--notification-heading-line-height: calc(var(--dt-font-size-20-line-height) * 1px);--notification-font-size: calc(var(--dt-font-size-16) * 1px);--notification-line-height: calc(var(--dt-font-size-16-line-height) * 1px);--notification-icon-fill: var(--dt-color-content-default);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 h1,.c-notification h2,.c-notification h3,.c-notification h4,.c-notification h5,.c-notification h6{margin:0;font-size:var(--notification-heading-font-size);line-height:var(--notification-heading-line-height)}.c-notification[isCompact]{--notification-direction: row}.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-content-section{display:flex;flex-direction:row}.c-notification-content-section article[hasGutter]{padding-inline-end:var(--dt-spacing-e)}.c-notification-content-section .has-icon{display:block ruby;margin-inline-end:var(--dt-spacing-c)}.c-notification-heading-icon{padding-block-start:var(--dt-spacing-a);color:var(--notification-icon-fill)}.c-notification-icon-close{position:absolute;inset-block-start:var(--dt-spacing-b);inset-inline-end:var(--dt-spacing-b)}.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: 640px){.c-notification-footer[isStacked]{flex-direction:column}}
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
13
  `;
14
- var B = Object.defineProperty, D = Object.getOwnPropertyDescriptor, e = (f, t, i, c) => {
15
- for (var r = c > 1 ? void 0 : c ? D(t, i) : t, d = f.length - 1, p; d >= 0; d--)
16
- (p = f[d]) && (r = (c ? p(t, i, r) : p(r)) || r);
17
- return c && r && B(t, i, r), r;
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;
18
18
  };
19
- class n extends N {
19
+ class n extends x {
20
20
  constructor() {
21
- super(...arguments), this.isOpen = !0, this.variant = "neutral", this.isDismissible = !0, this.isCompact = !1, this.headingLevel = "h2", this.hideIcon = !1, this.hideCloseIcon = !1, this.hasStackedActions = !1, this._hasExternalIcon = !1, this._hasIconClass = !1, this._hasContentGutter = !1;
22
- }
23
- /**
24
- * Lifecycle method executed after component renders.
25
- */
26
- firstUpdated() {
27
- this.updateIconProperties();
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;
28
22
  }
29
23
  /**
30
24
  * Lifecycle method executed when component is about to update.
31
25
  * It update icon properties if variant has changes.
32
26
  */
33
- willUpdate(t) {
34
- t.has("variant") && this.updateIconProperties();
27
+ willUpdate(i) {
28
+ i.has("variant") && this.updateIconProperties();
35
29
  }
36
30
  /**
37
31
  * Lifecycle method executed when component is updated.
38
32
  * It dispatches an event if notification is opened.
39
33
  * It applies a gutter if there's no heading content in order to avoid the close button overlap the content.
40
34
  */
41
- updated(t) {
42
- t.has("isOpen") && this.isOpen && u(this, S, { targetNotification: this }), (t.has("heading") || t.has("isDismissible") || t.has("isCompact")) && (this._hasContentGutter = (this.heading === "" || this.heading === void 0) && this.isDismissible && !this.isCompact);
35
+ updated(i) {
36
+ i.has("isOpen") && this.isOpen && u(this, V, { targetNotification: this });
43
37
  }
44
38
  /**
45
39
  * Method responsible to check if an external icon has been provided.
@@ -56,11 +50,11 @@ class n extends N {
56
50
  *
57
51
  * @private
58
52
  */
59
- renderFooter(t, i) {
53
+ renderFooter(i, t) {
60
54
  return l`
61
55
  <footer class="${h}-footer" data-test-id="${o}-footer" ?isCompact="${this.isCompact}" ?isStacked="${this.hasStackedActions && !this.isCompact}">
62
- ${i ? this.renderActionButton(i, "supporting") : a}
63
- ${t ? this.renderActionButton(t, "leading") : a}
56
+ ${t ? this.renderActionButton(t, "supporting") : c}
57
+ ${i ? this.renderActionButton(i, "leading") : c}
64
58
  </footer>
65
59
  `;
66
60
  }
@@ -73,12 +67,8 @@ class n extends N {
73
67
  *
74
68
  * @private
75
69
  */
76
- renderNotificationHeading(t, i) {
77
- return l`
78
- <header class="${h}-header" data-test-id="${o}-header">
79
- <${i} class="${h}-heading" data-test-id="${o}-heading">${t}</${i}>
80
- </header>
81
- `;
70
+ renderNotificationHeading(i, t) {
71
+ return l`<${t} class="${h}-heading" data-test-id="${o}-heading">${i}</${t}>`;
82
72
  }
83
73
  /**
84
74
  * Util method that returns a boolean if variant has a default icon.
@@ -87,8 +77,8 @@ class n extends N {
87
77
  *
88
78
  * @private
89
79
  */
90
- variantHasDefaultIcon(t) {
91
- return ["info", "success", "warning", "error"].includes(t);
80
+ variantHasDefaultIcon(i) {
81
+ return ["info", "success", "warning", "error"].includes(i);
92
82
  }
93
83
  /**
94
84
  * Util method that returns an icon from a variant that has default icon.
@@ -97,18 +87,18 @@ class n extends N {
97
87
  *
98
88
  * @private
99
89
  */
100
- getDefaultVariantIcon(t) {
101
- switch (t) {
90
+ getDefaultVariantIcon(i) {
91
+ switch (i) {
102
92
  case "info":
103
- return l`<icon-info-circle size="s" data-test-id="${o}-heading-icon-info"></icon-info-circle>`;
93
+ return l`<icon-info-circle size="m" data-test-id="${o}-heading-icon-info"></icon-info-circle>`;
104
94
  case "success":
105
- return l`<icon-check-circle size="s" data-test-id="${o}-heading-icon-success"></icon-check-circle>`;
95
+ return l`<icon-check-circle size="m" data-test-id="${o}-heading-icon-success"></icon-check-circle>`;
106
96
  case "warning":
107
- return l`<icon-alert-triangle size="s" data-test-id="${o}-heading-icon-warning"></icon-alert-triangle>`;
97
+ return l`<icon-alert-triangle size="m" data-test-id="${o}-heading-icon-warning"></icon-alert-triangle>`;
108
98
  case "error":
109
- return l`<icon-alert-circle size="s" data-test-id="${o}-heading-icon-error"></icon-alert-circle>`;
99
+ return l`<icon-alert-circle size="m" data-test-id="${o}-heading-icon-error"></icon-alert-circle>`;
110
100
  default:
111
- return a;
101
+ return c;
112
102
  }
113
103
  }
114
104
  /**
@@ -119,8 +109,8 @@ class n extends N {
119
109
  *
120
110
  * @private
121
111
  */
122
- renderIconVariant(t) {
123
- return this.variantHasDefaultIcon(t) ? this.getDefaultVariantIcon(t) : a;
112
+ renderIconVariant(i) {
113
+ return this.variantHasDefaultIcon(i) ? this.getDefaultVariantIcon(i) : c;
124
114
  }
125
115
  /**
126
116
  * Template for the heading icon area.
@@ -132,10 +122,10 @@ class n extends N {
132
122
  *
133
123
  * @private
134
124
  */
135
- renderIcon(t, i, c) {
125
+ renderIcon(i, t, a) {
136
126
  return l`
137
- <div data-test-id="${o}-icon-area" class="${c ? "has-icon " : ""}${h}-heading-icon">
138
- ${i ? a : this.renderIconVariant(t)}
127
+ <div data-test-id="${o}-icon-area" class="${a ? "has-icon " : ""}${h}-heading-icon">
128
+ ${t ? c : this.renderIconVariant(i)}
139
129
  <slot name="icon"></slot>
140
130
  </div>
141
131
  `;
@@ -165,7 +155,7 @@ class n extends N {
165
155
  * @private
166
156
  */
167
157
  handleCloseButton() {
168
- this.closeNotificationComponent(), u(this, z, { targetNotification: this });
158
+ this.closeNotificationComponent(), u(this, S, { targetNotification: this });
169
159
  }
170
160
  /**
171
161
  * Util method responsible to close the component.
@@ -183,8 +173,8 @@ class n extends N {
183
173
  *
184
174
  * @private
185
175
  */
186
- handleActionClick(t) {
187
- u(this, t === "leading" ? V : w, { targetNotification: this });
176
+ handleActionClick(i) {
177
+ u(this, i === "leading" ? T : B, { targetNotification: this });
188
178
  }
189
179
  /**
190
180
  * Render the action button depending on action type and its action.
@@ -195,60 +185,72 @@ class n extends N {
195
185
  * @returns {TemplateResult | typeof nothing} - The rendered action button or nothing if the action text is not defined.
196
186
  * @private
197
187
  */
198
- renderActionButton(t, i) {
199
- const { text: c, ariaLabel: r } = t;
200
- return c ? l`
188
+ renderActionButton(i, t) {
189
+ const { text: a, ariaLabel: r } = i;
190
+ return a ? l`
201
191
  <pie-button
202
- variant="${i === "leading" ? "primary" : "ghost"}"
192
+ variant="${t === "leading" ? "primary" : "ghost"}"
203
193
  size="small-productive"
204
- aria-label="${r || a}"
205
- @click="${() => this.handleActionClick(i)}"
206
- data-test-id="${o}-${i}-action"
194
+ aria-label="${r || c}"
195
+ @click="${() => this.handleActionClick(t)}"
196
+ data-test-id="${o}-${t}-action"
207
197
  ?isFullWidth="${this.hasStackedActions}"
208
198
  type="button">
209
- ${c}
199
+ ${a}
210
200
  </pie-button>
211
- ` : a;
201
+ ` : c;
212
202
  }
213
203
  render() {
214
204
  const {
215
- variant: t,
216
- heading: i,
217
- headingLevel: c,
218
- isDismissible: r,
219
- isCompact: d,
220
- _hasExternalIcon: p,
221
- hideIcon: C,
222
- _hasIconClass: $,
205
+ variant: i,
206
+ position: t,
207
+ heading: a,
208
+ headingLevel: r,
209
+ isDismissible: d,
210
+ isCompact: f,
211
+ _hasExternalIcon: b,
212
+ hideIcon: I,
213
+ _hasIconClass: C,
223
214
  leadingAction: v,
224
- supportingAction: I,
225
- isOpen: b,
226
- _hasContentGutter: y
215
+ supportingAction: y,
216
+ isOpen: _
227
217
  } = this;
228
- return b ? l`
229
- <div data-test-id="${o}" class="${h}" variant="${t}" ?isCompact="${d}">
230
- ${r && !d ? this.renderCloseButton() : a}
218
+ if (!_)
219
+ 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}
231
229
 
232
- <section class="${h}-content-section">
233
- ${C ? a : this.renderIcon(t, p, $)}
234
- <article ?hasGutter="${y}">
235
- ${i ? this.renderNotificationHeading(i, O(c)) : a}
230
+ <section class="${h}-content-section" ?isDismissible="${m}">
231
+ ${I ? c : this.renderIcon(i, b, C)}
232
+ <article>
233
+ ${a ? this.renderNotificationHeading(a, O(r)) : c}
236
234
  <slot></slot>
237
235
  </article>
238
236
  </section>
239
237
 
240
- ${v ? this.renderFooter(v, I) : a}
241
- </div>` : a;
238
+ ${v ? this.renderFooter(v, y) : c}
239
+ </div>`;
242
240
  }
243
241
  }
244
- n.styles = _(T);
242
+ n.styles = N(D);
245
243
  e([
246
244
  s({ type: Boolean })
247
245
  ], n.prototype, "isOpen", 2);
248
246
  e([
249
247
  s(),
250
- m(o, k, "neutral")
248
+ g(o, k, "neutral")
251
249
  ], n.prototype, "variant", 2);
250
+ e([
251
+ s(),
252
+ g(o, z, "inline-content")
253
+ ], n.prototype, "position", 2);
252
254
  e([
253
255
  s({ type: Boolean })
254
256
  ], n.prototype, "isDismissible", 2);
@@ -260,14 +262,11 @@ e([
260
262
  ], n.prototype, "heading", 2);
261
263
  e([
262
264
  s(),
263
- m(o, A, "h2")
265
+ g(o, A, "h2")
264
266
  ], n.prototype, "headingLevel", 2);
265
267
  e([
266
268
  s({ type: Boolean })
267
269
  ], n.prototype, "hideIcon", 2);
268
- e([
269
- s({ type: Boolean })
270
- ], n.prototype, "hideCloseIcon", 2);
271
270
  e([
272
271
  s({ type: Object })
273
272
  ], n.prototype, "leadingAction", 2);
@@ -278,26 +277,24 @@ e([
278
277
  s({ type: Boolean })
279
278
  ], n.prototype, "hasStackedActions", 2);
280
279
  e([
281
- E({ slot: "icon" })
280
+ w({ slot: "icon" })
282
281
  ], n.prototype, "_iconSlot", 2);
283
282
  e([
284
- g()
283
+ $()
285
284
  ], n.prototype, "_hasExternalIcon", 2);
286
285
  e([
287
- g()
286
+ $()
288
287
  ], n.prototype, "_hasIconClass", 2);
289
- e([
290
- g()
291
- ], n.prototype, "_hasContentGutter", 2);
292
- x(o, n);
288
+ E(o, n);
293
289
  export {
294
- z as ON_NOTIFICATION_CLOSE_EVENT,
295
- V as ON_NOTIFICATION_LEADING_ACTION_CLICK_EVENT,
296
- S as ON_NOTIFICATION_OPEN_EVENT,
297
- w as ON_NOTIFICATION_SUPPORTING_ACTION_CLICK_EVENT,
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,
298
294
  n as PieNotification,
299
295
  h as componentClass,
300
296
  o as componentSelector,
301
297
  A as headingLevels,
298
+ z as positions,
302
299
  k as variants
303
300
  };
package/dist/react.d.ts CHANGED
@@ -27,6 +27,10 @@ export declare interface NotificationProps {
27
27
  * Set the variant of the notification.
28
28
  */
29
29
  variant?: typeof variants[number];
30
+ /**
31
+ * The position of the notification defining proper styles if the component appear within the content or at the top of the interface.
32
+ */
33
+ position?: typeof positions[number];
30
34
  /**
31
35
  * When true, allows dismissing the notification by clicking on the close button.
32
36
  */
@@ -105,24 +109,19 @@ export declare const PieNotification: React_2.ForwardRefExoticComponent<Notifica
105
109
  declare class PieNotification_2 extends LitElement implements NotificationProps {
106
110
  isOpen: boolean;
107
111
  variant: NonNullable<NotificationProps['variant']>;
112
+ position: NonNullable<NotificationProps['position']>;
108
113
  isDismissible: boolean;
109
114
  isCompact: boolean;
110
115
  heading: string;
111
116
  headingLevel: NonNullable<NotificationProps['headingLevel']>;
112
117
  hideIcon: boolean;
113
- hideCloseIcon: boolean;
114
118
  leadingAction: NotificationProps['leadingAction'];
115
119
  supportingAction: NotificationProps['supportingAction'];
116
120
  hasStackedActions: boolean;
117
121
  _iconSlot: Array<HTMLElement>;
118
122
  protected _hasExternalIcon: boolean;
119
123
  protected _hasIconClass: boolean;
120
- protected _hasContentGutter: boolean;
121
124
  static styles: CSSResult;
122
- /**
123
- * Lifecycle method executed after component renders.
124
- */
125
- protected firstUpdated(): void;
126
125
  /**
127
126
  * Lifecycle method executed when component is about to update.
128
127
  * It update icon properties if variant has changes.
@@ -243,6 +242,8 @@ declare type PieNotificationEvents = {
243
242
  onPieNotificationOpen?: (event: CustomEvent) => void;
244
243
  };
245
244
 
245
+ export declare const positions: readonly ["inline-content", "full-width"];
246
+
246
247
  declare type ReactBaseType = React_2.HTMLAttributes<HTMLDivElement>;
247
248
 
248
249
  export declare const variants: readonly ["neutral", "neutral-alternative", "info", "success", "warning", "error"];
package/dist/react.js CHANGED
@@ -1,7 +1,7 @@
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, variants as S } 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";
5
5
  import "lit";
6
6
  import "lit/static-html.js";
7
7
  import "@justeattakeaway/pie-webc-core";
@@ -38,5 +38,6 @@ export {
38
38
  d as componentClass,
39
39
  k as componentSelector,
40
40
  F as headingLevels,
41
- S as variants
41
+ S as positions,
42
+ V as variants
42
43
  };
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.5.5",
4
+ "version": "0.6.0",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.js",
package/src/defs.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export const variants = ['neutral', 'neutral-alternative', 'info', 'success', 'warning', 'error'] as const;
2
2
  export const headingLevels = ['h2', 'h3', 'h4', 'h5', 'h6'] as const;
3
+ export const positions = ['inline-content', 'full-width'] as const;
3
4
 
4
5
  export type ActionProps = {
5
6
  /**
@@ -19,6 +20,11 @@ export interface NotificationProps {
19
20
  */
20
21
  variant?: typeof variants[number];
21
22
 
23
+ /**
24
+ * The position of the notification defining proper styles if the component appear within the content or at the top of the interface.
25
+ */
26
+ position?: typeof positions[number];
27
+
22
28
  /**
23
29
  * When true, allows dismissing the notification by clicking on the close button.
24
30
  */
package/src/index.ts CHANGED
@@ -12,6 +12,7 @@ import {
12
12
  type NotificationProps,
13
13
  type ActionProps,
14
14
  variants,
15
+ positions,
15
16
  headingLevels,
16
17
  componentSelector,
17
18
  componentClass,
@@ -48,6 +49,10 @@ export class PieNotification extends LitElement implements NotificationProps {
48
49
  @validPropertyValues(componentSelector, variants, 'neutral')
49
50
  public variant: NonNullable<NotificationProps['variant']> = 'neutral';
50
51
 
52
+ @property()
53
+ @validPropertyValues(componentSelector, positions, 'inline-content')
54
+ public position: NonNullable<NotificationProps['position']> = 'inline-content';
55
+
51
56
  @property({ type: Boolean })
52
57
  public isDismissible = true;
53
58
 
@@ -64,9 +69,6 @@ export class PieNotification extends LitElement implements NotificationProps {
64
69
  @property({ type: Boolean })
65
70
  public hideIcon = false;
66
71
 
67
- @property({ type: Boolean })
68
- public hideCloseIcon = false;
69
-
70
72
  @property({ type: Object })
71
73
  public leadingAction!: NotificationProps['leadingAction'];
72
74
 
@@ -84,19 +86,9 @@ export class PieNotification extends LitElement implements NotificationProps {
84
86
  @state()
85
87
  protected _hasIconClass = false;
86
88
 
87
- @state()
88
- protected _hasContentGutter = false;
89
-
90
89
  // Renders a `CSSResult` generated from SCSS by Vite
91
90
  static styles = unsafeCSS(styles);
92
91
 
93
- /**
94
- * Lifecycle method executed after component renders.
95
- */
96
- protected firstUpdated (): void {
97
- this.updateIconProperties();
98
- }
99
-
100
92
  /**
101
93
  * Lifecycle method executed when component is about to update.
102
94
  * It update icon properties if variant has changes.
@@ -116,10 +108,6 @@ export class PieNotification extends LitElement implements NotificationProps {
116
108
  if (_changedProperties.has('isOpen') && this.isOpen) {
117
109
  dispatchCustomEvent(this, ON_NOTIFICATION_OPEN_EVENT, { targetNotification: this });
118
110
  }
119
-
120
- if (_changedProperties.has('heading') || _changedProperties.has('isDismissible') || _changedProperties.has('isCompact')) {
121
- this._hasContentGutter = (this.heading === '' || this.heading === undefined) && (this.isDismissible && !this.isCompact);
122
- }
123
111
  }
124
112
 
125
113
  /**
@@ -158,11 +146,7 @@ export class PieNotification extends LitElement implements NotificationProps {
158
146
  * @private
159
147
  */
160
148
  private renderNotificationHeading (heading: NotificationProps['heading'], headingTag: StaticValue): TemplateResult {
161
- return html`
162
- <header class="${componentClass}-header" data-test-id="${componentSelector}-header">
163
- <${headingTag} class="${componentClass}-heading" data-test-id="${componentSelector}-heading">${heading}</${headingTag}>
164
- </header>
165
- `;
149
+ return html`<${headingTag} class="${componentClass}-heading" data-test-id="${componentSelector}-heading">${heading}</${headingTag}>`;
166
150
  }
167
151
 
168
152
  /**
@@ -188,13 +172,13 @@ export class PieNotification extends LitElement implements NotificationProps {
188
172
  private getDefaultVariantIcon (variant: NonNullable<NotificationProps['variant']>) {
189
173
  switch (variant) {
190
174
  case 'info':
191
- return html`<icon-info-circle size="s" data-test-id="${componentSelector}-heading-icon-info"></icon-info-circle>`;
175
+ return html`<icon-info-circle size="m" data-test-id="${componentSelector}-heading-icon-info"></icon-info-circle>`;
192
176
  case 'success':
193
- return html`<icon-check-circle size="s" data-test-id="${componentSelector}-heading-icon-success"></icon-check-circle>`;
177
+ return html`<icon-check-circle size="m" data-test-id="${componentSelector}-heading-icon-success"></icon-check-circle>`;
194
178
  case 'warning':
195
- return html`<icon-alert-triangle size="s" data-test-id="${componentSelector}-heading-icon-warning"></icon-alert-triangle>`;
179
+ return html`<icon-alert-triangle size="m" data-test-id="${componentSelector}-heading-icon-warning"></icon-alert-triangle>`;
196
180
  case 'error':
197
- return html`<icon-alert-circle size="s" data-test-id="${componentSelector}-heading-icon-error"></icon-alert-circle>`;
181
+ return html`<icon-alert-circle size="m" data-test-id="${componentSelector}-heading-icon-error"></icon-alert-circle>`;
198
182
  default:
199
183
  return nothing as never;
200
184
  }
@@ -323,6 +307,7 @@ export class PieNotification extends LitElement implements NotificationProps {
323
307
  render () {
324
308
  const {
325
309
  variant,
310
+ position,
326
311
  heading,
327
312
  headingLevel,
328
313
  isDismissible,
@@ -333,20 +318,26 @@ export class PieNotification extends LitElement implements NotificationProps {
333
318
  leadingAction,
334
319
  supportingAction,
335
320
  isOpen,
336
- _hasContentGutter,
337
321
  } = this;
338
322
 
339
323
  if (!isOpen) {
340
324
  return nothing;
341
325
  }
342
326
 
343
- return html`
344
- <div data-test-id="${componentSelector}" class="${componentClass}" variant="${variant}" ?isCompact="${isCompact}">
345
- ${isDismissible && !isCompact ? this.renderCloseButton() : nothing}
327
+ const showCloseButton = isDismissible && !isCompact;
346
328
 
347
- <section class="${componentClass}-content-section">
329
+ return html`
330
+ <div
331
+ data-test-id="${componentSelector}"
332
+ class="${componentClass}"
333
+ variant="${variant}"
334
+ position="${position}"
335
+ ?isCompact="${isCompact}">
336
+ ${showCloseButton ? this.renderCloseButton() : nothing}
337
+
338
+ <section class="${componentClass}-content-section" ?isDismissible="${showCloseButton}">
348
339
  ${!hideIcon ? this.renderIcon(variant, _hasExternalIcon, _hasIconClass) : nothing}
349
- <article ?hasGutter="${_hasContentGutter}">
340
+ <article>
350
341
  ${heading ? this.renderNotificationHeading(heading, unsafeStatic(headingLevel)) : nothing}
351
342
  <slot></slot>
352
343
  </article>
@@ -1,17 +1,18 @@
1
1
  @use '@justeattakeaway/pie-css/scss' as p;
2
2
 
3
3
  .c-notification {
4
- $breakpoint-narrow: 640px;
4
+ $breakpoint-wide: 768px;
5
5
 
6
6
  --notification-border-radius: var(--dt-radius-rounded-c);
7
7
  --notification-background-color: var(--dt-color-container-subtle);
8
8
  --notification-direction: column;
9
- --notification-icon-size-override: 22px;
10
- --notification-heading-font-size: #{p.font-size(--dt-font-size-20)};
11
- --notification-heading-line-height: calc(var(--dt-font-size-20-line-height) * 1px);
12
- --notification-font-size: #{p.font-size(--dt-font-size-16)};
13
- --notification-line-height: calc(var(--dt-font-size-16-line-height) * 1px);
9
+ --notification-heading-font-size: #{p.font-size(--dt-font-heading-s-size--narrow)};
10
+ --notification-heading-line-height: #{p.line-height(--dt-font-heading-s-line-height--narrow)};
11
+ --notification-font-size: #{p.font-size(--dt-font-body-l-size)};
12
+ --notification-line-height: #{p.line-height(--dt-font-body-l-line-height)};
14
13
  --notification-icon-fill: var(--dt-color-content-default);
14
+ --notification-close-icon-offset: var(--dt-spacing-b);
15
+ --notification-heading-icon-offset: 2px;
15
16
 
16
17
  padding: var(--dt-spacing-d);
17
18
  border-radius: var(--notification-border-radius);
@@ -23,21 +24,14 @@
23
24
  font-size: var(--notification-font-size);
24
25
  line-height: var(--notification-line-height);
25
26
 
26
- h1,
27
- h2,
28
- h3,
29
- h4,
30
- h5,
31
- h6 {
32
- margin: 0;
33
- font-size: var(--notification-heading-font-size);
34
- line-height: var(--notification-heading-line-height);
35
- }
36
-
37
27
  &[isCompact] {
38
28
  --notification-direction: row;
39
29
  }
40
30
 
31
+ &[position='full-width'] {
32
+ --notification-border-radius: var(--dt-radius-rounded-none);
33
+ }
34
+
41
35
  &[variant='neutral-alternative'] {
42
36
  --notification-background-color: var(--dt-color-container-default);
43
37
  }
@@ -60,31 +54,42 @@
60
54
  --notification-icon-fill: var(--dt-color-red);
61
55
  }
62
56
 
63
- &-content-section {
64
- display: flex;
65
- flex-direction: row;
66
57
 
67
- article {
68
- &[hasGutter] {
69
- padding-inline-end: var(--dt-spacing-e);
70
- }
58
+ &-heading {
59
+ margin: 0;
60
+ margin-block-end: var(--dt-spacing-a);
61
+ font-size: var(--notification-heading-font-size);
62
+ line-height: var(--notification-heading-line-height);
63
+
64
+ @media (min-width: $breakpoint-wide) {
65
+ --notification-heading-font-size: #{p.font-size(--dt-font-heading-s-size--wide)};
66
+ --notification-heading-line-height: #{p.line-height(--dt-font-heading-s-line-height--wide)};
71
67
  }
68
+ }
72
69
 
70
+ &-content-section {
71
+ display: flex;
72
+ flex-direction: row;
73
+
73
74
  .has-icon {
74
75
  display: block ruby; // This is a hack to avoid the icon overlap the text in Firefox
75
76
  margin-inline-end: var(--dt-spacing-c);
76
77
  }
78
+
79
+ &[isDismissible] {
80
+ max-width: calc(100% - var(--notification-close-icon-offset) - 40px); // 40px is the size of the medium icon button
81
+ }
77
82
  }
78
83
 
79
84
  &-heading-icon {
80
- padding-block-start: var(--dt-spacing-a);
85
+ padding-block-start: var(--notification-heading-icon-offset);
81
86
  color: var(--notification-icon-fill);
82
87
  }
83
88
 
84
89
  &-icon-close {
85
90
  position: absolute;
86
- inset-block-start: var(--dt-spacing-b);
87
- inset-inline-end: var(--dt-spacing-b);
91
+ inset-block-start: var(--notification-close-icon-offset);
92
+ inset-inline-end: var(--notification-close-icon-offset);
88
93
  }
89
94
 
90
95
  &-footer {
@@ -97,9 +102,9 @@
97
102
  align-self: flex-end;
98
103
  }
99
104
 
100
- @media (max-width: $breakpoint-narrow) {
105
+ @media (max-width: $breakpoint-wide) {
101
106
  &[isStacked] {
102
- flex-direction: column;
107
+ flex-direction: column-reverse;
103
108
  }
104
109
  }
105
110
  }