@justeattakeaway/pie-icon-button 0.20.0 → 0.21.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/README.md CHANGED
@@ -94,7 +94,8 @@ Then, in your markup, you would implement the component like this:
94
94
  |-------------|-----------|-----------------|----------------------------------------------------------------------|
95
95
  | size | `String` | `medium` | Size of the Icon Button, one of `sizes` – `xsmall`, `small`, `medium`, `large` |
96
96
  | variant | `String` | `primary` | Variant of the button, one of `variants` – `primary`, `secondary`, `outline`, `ghost`, `ghost-secondary` |
97
- | disabled | `Boolean` | `false` | If `true`, disables the button. |
97
+ | disabled | `Boolean` | `false`| If `true`, disables the button.|
98
+ | isLoading | `Boolean` | `false` | If `true`, displays a loading indicator inside the icon button. |
98
99
 
99
100
  In your HTML markup or JSX, you can then use these to set the properties for the `pie-icon-button` component, like so:
100
101
 
package/dist/index.d.ts CHANGED
@@ -1,32 +1,44 @@
1
1
  import type { CSSResult } from 'lit';
2
2
  import type { LitElement } from 'lit';
3
- import type { TemplateResult } from 'lit-html';
3
+ import type { TemplateResult } from 'lit';
4
4
 
5
5
  export declare interface IconButtonProps {
6
6
  /**
7
7
  * (Optional) What size the button should be.
8
8
  * @default "medium"
9
9
  */
10
- size: typeof sizes[number];
10
+ size?: typeof sizes[number];
11
11
  /**
12
12
  * (Optional) What style variant the button should be such as primary, outline or ghost.
13
13
  * @default "primary"
14
14
  */
15
- variant: typeof variants[number];
15
+ variant?: typeof variants[number];
16
16
  /**
17
17
  * (Optional) When true, the button element is disabled.
18
18
  * @default false
19
19
  */
20
- disabled: boolean;
20
+ disabled?: boolean;
21
+ /**
22
+ * (Optional) When true, a loading spinner is rendered.
23
+ * @default false
24
+ */
25
+ isLoading?: boolean;
21
26
  }
22
27
 
23
28
  /**
24
29
  * @tagname pie-icon-button
25
30
  */
26
31
  export declare class PieIconButton extends LitElement implements IconButtonProps {
27
- size: IconButtonProps['size'];
28
- variant: IconButtonProps['variant'];
29
- disabled: boolean;
32
+ size?: IconButtonProps['size'];
33
+ variant?: IconButtonProps['variant'];
34
+ disabled?: boolean | undefined;
35
+ isLoading?: boolean | undefined;
36
+ /**
37
+ * Template for the loading state
38
+ *
39
+ * @private
40
+ */
41
+ private renderSpinner;
30
42
  render(): TemplateResult<1>;
31
43
  static styles: CSSResult;
32
44
  }
package/dist/index.js CHANGED
@@ -1,26 +1,26 @@
1
- import { unsafeCSS as f, LitElement as m, html as u } from "lit";
2
- import { property as v } from "lit/decorators.js";
3
- const b = (r, o, a) => function(t, e) {
4
- const c = `#${e}`;
5
- Object.defineProperty(t, e, {
1
+ import { unsafeCSS as m, LitElement as g, html as d, nothing as z } from "lit";
2
+ import { property as c } from "lit/decorators.js";
3
+ const u = (n, o, t) => function(r, i) {
4
+ const a = `#${i}`;
5
+ Object.defineProperty(r, i, {
6
6
  get() {
7
- return this[c];
7
+ return this[a];
8
8
  },
9
9
  set(l) {
10
- const h = this[c];
11
- o.includes(l) ? this[c] = l : (console.error(
12
- `<${r}> Invalid value "${l}" provided for property "${e}".`,
10
+ const B = this[a];
11
+ o.includes(l) ? this[a] = l : (console.error(
12
+ `<${n}> Invalid value "${l}" provided for property "${i}".`,
13
13
  `Must be one of: ${o.join(" | ")}.`,
14
- `Falling back to default value: "${a}"`
15
- ), this[c] = a), this.requestUpdate(e, h);
14
+ `Falling back to default value: "${t}"`
15
+ ), this[a] = t), this.requestUpdate(i, B);
16
16
  }
17
17
  });
18
18
  };
19
- function g(r, o) {
20
- customElements.get(r) ? console.warn(`PIE Web Component: "${r}" has already been defined. Please ensure the component is only being defined once in your application.`) : customElements.define(r, o);
19
+ function x(n, o) {
20
+ customElements.get(n) ? console.warn(`PIE Web Component: "${n}" has already been defined. Please ensure the component is only being defined once in your application.`) : customElements.define(n, o);
21
21
  }
22
- const p = `:host{--btn-dimension: 48px;--btn-icon-size: 24px}.o-iconBtn{--btn-border-radius: var(--dt-radius-rounded-e);--btn-bg-color: var(--dt-color-interactive-brand);--btn-icon-fill: var(--dt-color-content-interactive-primary);block-size:var(--btn-dimension);inline-size:var(--btn-dimension);border-color:var(--btn-border-color);border-radius:var(--btn-border-radius);background-color:var(--btn-bg-color);color:var(--btn-icon-fill);cursor:pointer;user-select:none;outline:none;border:none;display:flex;align-items:center;justify-content:center}.o-iconBtn:focus-visible{box-shadow:0 0 0 2px var(--dt-color-focus-inner),0 0 0 4px var(--dt-color-focus-outer);outline:none}.o-iconBtn svg{height:var(--btn-icon-size);width:var(--btn-icon-size)}.o-iconBtn[variant=primary]:hover:not(:disabled){--hover-modifier: calc(-1 * var(--dt-color-hover-01));--btn-bg-color: hsl(var(--dt-color-interactive-brand-h), var(--dt-color-interactive-brand-s), calc(var(--dt-color-interactive-brand-l) + var(--hover-modifier)))}.o-iconBtn[variant=primary]:active:not(:disabled){--active-modifier: calc(-1 * var(--dt-color-active-01));--btn-bg-color: hsl(var(--dt-color-interactive-brand-h), var(--dt-color-interactive-brand-s), calc(var(--dt-color-interactive-brand-l) + var(--active-modifier)))}.o-iconBtn[variant=secondary]{--btn-bg-color: var(--dt-color-interactive-secondary);--btn-icon-fill: var(--dt-color-content-interactive-secondary)}.o-iconBtn[variant=secondary]:hover:not(:disabled){--hover-modifier: calc(-1 * var(--dt-color-hover-01));--btn-bg-color: hsl(var(--dt-color-interactive-secondary-h), var(--dt-color-interactive-secondary-s), calc(var(--dt-color-interactive-secondary-l) + var(--hover-modifier)))}.o-iconBtn[variant=secondary]:active:not(:disabled){--active-modifier: calc(-1 * var(--dt-color-active-01));--btn-bg-color: hsl(var(--dt-color-interactive-secondary-h), var(--dt-color-interactive-secondary-s), calc(var(--dt-color-interactive-secondary-l) + var(--active-modifier)))}.o-iconBtn[variant=outline]{--btn-bg-color: transparent;--btn-icon-fill: var(--dt-color-content-interactive-brand);border:1px solid var(--dt-color-border-strong)}.o-iconBtn[variant=outline]:hover:not(:disabled){--hover-modifier: calc(-1 * var(--dt-color-hover-01));--btn-bg-color: hsl(var(--dt-color-black-h), var(--dt-color-black-s), calc(var(--dt-color-black-l) + var(--hover-modifier)));--hover-modifier: var(--dt-color-hover-01);--btn-bg-color: hsl(var(--dt-color-black-h), var(--dt-color-black-s), var(--dt-color-black-l), var(--hover-modifier))}.o-iconBtn[variant=outline]:active:not(:disabled){--active-modifier: calc(-1 * var(--dt-color-active-01));--btn-bg-color: hsl(var(--dt-color-black-h), var(--dt-color-black-s), calc(var(--dt-color-black-l) + var(--active-modifier)));--active-modifier: var(--dt-color-active-01);--btn-bg-color: hsl(var(--dt-color-black-h), var(--dt-color-black-s), var(--dt-color-black-l), var(--active-modifier))}.o-iconBtn[variant=ghost]{--btn-bg-color: transparent;--btn-icon-fill: var(--dt-color-content-interactive-brand)}.o-iconBtn[variant=ghost]:hover:not(:disabled){--hover-modifier: calc(-1 * var(--dt-color-hover-01));--btn-bg-color: hsl(var(--dt-color-black-h), var(--dt-color-black-s), calc(var(--dt-color-black-l) + var(--hover-modifier)));--hover-modifier: var(--dt-color-hover-01);--btn-bg-color: hsl(var(--dt-color-black-h), var(--dt-color-black-s), var(--dt-color-black-l), var(--hover-modifier))}.o-iconBtn[variant=ghost]:active:not(:disabled){--active-modifier: calc(-1 * var(--dt-color-active-01));--btn-bg-color: hsl(var(--dt-color-black-h), var(--dt-color-black-s), calc(var(--dt-color-black-l) + var(--active-modifier)));--active-modifier: var(--dt-color-active-01);--btn-bg-color: hsl(var(--dt-color-black-h), var(--dt-color-black-s), var(--dt-color-black-l), var(--active-modifier))}.o-iconBtn[variant=ghost-secondary]{--btn-bg-color: transparent;--btn-icon-fill: var(--dt-color-content-interactive-secondary)}.o-iconBtn[variant=ghost-secondary]:hover:not(:disabled){--hover-modifier: calc(-1 * var(--dt-color-hover-01));--btn-bg-color: hsl(var(--dt-color-black-h), var(--dt-color-black-s), calc(var(--dt-color-black-l) + var(--hover-modifier)));--hover-modifier: var(--dt-color-hover-01);--btn-bg-color: hsl(var(--dt-color-black-h), var(--dt-color-black-s), var(--dt-color-black-l), var(--hover-modifier))}.o-iconBtn[variant=ghost-secondary]:active:not(:disabled){--active-modifier: calc(-1 * var(--dt-color-active-01));--btn-bg-color: hsl(var(--dt-color-black-h), var(--dt-color-black-s), calc(var(--dt-color-black-l) + var(--active-modifier)));--active-modifier: var(--dt-color-active-01);--btn-bg-color: hsl(var(--dt-color-black-h), var(--dt-color-black-s), var(--dt-color-black-l), var(--active-modifier))}.o-iconBtn[variant=inverse]{--btn-bg-color: var(--dt-color-interactive-inverse);--btn-icon-fill: var(--dt-color-content-interactive-brand)}.o-iconBtn[variant=inverse]:hover:not(:disabled){--hover-modifier: calc(-1 * var(--dt-color-hover-01));--btn-bg-color: hsl(var(--dt-color-interactive-inverse-h), var(--dt-color-interactive-inverse-s), calc(var(--dt-color-interactive-inverse-l) + var(--hover-modifier)))}.o-iconBtn[variant=inverse]:active:not(:disabled){--active-modifier: calc(-1 * var(--dt-color-active-01));--btn-bg-color: hsl(var(--dt-color-interactive-inverse-h), var(--dt-color-interactive-inverse-s), calc(var(--dt-color-interactive-inverse-l) + var(--active-modifier)))}.o-iconBtn[variant=ghost-inverse]{--btn-bg-color: transparent;--btn-icon-fill: var(--dt-color-content-inverse)}.o-iconBtn[variant=ghost-inverse]:hover:not(:disabled){--hover-modifier: calc(-1 * var(--dt-color-hover-01));--btn-bg-color: hsl(var(--dt-color-container-default-h), var(--dt-color-container-default-s), calc(var(--dt-color-container-default-l) + var(--hover-modifier)));--hover-modifier: var(--dt-color-hover-01);--btn-bg-color: hsl(var(--dt-color-container-default-h), var(--dt-color-container-default-s), var(--dt-color-container-default-l), var(--hover-modifier))}.o-iconBtn[variant=ghost-inverse]:active:not(:disabled){--active-modifier: calc(-1 * var(--dt-color-active-01));--btn-bg-color: hsl(var(--dt-color-container-default-h), var(--dt-color-container-default-s), calc(var(--dt-color-container-default-l) + var(--active-modifier)));--active-modifier: var(--dt-color-active-01);--btn-bg-color: hsl(var(--dt-color-container-default-h), var(--dt-color-container-default-s), var(--dt-color-container-default-l), var(--active-modifier))}.o-iconBtn[disabled]{--btn-icon-fill: var(--dt-color-content-disabled);cursor:not-allowed}.o-iconBtn[disabled]:not([variant=ghost],[variant=ghost-secondary],[variant=ghost-inverse]){--btn-bg-color: var(--dt-color-disabled-01)}.o-iconBtn[disabled][variant=outline]{border-color:var(--dt-color-disabled-01)}.o-iconBtn[size=xsmall]{--btn-dimension: 32px}.o-iconBtn[size=small]{--btn-dimension: 40px}.o-iconBtn[size=large]{--btn-dimension: 56px;--btn-icon-size: 28px}
23
- `, y = ["xsmall", "small", "medium", "large"], k = [
22
+ const $ = `:host{--btn-dimension: 48px;--btn-icon-size: 24px}.o-iconBtn{--btn-border-radius: var(--dt-radius-rounded-e);--btn-bg-color: var(--dt-color-interactive-brand);--btn-icon-fill: var(--dt-color-content-interactive-primary);block-size:var(--btn-dimension);inline-size:var(--btn-dimension);border-color:var(--btn-border-color);border-radius:var(--btn-border-radius);background-color:var(--btn-bg-color);color:var(--btn-icon-fill);cursor:pointer;user-select:none;outline:none;border:none;display:flex;align-items:center;justify-content:center}.o-iconBtn:focus-visible{box-shadow:0 0 0 2px var(--dt-color-focus-inner),0 0 0 4px var(--dt-color-focus-outer);outline:none}.o-iconBtn svg{height:var(--btn-icon-size);width:var(--btn-icon-size)}.o-iconBtn[variant=primary]:hover:not(:disabled){--hover-modifier: calc(-1 * var(--dt-color-hover-01));--btn-bg-color: hsl(var(--dt-color-interactive-brand-h), var(--dt-color-interactive-brand-s), calc(var(--dt-color-interactive-brand-l) + var(--hover-modifier)))}.o-iconBtn[variant=primary]:active:not(:disabled),.o-iconBtn[variant=primary][isLoading]:not(:disabled){--active-modifier: calc(-1 * var(--dt-color-active-01));--btn-bg-color: hsl(var(--dt-color-interactive-brand-h), var(--dt-color-interactive-brand-s), calc(var(--dt-color-interactive-brand-l) + var(--active-modifier)))}.o-iconBtn[variant=secondary]{--btn-bg-color: var(--dt-color-interactive-secondary);--btn-icon-fill: var(--dt-color-content-interactive-secondary)}.o-iconBtn[variant=secondary]:hover:not(:disabled){--hover-modifier: calc(-1 * var(--dt-color-hover-01));--btn-bg-color: hsl(var(--dt-color-interactive-secondary-h), var(--dt-color-interactive-secondary-s), calc(var(--dt-color-interactive-secondary-l) + var(--hover-modifier)))}.o-iconBtn[variant=secondary]:active:not(:disabled),.o-iconBtn[variant=secondary][isLoading]:not(:disabled){--active-modifier: calc(-1 * var(--dt-color-active-01));--btn-bg-color: hsl(var(--dt-color-interactive-secondary-h), var(--dt-color-interactive-secondary-s), calc(var(--dt-color-interactive-secondary-l) + var(--active-modifier)))}.o-iconBtn[variant=outline]{--btn-bg-color: transparent;--btn-icon-fill: var(--dt-color-content-interactive-brand);border:1px solid var(--dt-color-border-strong)}.o-iconBtn[variant=outline]:hover:not(:disabled){--hover-modifier: calc(-1 * var(--dt-color-hover-01));--hover-modifier: var(--dt-color-hover-01);--btn-bg-color: hsl(var(--dt-color-black-h), var(--dt-color-black-s), var(--dt-color-black-l), var(--hover-modifier))}.o-iconBtn[variant=outline]:active:not(:disabled),.o-iconBtn[variant=outline][isLoading]:not(:disabled){--active-modifier: calc(-1 * var(--dt-color-active-01));--active-modifier: var(--dt-color-active-01);--btn-bg-color: hsl(var(--dt-color-black-h), var(--dt-color-black-s), var(--dt-color-black-l), var(--active-modifier))}.o-iconBtn[variant=ghost]{--btn-bg-color: transparent;--btn-icon-fill: var(--dt-color-content-interactive-brand)}.o-iconBtn[variant=ghost]:hover:not(:disabled){--hover-modifier: calc(-1 * var(--dt-color-hover-01));--hover-modifier: var(--dt-color-hover-01);--btn-bg-color: hsl(var(--dt-color-black-h), var(--dt-color-black-s), var(--dt-color-black-l), var(--hover-modifier))}.o-iconBtn[variant=ghost]:active:not(:disabled),.o-iconBtn[variant=ghost][isLoading]:not(:disabled){--active-modifier: calc(-1 * var(--dt-color-active-01));--active-modifier: var(--dt-color-active-01);--btn-bg-color: hsl(var(--dt-color-black-h), var(--dt-color-black-s), var(--dt-color-black-l), var(--active-modifier))}.o-iconBtn[variant=ghost-secondary]{--btn-bg-color: transparent;--btn-icon-fill: var(--dt-color-content-interactive-secondary)}.o-iconBtn[variant=ghost-secondary]:hover:not(:disabled){--hover-modifier: calc(-1 * var(--dt-color-hover-01));--hover-modifier: var(--dt-color-hover-01);--btn-bg-color: hsl(var(--dt-color-black-h), var(--dt-color-black-s), var(--dt-color-black-l), var(--hover-modifier))}.o-iconBtn[variant=ghost-secondary]:active:not(:disabled),.o-iconBtn[variant=ghost-secondary][isLoading]:not(:disabled){--active-modifier: calc(-1 * var(--dt-color-active-01));--active-modifier: var(--dt-color-active-01);--btn-bg-color: hsl(var(--dt-color-black-h), var(--dt-color-black-s), var(--dt-color-black-l), var(--active-modifier))}.o-iconBtn[variant=inverse]{--btn-bg-color: var(--dt-color-interactive-inverse);--btn-icon-fill: var(--dt-color-content-interactive-brand)}.o-iconBtn[variant=inverse]:hover:not(:disabled){--hover-modifier: calc(-1 * var(--dt-color-hover-01));--btn-bg-color: hsl(var(--dt-color-interactive-inverse-h), var(--dt-color-interactive-inverse-s), calc(var(--dt-color-interactive-inverse-l) + var(--hover-modifier)))}.o-iconBtn[variant=inverse]:active:not(:disabled),.o-iconBtn[variant=inverse][isLoading]:not(:disabled){--active-modifier: calc(-1 * var(--dt-color-active-01));--btn-bg-color: hsl(var(--dt-color-interactive-inverse-h), var(--dt-color-interactive-inverse-s), calc(var(--dt-color-interactive-inverse-l) + var(--active-modifier)))}.o-iconBtn[variant=ghost-inverse]{--btn-bg-color: transparent;--btn-icon-fill: var(--dt-color-content-inverse)}.o-iconBtn[variant=ghost-inverse]:hover:not(:disabled){--hover-modifier: calc(-1 * var(--dt-color-hover-01));--hover-modifier: var(--dt-color-hover-01);--btn-bg-color: hsl(var(--dt-color-container-default-h), var(--dt-color-container-default-s), var(--dt-color-container-default-l), var(--hover-modifier))}.o-iconBtn[variant=ghost-inverse]:active:not(:disabled),.o-iconBtn[variant=ghost-inverse][isLoading]:not(:disabled){--active-modifier: calc(-1 * var(--dt-color-active-01));--active-modifier: var(--dt-color-active-01);--btn-bg-color: hsl(var(--dt-color-container-default-h), var(--dt-color-container-default-s), var(--dt-color-container-default-l), var(--active-modifier))}.o-iconBtn[disabled]{--btn-icon-fill: var(--dt-color-content-disabled);cursor:not-allowed}.o-iconBtn[disabled]:not([variant=ghost],[variant=ghost-secondary],[variant=ghost-inverse]){--btn-bg-color: var(--dt-color-disabled-01)}.o-iconBtn[disabled][variant=outline]{border-color:var(--dt-color-disabled-01)}.o-iconBtn[size=xsmall]{--btn-dimension: 32px}.o-iconBtn[size=small]{--btn-dimension: 40px}.o-iconBtn[size=large]{--btn-dimension: 56px;--btn-icon-size: 28px}
23
+ `, k = ["xsmall", "small", "medium", "large"], P = [
24
24
  "primary",
25
25
  "secondary",
26
26
  "outline",
@@ -28,48 +28,124 @@ const p = `:host{--btn-dimension: 48px;--btn-icon-size: 24px}.o-iconBtn{--btn-bo
28
28
  "ghost-secondary",
29
29
  "inverse",
30
30
  "ghost-inverse"
31
- ];
32
- var B = Object.defineProperty, x = Object.getOwnPropertyDescriptor, d = (r, o, a, i) => {
33
- for (var t = i > 1 ? void 0 : i ? x(o, a) : o, e = r.length - 1, c; e >= 0; e--)
34
- (c = r[e]) && (t = (i ? c(o, a, t) : c(t)) || t);
35
- return i && t && B(o, a, t), t;
31
+ ], y = (n, o, t) => function(e, r) {
32
+ const i = `#${r}`;
33
+ Object.defineProperty(e, r, {
34
+ get() {
35
+ return this[i];
36
+ },
37
+ set(a) {
38
+ const l = this[i];
39
+ o.includes(a) ? this[i] = a : (console.error(
40
+ `<${n}> Invalid value "${a}" provided for property "${r}".`,
41
+ `Must be one of: ${o.join(" | ")}.`,
42
+ `Falling back to default value: "${t}"`
43
+ ), this[i] = t), this.requestUpdate(r, l);
44
+ }
45
+ });
46
+ };
47
+ function w(n, o) {
48
+ customElements.get(n) ? console.warn(`PIE Web Component: "${n}" has already been defined. Please ensure the component is only being defined once in your application.`) : customElements.define(n, o);
49
+ }
50
+ const L = `*,*:before,*:after{box-sizing:border-box}@keyframes rotate360{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.c-spinner{--spinner-size: 24px;--spinner-left-color: hsl(var(--spinner-base-color-h), var(--spinner-base-color-s), var(--spinner-base-color-l), 1);--spinner-right-color: hsl(var(--spinner-base-color-h), var(--spinner-base-color-s), var(--spinner-base-color-l), .35);block-size:var(--spinner-size);inline-size:var(--spinner-size);border-radius:var(--dt-radius-rounded-e);border-width:calc(var(--spinner-size) / 8);border-style:solid;border-color:var(--spinner-left-color) var(--spinner-right-color) var(--spinner-right-color) var(--spinner-left-color);will-change:transform;animation:rotate360 1.15s linear infinite;--spinner-base-color-h: var(--dt-color-content-brand-h);--spinner-base-color-s: var(--dt-color-content-brand-s);--spinner-base-color-l: var(--dt-color-content-brand-l)}.c-spinner[variant=secondary]{--spinner-base-color-h: var(--dt-color-content-interactive-secondary-h);--spinner-base-color-s: var(--dt-color-content-interactive-secondary-s);--spinner-base-color-l: var(--dt-color-content-interactive-secondary-l)}.c-spinner[variant=inverse]{--spinner-base-color-h: var(--dt-color-content-inverse-h);--spinner-base-color-s: var(--dt-color-content-inverse-s);--spinner-base-color-l: var(--dt-color-content-inverse-l)}.c-spinner[size=xs]{--spinner-size: 16px}.c-spinner[size=s]{--spinner-size: 20px}.c-spinner[size=l]{--spinner-size: 32px}.c-spinner[size=xl]{--spinner-size: 48px}.c-spinner-label{position:absolute;display:block;height:1px;width:1px;overflow:hidden;padding:1px;white-space:nowrap}
51
+ `, j = ["xs", "s", "m", "l", "xl"], O = ["brand", "secondary", "inverse"];
52
+ var E = Object.defineProperty, _ = Object.getOwnPropertyDescriptor, p = (n, o, t, e) => {
53
+ for (var r = e > 1 ? void 0 : e ? _(o, t) : o, i = n.length - 1, a; i >= 0; i--)
54
+ (a = n[i]) && (r = (e ? a(o, t, r) : a(r)) || r);
55
+ return e && r && E(o, t, r), r;
36
56
  };
37
- const s = "pie-icon-button";
38
- class n extends m {
57
+ const h = "pie-spinner";
58
+ class v extends g {
39
59
  constructor() {
40
- super(...arguments), this.size = "medium", this.variant = "primary", this.disabled = !1;
60
+ super(...arguments), this.size = "m", this.variant = "brand";
61
+ }
62
+ render() {
63
+ const { variant: o, size: t, aria: e } = this;
64
+ return d`
65
+ <div
66
+ data-test-id="pie-spinner"
67
+ class="c-spinner"
68
+ role="status"
69
+ aria-live="polite"
70
+ size="${t}"
71
+ variant="${o}">
72
+ ${e != null && e.label ? d`<span class="c-spinner-label">${e.label}</span>` : z}
73
+ </div>`;
74
+ }
75
+ }
76
+ v.styles = m(L);
77
+ p([
78
+ c({ type: Object })
79
+ ], v.prototype, "aria", 2);
80
+ p([
81
+ c(),
82
+ y(h, j, "m")
83
+ ], v.prototype, "size", 2);
84
+ p([
85
+ c(),
86
+ y(h, O, "brand")
87
+ ], v.prototype, "variant", 2);
88
+ w(h, v);
89
+ var C = Object.defineProperty, I = Object.getOwnPropertyDescriptor, b = (n, o, t, e) => {
90
+ for (var r = e > 1 ? void 0 : e ? I(o, t) : o, i = n.length - 1, a; i >= 0; i--)
91
+ (a = n[i]) && (r = (e ? a(o, t, r) : a(r)) || r);
92
+ return e && r && C(o, t, r), r;
93
+ };
94
+ const f = "pie-icon-button";
95
+ class s extends g {
96
+ constructor() {
97
+ super(...arguments), this.size = "medium", this.variant = "primary", this.disabled = !1, this.isLoading = !1;
98
+ }
99
+ /**
100
+ * Template for the loading state
101
+ *
102
+ * @private
103
+ */
104
+ renderSpinner() {
105
+ const { variant: o, size: t } = this, e = t === "xsmall" ? "s" : "m";
106
+ let r = "brand";
107
+ return o != null && o.includes("secondary") && (r = "secondary"), (o === "primary" || o === "ghost-inverse") && (r = "inverse"), d`
108
+ <pie-spinner
109
+ size="${e}"
110
+ variant="${r}"
111
+ </pie-spinner>`;
41
112
  }
42
113
  render() {
43
114
  const {
44
115
  disabled: o,
45
- size: a,
46
- variant: i
116
+ size: t,
117
+ variant: e,
118
+ isLoading: r
47
119
  } = this;
48
- return u`
120
+ return d`
49
121
  <button
50
122
  class="o-iconBtn"
51
- size=${a}
52
- variant=${i}
53
- ?disabled=${o}>
54
- <slot></slot>
123
+ size="${t}"
124
+ variant="${e}"
125
+ ?disabled="${o}"
126
+ ?isLoading="${r}">
127
+ ${r ? this.renderSpinner() : d`<slot></slot>`}
55
128
  </button>`;
56
129
  }
57
130
  }
58
- n.styles = f(p);
59
- d([
60
- v(),
61
- b(s, y, "medium")
62
- ], n.prototype, "size", 2);
63
- d([
64
- v(),
65
- b(s, k, "primary")
66
- ], n.prototype, "variant", 2);
67
- d([
68
- v({ type: Boolean })
69
- ], n.prototype, "disabled", 2);
70
- g(s, n);
131
+ s.styles = m($);
132
+ b([
133
+ c(),
134
+ u(f, k, "medium")
135
+ ], s.prototype, "size", 2);
136
+ b([
137
+ c(),
138
+ u(f, P, "primary")
139
+ ], s.prototype, "variant", 2);
140
+ b([
141
+ c({ type: Boolean })
142
+ ], s.prototype, "disabled", 2);
143
+ b([
144
+ c({ type: Boolean })
145
+ ], s.prototype, "isLoading", 2);
146
+ x(f, s);
71
147
  export {
72
- n as PieIconButton,
73
- y as sizes,
74
- k as variants
148
+ s as PieIconButton,
149
+ k as sizes,
150
+ P as variants
75
151
  };
package/dist/react.d.ts CHANGED
@@ -1,24 +1,29 @@
1
1
  import type { CSSResult } from 'lit';
2
2
  import type { LitElement } from 'lit';
3
3
  import type { ReactWebComponent } from '@lit-labs/react';
4
- import type { TemplateResult } from 'lit-html';
4
+ import type { TemplateResult } from 'lit';
5
5
 
6
6
  export declare interface IconButtonProps {
7
7
  /**
8
8
  * (Optional) What size the button should be.
9
9
  * @default "medium"
10
10
  */
11
- size: typeof sizes[number];
11
+ size?: typeof sizes[number];
12
12
  /**
13
13
  * (Optional) What style variant the button should be such as primary, outline or ghost.
14
14
  * @default "primary"
15
15
  */
16
- variant: typeof variants[number];
16
+ variant?: typeof variants[number];
17
17
  /**
18
18
  * (Optional) When true, the button element is disabled.
19
19
  * @default false
20
20
  */
21
- disabled: boolean;
21
+ disabled?: boolean;
22
+ /**
23
+ * (Optional) When true, a loading spinner is rendered.
24
+ * @default false
25
+ */
26
+ isLoading?: boolean;
22
27
  }
23
28
 
24
29
  export declare const PieIconButton: ReactWebComponent<PieIconButton_2, {}>;
@@ -27,9 +32,16 @@ export declare const PieIconButton: ReactWebComponent<PieIconButton_2, {}>;
27
32
  * @tagname pie-icon-button
28
33
  */
29
34
  declare class PieIconButton_2 extends LitElement implements IconButtonProps {
30
- size: IconButtonProps['size'];
31
- variant: IconButtonProps['variant'];
32
- disabled: boolean;
35
+ size?: IconButtonProps['size'];
36
+ variant?: IconButtonProps['variant'];
37
+ disabled?: boolean | undefined;
38
+ isLoading?: boolean | undefined;
39
+ /**
40
+ * Template for the loading state
41
+ *
42
+ * @private
43
+ */
44
+ private renderSpinner;
33
45
  render(): TemplateResult<1>;
34
46
  static styles: CSSResult;
35
47
  }
package/dist/react.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as g from "react";
2
- import { PieIconButton as b } from "./index.js";
2
+ import { PieIconButton as E } from "./index.js";
3
3
  import { sizes as j, variants as k } from "./index.js";
4
4
  import "lit";
5
5
  import "lit/decorators.js";
@@ -8,58 +8,59 @@ import "lit/decorators.js";
8
8
  * Copyright 2018 Google LLC
9
9
  * SPDX-License-Identifier: BSD-3-Clause
10
10
  */
11
- const B = /* @__PURE__ */ new Set(["children", "localName", "ref", "style", "className"]), E = /* @__PURE__ */ new WeakMap(), I = (d, l, m, p, u) => {
12
- const o = u == null ? void 0 : u[l];
13
- o === void 0 || m === p ? m == null && l in HTMLElement.prototype ? d.removeAttribute(l) : d[l] = m : ((i, t, h) => {
14
- let s = E.get(i);
15
- s === void 0 && E.set(i, s = /* @__PURE__ */ new Map());
16
- let a = s.get(t);
17
- h !== void 0 ? a === void 0 ? (s.set(t, a = { handleEvent: h }), i.addEventListener(t, a)) : a.handleEvent = h : a !== void 0 && (s.delete(t), i.removeEventListener(t, a));
18
- })(d, o, m);
11
+ const b = /* @__PURE__ */ new Set(["children", "localName", "ref", "style", "className"]), w = /* @__PURE__ */ new WeakMap(), B = (t, n, d, m, p) => {
12
+ const s = p == null ? void 0 : p[n];
13
+ s === void 0 || d === m ? d == null && n in HTMLElement.prototype ? t.removeAttribute(n) : t[n] = d : ((r, o, u) => {
14
+ let a = w.get(r);
15
+ a === void 0 && w.set(r, a = /* @__PURE__ */ new Map());
16
+ let l = a.get(o);
17
+ u !== void 0 ? l === void 0 ? (a.set(o, l = { handleEvent: u }), r.addEventListener(o, l)) : l.handleEvent = u : l !== void 0 && (a.delete(o), r.removeEventListener(o, l));
18
+ })(t, s, d);
19
+ }, I = (t, n) => {
20
+ typeof t == "function" ? t(n) : t.current = n;
19
21
  };
20
- function M(d = window.React, l, m, p, u) {
21
- let o, i, t;
22
- if (l === void 0) {
23
- const r = d;
24
- ({ tagName: i, elementClass: t, events: p, displayName: u } = r), o = r.react;
22
+ function M(t = window.React, n, d, m, p) {
23
+ let s, r, o;
24
+ if (n === void 0) {
25
+ const c = t;
26
+ ({ tagName: r, elementClass: o, events: m, displayName: p } = c), s = c.react;
25
27
  } else
26
- o = d, t = m, i = l;
27
- const h = o.Component, s = o.createElement, a = new Set(Object.keys(p ?? {}));
28
- class f extends h {
28
+ s = t, o = d, r = n;
29
+ const u = s.Component, a = s.createElement, l = new Set(Object.keys(m ?? {}));
30
+ class f extends u {
29
31
  constructor() {
30
32
  super(...arguments), this.o = null;
31
33
  }
32
34
  t(e) {
33
35
  if (this.o !== null)
34
- for (const v in this.i)
35
- I(this.o, v, this.props[v], e ? e[v] : void 0, p);
36
+ for (const h in this.i)
37
+ B(this.o, h, this.props[h], e ? e[h] : void 0, m);
36
38
  }
37
39
  componentDidMount() {
38
- this.t();
40
+ var e;
41
+ this.t(), (e = this.o) === null || e === void 0 || e.removeAttribute("defer-hydration");
39
42
  }
40
43
  componentDidUpdate(e) {
41
44
  this.t(e);
42
45
  }
43
46
  render() {
44
- const { _$Gl: e, ...v } = this.props;
45
- this.h !== e && (this.u = (n) => {
46
- e !== null && ((c, w) => {
47
- typeof c == "function" ? c(w) : c.current = w;
48
- })(e, n), this.o = n, this.h = e;
47
+ const { _$Gl: e, ...h } = this.props;
48
+ this.h !== e && (this.u = (i) => {
49
+ e !== null && I(e, i), this.o = i, this.h = e;
49
50
  }), this.i = {};
50
- const y = { ref: this.u };
51
- for (const [n, c] of Object.entries(v))
52
- B.has(n) ? y[n === "className" ? "class" : n] = c : a.has(n) || n in t.prototype ? this.i[n] = c : y[n] = c;
53
- return s(i, y);
51
+ const v = { ref: this.u };
52
+ for (const [i, y] of Object.entries(h))
53
+ b.has(i) ? v[i === "className" ? "class" : i] = y : l.has(i) || i in o.prototype ? this.i[i] = y : v[i] = y;
54
+ return v.suppressHydrationWarning = !0, a(r, v);
54
55
  }
55
56
  }
56
- f.displayName = u ?? t.name;
57
- const N = o.forwardRef((r, e) => s(f, { ...r, _$Gl: e }, r == null ? void 0 : r.children));
57
+ f.displayName = p ?? o.name;
58
+ const N = s.forwardRef((c, e) => a(f, { ...c, _$Gl: e }, c == null ? void 0 : c.children));
58
59
  return N.displayName = f.displayName, N;
59
60
  }
60
61
  const L = M({
61
62
  displayName: "PieIconButton",
62
- elementClass: b,
63
+ elementClass: E,
63
64
  react: g,
64
65
  tagName: "pie-icon-button",
65
66
  events: {}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@justeattakeaway/pie-icon-button",
3
- "version": "0.20.0",
3
+ "version": "0.21.0",
4
4
  "description": "PIE Design System Icon Button built using Web Components",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
@@ -25,13 +25,11 @@
25
25
  },
26
26
  "author": "Just Eat Takeaway.com - Design System Team",
27
27
  "license": "Apache-2.0",
28
- "devDependencies": {
28
+ "dependencies": {
29
29
  "@justeattakeaway/pie-icons-webc": "0.11.1",
30
+ "@justeattakeaway/pie-spinner": "0.2.0",
30
31
  "@justeattakeaway/pie-webc-core": "0.11.0"
31
32
  },
32
- "peerDependencies": {
33
- "@justeat/pie-design-tokens": "^5.8.2"
34
- },
35
33
  "volta": {
36
34
  "extends": "../../../package.json"
37
35
  },
package/src/defs.ts CHANGED
@@ -7,15 +7,20 @@ export interface IconButtonProps {
7
7
  * (Optional) What size the button should be.
8
8
  * @default "medium"
9
9
  */
10
- size: typeof sizes[number];
10
+ size?: typeof sizes[number];
11
11
  /**
12
12
  * (Optional) What style variant the button should be such as primary, outline or ghost.
13
13
  * @default "primary"
14
14
  */
15
- variant: typeof variants[number];
15
+ variant?: typeof variants[number];
16
16
  /**
17
17
  * (Optional) When true, the button element is disabled.
18
18
  * @default false
19
19
  */
20
- disabled: boolean;
20
+ disabled?: boolean;
21
+ /**
22
+ * (Optional) When true, a loading spinner is rendered.
23
+ * @default false
24
+ */
25
+ isLoading?: boolean;
21
26
  }
@@ -1,28 +1,5 @@
1
1
  @use '@justeattakeaway/pie-css/scss' as p;
2
2
 
3
- @mixin button-interactive-states($bg-color, $mode: 'default') {
4
- &:hover:not(:disabled) {
5
- --hover-modifier: calc(-1 * var(--dt-color-hover-01));
6
- --btn-bg-color: hsl(var(#{$bg-color}-h), var(#{$bg-color}-s), calc(var(#{$bg-color}-l) + var(--hover-modifier)));
7
-
8
- // for mode=transparent, use the hsla syntax to make the button background opaque by a set percentage
9
- @if $mode == 'transparent' {
10
- --hover-modifier: var(--dt-color-hover-01);
11
- --btn-bg-color: hsl(var(#{$bg-color}-h), var(#{$bg-color}-s), var(#{$bg-color}-l), var(--hover-modifier));
12
- }
13
- }
14
-
15
- &:active:not(:disabled) {
16
- --active-modifier: calc(-1 * var(--dt-color-active-01));
17
- --btn-bg-color: hsl(var(#{$bg-color}-h), var(#{$bg-color}-s), calc(var(#{$bg-color}-l) + var(--active-modifier)));
18
-
19
- @if $mode == 'transparent' {
20
- --active-modifier: var(--dt-color-active-01);
21
- --btn-bg-color: hsl(var(#{$bg-color}-h), var(#{$bg-color}-s), var(#{$bg-color}-l), var(--active-modifier));
22
- }
23
- }
24
- }
25
-
26
3
  // Normally we don't expect consumers to override these, but there are situations where it may be necessary
27
4
  :host {
28
5
  // The base values are set to the size default, which is for the medium button size
@@ -66,14 +43,14 @@
66
43
  &[variant='primary'] {
67
44
  /* Same as default styles */
68
45
 
69
- @include button-interactive-states('--dt-color-interactive-brand');
46
+ @include p.button-interactive-states('--dt-color-interactive-brand');
70
47
  }
71
48
 
72
49
  &[variant='secondary'] {
73
50
  --btn-bg-color: var(--dt-color-interactive-secondary);
74
51
  --btn-icon-fill: var(--dt-color-content-interactive-secondary);
75
52
 
76
- @include button-interactive-states('--dt-color-interactive-secondary');
53
+ @include p.button-interactive-states('--dt-color-interactive-secondary');
77
54
  }
78
55
 
79
56
  &[variant='outline'] {
@@ -82,35 +59,35 @@
82
59
 
83
60
  border: 1px solid var(--dt-color-border-strong);
84
61
 
85
- @include button-interactive-states('--dt-color-black', 'transparent');
62
+ @include p.button-interactive-states('--dt-color-black', 'transparent');
86
63
  }
87
64
 
88
65
  &[variant='ghost'] {
89
66
  --btn-bg-color: transparent;
90
67
  --btn-icon-fill: var(--dt-color-content-interactive-brand);
91
68
 
92
- @include button-interactive-states('--dt-color-black', 'transparent');
69
+ @include p.button-interactive-states('--dt-color-black', 'transparent');
93
70
  }
94
71
 
95
72
  &[variant='ghost-secondary'] {
96
73
  --btn-bg-color: transparent;
97
74
  --btn-icon-fill: var(--dt-color-content-interactive-secondary);
98
75
 
99
- @include button-interactive-states('--dt-color-black', 'transparent');
76
+ @include p.button-interactive-states('--dt-color-black', 'transparent');
100
77
  }
101
78
 
102
79
  &[variant='inverse'] {
103
80
  --btn-bg-color: var(--dt-color-interactive-inverse);
104
81
  --btn-icon-fill: var(--dt-color-content-interactive-brand);
105
82
 
106
- @include button-interactive-states('--dt-color-interactive-inverse');
83
+ @include p.button-interactive-states('--dt-color-interactive-inverse');
107
84
  }
108
85
 
109
86
  &[variant='ghost-inverse'] {
110
87
  --btn-bg-color: transparent;
111
88
  --btn-icon-fill: var(--dt-color-content-inverse);
112
89
 
113
- @include button-interactive-states('--dt-color-container-default', 'transparent');
90
+ @include p.button-interactive-states('--dt-color-container-default', 'transparent');
114
91
  }
115
92
 
116
93
  &[disabled] {
package/src/index.ts CHANGED
@@ -1,11 +1,13 @@
1
- import { LitElement, html, unsafeCSS } from 'lit';
1
+ import {
2
+ LitElement, TemplateResult, html, unsafeCSS,
3
+ } from 'lit';
2
4
  import { property } from 'lit/decorators.js';
3
5
  import { validPropertyValues, defineCustomElement } from '@justeattakeaway/pie-webc-core';
4
-
5
6
  import styles from './iconButton.scss?inline';
6
7
  import {
7
8
  IconButtonProps, sizes, variants,
8
9
  } from './defs';
10
+ import '@justeattakeaway/pie-spinner';
9
11
 
10
12
  // Valid values available to consumers
11
13
  export * from './defs';
@@ -18,28 +20,51 @@ const componentSelector = 'pie-icon-button';
18
20
  export class PieIconButton extends LitElement implements IconButtonProps {
19
21
  @property()
20
22
  @validPropertyValues(componentSelector, sizes, 'medium')
21
- public size: IconButtonProps['size'] = 'medium';
23
+ public size?: IconButtonProps['size'] = 'medium';
22
24
 
23
25
  @property()
24
26
  @validPropertyValues(componentSelector, variants, 'primary')
25
- public variant: IconButtonProps['variant'] = 'primary';
27
+ public variant?: IconButtonProps['variant'] = 'primary';
28
+
29
+ @property({ type: Boolean })
30
+ public disabled? = false;
26
31
 
27
32
  @property({ type: Boolean })
28
- public disabled = false;
33
+ public isLoading? = false;
34
+
35
+ /**
36
+ * Template for the loading state
37
+ *
38
+ * @private
39
+ */
40
+ private renderSpinner (): TemplateResult {
41
+ const { variant, size } = this;
42
+ const spinnerSize = size === 'xsmall' ? 's' : 'm';
43
+ let spinnerVariant = 'brand';
44
+ if (variant?.includes('secondary')) spinnerVariant = 'secondary';
45
+ if (variant === 'primary' || variant === 'ghost-inverse') spinnerVariant = 'inverse';
46
+
47
+ return html`
48
+ <pie-spinner
49
+ size="${spinnerSize}"
50
+ variant="${spinnerVariant}"
51
+ </pie-spinner>`;
52
+ }
29
53
 
30
54
  render () {
31
55
  const {
32
- disabled, size, variant,
56
+ disabled, size, variant, isLoading,
33
57
  } = this;
34
58
 
35
59
  // The inline SVG is temporary until we have a proper icon integration
36
60
  return html`
37
61
  <button
38
62
  class="o-iconBtn"
39
- size=${size}
40
- variant=${variant}
41
- ?disabled=${disabled}>
42
- <slot></slot>
63
+ size="${size}"
64
+ variant="${variant}"
65
+ ?disabled="${disabled}"
66
+ ?isLoading="${isLoading}">
67
+ ${isLoading ? this.renderSpinner() : html`<slot></slot>`}
43
68
  </button>`;
44
69
  }
45
70