@justeattakeaway/pie-cookie-banner 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -5,7 +5,62 @@ import type { TemplateResult } from 'lit-html';
5
5
  export declare interface CookieBannerProps {
6
6
  }
7
7
 
8
+ /**
9
+ * Event name for when all cookies are accepted.
10
+ *
11
+ * @constant
12
+ */
13
+ export declare const ON_COOKIE_BANNER_ACCEPT_ALL = "pie-cookie-banner-accept-all";
14
+
15
+ /**
16
+ * Event name for when a user clicks manage preferences.
17
+ *
18
+ * @constant
19
+ */
20
+ export declare const ON_COOKIE_BANNER_MANAGE_PREFS = "pie-cookie-manage-prefs";
21
+
22
+ /**
23
+ * Event name for when all only necessary cookies are accepted.
24
+ *
25
+ * @constant
26
+ */
27
+ export declare const ON_COOKIE_BANNER_NECESSARY_ONLY = "pie-cookie-banner-necessary-only";
28
+
29
+ /**
30
+ * @event {CustomEvent} pie-cookie-banner-accept-all - when all cookies are accepted.
31
+ * @event {CustomEvent} pie-cookie-banner-necessary-only - when all only necessary cookies are accepted.
32
+ * @event {CustomEvent} pie-cookie-manage-prefs - when a user clicks manage preferences.
33
+ */
8
34
  export declare class PieCookieBanner extends LitElement implements CookieBannerProps {
35
+ private _isCookieBannerHidden;
36
+ private _isModalOpen;
37
+ connectedCallback(): void;
38
+ disconnectedCallback(): void;
39
+ /**
40
+ * Handles closing the modal and re-displaying the cookie banner
41
+ * and making the cookie banner visible
42
+ */
43
+ private _displayCookieBanner;
44
+ /**
45
+ * Handles saving the user cookie preferences, closing the modal and the cookie banner
46
+ */
47
+ private _handlePreferencesSaved;
48
+ /**
49
+ * Note: We should aim to have a shareable event helper system to allow
50
+ * us to share this across components in-future.
51
+ *
52
+ * Dispatch a custom event.
53
+ *
54
+ * To be used whenever we have behavioral events we want to
55
+ * bubble up through the cookie banner.
56
+ *
57
+ * @param {string} eventType
58
+ */
59
+ private _dispatchCookieBannerCustomEvent;
60
+ /**
61
+ * Opens the manage preferences modal and emits an event letting users know
62
+ */
63
+ private _openManagePreferencesModal;
9
64
  render(): TemplateResult<1>;
10
65
  static styles: CSSResult;
11
66
  }
package/dist/index.js CHANGED
@@ -1,10 +1,60 @@
1
- import { unsafeCSS as i, LitElement as n, html as t } from "lit";
2
- const a = `*{margin:0}.c-cookieBanner{--cb-font-family: var(--dt-font-interactive-m-family);--cb-font-size: calc(var(--dt-font-body-l-size) * 1px);--cb-line-height: calc(var(--dt-font-body-l-line-height) * 1px);--cb-font-weight: var(--dt-font-body-l-weight);--cb-padding-inline: var(--dt-spacing-d);--cb-padding-block: var(--dt-spacing-d);--cb-offset: 0;color-scheme:only dark;background-color:var(--dt-color-background-dark);color:var(--dt-color-content-inverse);font-family:var(--cb-font-family);font-size:var(--cb-font-size);line-height:var(--cb-line-height);font-weight:var(--cb-font-weight);padding-block-start:var(--cb-padding-block);padding-block-end:var(--cb-padding-block);max-height:432px;position:fixed;bottom:var(--cb-offset);left:var(--cb-offset);right:var(--cb-offset);border-top-left-radius:var(--dt-radius-rounded-c);border-top-right-radius:var(--dt-radius-rounded-c)}@media (min-width: 700px) and (orientation: landscape){.c-cookieBanner{--cb-padding-inline: var(--dt-spacing-f);--cb-offset: var(--dt-spacing-d);max-height:90%;border-bottom-left-radius:var(--dt-radius-rounded-c);border-bottom-right-radius:var(--dt-radius-rounded-c)}}.c-cookieBanner-title,.c-cookieBanner-body,.c-cookieBanner-actions{padding-inline-start:var(--cb-padding-inline);padding-inline-end:var(--cb-padding-inline)}.c-cookieBanner-title{--cb-title-font-size: var(--dt-font-heading-s-size--narrow);--cb-title-line-height: var(--dt-font-heading-s-line-height--narrow);font-size:calc(var(--cb-title-font-size) * 1px);font-weight:var(--dt-font-heading-s-weight);line-height:calc(var(--cb-title-line-height) * 1px)}@media (min-width: 700px) and (orientation: landscape){.c-cookieBanner-title{--cb-title-font-size: var(--dt-font-heading-s-size--wide);--cb-title-line-height: var(--dt-font-heading-s-line-height--wide)}}.c-cookieBanner-body{--cb-scroll-shadow-color: var(--dt-color-black);margin-block-start:var(--dt-spacing-a);max-height:200px;overflow-y:auto;background:linear-gradient(to bottom,transparent,var(--dt-color-background-dark) 75%) center bottom,linear-gradient(transparent,var(--cb-scroll-shadow-color)) center bottom;background-repeat:no-repeat;background-size:100% 48px,100% 8px;background-attachment:local,scroll}@media (min-width: 700px) and (orientation: landscape){.c-cookieBanner-body{max-height:150px}}.c-cookieBanner-actions{--cb-actions-flex-dir: column;margin-block-start:var(--dt-spacing-d);display:flex;gap:var(--dt-spacing-d);flex-direction:var(--cb-actions-flex-dir)}.c-cookieBanner-actions>pie-link{width:max-content;margin-inline-start:auto;margin-inline-end:auto}@media (min-width: 700px) and (orientation: landscape){.c-cookieBanner-actions{--cb-actions-flex-dir: row-reverse;justify-content:flex-start;align-items:center}.c-cookieBanner-actions>pie-link{margin-inline-start:0;margin-inline-end:0}}
3
- `, o = "pie-cookie-banner";
4
- class e extends n {
1
+ import { unsafeCSS as l, LitElement as p, html as h } from "lit";
2
+ import { state as c } from "lit/decorators.js";
3
+ const b = `*{margin:0}.c-cookieBanner{--cb-font-family: var(--dt-font-interactive-m-family);--cb-font-size: calc(var(--dt-font-body-l-size) * 1px);--cb-line-height: calc(var(--dt-font-body-l-line-height) * 1px);--cb-font-weight: var(--dt-font-body-l-weight);--cb-padding-inline: var(--dt-spacing-d);--cb-padding-block: var(--dt-spacing-d);--cb-offset: 0;color-scheme:only dark;background-color:var(--dt-color-background-dark);color:var(--dt-color-content-inverse);font-family:var(--cb-font-family);font-size:var(--cb-font-size);line-height:var(--cb-line-height);font-weight:var(--cb-font-weight);padding-block-start:var(--cb-padding-block);padding-block-end:var(--cb-padding-block);max-height:432px;position:fixed;bottom:var(--cb-offset);left:var(--cb-offset);right:var(--cb-offset);border-top-left-radius:var(--dt-radius-rounded-c);border-top-right-radius:var(--dt-radius-rounded-c)}@media (min-width: 700px) and (orientation: landscape){.c-cookieBanner{--cb-padding-inline: var(--dt-spacing-f);--cb-offset: var(--dt-spacing-d);max-height:90%;border-bottom-left-radius:var(--dt-radius-rounded-c);border-bottom-right-radius:var(--dt-radius-rounded-c)}}.c-cookieBanner[isCookieBannerHidden]{display:none}.c-cookieBanner-title,.c-cookieBanner-body,.c-cookieBanner-actions{padding-inline-start:var(--cb-padding-inline);padding-inline-end:var(--cb-padding-inline)}.c-cookieBanner-title{--cb-title-font-size: var(--dt-font-heading-s-size--narrow);--cb-title-line-height: var(--dt-font-heading-s-line-height--narrow);font-size:calc(var(--cb-title-font-size) * 1px);font-weight:var(--dt-font-heading-s-weight);line-height:calc(var(--cb-title-line-height) * 1px)}@media (min-width: 700px) and (orientation: landscape){.c-cookieBanner-title{--cb-title-font-size: var(--dt-font-heading-s-size--wide);--cb-title-line-height: var(--dt-font-heading-s-line-height--wide)}}.c-cookieBanner-body{--cb-scroll-shadow-color: var(--dt-color-black);margin-block-start:var(--dt-spacing-a);max-height:200px;overflow-y:auto;background:linear-gradient(to bottom,transparent,var(--dt-color-background-dark) 75%) center bottom,linear-gradient(transparent,var(--cb-scroll-shadow-color)) center bottom;background-repeat:no-repeat;background-size:100% 48px,100% 8px;background-attachment:local,scroll}@media (min-width: 700px) and (orientation: landscape){.c-cookieBanner-body{max-height:150px}}.c-cookieBanner-actions{--cb-actions-flex-dir: column;margin-block-start:var(--dt-spacing-d);display:flex;gap:var(--dt-spacing-d);flex-direction:var(--cb-actions-flex-dir)}.c-cookieBanner-actions>pie-link{width:max-content;margin-inline-start:auto;margin-inline-end:auto}@media (min-width: 700px) and (orientation: landscape){.c-cookieBanner-actions{--cb-actions-flex-dir: row-reverse;justify-content:flex-start;align-items:center}.c-cookieBanner-actions>pie-link{margin-inline-start:0;margin-inline-end:0}}
4
+ `, v = "pie-cookie-banner-accept-all", k = "pie-cookie-banner-necessary-only", g = "pie-cookie-manage-prefs";
5
+ var f = Object.defineProperty, m = Object.getOwnPropertyDescriptor, d = (o, e, n, a) => {
6
+ for (var i = a > 1 ? void 0 : a ? m(e, n) : e, r = o.length - 1, s; r >= 0; r--)
7
+ (s = o[r]) && (i = (a ? s(e, n, i) : s(i)) || i);
8
+ return a && i && f(e, n, i), i;
9
+ };
10
+ const u = "pie-cookie-banner";
11
+ class t extends p {
12
+ constructor() {
13
+ super(...arguments), this._isCookieBannerHidden = !1, this._isModalOpen = !1, this._dispatchCookieBannerCustomEvent = (e) => {
14
+ const n = new CustomEvent(e, {
15
+ bubbles: !0,
16
+ composed: !0
17
+ });
18
+ this.dispatchEvent(n);
19
+ }, this._openManagePreferencesModal = () => {
20
+ this._isCookieBannerHidden = !0, this._dispatchCookieBannerCustomEvent(g), this._isModalOpen = !0;
21
+ };
22
+ }
23
+ connectedCallback() {
24
+ super.connectedCallback(), document.addEventListener("pie-modal-back", this._displayCookieBanner.bind(this)), document.addEventListener("pie-modal-leading-action-click", this._handlePreferencesSaved.bind(this));
25
+ }
26
+ disconnectedCallback() {
27
+ document.removeEventListener("pie-modal-back", this._displayCookieBanner.bind(this)), document.removeEventListener("pie-modal-leading-action-click", this._handlePreferencesSaved.bind(this)), super.disconnectedCallback();
28
+ }
29
+ /**
30
+ * Handles closing the modal and re-displaying the cookie banner
31
+ * and making the cookie banner visible
32
+ */
33
+ _displayCookieBanner() {
34
+ this._isModalOpen = !1, this._isCookieBannerHidden = !1;
35
+ }
36
+ /**
37
+ * Handles saving the user cookie preferences, closing the modal and the cookie banner
38
+ */
39
+ _handlePreferencesSaved() {
40
+ this._isModalOpen = !1, this._isCookieBannerHidden = !0, console.info("Cookie Preferences saved");
41
+ }
5
42
  render() {
6
- return t`
7
- <aside data-test-id="pie-cookie-banner" class="c-cookieBanner">
43
+ const e = {
44
+ text: "Save",
45
+ variant: "primary",
46
+ ariaLabel: "Save your cookie preferences"
47
+ };
48
+ return h`
49
+ <pie-modal
50
+ .isOpen="${this._isModalOpen}"
51
+ hasBackButton
52
+ hasStackedActions
53
+ size="large"
54
+ heading="Manage your preferences"
55
+ .leadingAction="${e}"
56
+ ></pie-modal>
57
+ <aside data-test-id="pie-cookie-banner" class="c-cookieBanner" ?isCookieBannerHidden=${this._isCookieBannerHidden}>
8
58
  <h2 class="c-cookieBanner-title">Cookies</h2>
9
59
  <div class="c-cookieBanner-body">
10
60
  <p>We use our own and third party cookies and other tech to enhance and personalise your user experience,
@@ -16,21 +66,49 @@ class e extends n {
16
66
  </div>
17
67
 
18
68
  <div class="c-cookieBanner-actions">
19
- <pie-button variant="primary" isFullWidth="true" size="small-expressive">
69
+ <pie-button
70
+ data-test-id="accept-all"
71
+ @click="${() => {
72
+ this._dispatchCookieBannerCustomEvent(v), this._isCookieBannerHidden = !0;
73
+ }}"
74
+ variant="primary"
75
+ isFullWidth
76
+ size="small-expressive">
20
77
  Accept all
21
78
  </pie-button>
22
- <pie-button variant="outline" isFullWidth="true" size="small-expressive">
79
+ <pie-button
80
+ data-test-id="necessary-only"
81
+ @click="${() => {
82
+ this._dispatchCookieBannerCustomEvent(k), this._isCookieBannerHidden = !0;
83
+ }}"
84
+ variant="outline-inverse"
85
+ isFullWidth
86
+ size="small-expressive">
23
87
  Necessary only
24
88
  </pie-button>
25
- <pie-link variant="inverse" size="medium" isBold="true">
89
+ <pie-link
90
+ data-test-id="manage-prefs"
91
+ @click="${() => this._openManagePreferencesModal()}"
92
+ tag="button"
93
+ variant="inverse"
94
+ isBold="true">
26
95
  Manage preferences
27
96
  </pie-link>
28
97
  </div>
29
98
  </aside>`;
30
99
  }
31
100
  }
32
- e.styles = i(a);
33
- customElements.define(o, e);
101
+ t.styles = l(b);
102
+ d([
103
+ c()
104
+ ], t.prototype, "_isCookieBannerHidden", 2);
105
+ d([
106
+ c()
107
+ ], t.prototype, "_isModalOpen", 2);
108
+ customElements.define(u, t);
34
109
  export {
35
- e as PieCookieBanner
110
+ v as ON_COOKIE_BANNER_ACCEPT_ALL,
111
+ g as ON_COOKIE_BANNER_MANAGE_PREFS,
112
+ k as ON_COOKIE_BANNER_NECESSARY_ONLY,
113
+ t as PieCookieBanner
36
114
  };
package/dist/react.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import type { CSSResult } from 'lit';
2
+ import type { EventName } from '@lit-labs/react';
2
3
  import type { LitElement } from 'lit';
3
4
  import type { ReactWebComponent } from '@lit-labs/react';
4
5
  import type { TemplateResult } from 'lit-html';
@@ -6,9 +7,68 @@ import type { TemplateResult } from 'lit-html';
6
7
  export declare interface CookieBannerProps {
7
8
  }
8
9
 
9
- export declare const PieCookieBanner: ReactWebComponent<PieCookieBanner_2, {}>;
10
+ /**
11
+ * Event name for when all cookies are accepted.
12
+ *
13
+ * @constant
14
+ */
15
+ export declare const ON_COOKIE_BANNER_ACCEPT_ALL = "pie-cookie-banner-accept-all";
10
16
 
17
+ /**
18
+ * Event name for when a user clicks manage preferences.
19
+ *
20
+ * @constant
21
+ */
22
+ export declare const ON_COOKIE_BANNER_MANAGE_PREFS = "pie-cookie-manage-prefs";
23
+
24
+ /**
25
+ * Event name for when all only necessary cookies are accepted.
26
+ *
27
+ * @constant
28
+ */
29
+ export declare const ON_COOKIE_BANNER_NECESSARY_ONLY = "pie-cookie-banner-necessary-only";
30
+
31
+ export declare const PieCookieBanner: ReactWebComponent<PieCookieBanner_2, {
32
+ onPieCookieBannerAcceptAll: EventName<CustomEvent<any>>;
33
+ onPieCookieBannerNecessaryOnly: EventName<CustomEvent<any>>;
34
+ onPieCookieManagePrefs: EventName<CustomEvent<any>>;
35
+ }>;
36
+
37
+ /**
38
+ * @event {CustomEvent} pie-cookie-banner-accept-all - when all cookies are accepted.
39
+ * @event {CustomEvent} pie-cookie-banner-necessary-only - when all only necessary cookies are accepted.
40
+ * @event {CustomEvent} pie-cookie-manage-prefs - when a user clicks manage preferences.
41
+ */
11
42
  declare class PieCookieBanner_2 extends LitElement implements CookieBannerProps {
43
+ private _isCookieBannerHidden;
44
+ private _isModalOpen;
45
+ connectedCallback(): void;
46
+ disconnectedCallback(): void;
47
+ /**
48
+ * Handles closing the modal and re-displaying the cookie banner
49
+ * and making the cookie banner visible
50
+ */
51
+ private _displayCookieBanner;
52
+ /**
53
+ * Handles saving the user cookie preferences, closing the modal and the cookie banner
54
+ */
55
+ private _handlePreferencesSaved;
56
+ /**
57
+ * Note: We should aim to have a shareable event helper system to allow
58
+ * us to share this across components in-future.
59
+ *
60
+ * Dispatch a custom event.
61
+ *
62
+ * To be used whenever we have behavioral events we want to
63
+ * bubble up through the cookie banner.
64
+ *
65
+ * @param {string} eventType
66
+ */
67
+ private _dispatchCookieBannerCustomEvent;
68
+ /**
69
+ * Opens the manage preferences modal and emits an event letting users know
70
+ */
71
+ private _openManagePreferencesModal;
12
72
  render(): TemplateResult<1>;
13
73
  static styles: CSSResult;
14
74
  }
package/dist/react.js CHANGED
@@ -1,36 +1,38 @@
1
- import * as C from "react";
2
- import { PieCookieBanner as E } from "./index.js";
1
+ import * as _ from "react";
2
+ import { PieCookieBanner as k } from "./index.js";
3
+ import { ON_COOKIE_BANNER_ACCEPT_ALL as M, ON_COOKIE_BANNER_MANAGE_PREFS as S, ON_COOKIE_BANNER_NECESSARY_ONLY as x } from "./index.js";
3
4
  import "lit";
5
+ import "lit/decorators.js";
4
6
  /**
5
7
  * @license
6
8
  * Copyright 2018 Google LLC
7
9
  * SPDX-License-Identifier: BSD-3-Clause
8
10
  */
9
- const g = /* @__PURE__ */ new Set(["children", "localName", "ref", "style", "className"]), w = /* @__PURE__ */ new WeakMap(), b = (d, r, m, p, h) => {
10
- const i = h == null ? void 0 : h[r];
11
- i === void 0 || m === p ? m == null && r in HTMLElement.prototype ? d.removeAttribute(r) : d[r] = m : ((o, t, u) => {
12
- let s = w.get(o);
13
- s === void 0 && w.set(o, s = /* @__PURE__ */ new Map());
14
- let a = s.get(t);
15
- u !== void 0 ? a === void 0 ? (s.set(t, a = { handleEvent: u }), o.addEventListener(t, a)) : a.handleEvent = u : a !== void 0 && (s.delete(t), o.removeEventListener(t, a));
16
- })(d, i, m);
11
+ const O = /* @__PURE__ */ new Set(["children", "localName", "ref", "style", "className"]), y = /* @__PURE__ */ new WeakMap(), A = (p, r, d, m, h) => {
12
+ const o = h == null ? void 0 : h[r];
13
+ o === void 0 || d === m ? d == null && r in HTMLElement.prototype ? p.removeAttribute(r) : p[r] = d : ((i, n, N) => {
14
+ let s = y.get(i);
15
+ s === void 0 && y.set(i, s = /* @__PURE__ */ new Map());
16
+ let a = s.get(n);
17
+ N !== void 0 ? a === void 0 ? (s.set(n, a = { handleEvent: N }), i.addEventListener(n, a)) : a.handleEvent = N : a !== void 0 && (s.delete(n), i.removeEventListener(n, a));
18
+ })(p, o, d);
17
19
  };
18
- function B(d = window.React, r, m, p, h) {
19
- let i, o, t;
20
+ function P(p = window.React, r, d, m, h) {
21
+ let o, i, n;
20
22
  if (r === void 0) {
21
- const l = d;
22
- ({ tagName: o, elementClass: t, events: p, displayName: h } = l), i = l.react;
23
+ const l = p;
24
+ ({ tagName: i, elementClass: n, events: m, displayName: h } = l), o = l.react;
23
25
  } else
24
- i = d, t = m, o = r;
25
- const u = i.Component, s = i.createElement, a = new Set(Object.keys(p ?? {}));
26
- class f extends u {
26
+ o = p, n = d, i = r;
27
+ const N = o.Component, s = o.createElement, a = new Set(Object.keys(m ?? {}));
28
+ class f extends N {
27
29
  constructor() {
28
30
  super(...arguments), this.o = null;
29
31
  }
30
32
  t(e) {
31
33
  if (this.o !== null)
32
- for (const v in this.i)
33
- b(this.o, v, this.props[v], e ? e[v] : void 0, p);
34
+ for (const u in this.i)
35
+ A(this.o, u, this.props[u], e ? e[u] : void 0, m);
34
36
  }
35
37
  componentDidMount() {
36
38
  this.t();
@@ -39,29 +41,39 @@ function B(d = window.React, r, m, p, h) {
39
41
  this.t(e);
40
42
  }
41
43
  render() {
42
- const { _$Gl: e, ...v } = this.props;
43
- this.h !== e && (this.u = (n) => {
44
- e !== null && ((c, k) => {
45
- typeof c == "function" ? c(k) : c.current = k;
46
- })(e, n), this.o = n, this.h = e;
44
+ const { _$Gl: e, ...u } = this.props;
45
+ this.h !== e && (this.u = (t) => {
46
+ e !== null && ((c, C) => {
47
+ typeof c == "function" ? c(C) : c.current = C;
48
+ })(e, t), this.o = t, this.h = e;
47
49
  }), this.i = {};
48
- const y = { ref: this.u };
49
- for (const [n, c] of Object.entries(v))
50
- g.has(n) ? y[n === "className" ? "class" : n] = c : a.has(n) || n in t.prototype ? this.i[n] = c : y[n] = c;
51
- return s(o, y);
50
+ const v = { ref: this.u };
51
+ for (const [t, c] of Object.entries(u))
52
+ O.has(t) ? v[t === "className" ? "class" : t] = c : a.has(t) || t in n.prototype ? this.i[t] = c : v[t] = c;
53
+ return s(i, v);
52
54
  }
53
55
  }
54
- f.displayName = h ?? t.name;
55
- const N = i.forwardRef((l, e) => s(f, { ...l, _$Gl: e }, l == null ? void 0 : l.children));
56
- return N.displayName = f.displayName, N;
56
+ f.displayName = h ?? n.name;
57
+ const E = o.forwardRef((l, e) => s(f, { ...l, _$Gl: e }, l == null ? void 0 : l.children));
58
+ return E.displayName = f.displayName, E;
57
59
  }
58
- const L = B({
60
+ const w = P({
59
61
  displayName: "PieCookieBanner",
60
- elementClass: E,
61
- react: C,
62
+ elementClass: k,
63
+ react: _,
62
64
  tagName: "pie-cookie-banner",
63
- events: {}
65
+ events: {
66
+ onPieCookieBannerAcceptAll: "pie-cookie-banner-accept-all",
67
+ // when all cookies are accepted.
68
+ onPieCookieBannerNecessaryOnly: "pie-cookie-banner-necessary-only",
69
+ // when all only necessary cookies are accepted.
70
+ onPieCookieManagePrefs: "pie-cookie-manage-prefs"
71
+ // when a user clicks manage preferences.
72
+ }
64
73
  });
65
74
  export {
66
- L as PieCookieBanner
75
+ M as ON_COOKIE_BANNER_ACCEPT_ALL,
76
+ S as ON_COOKIE_BANNER_MANAGE_PREFS,
77
+ x as ON_COOKIE_BANNER_NECESSARY_ONLY,
78
+ w as PieCookieBanner
67
79
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@justeattakeaway/pie-cookie-banner",
3
3
  "description": "PIE Design System Cookie Banner built using Web Components",
4
- "version": "0.1.0",
4
+ "version": "0.2.0",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.js",
@@ -28,9 +28,11 @@
28
28
  "author": "JustEatTakeaway.com - Design System Web Team",
29
29
  "license": "Apache-2.0",
30
30
  "devDependencies": {
31
- "@justeattakeaway/pie-button": "0.26.0",
31
+ "@justeattakeaway/pie-button": "0.27.0",
32
32
  "@justeattakeaway/pie-components-config": "0.4.0",
33
- "@justeattakeaway/pie-link": "0.3.0"
33
+ "@justeattakeaway/pie-icon-button": "0.14.0",
34
+ "@justeattakeaway/pie-link": "0.3.0",
35
+ "@justeattakeaway/pie-modal": "0.19.0"
34
36
  },
35
37
  "dependencies": {
36
38
  "@justeattakeaway/pie-webc-core": "0.8.0"
@@ -41,6 +41,10 @@ $breakpoint-wide: 700px;
41
41
  border-bottom-left-radius: var(--dt-radius-rounded-c);
42
42
  border-bottom-right-radius: var(--dt-radius-rounded-c);
43
43
  }
44
+
45
+ &[isCookieBannerHidden] {
46
+ display: none;
47
+ }
44
48
  }
45
49
 
46
50
  .c-cookieBanner-title,
package/src/defs.ts CHANGED
@@ -1,3 +1,24 @@
1
1
  // TODO - please remove the eslint disable comment below when you add props to this interface
2
2
  // eslint-disable-next-line @typescript-eslint/no-empty-interface
3
3
  export interface CookieBannerProps {}
4
+
5
+ /**
6
+ * Event name for when all cookies are accepted.
7
+ *
8
+ * @constant
9
+ */
10
+ export const ON_COOKIE_BANNER_ACCEPT_ALL = 'pie-cookie-banner-accept-all';
11
+
12
+ /**
13
+ * Event name for when all only necessary cookies are accepted.
14
+ *
15
+ * @constant
16
+ */
17
+ export const ON_COOKIE_BANNER_NECESSARY_ONLY = 'pie-cookie-banner-necessary-only';
18
+
19
+ /**
20
+ * Event name for when a user clicks manage preferences.
21
+ *
22
+ * @constant
23
+ */
24
+ export const ON_COOKIE_BANNER_MANAGE_PREFS = 'pie-cookie-manage-prefs';
package/src/index.ts CHANGED
@@ -1,17 +1,108 @@
1
- import { LitElement, html, unsafeCSS } from 'lit';
2
-
1
+ import {
2
+ LitElement, html, unsafeCSS,
3
+ } from 'lit';
4
+ import { state } from 'lit/decorators.js';
3
5
  import styles from './cookie-banner.scss?inline';
4
- import { CookieBannerProps } from './defs';
6
+ import {
7
+ CookieBannerProps,
8
+ ON_COOKIE_BANNER_ACCEPT_ALL,
9
+ ON_COOKIE_BANNER_NECESSARY_ONLY,
10
+ ON_COOKIE_BANNER_MANAGE_PREFS,
11
+ } from './defs';
5
12
 
6
13
  // Valid values available to consumers
7
14
  export * from './defs';
8
15
 
9
16
  const componentSelector = 'pie-cookie-banner';
10
17
 
18
+ /**
19
+ * @event {CustomEvent} pie-cookie-banner-accept-all - when all cookies are accepted.
20
+ * @event {CustomEvent} pie-cookie-banner-necessary-only - when all only necessary cookies are accepted.
21
+ * @event {CustomEvent} pie-cookie-manage-prefs - when a user clicks manage preferences.
22
+ */
11
23
  export class PieCookieBanner extends LitElement implements CookieBannerProps {
24
+ @state()
25
+ private _isCookieBannerHidden = false;
26
+
27
+ @state()
28
+ private _isModalOpen = false;
29
+
30
+ connectedCallback () : void {
31
+ super.connectedCallback();
32
+ document.addEventListener('pie-modal-back', this._displayCookieBanner.bind(this));
33
+ document.addEventListener('pie-modal-leading-action-click', this._handlePreferencesSaved.bind(this));
34
+ }
35
+
36
+ disconnectedCallback () : void {
37
+ document.removeEventListener('pie-modal-back', this._displayCookieBanner.bind(this));
38
+ document.removeEventListener('pie-modal-leading-action-click', this._handlePreferencesSaved.bind(this));
39
+ super.disconnectedCallback();
40
+ }
41
+
42
+ /**
43
+ * Handles closing the modal and re-displaying the cookie banner
44
+ * and making the cookie banner visible
45
+ */
46
+ private _displayCookieBanner () : void {
47
+ this._isModalOpen = false;
48
+ this._isCookieBannerHidden = false;
49
+ }
50
+
51
+ /**
52
+ * Handles saving the user cookie preferences, closing the modal and the cookie banner
53
+ */
54
+ private _handlePreferencesSaved () : void {
55
+ this._isModalOpen = false;
56
+ this._isCookieBannerHidden = true;
57
+ console.info('Cookie Preferences saved');
58
+ }
59
+
60
+ /**
61
+ * Note: We should aim to have a shareable event helper system to allow
62
+ * us to share this across components in-future.
63
+ *
64
+ * Dispatch a custom event.
65
+ *
66
+ * To be used whenever we have behavioral events we want to
67
+ * bubble up through the cookie banner.
68
+ *
69
+ * @param {string} eventType
70
+ */
71
+ private _dispatchCookieBannerCustomEvent = (eventType: string) : void => {
72
+ const event = new CustomEvent(eventType, {
73
+ bubbles: true,
74
+ composed: true,
75
+ });
76
+
77
+ this.dispatchEvent(event);
78
+ };
79
+
80
+ /**
81
+ * Opens the manage preferences modal and emits an event letting users know
82
+ */
83
+ private _openManagePreferencesModal = () : void => {
84
+ this._isCookieBannerHidden = true;
85
+ this._dispatchCookieBannerCustomEvent(ON_COOKIE_BANNER_MANAGE_PREFS);
86
+ this._isModalOpen = true;
87
+ };
88
+
12
89
  render () {
90
+ const modalActionProps = {
91
+ text: 'Save',
92
+ variant: 'primary',
93
+ ariaLabel: 'Save your cookie preferences',
94
+ };
95
+
13
96
  return html`
14
- <aside data-test-id="pie-cookie-banner" class="c-cookieBanner">
97
+ <pie-modal
98
+ .isOpen="${this._isModalOpen}"
99
+ hasBackButton
100
+ hasStackedActions
101
+ size="large"
102
+ heading="Manage your preferences"
103
+ .leadingAction="${modalActionProps}"
104
+ ></pie-modal>
105
+ <aside data-test-id="pie-cookie-banner" class="c-cookieBanner" ?isCookieBannerHidden=${this._isCookieBannerHidden}>
15
106
  <h2 class="c-cookieBanner-title">Cookies</h2>
16
107
  <div class="c-cookieBanner-body">
17
108
  <p>We use our own and third party cookies and other tech to enhance and personalise your user experience,
@@ -23,13 +114,28 @@ export class PieCookieBanner extends LitElement implements CookieBannerProps {
23
114
  </div>
24
115
 
25
116
  <div class="c-cookieBanner-actions">
26
- <pie-button variant="primary" isFullWidth="true" size="small-expressive">
117
+ <pie-button
118
+ data-test-id="accept-all"
119
+ @click="${() => { this._dispatchCookieBannerCustomEvent(ON_COOKIE_BANNER_ACCEPT_ALL); this._isCookieBannerHidden = true; }}"
120
+ variant="primary"
121
+ isFullWidth
122
+ size="small-expressive">
27
123
  Accept all
28
124
  </pie-button>
29
- <pie-button variant="outline" isFullWidth="true" size="small-expressive">
125
+ <pie-button
126
+ data-test-id="necessary-only"
127
+ @click="${() => { this._dispatchCookieBannerCustomEvent(ON_COOKIE_BANNER_NECESSARY_ONLY); this._isCookieBannerHidden = true; }}"
128
+ variant="outline-inverse"
129
+ isFullWidth
130
+ size="small-expressive">
30
131
  Necessary only
31
132
  </pie-button>
32
- <pie-link variant="inverse" size="medium" isBold="true">
133
+ <pie-link
134
+ data-test-id="manage-prefs"
135
+ @click="${() => this._openManagePreferencesModal()}"
136
+ tag="button"
137
+ variant="inverse"
138
+ isBold="true">
33
139
  Manage preferences
34
140
  </pie-link>
35
141
  </div>