@justeattakeaway/pie-icon-button 0.20.0 → 0.21.1
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 +17 -4
- package/dist/index.d.ts +19 -7
- package/dist/index.js +122 -46
- package/dist/react.d.ts +19 -7
- package/dist/react.js +33 -32
- package/package.json +3 -5
- package/src/defs.ts +8 -3
- package/src/iconButton.scss +7 -30
- package/src/index.ts +35 -10
package/README.md
CHANGED
|
@@ -46,16 +46,28 @@ For full information on using PIE components as part of an application, check ou
|
|
|
46
46
|
|
|
47
47
|
### Importing the component
|
|
48
48
|
|
|
49
|
+
#### JavaScript
|
|
49
50
|
```js
|
|
50
|
-
// Default – for Native JS Applications, Vue, Angular, Svelte etc.
|
|
51
|
+
// Default – for Native JS Applications, Vue, Angular, Svelte, etc.
|
|
51
52
|
import { PieIconButton } from '@justeattakeaway/pie-icon-button';
|
|
52
53
|
|
|
54
|
+
// If you don't need to reference the imported object, you can simply
|
|
55
|
+
// import the module which registers the component as a custom element.
|
|
56
|
+
import '@justeattakeaway/pie-icon-button';
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
#### React
|
|
60
|
+
```js
|
|
53
61
|
// React
|
|
54
|
-
// For React, you will need to import our React
|
|
55
|
-
//
|
|
62
|
+
// For React, you will need to import our React-specific component build
|
|
63
|
+
// which wraps the web component using @lit-labs/react
|
|
56
64
|
import { PieIconButton } from '@justeattakeaway/pie-icon-button/dist/react';
|
|
57
65
|
```
|
|
58
66
|
|
|
67
|
+
> [!NOTE]
|
|
68
|
+
> When using the React version of the component, please make sure to also
|
|
69
|
+
> include React as a [peer dependency](#peer-dependencies) in your project.
|
|
70
|
+
|
|
59
71
|
|
|
60
72
|
## Peer Dependencies
|
|
61
73
|
|
|
@@ -94,7 +106,8 @@ Then, in your markup, you would implement the component like this:
|
|
|
94
106
|
|-------------|-----------|-----------------|----------------------------------------------------------------------|
|
|
95
107
|
| size | `String` | `medium` | Size of the Icon Button, one of `sizes` – `xsmall`, `small`, `medium`, `large` |
|
|
96
108
|
| variant | `String` | `primary` | Variant of the button, one of `variants` – `primary`, `secondary`, `outline`, `ghost`, `ghost-secondary` |
|
|
97
|
-
| disabled | `Boolean` | `false
|
|
109
|
+
| disabled | `Boolean` | `false`| If `true`, disables the button.|
|
|
110
|
+
| isLoading | `Boolean` | `false` | If `true`, displays a loading indicator inside the icon button. |
|
|
98
111
|
|
|
99
112
|
In your HTML markup or JSX, you can then use these to set the properties for the `pie-icon-button` component, like so:
|
|
100
113
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
28
|
-
variant
|
|
29
|
-
disabled
|
|
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
|
|
2
|
-
import { property as
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
Object.defineProperty(
|
|
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[
|
|
7
|
+
return this[a];
|
|
8
8
|
},
|
|
9
9
|
set(l) {
|
|
10
|
-
const
|
|
11
|
-
o.includes(l) ? this[
|
|
12
|
-
`<${
|
|
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: "${
|
|
15
|
-
), this[
|
|
14
|
+
`Falling back to default value: "${t}"`
|
|
15
|
+
), this[a] = t), this.requestUpdate(i, B);
|
|
16
16
|
}
|
|
17
17
|
});
|
|
18
18
|
};
|
|
19
|
-
function
|
|
20
|
-
customElements.get(
|
|
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
|
|
23
|
-
`,
|
|
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
|
-
|
|
33
|
-
|
|
34
|
-
(
|
|
35
|
-
|
|
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
|
|
38
|
-
class
|
|
57
|
+
const h = "pie-spinner";
|
|
58
|
+
class v extends g {
|
|
39
59
|
constructor() {
|
|
40
|
-
super(...arguments), this.size = "
|
|
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:
|
|
46
|
-
variant:
|
|
116
|
+
size: t,
|
|
117
|
+
variant: e,
|
|
118
|
+
isLoading: r
|
|
47
119
|
} = this;
|
|
48
|
-
return
|
|
120
|
+
return d`
|
|
49
121
|
<button
|
|
50
122
|
class="o-iconBtn"
|
|
51
|
-
size
|
|
52
|
-
variant
|
|
53
|
-
?disabled
|
|
54
|
-
|
|
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
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
],
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
],
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
],
|
|
70
|
-
|
|
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
|
-
|
|
73
|
-
|
|
74
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
31
|
-
variant
|
|
32
|
-
disabled
|
|
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
|
|
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
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
let
|
|
15
|
-
|
|
16
|
-
let
|
|
17
|
-
|
|
18
|
-
})(
|
|
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(
|
|
21
|
-
let
|
|
22
|
-
if (
|
|
23
|
-
const
|
|
24
|
-
({ tagName:
|
|
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
|
-
|
|
27
|
-
const
|
|
28
|
-
class f extends
|
|
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
|
|
35
|
-
|
|
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
|
-
|
|
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, ...
|
|
45
|
-
this.h !== e && (this.u = (
|
|
46
|
-
e !== null && (
|
|
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
|
|
51
|
-
for (const [
|
|
52
|
-
|
|
53
|
-
return
|
|
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 =
|
|
57
|
-
const N =
|
|
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:
|
|
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.
|
|
3
|
+
"version": "0.21.1",
|
|
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
|
-
"
|
|
28
|
+
"dependencies": {
|
|
29
29
|
"@justeattakeaway/pie-icons-webc": "0.11.1",
|
|
30
|
+
"@justeattakeaway/pie-spinner": "0.2.1",
|
|
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
|
|
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
|
|
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
|
|
20
|
+
disabled?: boolean;
|
|
21
|
+
/**
|
|
22
|
+
* (Optional) When true, a loading spinner is rendered.
|
|
23
|
+
* @default false
|
|
24
|
+
*/
|
|
25
|
+
isLoading?: boolean;
|
|
21
26
|
}
|
package/src/iconButton.scss
CHANGED
|
@@ -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 {
|
|
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
|
|
23
|
+
public size?: IconButtonProps['size'] = 'medium';
|
|
22
24
|
|
|
23
25
|
@property()
|
|
24
26
|
@validPropertyValues(componentSelector, variants, 'primary')
|
|
25
|
-
public variant
|
|
27
|
+
public variant?: IconButtonProps['variant'] = 'primary';
|
|
28
|
+
|
|
29
|
+
@property({ type: Boolean })
|
|
30
|
+
public disabled? = false;
|
|
26
31
|
|
|
27
32
|
@property({ type: Boolean })
|
|
28
|
-
public
|
|
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
|
|
40
|
-
variant
|
|
41
|
-
?disabled
|
|
42
|
-
|
|
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
|
|