@justeattakeaway/pie-spinner 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -1
- package/dist/index.d.ts +23 -0
- package/dist/index.js +59 -9
- package/dist/react.d.ts +23 -0
- package/dist/react.js +41 -36
- package/package.json +1 -1
- package/src/defs.ts +21 -3
- package/src/index.ts +34 -5
- package/src/spinner.scss +81 -0
package/README.md
CHANGED
|
@@ -60,7 +60,9 @@ import { PieSpinner } from '@justeattakeaway/pie-spinner/dist/react';
|
|
|
60
60
|
|
|
61
61
|
| Property | Type | Default | Description |
|
|
62
62
|
|---|---|---|---|
|
|
63
|
-
|
|
|
63
|
+
| size | `String` | `m` | Size of the spinner, one of `sizes` – `xs`, `s`, `m`, `l`, `xl` |
|
|
64
|
+
| variant | `String` | `brand` | Variant of the spinner, one of `variants` – `brand`, `secondary`, `inverse` |
|
|
65
|
+
| aria | `Object` | `undefined` | An object representing the aria attributes such as label;
|
|
64
66
|
|
|
65
67
|
In your markup or JSX, you can then use these to set the properties for the `pie-spinner` component:
|
|
66
68
|
|
package/dist/index.d.ts
CHANGED
|
@@ -2,15 +2,38 @@ import type { CSSResult } from 'lit';
|
|
|
2
2
|
import type { LitElement } from 'lit';
|
|
3
3
|
import type { TemplateResult } from 'lit-html';
|
|
4
4
|
|
|
5
|
+
export declare type AriaProps = {
|
|
6
|
+
label?: string;
|
|
7
|
+
};
|
|
8
|
+
|
|
5
9
|
/**
|
|
6
10
|
* @tagname pie-spinner
|
|
7
11
|
*/
|
|
8
12
|
export declare class PieSpinner extends LitElement implements SpinnerProps {
|
|
13
|
+
aria?: AriaProps;
|
|
14
|
+
size?: SpinnerProps['size'];
|
|
15
|
+
variant?: SpinnerProps['variant'];
|
|
9
16
|
render(): TemplateResult<1>;
|
|
10
17
|
static styles: CSSResult;
|
|
11
18
|
}
|
|
12
19
|
|
|
20
|
+
export declare const sizes: readonly ["xs", "s", "m", "l", "xl"];
|
|
21
|
+
|
|
13
22
|
export declare interface SpinnerProps {
|
|
23
|
+
/**
|
|
24
|
+
* The ARIA labels used for the spinner component.
|
|
25
|
+
*/
|
|
26
|
+
aria?: AriaProps;
|
|
27
|
+
/**
|
|
28
|
+
* What size the spinner should be.
|
|
29
|
+
*/
|
|
30
|
+
size?: typeof sizes[number];
|
|
31
|
+
/**
|
|
32
|
+
* What style variant the spinner should be such as brand, secondary or inverse.
|
|
33
|
+
*/
|
|
34
|
+
variant?: typeof variants[number];
|
|
14
35
|
}
|
|
15
36
|
|
|
37
|
+
export declare const variants: readonly ["brand", "secondary", "inverse"];
|
|
38
|
+
|
|
16
39
|
export { }
|
package/dist/index.js
CHANGED
|
@@ -1,15 +1,65 @@
|
|
|
1
|
-
import { unsafeCSS as
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import { unsafeCSS as f, LitElement as u, html as v, nothing as m } from "lit";
|
|
2
|
+
import { property as c } from "lit/decorators.js";
|
|
3
|
+
const b = (r, e, o) => function(s, i) {
|
|
4
|
+
const t = `#${i}`;
|
|
5
|
+
Object.defineProperty(s, i, {
|
|
6
|
+
get() {
|
|
7
|
+
return this[t];
|
|
8
|
+
},
|
|
9
|
+
set(l) {
|
|
10
|
+
const h = this[t];
|
|
11
|
+
e.includes(l) ? this[t] = l : (console.error(
|
|
12
|
+
`<${r}> Invalid value "${l}" provided for property "${i}".`,
|
|
13
|
+
`Must be one of: ${e.join(" | ")}.`,
|
|
14
|
+
`Falling back to default value: "${o}"`
|
|
15
|
+
), this[t] = o), this.requestUpdate(i, h);
|
|
16
|
+
}
|
|
17
|
+
});
|
|
18
|
+
};
|
|
19
|
+
function z(r, e) {
|
|
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, e);
|
|
4
21
|
}
|
|
5
|
-
const
|
|
6
|
-
|
|
22
|
+
const y = `*,*: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}
|
|
23
|
+
`, x = ["xs", "s", "m", "l", "xl"], g = ["brand", "secondary", "inverse"];
|
|
24
|
+
var P = Object.defineProperty, $ = Object.getOwnPropertyDescriptor, p = (r, e, o, n) => {
|
|
25
|
+
for (var s = n > 1 ? void 0 : n ? $(e, o) : e, i = r.length - 1, t; i >= 0; i--)
|
|
26
|
+
(t = r[i]) && (s = (n ? t(e, o, s) : t(s)) || s);
|
|
27
|
+
return n && s && P(e, o, s), s;
|
|
28
|
+
};
|
|
29
|
+
const d = "pie-spinner";
|
|
30
|
+
class a extends u {
|
|
31
|
+
constructor() {
|
|
32
|
+
super(...arguments), this.size = "m", this.variant = "brand";
|
|
33
|
+
}
|
|
7
34
|
render() {
|
|
8
|
-
|
|
35
|
+
const { variant: e, size: o, aria: n } = this;
|
|
36
|
+
return v`
|
|
37
|
+
<div
|
|
38
|
+
data-test-id="pie-spinner"
|
|
39
|
+
class="c-spinner"
|
|
40
|
+
role="status"
|
|
41
|
+
aria-live="polite"
|
|
42
|
+
size="${o}"
|
|
43
|
+
variant="${e}">
|
|
44
|
+
${n != null && n.label ? v`<span class="c-spinner-label">${n.label}</span>` : m}
|
|
45
|
+
</div>`;
|
|
9
46
|
}
|
|
10
47
|
}
|
|
11
|
-
|
|
12
|
-
|
|
48
|
+
a.styles = f(y);
|
|
49
|
+
p([
|
|
50
|
+
c({ type: Object })
|
|
51
|
+
], a.prototype, "aria", 2);
|
|
52
|
+
p([
|
|
53
|
+
c(),
|
|
54
|
+
b(d, x, "m")
|
|
55
|
+
], a.prototype, "size", 2);
|
|
56
|
+
p([
|
|
57
|
+
c(),
|
|
58
|
+
b(d, g, "brand")
|
|
59
|
+
], a.prototype, "variant", 2);
|
|
60
|
+
z(d, a);
|
|
13
61
|
export {
|
|
14
|
-
|
|
62
|
+
a as PieSpinner,
|
|
63
|
+
x as sizes,
|
|
64
|
+
g as variants
|
|
15
65
|
};
|
package/dist/react.d.ts
CHANGED
|
@@ -3,17 +3,40 @@ import type { LitElement } from 'lit';
|
|
|
3
3
|
import type { ReactWebComponent } from '@lit-labs/react';
|
|
4
4
|
import type { TemplateResult } from 'lit-html';
|
|
5
5
|
|
|
6
|
+
export declare type AriaProps = {
|
|
7
|
+
label?: string;
|
|
8
|
+
};
|
|
9
|
+
|
|
6
10
|
export declare const PieSpinner: ReactWebComponent<PieSpinner_2, {}>;
|
|
7
11
|
|
|
8
12
|
/**
|
|
9
13
|
* @tagname pie-spinner
|
|
10
14
|
*/
|
|
11
15
|
declare class PieSpinner_2 extends LitElement implements SpinnerProps {
|
|
16
|
+
aria?: AriaProps;
|
|
17
|
+
size?: SpinnerProps['size'];
|
|
18
|
+
variant?: SpinnerProps['variant'];
|
|
12
19
|
render(): TemplateResult<1>;
|
|
13
20
|
static styles: CSSResult;
|
|
14
21
|
}
|
|
15
22
|
|
|
23
|
+
export declare const sizes: readonly ["xs", "s", "m", "l", "xl"];
|
|
24
|
+
|
|
16
25
|
export declare interface SpinnerProps {
|
|
26
|
+
/**
|
|
27
|
+
* The ARIA labels used for the spinner component.
|
|
28
|
+
*/
|
|
29
|
+
aria?: AriaProps;
|
|
30
|
+
/**
|
|
31
|
+
* What size the spinner should be.
|
|
32
|
+
*/
|
|
33
|
+
size?: typeof sizes[number];
|
|
34
|
+
/**
|
|
35
|
+
* What style variant the spinner should be such as brand, secondary or inverse.
|
|
36
|
+
*/
|
|
37
|
+
variant?: typeof variants[number];
|
|
17
38
|
}
|
|
18
39
|
|
|
40
|
+
export declare const variants: readonly ["brand", "secondary", "inverse"];
|
|
41
|
+
|
|
19
42
|
export { }
|
package/dist/react.js
CHANGED
|
@@ -1,67 +1,72 @@
|
|
|
1
|
-
import * as
|
|
2
|
-
import { PieSpinner as
|
|
1
|
+
import * as g from "react";
|
|
2
|
+
import { PieSpinner as E } from "./index.js";
|
|
3
|
+
import { sizes as k, variants as A } from "./index.js";
|
|
3
4
|
import "lit";
|
|
5
|
+
import "lit/decorators.js";
|
|
4
6
|
/**
|
|
5
7
|
* @license
|
|
6
8
|
* Copyright 2018 Google LLC
|
|
7
9
|
* SPDX-License-Identifier: BSD-3-Clause
|
|
8
10
|
*/
|
|
9
|
-
const
|
|
10
|
-
const
|
|
11
|
-
|
|
12
|
-
let
|
|
13
|
-
|
|
14
|
-
let
|
|
15
|
-
|
|
16
|
-
})(
|
|
11
|
+
const S = /* @__PURE__ */ new Set(["children", "localName", "ref", "style", "className"]), w = /* @__PURE__ */ new WeakMap(), b = (t, n, c, d, m) => {
|
|
12
|
+
const o = m == null ? void 0 : m[n];
|
|
13
|
+
o === void 0 || c === d ? c == null && n in HTMLElement.prototype ? t.removeAttribute(n) : t[n] = c : ((r, i, h) => {
|
|
14
|
+
let a = w.get(r);
|
|
15
|
+
a === void 0 && w.set(r, a = /* @__PURE__ */ new Map());
|
|
16
|
+
let l = a.get(i);
|
|
17
|
+
h !== void 0 ? l === void 0 ? (a.set(i, l = { handleEvent: h }), r.addEventListener(i, l)) : l.handleEvent = h : l !== void 0 && (a.delete(i), r.removeEventListener(i, l));
|
|
18
|
+
})(t, o, c);
|
|
19
|
+
}, M = (t, n) => {
|
|
20
|
+
typeof t == "function" ? t(n) : t.current = n;
|
|
17
21
|
};
|
|
18
|
-
function
|
|
19
|
-
let
|
|
20
|
-
if (
|
|
21
|
-
const
|
|
22
|
-
({ tagName:
|
|
22
|
+
function P(t = window.React, n, c, d, m) {
|
|
23
|
+
let o, r, i;
|
|
24
|
+
if (n === void 0) {
|
|
25
|
+
const p = t;
|
|
26
|
+
({ tagName: r, elementClass: i, events: d, displayName: m } = p), o = p.react;
|
|
23
27
|
} else
|
|
24
|
-
|
|
25
|
-
const
|
|
26
|
-
class f extends
|
|
28
|
+
o = t, i = c, r = n;
|
|
29
|
+
const h = o.Component, a = o.createElement, l = new Set(Object.keys(d ?? {}));
|
|
30
|
+
class f extends h {
|
|
27
31
|
constructor() {
|
|
28
32
|
super(...arguments), this.o = null;
|
|
29
33
|
}
|
|
30
34
|
t(e) {
|
|
31
35
|
if (this.o !== null)
|
|
32
|
-
for (const
|
|
33
|
-
|
|
36
|
+
for (const u in this.i)
|
|
37
|
+
b(this.o, u, this.props[u], e ? e[u] : void 0, d);
|
|
34
38
|
}
|
|
35
39
|
componentDidMount() {
|
|
36
|
-
|
|
40
|
+
var e;
|
|
41
|
+
this.t(), (e = this.o) === null || e === void 0 || e.removeAttribute("defer-hydration");
|
|
37
42
|
}
|
|
38
43
|
componentDidUpdate(e) {
|
|
39
44
|
this.t(e);
|
|
40
45
|
}
|
|
41
46
|
render() {
|
|
42
|
-
const { _$Gl: e, ...
|
|
43
|
-
this.h !== e && (this.u = (
|
|
44
|
-
e !== null && (
|
|
45
|
-
typeof c == "function" ? c(w) : c.current = w;
|
|
46
|
-
})(e, n), this.o = n, this.h = e;
|
|
47
|
+
const { _$Gl: e, ...u } = this.props;
|
|
48
|
+
this.h !== e && (this.u = (s) => {
|
|
49
|
+
e !== null && M(e, s), this.o = s, this.h = e;
|
|
47
50
|
}), this.i = {};
|
|
48
|
-
const
|
|
49
|
-
for (const [
|
|
50
|
-
|
|
51
|
-
return
|
|
51
|
+
const v = { ref: this.u };
|
|
52
|
+
for (const [s, y] of Object.entries(u))
|
|
53
|
+
S.has(s) ? v[s === "className" ? "class" : s] = y : l.has(s) || s in i.prototype ? this.i[s] = y : v[s] = y;
|
|
54
|
+
return v.suppressHydrationWarning = !0, a(r, v);
|
|
52
55
|
}
|
|
53
56
|
}
|
|
54
|
-
f.displayName =
|
|
55
|
-
const N =
|
|
57
|
+
f.displayName = m ?? i.name;
|
|
58
|
+
const N = o.forwardRef((p, e) => a(f, { ...p, _$Gl: e }, p == null ? void 0 : p.children));
|
|
56
59
|
return N.displayName = f.displayName, N;
|
|
57
60
|
}
|
|
58
|
-
const R =
|
|
61
|
+
const R = P({
|
|
59
62
|
displayName: "PieSpinner",
|
|
60
|
-
elementClass:
|
|
61
|
-
react:
|
|
63
|
+
elementClass: E,
|
|
64
|
+
react: g,
|
|
62
65
|
tagName: "pie-spinner",
|
|
63
66
|
events: {}
|
|
64
67
|
});
|
|
65
68
|
export {
|
|
66
|
-
R as PieSpinner
|
|
69
|
+
R as PieSpinner,
|
|
70
|
+
k as sizes,
|
|
71
|
+
A as variants
|
|
67
72
|
};
|
package/package.json
CHANGED
package/src/defs.ts
CHANGED
|
@@ -1,3 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
export const sizes = ['xs', 's', 'm', 'l', 'xl'] as const;
|
|
2
|
+
export const variants = ['brand', 'secondary', 'inverse'] as const;
|
|
3
|
+
|
|
4
|
+
export type AriaProps = {
|
|
5
|
+
label?: string;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export interface SpinnerProps {
|
|
9
|
+
/**
|
|
10
|
+
* The ARIA labels used for the spinner component.
|
|
11
|
+
*/
|
|
12
|
+
aria?: AriaProps;
|
|
13
|
+
/**
|
|
14
|
+
* What size the spinner should be.
|
|
15
|
+
*/
|
|
16
|
+
size?: typeof sizes[number];
|
|
17
|
+
/**
|
|
18
|
+
* What style variant the spinner should be such as brand, secondary or inverse.
|
|
19
|
+
*/
|
|
20
|
+
variant?: typeof variants[number];
|
|
21
|
+
}
|
package/src/index.ts
CHANGED
|
@@ -1,8 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
import {
|
|
2
|
+
LitElement, html, nothing, unsafeCSS,
|
|
3
|
+
} from 'lit';
|
|
4
|
+
import { property } from 'lit/decorators.js';
|
|
5
|
+
import { validPropertyValues, defineCustomElement } from '@justeattakeaway/pie-webc-core';
|
|
4
6
|
import styles from './spinner.scss?inline';
|
|
5
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
SpinnerProps,
|
|
9
|
+
sizes,
|
|
10
|
+
variants,
|
|
11
|
+
type AriaProps,
|
|
12
|
+
} from './defs';
|
|
6
13
|
|
|
7
14
|
// Valid values available to consumers
|
|
8
15
|
export * from './defs';
|
|
@@ -13,8 +20,30 @@ const componentSelector = 'pie-spinner';
|
|
|
13
20
|
* @tagname pie-spinner
|
|
14
21
|
*/
|
|
15
22
|
export class PieSpinner extends LitElement implements SpinnerProps {
|
|
23
|
+
@property({ type: Object })
|
|
24
|
+
public aria?: AriaProps;
|
|
25
|
+
|
|
26
|
+
@property()
|
|
27
|
+
@validPropertyValues(componentSelector, sizes, 'm')
|
|
28
|
+
public size?: SpinnerProps['size'] = 'm';
|
|
29
|
+
|
|
30
|
+
@property()
|
|
31
|
+
@validPropertyValues(componentSelector, variants, 'brand')
|
|
32
|
+
public variant?: SpinnerProps['variant'] = 'brand';
|
|
33
|
+
|
|
16
34
|
render () {
|
|
17
|
-
|
|
35
|
+
const { variant, size, aria } = this;
|
|
36
|
+
|
|
37
|
+
return html`
|
|
38
|
+
<div
|
|
39
|
+
data-test-id="pie-spinner"
|
|
40
|
+
class="c-spinner"
|
|
41
|
+
role="status"
|
|
42
|
+
aria-live="polite"
|
|
43
|
+
size="${size}"
|
|
44
|
+
variant="${variant}">
|
|
45
|
+
${aria?.label ? html`<span class="c-spinner-label">${aria.label}</span>` : nothing}
|
|
46
|
+
</div>`;
|
|
18
47
|
}
|
|
19
48
|
|
|
20
49
|
// Renders a `CSSResult` generated from SCSS by Vite
|
package/src/spinner.scss
CHANGED
|
@@ -1 +1,82 @@
|
|
|
1
1
|
@use '@justeattakeaway/pie-css/scss' as p;
|
|
2
|
+
|
|
3
|
+
*,
|
|
4
|
+
*:before,
|
|
5
|
+
*:after {
|
|
6
|
+
box-sizing: border-box;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Shorthand mixin for updating the HSL custom properties for the loading spinner.
|
|
11
|
+
* Takes in the name of the color to be split into its HSL components.
|
|
12
|
+
*/
|
|
13
|
+
@mixin spinner-base-colors($color) {
|
|
14
|
+
--spinner-base-color-h: var(#{$color}-h);
|
|
15
|
+
--spinner-base-color-s: var(#{$color}-s);
|
|
16
|
+
--spinner-base-color-l: var(#{$color}-l);
|
|
17
|
+
}
|
|
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
|
+
|
|
30
|
+
.c-spinner {
|
|
31
|
+
--spinner-size: 24px;
|
|
32
|
+
--spinner-left-color: hsl(var(--spinner-base-color-h), var(--spinner-base-color-s), var(--spinner-base-color-l), 1);
|
|
33
|
+
--spinner-right-color: hsl(var(--spinner-base-color-h), var(--spinner-base-color-s), var(--spinner-base-color-l), 0.35);
|
|
34
|
+
|
|
35
|
+
block-size: var(--spinner-size);
|
|
36
|
+
inline-size: var(--spinner-size);
|
|
37
|
+
border-radius: var(--dt-radius-rounded-e);
|
|
38
|
+
border-width: calc(var(--spinner-size) / 8);
|
|
39
|
+
border-style: solid;
|
|
40
|
+
border-color: var(--spinner-left-color) var(--spinner-right-color) var(--spinner-right-color) var(--spinner-left-color);
|
|
41
|
+
will-change: transform;
|
|
42
|
+
animation: rotate360 1.15s linear infinite;
|
|
43
|
+
|
|
44
|
+
@include spinner-base-colors('--dt-color-content-brand');
|
|
45
|
+
|
|
46
|
+
&[variant='brand'] {
|
|
47
|
+
/* Same as default styles */
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
&[variant='secondary'] {
|
|
51
|
+
@include spinner-base-colors('--dt-color-content-interactive-secondary');
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
&[variant='inverse'] {
|
|
55
|
+
@include spinner-base-colors('--dt-color-content-inverse');
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
&[size='xs'] {
|
|
59
|
+
--spinner-size: 16px;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
&[size='s'] {
|
|
63
|
+
--spinner-size: 20px;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
&[size='m'] {
|
|
67
|
+
/* Same as default styles */
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
&[size='l'] {
|
|
71
|
+
--spinner-size: 32px;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
&[size='xl'] {
|
|
75
|
+
--spinner-size: 48px;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// The label is only required for screen readers so we need to visually hide it
|
|
80
|
+
.c-spinner-label {
|
|
81
|
+
@include p.visually-hidden;
|
|
82
|
+
}
|