@justeattakeaway/pie-button 0.18.0 → 0.20.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/.turbo/turbo-build.log +7 -7
- package/CHANGELOG.md +12 -0
- package/README.md +32 -6
- package/dist/index.js +54 -43
- package/dist/react.js +0 -0
- package/dist/types/index.d.ts +0 -0
- package/dist/types/packages/components/pie-button/src/defs.d.ts +11 -11
- package/dist/types/packages/components/pie-button/src/defs.d.ts.map +1 -1
- package/dist/types/packages/components/pie-button/src/index.d.ts +8 -1
- package/dist/types/packages/components/pie-button/src/index.d.ts.map +1 -1
- package/dist/types/packages/components/pie-button/src/react.d.ts +0 -0
- package/dist/types/packages/components/pie-button/src/react.d.ts.map +1 -1
- package/dist/types/react.d.ts +0 -0
- package/package.json +1 -1
- package/src/button.scss +121 -2
- package/src/defs.ts +12 -11
- package/src/index.ts +19 -4
- package/test/visual/pie-button.spec.ts +49 -2
package/.turbo/turbo-build.log
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
[
|
|
1
|
+
[9:56:25 AM] @custom-elements-manifest/analyzer: Created new manifest.
|
|
2
2
|
react wrapper has been added!
|
|
3
3
|
[36mvite v4.3.9 [32mbuilding for production...[36m[39m
|
|
4
4
|
transforming...
|
|
5
5
|
[32m✓[39m 22 modules transformed.
|
|
6
6
|
rendering chunks...
|
|
7
7
|
computing gzip size...
|
|
8
|
-
[2mdist/[22m[36mindex.js [39m[1m[
|
|
8
|
+
[2mdist/[22m[36mindex.js [39m[1m[2m12.02 kB[22m[1m[22m[2m │ gzip: 2.53 kB[22m
|
|
9
9
|
[2mdist/[22m[36mreact.js [39m[1m[2m59.01 kB[22m[1m[22m[2m │ gzip: 15.91 kB[22m
|
|
10
|
-
|
|
11
|
-
[vite:dts] Start generate declaration files
|
|
12
|
-
[32m✓ built in
|
|
13
|
-
[vite:dts] Declaration files built in
|
|
14
|
-
|
|
10
|
+
[32m
|
|
11
|
+
[36m[vite:dts][32m Start generate declaration files...[39m
|
|
12
|
+
[32m✓ built in 13.84s[39m
|
|
13
|
+
[32m[36m[vite:dts][32m Declaration files built in 12693ms.
|
|
14
|
+
[39m
|
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.20.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [Added] - Slots for leading and trailing icons ([#634](https://github.com/justeattakeaway/pie/pull/634)) by [@ashleynolan](https://github.com/ashleynolan)
|
|
8
|
+
|
|
9
|
+
## 0.19.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- [Added] - pie-button loading state ([#603](https://github.com/justeattakeaway/pie/pull/603)) by [@jamieomaguire](https://github.com/jamieomaguire)
|
|
14
|
+
|
|
3
15
|
## 0.18.0
|
|
4
16
|
|
|
5
17
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -65,13 +65,14 @@ import { PieButton } from '@justeattakeaway/pie-button/dist/react';
|
|
|
65
65
|
|
|
66
66
|
## Props
|
|
67
67
|
|
|
68
|
-
| Property | Type | Default | Description
|
|
69
|
-
|
|
70
|
-
| size | `String` | `medium` | Size of the button, one of `sizes` – `xsmall`, `small-expressive`, `small-productive`, `medium`, `large`
|
|
71
|
-
| type | `String` | `submit` | Type of the button, one of `types` – `submit`, `button`, `reset`, `menu`
|
|
68
|
+
| Property | Type | Default | Description |
|
|
69
|
+
|-------------|-----------|-----------------|-------------------------------------------------------------------------------------------------------------------|
|
|
70
|
+
| size | `String` | `medium` | Size of the button, one of `sizes` – `xsmall`, `small-expressive`, `small-productive`, `medium`, `large` |
|
|
71
|
+
| type | `String` | `submit` | Type of the button, one of `types` – `submit`, `button`, `reset`, `menu` |
|
|
72
72
|
| variant | `String` | `primary` | Variant of the button, one of `variants` – `primary`, `secondary`, `outline`, `ghost`, `inverse`, `ghost-inverse` |
|
|
73
|
-
| disabled | `Boolean` | `false` | If `true`, disables the button.
|
|
74
|
-
| isFullWidth | `Boolean` | `false` | If `true`, sets the button width to 100% of it's container.
|
|
73
|
+
| disabled | `Boolean` | `false` | If `true`, disables the button. |
|
|
74
|
+
| isFullWidth | `Boolean` | `false` | If `true`, sets the button width to 100% of it's container. |
|
|
75
|
+
| isLoading | `Boolean` | `false` | If `true`, displays a loading indicator inside the button. |
|
|
75
76
|
|
|
76
77
|
In your markup or JSX, you can then use these to set the properties for the `pie-button` component:
|
|
77
78
|
|
|
@@ -83,6 +84,31 @@ In your markup or JSX, you can then use these to set the properties for the `pie
|
|
|
83
84
|
<PieButton size='medium' type='button' variant='primary'>Click me!</PieButton>
|
|
84
85
|
```
|
|
85
86
|
|
|
87
|
+
## Slots
|
|
88
|
+
|
|
89
|
+
| Slot | Description |
|
|
90
|
+
|---------------|------------------------------------------------------------------------------------------------------------------------------------|
|
|
91
|
+
| Default slot | The default slot is used to pass text into the button component. |
|
|
92
|
+
| icon-leading | Used to pass in a leading icon. We recommend using `pie-icons-webc` for defining this icon, but this can also accept an SVG icon. |
|
|
93
|
+
| icon-trailing | Used to pass in a trailing icon. We recommend using `pie-icons-webc` for defining this icon, but this can also accept an SVG icon. |
|
|
94
|
+
|
|
95
|
+
### Using `pie-icons-webc` with `pie-button`icon slots
|
|
96
|
+
|
|
97
|
+
We recommend using `pie-icons-webc` when using the `icon-leading` and `icon-trailing` slots. Here is an example of how you would do this:
|
|
98
|
+
|
|
99
|
+
```html
|
|
100
|
+
<!--
|
|
101
|
+
Note that pie-button and the icons that you want to use will need to be imported as components into your application.
|
|
102
|
+
See the `pie-icons-webc` README for more info on importing these icons.
|
|
103
|
+
-->
|
|
104
|
+
<pie-button>
|
|
105
|
+
<icon-plus-circle slot="icon-leading"></icon-plus-circle>
|
|
106
|
+
Search
|
|
107
|
+
<icon-chevron-down slot="icon-trailing"></icon-chevron-down>
|
|
108
|
+
</pie-button>
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
|
|
86
112
|
## Events
|
|
87
113
|
|
|
88
114
|
This component does not use any custom event handlers. In order to add event listening to this component, you can treat it like a native HTML element in your application.
|
package/dist/index.js
CHANGED
|
@@ -1,73 +1,84 @@
|
|
|
1
1
|
import { unsafeCSS as h, LitElement as u, html as g } from "lit";
|
|
2
|
-
import { property as
|
|
2
|
+
import { property as s } from "lit/decorators.js";
|
|
3
3
|
import "lit/decorators/property.js";
|
|
4
|
-
const b = (
|
|
5
|
-
const
|
|
6
|
-
Object.defineProperty(
|
|
4
|
+
const b = (l, r, t) => function(o, n) {
|
|
5
|
+
const e = `#${n}`;
|
|
6
|
+
Object.defineProperty(o, n, {
|
|
7
7
|
get() {
|
|
8
|
-
return this[
|
|
8
|
+
return this[e];
|
|
9
9
|
},
|
|
10
10
|
set(v) {
|
|
11
|
-
const p = this[
|
|
12
|
-
|
|
13
|
-
`<${
|
|
14
|
-
`Must be one of: ${
|
|
15
|
-
`Falling back to default value: "${
|
|
16
|
-
), this[
|
|
11
|
+
const p = this[e];
|
|
12
|
+
r.includes(v) ? this[e] = v : (console.error(
|
|
13
|
+
`<${l}> Invalid value "${v}" provided for property "${n}".`,
|
|
14
|
+
`Must be one of: ${r.join(" | ")}.`,
|
|
15
|
+
`Falling back to default value: "${t}"`
|
|
16
|
+
), this[e] = t), this.requestUpdate(n, p);
|
|
17
17
|
}
|
|
18
18
|
});
|
|
19
|
-
}, m =
|
|
19
|
+
}, m = `*,*:before,*:after{box-sizing:border-box}@keyframes rotate360{0%{transform:rotate(0)}to{transform:rotate(360deg)}}.o-btn{--btn-border-radius: var(--dt-radius-rounded-e);--btn-font-family: var(--dt-font-interactive-m-family);--btn-font-weight: var(--dt-font-interactive-m-weight);--btn-padding: 10px var(--dt-spacing-e);--btn-font-size: calc(var(--dt-font-size-20) * 1px);--btn-line-height: calc(var(--dt-font-size-20-line-height) * 1px);--btn-bg-color: var(--dt-color-interactive-brand);--btn-text-color: var(--dt-color-content-interactive-primary);--btn-icon-size: 24px;--spinner-size-s: 20px;--spinner-size-m: 24px;--spinner-border-width-s: 2.5px;--spinner-border-width-m: 3px;--spinner-size: var(--spinner-size-m);--spinner-border-width: var(--spinner-border-width-m);--spinner-base-color-h: var(--dt-color-content-interactive-primary-h);--spinner-base-color-s: var(--dt-color-content-interactive-primary-s);--spinner-base-color-l: var(--dt-color-content-interactive-primary-l);--spinner-left-color-opacity: .35;--spinner-left-color: hsl(var(--spinner-base-color-h), var(--spinner-base-color-s), var(--spinner-base-color-l), var(--spinner-left-color-opacity));--spinner-right-color: hsl(var(--spinner-base-color-h), var(--spinner-base-color-s), var(--spinner-base-color-l), 1);--spinner-animation-duration: 1.15s;--spinner-animation-timing-function: linear;--spinner-animation-iteration-count: infinite;position:relative;display:flex;gap:var(--dt-spacing-b);align-items:center;justify-content:center;box-sizing:border-box;padding:var(--btn-padding);border:none;border-radius:var(--btn-border-radius);outline:none;background-color:var(--btn-bg-color);font-family:var(--btn-font-family);font-size:var(--btn-font-size);font-weight:var(--btn-font-weight);color:var(--btn-text-color);line-height:var(--btn-line-height);cursor:pointer;user-select:none;text-rendering:optimizelegibility;-webkit-font-smoothing:antialiased;-moz-font-smoothing:antialiased}.o-btn:focus-visible{box-shadow:0 0 0 2px var(--dt-color-focus-inner);outline:none;position:relative}.o-btn:focus-visible:after{content:"";display:block;position:absolute;top:-3px;left:-3px;right:-3px;bottom:-3px;border-radius:var(--btn-border-radius);box-shadow:0 0 0 2px var(--dt-color-focus-outer)}.o-btn[variant=primary]:hover:not(:disabled){background-color:hsl(var(--dt-color-interactive-brand-h),var(--dt-color-interactive-brand-s),calc(var(--dt-color-interactive-brand-l) - var(--dt-color-hover-01)))}.o-btn[variant=primary]:active:not(:disabled){background-color:hsl(var(--dt-color-interactive-brand-h),var(--dt-color-interactive-brand-s),calc(var(--dt-color-interactive-brand-l) - var(--dt-color-active-01)))}.o-btn[variant=primary][size=xsmall],.o-btn[variant=primary][size=small-productive]{--btn-bg-color: var(--dt-color-interactive-primary)}.o-btn[variant=primary][size=xsmall]:hover:not(:disabled),.o-btn[variant=primary][size=small-productive]:hover:not(:disabled){background-color:hsl(var(--dt-color-interactive-primary-h),var(--dt-color-interactive-primary-s),calc(var(--dt-color-interactive-primary-l) - var(--dt-color-hover-01)))}.o-btn[variant=primary][size=xsmall]:active:not(:disabled),.o-btn[variant=primary][size=small-productive]:active:not(:disabled){background-color:hsl(var(--dt-color-interactive-primary-h),var(--dt-color-interactive-primary-s),calc(var(--dt-color-interactive-primary-l) - var(--dt-color-active-01)))}.o-btn[variant=secondary]{--btn-bg-color: var(--dt-color-interactive-secondary);--btn-text-color: var(--dt-color-content-interactive-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)}.o-btn[variant=secondary]:hover:not(:disabled){background-color:hsl(var(--dt-color-interactive-secondary-h),var(--dt-color-interactive-secondary-s),calc(var(--dt-color-interactive-secondary-l) - var(--dt-color-hover-01)))}.o-btn[variant=secondary]:active:not(:disabled){background-color:hsl(var(--dt-color-interactive-secondary-h),var(--dt-color-interactive-secondary-s),calc(var(--dt-color-interactive-secondary-l) - var(--dt-color-active-01)))}.o-btn[variant=outline]{--btn-bg-color: var(--dt-color-container-default);--btn-text-color: var(--dt-color-content-interactive-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);border:1px solid var(--dt-color-border-strong)}.o-btn[variant=outline]:hover:not(:disabled){background-color:hsl(var(--dt-color-container-default-h),var(--dt-color-container-default-s),calc(var(--dt-color-container-default-l) - var(--dt-color-hover-01)))}.o-btn[variant=outline]:active:not(:disabled){background-color:hsl(var(--dt-color-container-default-h),var(--dt-color-container-default-s),calc(var(--dt-color-container-default-l) - var(--dt-color-active-01)))}.o-btn[variant=ghost]{--btn-bg-color: transparent;--btn-text-color: var(--dt-color-content-link);--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)}.o-btn[variant=ghost]:hover:not(:disabled){background-color:hsl(var(--dt-color-container-default-h),var(--dt-color-container-default-s),calc(var(--dt-color-container-default-l) - var(--dt-color-hover-01)))}.o-btn[variant=ghost]:active:not(:disabled){background-color:hsl(var(--dt-color-container-default-h),var(--dt-color-container-default-s),calc(var(--dt-color-container-default-l) - var(--dt-color-active-01)))}.o-btn[variant=inverse]{--btn-bg-color: var(--dt-color-interactive-inverse);--btn-text-color: var(--dt-color-content-interactive-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)}.o-btn[variant=inverse]:hover:not(:disabled){background-color:hsl(var(--dt-color-interactive-inverse-h),var(--dt-color-interactive-inverse-s),calc(var(--dt-color-interactive-inverse-l) - var(--dt-color-hover-01)))}.o-btn[variant=inverse]:active:not(:disabled){background-color:hsl(var(--dt-color-interactive-inverse-h),var(--dt-color-interactive-inverse-s),calc(var(--dt-color-interactive-inverse-l) - var(--dt-color-active-01)))}.o-btn[variant=ghost-inverse]{--btn-bg-color: transparent;--btn-text-color: var(--dt-color-content-interactive-primary);--spinner-base-color-h: var(--dt-color-content-interactive-primary-h);--spinner-base-color-s: var(--dt-color-content-interactive-primary-s);--spinner-base-color-l: var(--dt-color-content-interactive-primary-l)}.o-btn[variant=ghost-inverse]:hover:not(:disabled){background-color:hsl(var(--dt-color-container-inverse-h),var(--dt-color-container-inverse-s),calc(var(--dt-color-container-inverse-l) - var(--dt-color-hover-01)))}.o-btn[variant=ghost-inverse]:active:not(:disabled){background-color:hsl(var(--dt-color-container-inverse-h),var(--dt-color-container-inverse-s),calc(var(--dt-color-container-inverse-l) - var(--dt-color-active-01)))}.o-btn[isFullWidth]{inline-size:100%}.o-btn[disabled]{--btn-text-color: var(--dt-color-content-disabled) !important;cursor:not-allowed}.o-btn[disabled]:not([variant=ghost],[variant=ghost-inverse]){--btn-bg-color: var(--dt-color-disabled-01) !important}.o-btn[disabled][variant=outline]{border-color:var(--dt-color-disabled-01)!important}.o-btn[size=xsmall]{--btn-padding: 6px var(--dt-spacing-b);--btn-font-size: calc(var(--dt-font-size-14) * 1px);--btn-line-height: calc(var(--dt-font-size-14-line-height) * 1px);--btn-icon-size: 16px;--spinner-size: var(--spinner-size-s);--spinner-border-width: var(--spinner-border-width-s)}.o-btn[size=small-expressive]{--btn-padding: 6px var(--dt-spacing-d);--btn-font-size: calc(var(--dt-font-size-20) * 1px);--btn-line-height: calc(var(--dt-font-size-20-line-height) * 1px);--btn-icon-size: 20px;--spinner-size: var(--spinner-size-s);--spinner-border-width: var(--spinner-border-width-s)}.o-btn[size=small-productive]{--btn-padding: 8px var(--dt-spacing-d);--btn-font-size: calc(var(--dt-font-size-16) * 1px);--btn-line-height: calc(var(--dt-font-size-16-line-height) * 1px);--btn-icon-size: 20px;--spinner-size: var(--spinner-size-s);--spinner-border-width: var(--spinner-border-width-s)}.o-btn[size=large]{--btn-padding: 14px var(--dt-spacing-e);--btn-font-size: calc(var(--dt-font-size-20) * 1px);--btn-line-height: calc(var(--dt-font-size-20-line-height) * 1px);--spinner-size: var(--spinner-size-m);--spinner-border-width: var(--spinner-border-width-m)}.o-btn:before{content:"";position:absolute;left:50%;top:50%;translate:-50% -50%;height:var(--spinner-size);width:var(--spinner-size);display:block;background-color:transparent;border-radius:50%;border-color:var(--spinner-left-color) var(--spinner-right-color) var(--spinner-right-color) var(--spinner-left-color);border-width:var(--spinner-border-width);border-style:solid;will-change:transform;opacity:0}.o-btn .o-btn-text{flex-grow:1}.o-btn[isLoading]:before{animation:rotate360 var(--spinner-animation-duration) var(--spinner-animation-timing-function) var(--spinner-animation-iteration-count);opacity:1}.o-btn[isLoading] .o-btn-text{opacity:0}::slotted(svg){height:var(--btn-icon-size);width:var(--btn-icon-size)}
|
|
20
20
|
`, f = ["xsmall", "small-productive", "small-expressive", "medium", "large"], y = ["submit", "button", "reset", "menu"], x = ["primary", "secondary", "outline", "ghost", "inverse", "ghost-inverse"];
|
|
21
|
-
var z = Object.defineProperty,
|
|
22
|
-
for (var
|
|
23
|
-
(
|
|
24
|
-
return
|
|
21
|
+
var z = Object.defineProperty, w = Object.getOwnPropertyDescriptor, c = (l, r, t, a) => {
|
|
22
|
+
for (var o = a > 1 ? void 0 : a ? w(r, t) : r, n = l.length - 1, e; n >= 0; n--)
|
|
23
|
+
(e = l[n]) && (o = (a ? e(r, t, o) : e(o)) || o);
|
|
24
|
+
return a && o && z(r, t, o), o;
|
|
25
25
|
};
|
|
26
|
-
const
|
|
26
|
+
const d = "pie-button";
|
|
27
27
|
class i extends u {
|
|
28
28
|
constructor() {
|
|
29
|
-
super(...arguments), this.size = "medium", this.type = "submit", this.variant = "primary", this.disabled = !1, this.isFullWidth = !1;
|
|
29
|
+
super(...arguments), this.size = "medium", this.type = "submit", this.variant = "primary", this.disabled = !1, this.isLoading = !1, this.isFullWidth = !1;
|
|
30
30
|
}
|
|
31
31
|
render() {
|
|
32
32
|
const {
|
|
33
|
-
type:
|
|
34
|
-
disabled:
|
|
35
|
-
isFullWidth:
|
|
36
|
-
variant:
|
|
37
|
-
size:
|
|
33
|
+
type: r,
|
|
34
|
+
disabled: t,
|
|
35
|
+
isFullWidth: a,
|
|
36
|
+
variant: o,
|
|
37
|
+
size: n,
|
|
38
|
+
isLoading: e
|
|
38
39
|
} = this;
|
|
39
40
|
return g`
|
|
40
41
|
<button
|
|
41
42
|
class="o-btn"
|
|
42
|
-
type=${
|
|
43
|
-
variant=${
|
|
44
|
-
size=${
|
|
45
|
-
?disabled=${
|
|
46
|
-
?isFullWidth=${
|
|
47
|
-
|
|
43
|
+
type=${r}
|
|
44
|
+
variant=${o}
|
|
45
|
+
size=${n}
|
|
46
|
+
?disabled=${t}
|
|
47
|
+
?isFullWidth=${a}
|
|
48
|
+
?isLoading=${e}>
|
|
49
|
+
<slot name="icon-leading"></slot>
|
|
50
|
+
<span class="o-btn-text"><slot></slot></span>
|
|
51
|
+
<slot name="icon-trailing"></slot>
|
|
48
52
|
</button>`;
|
|
49
53
|
}
|
|
54
|
+
focus() {
|
|
55
|
+
var r, t;
|
|
56
|
+
(t = (r = this.shadowRoot) == null ? void 0 : r.querySelector("button")) == null || t.focus();
|
|
57
|
+
}
|
|
50
58
|
}
|
|
51
59
|
i.styles = h(m);
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
b(
|
|
60
|
+
c([
|
|
61
|
+
s(),
|
|
62
|
+
b(d, f, "medium")
|
|
55
63
|
], i.prototype, "size", 2);
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
b(
|
|
64
|
+
c([
|
|
65
|
+
s(),
|
|
66
|
+
b(d, y, "submit")
|
|
59
67
|
], i.prototype, "type", 2);
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
b(
|
|
68
|
+
c([
|
|
69
|
+
s(),
|
|
70
|
+
b(d, x, "primary")
|
|
63
71
|
], i.prototype, "variant", 2);
|
|
64
|
-
|
|
65
|
-
|
|
72
|
+
c([
|
|
73
|
+
s({ type: Boolean })
|
|
66
74
|
], i.prototype, "disabled", 2);
|
|
67
|
-
|
|
68
|
-
|
|
75
|
+
c([
|
|
76
|
+
s({ type: Boolean, reflect: !0 })
|
|
77
|
+
], i.prototype, "isLoading", 2);
|
|
78
|
+
c([
|
|
79
|
+
s({ type: Boolean })
|
|
69
80
|
], i.prototype, "isFullWidth", 2);
|
|
70
|
-
customElements.define(
|
|
81
|
+
customElements.define(d, i);
|
|
71
82
|
export {
|
|
72
83
|
i as PieButton,
|
|
73
84
|
f as sizes,
|
package/dist/react.js
CHANGED
|
File without changes
|
package/dist/types/index.d.ts
CHANGED
|
File without changes
|
|
@@ -1,31 +1,31 @@
|
|
|
1
1
|
export declare const sizes: readonly ["xsmall", "small-productive", "small-expressive", "medium", "large"];
|
|
2
2
|
export declare const types: readonly ["submit", "button", "reset", "menu"];
|
|
3
3
|
export declare const variants: readonly ["primary", "secondary", "outline", "ghost", "inverse", "ghost-inverse"];
|
|
4
|
+
export type Variant = typeof variants[number];
|
|
4
5
|
export interface ButtonProps {
|
|
5
6
|
/**
|
|
6
|
-
*
|
|
7
|
-
* @default "medium"
|
|
7
|
+
* What size the button should be.
|
|
8
8
|
*/
|
|
9
9
|
size: typeof sizes[number];
|
|
10
10
|
/**
|
|
11
|
-
*
|
|
12
|
-
* @default "submit"
|
|
11
|
+
* What type attribute should be applied to the button. For example submit, button or menu.
|
|
13
12
|
*/
|
|
14
13
|
type: typeof types[number];
|
|
15
14
|
/**
|
|
16
|
-
*
|
|
17
|
-
* @default "primary"
|
|
15
|
+
* What style variant the button should be such as primary, outline or ghost.
|
|
18
16
|
*/
|
|
19
|
-
variant:
|
|
17
|
+
variant: Variant;
|
|
20
18
|
/**
|
|
21
|
-
*
|
|
22
|
-
* @default false
|
|
19
|
+
* When true, the button element is disabled.
|
|
23
20
|
*/
|
|
24
21
|
disabled: boolean;
|
|
25
22
|
/**
|
|
26
|
-
*
|
|
27
|
-
* @default false
|
|
23
|
+
* When true, the button element will occupy the full width of its container.
|
|
28
24
|
*/
|
|
29
25
|
isFullWidth: boolean;
|
|
26
|
+
/**
|
|
27
|
+
* When true, displays a loading indicator inside the button.
|
|
28
|
+
*/
|
|
29
|
+
isLoading: boolean;
|
|
30
30
|
}
|
|
31
31
|
//# sourceMappingURL=defs.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"defs.d.ts","sourceRoot":"","sources":["../../../src/defs.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,KAAK,gFAAiF,CAAC;AACpG,eAAO,MAAM,KAAK,gDAAiD,CAAC;AACpE,eAAO,MAAM,QAAQ,mFAAoF,CAAC;AAE1G,MAAM,WAAW,WAAW;IACxB
|
|
1
|
+
{"version":3,"file":"defs.d.ts","sourceRoot":"","sources":["../../../src/defs.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,KAAK,gFAAiF,CAAC;AACpG,eAAO,MAAM,KAAK,gDAAiD,CAAC;AACpE,eAAO,MAAM,QAAQ,mFAAoF,CAAC;AAE1G,MAAM,MAAM,OAAO,GAAG,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC;AAE9C,MAAM,WAAW,WAAW;IACxB;;OAEG;IACH,IAAI,EAAE,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC;IAC3B;;OAEG;IACH,IAAI,EAAE,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC;IAC3B;;OAEG;IACH,OAAO,EAAE,OAAO,CAAC;IACjB;;OAEG;IACH,QAAQ,EAAE,OAAO,CAAC;IAClB;;OAEG;IACH,WAAW,EAAE,OAAO,CAAC;IACrB;;OAEG;IACH,SAAS,EAAE,OAAO,CAAC;CACtB"}
|
|
@@ -2,13 +2,20 @@ import { LitElement } from 'lit';
|
|
|
2
2
|
import { ButtonProps, sizes, types, variants } from './defs';
|
|
3
3
|
export { type ButtonProps, sizes, types, variants, };
|
|
4
4
|
declare const componentSelector = "pie-button";
|
|
5
|
-
|
|
5
|
+
/**
|
|
6
|
+
* @slot icon-leading - Leading icon
|
|
7
|
+
* @slot icon-trailing - Trailing icon
|
|
8
|
+
* @slot - Default slot
|
|
9
|
+
*/
|
|
10
|
+
export declare class PieButton extends LitElement implements ButtonProps {
|
|
6
11
|
size: ButtonProps['size'];
|
|
7
12
|
type: ButtonProps['type'];
|
|
8
13
|
variant: ButtonProps['variant'];
|
|
9
14
|
disabled: boolean;
|
|
15
|
+
isLoading: boolean;
|
|
10
16
|
isFullWidth: boolean;
|
|
11
17
|
render(): import("lit-html").TemplateResult<1>;
|
|
18
|
+
focus(): void;
|
|
12
19
|
static styles: import("lit").CSSResult;
|
|
13
20
|
}
|
|
14
21
|
declare global {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAmB,MAAM,KAAK,CAAC;AAIlD,OAAO,EACH,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EACtC,MAAM,QAAQ,CAAC;AAGhB,OAAO,EACH,KAAK,WAAW,EAChB,KAAK,EACL,KAAK,EACL,QAAQ,GACX,CAAC;AAEF,QAAA,MAAM,iBAAiB,eAAe,CAAC;AAEvC,qBAAa,SAAU,SAAQ,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAmB,MAAM,KAAK,CAAC;AAIlD,OAAO,EACH,WAAW,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EACtC,MAAM,QAAQ,CAAC;AAGhB,OAAO,EACH,KAAK,WAAW,EAChB,KAAK,EACL,KAAK,EACL,QAAQ,GACX,CAAC;AAEF,QAAA,MAAM,iBAAiB,eAAe,CAAC;AAEvC;;;;GAIG;AACH,qBAAa,SAAU,SAAQ,UAAW,YAAW,WAAW;IAGrD,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,CAAY;IAIrC,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC,CAAY;IAIrC,OAAO,EAAE,WAAW,CAAC,SAAS,CAAC,CAAa;IAG5C,QAAQ,UAAS;IAGjB,SAAS,UAAS;IAGlB,WAAW,UAAS;IAE3B,MAAM;IAoBN,KAAK;IAKL,MAAM,CAAC,MAAM,0BAAqB;CACrC;AAID,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,qBAAqB;QAC3B,CAAC,iBAAiB,CAAC,EAAE,SAAS,CAAC;KAClC;CACJ"}
|
|
File without changes
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../../../src/react.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"react.d.ts","sourceRoot":"","sources":["../../../src/react.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,SAAS,IAAI,cAAc,EAAE,MAAM,SAAS,CAAC;AAEtD,eAAO,MAAM,SAAS,iEAMpB,CAAC"}
|
package/dist/types/react.d.ts
CHANGED
|
File without changes
|
package/package.json
CHANGED
package/src/button.scss
CHANGED
|
@@ -1,3 +1,9 @@
|
|
|
1
|
+
*,
|
|
2
|
+
*:before,
|
|
3
|
+
*:after {
|
|
4
|
+
box-sizing: border-box;
|
|
5
|
+
}
|
|
6
|
+
|
|
1
7
|
// Defines button interactive states for hover and active using HSL & calc
|
|
2
8
|
// Takes a color token name as an argument
|
|
3
9
|
@mixin button-interactive-states($bg-color) {
|
|
@@ -10,6 +16,17 @@
|
|
|
10
16
|
}
|
|
11
17
|
}
|
|
12
18
|
|
|
19
|
+
// Spin animation for loading state
|
|
20
|
+
@keyframes rotate360 {
|
|
21
|
+
from {
|
|
22
|
+
transform: rotate(0deg);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
to {
|
|
26
|
+
transform: rotate(360deg);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
13
30
|
// Base button styles
|
|
14
31
|
.o-btn {
|
|
15
32
|
// Custom Property Declarations
|
|
@@ -20,7 +37,6 @@
|
|
|
20
37
|
|
|
21
38
|
// The base values are set to the size default, which is for the medium button size
|
|
22
39
|
--btn-padding: 10px var(--dt-spacing-e);
|
|
23
|
-
--btn-min-height: 48px;
|
|
24
40
|
--btn-font-size: calc(var(--dt-font-size-20) * 1px);
|
|
25
41
|
--btn-line-height: calc(var(--dt-font-size-20-line-height) * 1px);
|
|
26
42
|
|
|
@@ -29,7 +45,36 @@
|
|
|
29
45
|
--btn-bg-color: var(--dt-color-interactive-brand);
|
|
30
46
|
--btn-text-color: var(--dt-color-content-interactive-primary);
|
|
31
47
|
|
|
32
|
-
|
|
48
|
+
// Sizing is set to Medium button icon size, as that is the default
|
|
49
|
+
--btn-icon-size: 24px;
|
|
50
|
+
|
|
51
|
+
// Spinner sizes defaults - currently set for the medium button styles
|
|
52
|
+
--spinner-size-s: 20px;
|
|
53
|
+
--spinner-size-m: 24px;
|
|
54
|
+
--spinner-border-width-s: 2.5px;
|
|
55
|
+
--spinner-border-width-m: 3px;
|
|
56
|
+
--spinner-size: var(--spinner-size-m);
|
|
57
|
+
--spinner-border-width: var(--spinner-border-width-m);
|
|
58
|
+
|
|
59
|
+
// Spinner colors - currently set for the primary button styles
|
|
60
|
+
--spinner-base-color-h: var(--dt-color-content-interactive-primary-h);
|
|
61
|
+
--spinner-base-color-s: var(--dt-color-content-interactive-primary-s);
|
|
62
|
+
--spinner-base-color-l: var(--dt-color-content-interactive-primary-l);
|
|
63
|
+
--spinner-left-color-opacity: 0.35;
|
|
64
|
+
--spinner-left-color: hsl(var(--spinner-base-color-h), var(--spinner-base-color-s), var(--spinner-base-color-l), var(--spinner-left-color-opacity));
|
|
65
|
+
--spinner-right-color: hsl(var(--spinner-base-color-h), var(--spinner-base-color-s), var(--spinner-base-color-l), 1);
|
|
66
|
+
|
|
67
|
+
// Spinner animations
|
|
68
|
+
--spinner-animation-duration: 1.15s;
|
|
69
|
+
--spinner-animation-timing-function: linear;
|
|
70
|
+
--spinner-animation-iteration-count: infinite;
|
|
71
|
+
|
|
72
|
+
position: relative;
|
|
73
|
+
display: flex;
|
|
74
|
+
gap: var(--dt-spacing-b);
|
|
75
|
+
align-items: center;
|
|
76
|
+
justify-content: center;
|
|
77
|
+
box-sizing: border-box;
|
|
33
78
|
padding: var(--btn-padding);
|
|
34
79
|
border: none;
|
|
35
80
|
border-radius: var(--btn-border-radius);
|
|
@@ -43,6 +88,12 @@
|
|
|
43
88
|
cursor: pointer;
|
|
44
89
|
user-select: none;
|
|
45
90
|
|
|
91
|
+
// TODO: This should be moved into global CSS typography setting
|
|
92
|
+
// This should be imported by consuming apps and set on the application body
|
|
93
|
+
text-rendering: optimizelegibility;
|
|
94
|
+
-webkit-font-smoothing: antialiased;
|
|
95
|
+
-moz-font-smoothing: antialiased;
|
|
96
|
+
|
|
46
97
|
&:focus-visible {
|
|
47
98
|
/*
|
|
48
99
|
TODO: This focus styling should be extracted out into a shared mixin to share among other components
|
|
@@ -102,6 +153,9 @@
|
|
|
102
153
|
&[variant='secondary'] {
|
|
103
154
|
--btn-bg-color: var(--dt-color-interactive-secondary);
|
|
104
155
|
--btn-text-color: var(--dt-color-content-interactive-secondary);
|
|
156
|
+
--spinner-base-color-h: var(--dt-color-content-interactive-secondary-h);
|
|
157
|
+
--spinner-base-color-s: var(--dt-color-content-interactive-secondary-s);
|
|
158
|
+
--spinner-base-color-l: var(--dt-color-content-interactive-secondary-l);
|
|
105
159
|
|
|
106
160
|
@include button-interactive-states('--dt-color-interactive-secondary');
|
|
107
161
|
}
|
|
@@ -109,6 +163,9 @@
|
|
|
109
163
|
&[variant='outline'] {
|
|
110
164
|
--btn-bg-color: var(--dt-color-container-default);
|
|
111
165
|
--btn-text-color: var(--dt-color-content-interactive-secondary);
|
|
166
|
+
--spinner-base-color-h: var(--dt-color-content-interactive-secondary-h);
|
|
167
|
+
--spinner-base-color-s: var(--dt-color-content-interactive-secondary-s);
|
|
168
|
+
--spinner-base-color-l: var(--dt-color-content-interactive-secondary-l);
|
|
112
169
|
|
|
113
170
|
border: 1px solid var(--dt-color-border-strong);
|
|
114
171
|
|
|
@@ -118,6 +175,9 @@
|
|
|
118
175
|
&[variant='ghost'] {
|
|
119
176
|
--btn-bg-color: transparent;
|
|
120
177
|
--btn-text-color: var(--dt-color-content-link);
|
|
178
|
+
--spinner-base-color-h: var(--dt-color-content-interactive-secondary-h);
|
|
179
|
+
--spinner-base-color-s: var(--dt-color-content-interactive-secondary-s);
|
|
180
|
+
--spinner-base-color-l: var(--dt-color-content-interactive-secondary-l);
|
|
121
181
|
|
|
122
182
|
@include button-interactive-states('--dt-color-container-default');
|
|
123
183
|
}
|
|
@@ -125,6 +185,9 @@
|
|
|
125
185
|
&[variant='inverse'] {
|
|
126
186
|
--btn-bg-color: var(--dt-color-interactive-inverse);
|
|
127
187
|
--btn-text-color: var(--dt-color-content-interactive-secondary);
|
|
188
|
+
--spinner-base-color-h: var(--dt-color-content-interactive-secondary-h);
|
|
189
|
+
--spinner-base-color-s: var(--dt-color-content-interactive-secondary-s);
|
|
190
|
+
--spinner-base-color-l: var(--dt-color-content-interactive-secondary-l);
|
|
128
191
|
|
|
129
192
|
@include button-interactive-states('--dt-color-interactive-inverse');
|
|
130
193
|
}
|
|
@@ -132,6 +195,9 @@
|
|
|
132
195
|
&[variant='ghost-inverse'] {
|
|
133
196
|
--btn-bg-color: transparent;
|
|
134
197
|
--btn-text-color: var(--dt-color-content-interactive-primary);
|
|
198
|
+
--spinner-base-color-h: var(--dt-color-content-interactive-primary-h);
|
|
199
|
+
--spinner-base-color-s: var(--dt-color-content-interactive-primary-s);
|
|
200
|
+
--spinner-base-color-l: var(--dt-color-content-interactive-primary-l);
|
|
135
201
|
|
|
136
202
|
@include button-interactive-states('--dt-color-container-inverse');
|
|
137
203
|
}
|
|
@@ -161,18 +227,27 @@
|
|
|
161
227
|
--btn-padding: 6px var(--dt-spacing-b);
|
|
162
228
|
--btn-font-size: calc(var(--dt-font-size-14) * 1px);
|
|
163
229
|
--btn-line-height: calc(var(--dt-font-size-14-line-height) * 1px);
|
|
230
|
+
--btn-icon-size: 16px;
|
|
231
|
+
--spinner-size: var(--spinner-size-s);
|
|
232
|
+
--spinner-border-width: var(--spinner-border-width-s);
|
|
164
233
|
}
|
|
165
234
|
|
|
166
235
|
&[size='small-expressive'] {
|
|
167
236
|
--btn-padding: 6px var(--dt-spacing-d);
|
|
168
237
|
--btn-font-size: calc(var(--dt-font-size-20) * 1px);
|
|
169
238
|
--btn-line-height: calc(var(--dt-font-size-20-line-height) * 1px);
|
|
239
|
+
--btn-icon-size: 20px;
|
|
240
|
+
--spinner-size: var(--spinner-size-s);
|
|
241
|
+
--spinner-border-width: var(--spinner-border-width-s);
|
|
170
242
|
}
|
|
171
243
|
|
|
172
244
|
&[size='small-productive'] {
|
|
173
245
|
--btn-padding: 8px var(--dt-spacing-d);
|
|
174
246
|
--btn-font-size: calc(var(--dt-font-size-16) * 1px);
|
|
175
247
|
--btn-line-height: calc(var(--dt-font-size-16-line-height) * 1px);
|
|
248
|
+
--btn-icon-size: 20px;
|
|
249
|
+
--spinner-size: var(--spinner-size-s);
|
|
250
|
+
--spinner-border-width: var(--spinner-border-width-s);
|
|
176
251
|
}
|
|
177
252
|
|
|
178
253
|
&[size='medium'] {
|
|
@@ -183,5 +258,49 @@
|
|
|
183
258
|
--btn-padding: 14px var(--dt-spacing-e);
|
|
184
259
|
--btn-font-size: calc(var(--dt-font-size-20) * 1px);
|
|
185
260
|
--btn-line-height: calc(var(--dt-font-size-20-line-height) * 1px);
|
|
261
|
+
--spinner-size: var(--spinner-size-m);
|
|
262
|
+
--spinner-border-width: var(--spinner-border-width-m);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
&:before {
|
|
266
|
+
content: '';
|
|
267
|
+
|
|
268
|
+
// Centre the spinner over the top of the button text
|
|
269
|
+
position: absolute;
|
|
270
|
+
left: 50%;
|
|
271
|
+
top: 50%;
|
|
272
|
+
translate: -50% -50%;
|
|
273
|
+
|
|
274
|
+
height: var(--spinner-size);
|
|
275
|
+
width: var(--spinner-size);
|
|
276
|
+
display: block;
|
|
277
|
+
background-color: transparent;
|
|
278
|
+
border-radius: 50%;
|
|
279
|
+
border-color: var(--spinner-left-color) var(--spinner-right-color) var(--spinner-right-color) var(--spinner-left-color);
|
|
280
|
+
border-width: var(--spinner-border-width);
|
|
281
|
+
border-style: solid;
|
|
282
|
+
will-change: transform;
|
|
283
|
+
opacity: 0;
|
|
186
284
|
}
|
|
285
|
+
|
|
286
|
+
.o-btn-text {
|
|
287
|
+
flex-grow: 1;
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
&[isLoading] {
|
|
291
|
+
&:before {
|
|
292
|
+
animation: rotate360 var(--spinner-animation-duration) var(--spinner-animation-timing-function) var(--spinner-animation-iteration-count);
|
|
293
|
+
opacity: 1;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
& .o-btn-text {
|
|
297
|
+
opacity: 0;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// Used to size an SVG if one is passed in (when not using the component icons)
|
|
303
|
+
::slotted(svg) {
|
|
304
|
+
height: var(--btn-icon-size);
|
|
305
|
+
width: var(--btn-icon-size);
|
|
187
306
|
}
|
package/src/defs.ts
CHANGED
|
@@ -2,30 +2,31 @@ export const sizes = ['xsmall', 'small-productive', 'small-expressive', 'medium'
|
|
|
2
2
|
export const types = ['submit', 'button', 'reset', 'menu'] as const;
|
|
3
3
|
export const variants = ['primary', 'secondary', 'outline', 'ghost', 'inverse', 'ghost-inverse'] as const;
|
|
4
4
|
|
|
5
|
+
export type Variant = typeof variants[number];
|
|
6
|
+
|
|
5
7
|
export interface ButtonProps {
|
|
6
8
|
/**
|
|
7
|
-
*
|
|
8
|
-
* @default "medium"
|
|
9
|
+
* What size the button should be.
|
|
9
10
|
*/
|
|
10
11
|
size: typeof sizes[number];
|
|
11
12
|
/**
|
|
12
|
-
*
|
|
13
|
-
* @default "submit"
|
|
13
|
+
* What type attribute should be applied to the button. For example submit, button or menu.
|
|
14
14
|
*/
|
|
15
15
|
type: typeof types[number];
|
|
16
16
|
/**
|
|
17
|
-
*
|
|
18
|
-
* @default "primary"
|
|
17
|
+
* What style variant the button should be such as primary, outline or ghost.
|
|
19
18
|
*/
|
|
20
|
-
variant:
|
|
19
|
+
variant: Variant;
|
|
21
20
|
/**
|
|
22
|
-
*
|
|
23
|
-
* @default false
|
|
21
|
+
* When true, the button element is disabled.
|
|
24
22
|
*/
|
|
25
23
|
disabled: boolean;
|
|
26
24
|
/**
|
|
27
|
-
*
|
|
28
|
-
* @default false
|
|
25
|
+
* When true, the button element will occupy the full width of its container.
|
|
29
26
|
*/
|
|
30
27
|
isFullWidth: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* When true, displays a loading indicator inside the button.
|
|
30
|
+
*/
|
|
31
|
+
isLoading: boolean;
|
|
31
32
|
}
|
package/src/index.ts
CHANGED
|
@@ -16,7 +16,12 @@ export {
|
|
|
16
16
|
|
|
17
17
|
const componentSelector = 'pie-button';
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
/**
|
|
20
|
+
* @slot icon-leading - Leading icon
|
|
21
|
+
* @slot icon-trailing - Trailing icon
|
|
22
|
+
* @slot - Default slot
|
|
23
|
+
*/
|
|
24
|
+
export class PieButton extends LitElement implements ButtonProps {
|
|
20
25
|
@property()
|
|
21
26
|
@validPropertyValues(componentSelector, sizes, 'medium')
|
|
22
27
|
public size: ButtonProps['size'] = 'medium';
|
|
@@ -32,12 +37,15 @@ export class PieButton extends LitElement {
|
|
|
32
37
|
@property({ type: Boolean })
|
|
33
38
|
public disabled = false;
|
|
34
39
|
|
|
40
|
+
@property({ type: Boolean, reflect: true })
|
|
41
|
+
public isLoading = false;
|
|
42
|
+
|
|
35
43
|
@property({ type: Boolean })
|
|
36
44
|
public isFullWidth = false;
|
|
37
45
|
|
|
38
46
|
render () {
|
|
39
47
|
const {
|
|
40
|
-
type, disabled, isFullWidth, variant, size,
|
|
48
|
+
type, disabled, isFullWidth, variant, size, isLoading,
|
|
41
49
|
} = this;
|
|
42
50
|
|
|
43
51
|
return html`
|
|
@@ -47,11 +55,18 @@ export class PieButton extends LitElement {
|
|
|
47
55
|
variant=${variant}
|
|
48
56
|
size=${size}
|
|
49
57
|
?disabled=${disabled}
|
|
50
|
-
?isFullWidth=${isFullWidth}
|
|
51
|
-
|
|
58
|
+
?isFullWidth=${isFullWidth}
|
|
59
|
+
?isLoading=${isLoading}>
|
|
60
|
+
<slot name="icon-leading"></slot>
|
|
61
|
+
<span class="o-btn-text"><slot></slot></span>
|
|
62
|
+
<slot name="icon-trailing"></slot>
|
|
52
63
|
</button>`;
|
|
53
64
|
}
|
|
54
65
|
|
|
66
|
+
focus () {
|
|
67
|
+
this.shadowRoot?.querySelector('button')?.focus();
|
|
68
|
+
}
|
|
69
|
+
|
|
55
70
|
// Renders a `CSSResult` generated from SCSS by Vite
|
|
56
71
|
static styles = unsafeCSS(styles);
|
|
57
72
|
}
|
|
@@ -21,10 +21,11 @@ const props: PropObject = {
|
|
|
21
21
|
type: 'button', // Changing the type does not affect the appearance of the button
|
|
22
22
|
isFullWidth: [true, false],
|
|
23
23
|
disabled: [true, false],
|
|
24
|
+
isLoading: [true, false],
|
|
24
25
|
};
|
|
25
26
|
|
|
26
27
|
// Renders a <pie-button> HTML string with the given prop values
|
|
27
|
-
const renderTestPieButton = (propVals: WebComponentPropValues) => `<pie-button variant="${propVals.variant}" size="${propVals.size}" type="${propVals.type}" ${propVals.isFullWidth ? 'isFullWidth' : ''} ${propVals.disabled ? 'disabled' : ''}>Hello world</pie-button>`;
|
|
28
|
+
const renderTestPieButton = (propVals: WebComponentPropValues) => `<pie-button variant="${propVals.variant}" size="${propVals.size}" type="${propVals.type}" ${propVals.isFullWidth ? 'isFullWidth' : ''} ${propVals.disabled ? 'disabled' : ''} ${propVals.isLoading ? 'isLoading' : ''}>Hello world</pie-button>`;
|
|
28
29
|
|
|
29
30
|
const componentPropsMatrix : WebComponentPropValues[] = getAllPropCombinations(props);
|
|
30
31
|
const componentPropsMatrixByVariant: Record<string, WebComponentPropValues[]> = splitCombinationsByPropertyValue(componentPropsMatrix, 'variant');
|
|
@@ -48,7 +49,7 @@ test.beforeEach(async ({ page, mount }) => {
|
|
|
48
49
|
componentVariants.forEach((variant) => test(`Render all prop variations for Variant: ${variant}`, async ({ page, mount }) => {
|
|
49
50
|
await Promise.all(componentPropsMatrixByVariant[variant].map(async (combo: WebComponentPropValues) => {
|
|
50
51
|
const testComponent: WebComponentTestInput = createTestWebComponent(combo, renderTestPieButton);
|
|
51
|
-
const propKeyValues = `size: ${testComponent.propValues.size}, isFullWidth: ${testComponent.propValues.isFullWidth}, disabled: ${testComponent.propValues.disabled}`;
|
|
52
|
+
const propKeyValues = `size: ${testComponent.propValues.size}, isFullWidth: ${testComponent.propValues.isFullWidth}, disabled: ${testComponent.propValues.disabled}, isLoading: ${testComponent.propValues.isLoading}`;
|
|
52
53
|
const darkMode = variant === 'inverse' || variant === 'ghost-inverse';
|
|
53
54
|
|
|
54
55
|
await mount(
|
|
@@ -64,3 +65,49 @@ componentVariants.forEach((variant) => test(`Render all prop variations for Vari
|
|
|
64
65
|
|
|
65
66
|
await percySnapshot(page, `PIE Button - Variant: ${variant}`);
|
|
66
67
|
}));
|
|
68
|
+
|
|
69
|
+
// TODO: Currently setting the slot to use a straight up SVG
|
|
70
|
+
// This should be updated to use pie-icons-webc, but after some investigation, we think that we'll
|
|
71
|
+
// need to convert the webc icons to use Lit, as currently the components don't work well in a Node env like Playwright
|
|
72
|
+
// Atm, importing them like `import '@justeattakeaway/pie-icons-webc/icons/IconClose.js';` results in an `HTMLElement is not defined` error
|
|
73
|
+
const plusSVG = '<svg xmlns="http://www.w3.org/2000/svg" role="presentation" focusable="false" fill="currentColor" viewBox="0 0 16 16" class="c-pieIcon c-pieIcon--plusCircle"><path d="M8.656 4.596H7.344v2.748H4.596v1.312h2.748v2.748h1.312V8.656h2.748V7.344H8.656V4.596Z"></path><path d="M12.795 3.205a6.781 6.781 0 1 0 0 9.625 6.79 6.79 0 0 0 0-9.625Zm-.927 8.662a5.469 5.469 0 1 1-7.734-7.735 5.469 5.469 0 0 1 7.734 7.736Z"></path></svg>';
|
|
74
|
+
const chevronSVG = '<svg xmlns="http://www.w3.org/2000/svg" role="presentation" focusable="false" fill="currentColor" viewBox="0 0 16 16" class="c-pieIcon c-pieIcon--chevronDown"><path d="M2.82 5.044 8 10.399 13.197 5l.963.875-5.364 5.565a1.164 1.164 0 0 1-1.636 0L1.875 5.945l.945-.901Z"></path></svg>';
|
|
75
|
+
|
|
76
|
+
sizes.forEach((size) => test(`Render icon slot variations for Size: ${size}`, async ({ page, mount }) => {
|
|
77
|
+
const iconSlotVariations = [
|
|
78
|
+
{
|
|
79
|
+
'icon-leading': plusSVG,
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
'icon-trailing': chevronSVG,
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
'icon-leading': plusSVG,
|
|
86
|
+
'icon-trailing': chevronSVG,
|
|
87
|
+
},
|
|
88
|
+
];
|
|
89
|
+
|
|
90
|
+
await Promise.all(iconSlotVariations.map(async (iconSlots) => {
|
|
91
|
+
const iconLeading = iconSlots['icon-leading'] ? iconSlots['icon-leading'].replace('<svg', '<svg slot="icon-leading"') : '';
|
|
92
|
+
const iconTrailing = iconSlots['icon-trailing'] ? iconSlots['icon-trailing'].replace('<svg', '<svg slot="icon-trailing"') : '';
|
|
93
|
+
|
|
94
|
+
await mount(
|
|
95
|
+
WebComponentTestWrapper,
|
|
96
|
+
{
|
|
97
|
+
props: {
|
|
98
|
+
size,
|
|
99
|
+
},
|
|
100
|
+
slots: {
|
|
101
|
+
component: `<pie-button size="${size}">
|
|
102
|
+
${iconLeading || ''}
|
|
103
|
+
Hello, ${size} Button!
|
|
104
|
+
${iconTrailing || ''}
|
|
105
|
+
</pie-button>`,
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
);
|
|
109
|
+
}));
|
|
110
|
+
|
|
111
|
+
await percySnapshot(page, `PIE Button Leading Icon - Size: ${size}`);
|
|
112
|
+
}));
|
|
113
|
+
|