@rak200/ui 0.2.15 → 0.2.16
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 +2 -2
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/toast.d.ts +158 -0
- package/dist/toast.d.ts.map +1 -0
- package/dist/toast.js +494 -0
- package/dist/toast.js.map +1 -0
- package/dist/tokens.d.ts +1 -1
- package/dist/tokens.d.ts.map +1 -1
- package/dist/tokens.js +27 -0
- package/dist/tokens.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -86,9 +86,9 @@ components; `docs/` is what describes them.
|
|
|
86
86
|
|
|
87
87
|
## Status
|
|
88
88
|
|
|
89
|
-
**v0.**
|
|
89
|
+
**v0.** Fifteen components — `<ui-button>`, `<ui-card>`, `<ui-field>`, `<ui-dialog>`, `<ui-input>`,
|
|
90
90
|
`<ui-textarea>`, `<ui-checkbox>`, `<ui-switch>`, `<ui-select>`, `<ui-radio-group>`, `<ui-radio>`,
|
|
91
|
-
`<ui-tooltip>` and `<ui-icon>` — the token layer
|
|
91
|
+
`<ui-tooltip>`, `<ui-toaster>`, `<ui-toast>` and `<ui-icon>` — the token layer
|
|
92
92
|
under them, and an adopted glyph set, built to the ecosystem's full quality bar rather than
|
|
93
93
|
sketched: type-checked at the strictest available setting, formatted, tested in a real browser and
|
|
94
94
|
**asserted against axe** for WCAG A/AA, 100% coverage and **100% mutation score**, scanned, and
|
package/dist/index.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ export { UiIcon, register } from './icon.js';
|
|
|
7
7
|
export { UiInput, UiTextarea } from './input.js';
|
|
8
8
|
export { UiRadio, UiRadioGroup, type RadioOrientation } from './radio.js';
|
|
9
9
|
export { UiSelect } from './select.js';
|
|
10
|
+
export { UiToast, UiToaster, type ToastVariant } from './toast.js';
|
|
10
11
|
export { UiTooltip } from './tooltip.js';
|
|
11
12
|
export { tokens, derivedTokens, defaults, formulas, darkScheme, tokenStyleSheet, type Token, type DerivedToken, } from './tokens.js';
|
|
12
13
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACnC,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC1E,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EACH,MAAM,EACN,aAAa,EACb,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,eAAe,EACf,KAAK,KAAK,EACV,KAAK,YAAY,GACpB,MAAM,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACnC,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,YAAY,EAAE,KAAK,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC1E,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EACH,MAAM,EACN,aAAa,EACb,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,eAAe,EACf,KAAK,KAAK,EACV,KAAK,YAAY,GACpB,MAAM,aAAa,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -7,6 +7,7 @@ export { UiIcon, register } from './icon.js';
|
|
|
7
7
|
export { UiInput, UiTextarea } from './input.js';
|
|
8
8
|
export { UiRadio, UiRadioGroup } from './radio.js';
|
|
9
9
|
export { UiSelect } from './select.js';
|
|
10
|
+
export { UiToast, UiToaster } from './toast.js';
|
|
10
11
|
export { UiTooltip } from './tooltip.js';
|
|
11
12
|
export { tokens, derivedTokens, defaults, formulas, darkScheme, tokenStyleSheet, } from './tokens.js';
|
|
12
13
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAsB,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACnC,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,YAAY,EAAyB,MAAM,YAAY,CAAC;AAC1E,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EACH,MAAM,EACN,aAAa,EACb,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,eAAe,GAGlB,MAAM,aAAa,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAsB,MAAM,aAAa,CAAC;AAC3D,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AACnC,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACjD,OAAO,EAAE,OAAO,EAAE,YAAY,EAAyB,MAAM,YAAY,CAAC;AAC1E,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACvC,OAAO,EAAE,OAAO,EAAE,SAAS,EAAqB,MAAM,YAAY,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EACH,MAAM,EACN,aAAa,EACb,QAAQ,EACR,QAAQ,EACR,UAAU,EACV,eAAe,GAGlB,MAAM,aAAa,CAAC"}
|
package/dist/toast.d.ts
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import { LitElement, type TemplateResult } from 'lit';
|
|
2
|
+
/** What a toast is telling the reader, which decides how it looks *and* how it is announced. */
|
|
3
|
+
export type ToastVariant = 'info' | 'success' | 'warning' | 'danger';
|
|
4
|
+
/**
|
|
5
|
+
* The live regions a toast is announced through, and the box the stack is drawn in.
|
|
6
|
+
*
|
|
7
|
+
* **One container, two regions, and the count is the number of politenesses rather than
|
|
8
|
+
* the number of messages.** A live region has to be in the document *before* the text is
|
|
9
|
+
* put into it — a region that arrives with its content already inside is the single most
|
|
10
|
+
* common way a toast is never announced — so the regions are rendered on connection and
|
|
11
|
+
* never removed, and a toast is added to whichever one its variant names.
|
|
12
|
+
*
|
|
13
|
+
* That is the whole reason there are two. `aria-live` cannot vary per message inside one
|
|
14
|
+
* region, and giving each toast its own `aria-live` would make every message its own
|
|
15
|
+
* region root, which is the shape this component exists to avoid. Two regions that outlive
|
|
16
|
+
* every message answer *politeness is per toast* without ever creating one.
|
|
17
|
+
*
|
|
18
|
+
* **Neither region carries `role="alert"` or `role="status"`**, and that is not a shortcut.
|
|
19
|
+
* Both roles imply `aria-atomic="true"`, so every arrival re-announces the whole stack —
|
|
20
|
+
* three toasts up means the third one reads all three. `aria-live` alone leaves
|
|
21
|
+
* `aria-atomic` at its `false` default, which announces the toast that arrived and nothing
|
|
22
|
+
* else. The semantics of `role="alert"` are `aria-live="assertive"` plus that atomicity;
|
|
23
|
+
* this keeps the half that is right for a stack.
|
|
24
|
+
*
|
|
25
|
+
* ## Where it sits
|
|
26
|
+
*
|
|
27
|
+
* A `popover`, for the reason `<ui-tooltip>` is one: the top layer escapes every stacking
|
|
28
|
+
* context and every `overflow: hidden` above it, so this package still names no `z-index`
|
|
29
|
+
* and opens no layering category — the third overlay in a row not to. `manual`, because an
|
|
30
|
+
* `auto` popover light-dismisses, and a toast that vanished on the next click somewhere
|
|
31
|
+
* else would be a notice the user never read.
|
|
32
|
+
*
|
|
33
|
+
* It is shown once, on connection, and never hidden — which costs the one thing promotion
|
|
34
|
+
* would have bought. A modal `<dialog>` opened *after* the toaster connects sits above it
|
|
35
|
+
* in the top layer, and re-promoting the stack per message would fix that ordering and
|
|
36
|
+
* break the announcement, by taking the region out of the tree and putting it back with
|
|
37
|
+
* content already in it. The trade is not close, and it is not the real limit anyway: a
|
|
38
|
+
* modal makes the rest of the document **inert**, so a toaster outside an open modal is out
|
|
39
|
+
* of the accessibility tree whichever layer it is in. `docs/toast.md` says where to put one
|
|
40
|
+
* for a page that toasts from inside a dialog.
|
|
41
|
+
*
|
|
42
|
+
* @example
|
|
43
|
+
* ```html
|
|
44
|
+
* <ui-toaster></ui-toaster>
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export declare class UiToaster extends LitElement {
|
|
48
|
+
static readonly styles: import("lit").CSSResult;
|
|
49
|
+
connectedCallback(): void;
|
|
50
|
+
render(): TemplateResult;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* One message in a {@link UiToaster}.
|
|
54
|
+
*
|
|
55
|
+
* ## The variant decides three things, and that is the design
|
|
56
|
+
*
|
|
57
|
+
* `variant` is not only how the toast looks. It decides how urgently the message is
|
|
58
|
+
* announced and whether it expires, because those three answers are one answer: **an error
|
|
59
|
+
* is the message the reader has to see, hear, and keep.** So `danger` is announced
|
|
60
|
+
* assertively and never times out, and every other variant is polite and does.
|
|
61
|
+
*
|
|
62
|
+
* The alternative was a second attribute for politeness, and it was rejected for what it
|
|
63
|
+
* makes possible rather than for what it costs: two knobs can disagree, and a polite error
|
|
64
|
+
* or an assertive success is a defect nothing reports. The issue behind this component
|
|
65
|
+
* asked for `assertive` to be *reserved for errors* — a rule the API can hold is worth more
|
|
66
|
+
* than a rule the documentation states. What it gives up is stated in `docs/toast.md`:
|
|
67
|
+
* there is no way to write an assertive success.
|
|
68
|
+
*
|
|
69
|
+
* **The colour is redundant and must stay redundant.** WCAG 1.4.1 asks that colour never be
|
|
70
|
+
* the only carrier of information, and here it never is: the message says what happened and
|
|
71
|
+
* the edge agrees with it. That is also what makes the component correct under
|
|
72
|
+
* `forced-colors`, where the edge goes flat and nothing is lost.
|
|
73
|
+
*
|
|
74
|
+
* ## Dismissal
|
|
75
|
+
*
|
|
76
|
+
* Manual always, timed unless the toast is an error or `duration` is `0`. There is
|
|
77
|
+
* deliberately no way to remove the dismiss button: a toast that cannot be dismissed *and*
|
|
78
|
+
* does not expire is a permanent obstruction, and that combination is one attribute away in
|
|
79
|
+
* every kit that offers the knob.
|
|
80
|
+
*
|
|
81
|
+
* The timer stops while the pointer is over the toast or the focus is inside it, and starts
|
|
82
|
+
* again when both have left — a notice must not expire while it is being read, which is
|
|
83
|
+
* WCAG 2.2.1 aimed at the only time limit this component has.
|
|
84
|
+
*
|
|
85
|
+
* **A dismissed toast removes itself.** `ui-dismiss` is dispatched first, while the element
|
|
86
|
+
* is still in the tree so the event can reach a listener above it; a framework rendering a
|
|
87
|
+
* list of toasts drops the entry there rather than leaving the element to be put back.
|
|
88
|
+
*
|
|
89
|
+
* @example
|
|
90
|
+
* ```html
|
|
91
|
+
* <ui-toaster>
|
|
92
|
+
* <ui-toast variant="success">Saved.</ui-toast>
|
|
93
|
+
* </ui-toaster>
|
|
94
|
+
* ```
|
|
95
|
+
*/
|
|
96
|
+
export declare class UiToast extends LitElement {
|
|
97
|
+
#private;
|
|
98
|
+
static readonly styles: import("lit").CSSResult;
|
|
99
|
+
static readonly properties: {
|
|
100
|
+
variant: {
|
|
101
|
+
type: StringConstructor;
|
|
102
|
+
reflect: boolean;
|
|
103
|
+
};
|
|
104
|
+
duration: {
|
|
105
|
+
type: NumberConstructor;
|
|
106
|
+
};
|
|
107
|
+
dismissLabel: {
|
|
108
|
+
type: StringConstructor;
|
|
109
|
+
attribute: string;
|
|
110
|
+
};
|
|
111
|
+
};
|
|
112
|
+
/**
|
|
113
|
+
* What this toast is telling the reader.
|
|
114
|
+
*
|
|
115
|
+
* Reflected, because it is what the stylesheet selects on — and because it is the
|
|
116
|
+
* attribute a host reads back to find out how the toast will behave.
|
|
117
|
+
*
|
|
118
|
+
* A plain field rather than the `accessor` keyword, for the reason `src/button.ts`
|
|
119
|
+
* states beside its own.
|
|
120
|
+
*/
|
|
121
|
+
variant: ToastVariant;
|
|
122
|
+
/**
|
|
123
|
+
* How long the toast waits before dismissing itself, in milliseconds; `0` never.
|
|
124
|
+
*
|
|
125
|
+
* Ignored when the variant is `danger`, which never expires. Not a token, for the
|
|
126
|
+
* reason the default carries: every duration name collapses under reduced motion, and
|
|
127
|
+
* a dwell time that collapsed would take the notice away from the reader who asked for
|
|
128
|
+
* less movement.
|
|
129
|
+
*/
|
|
130
|
+
duration: number;
|
|
131
|
+
/**
|
|
132
|
+
* The accessible name of the dismiss button.
|
|
133
|
+
*
|
|
134
|
+
* This package's one user-facing string, and an attribute precisely because it is one:
|
|
135
|
+
* a page that is not in English replaces it rather than forking the component. It names
|
|
136
|
+
* the button and never appears on screen, which is why there is no way to leave it
|
|
137
|
+
* empty — an unnamed control is the failure this default exists to prevent.
|
|
138
|
+
*/
|
|
139
|
+
dismissLabel: string;
|
|
140
|
+
connectedCallback(): void;
|
|
141
|
+
disconnectedCallback(): void;
|
|
142
|
+
willUpdate(): void;
|
|
143
|
+
render(): TemplateResult;
|
|
144
|
+
/**
|
|
145
|
+
* Runs the exit, announces it, and takes the toast off the page.
|
|
146
|
+
*
|
|
147
|
+
* Bound as a field so it can be handed to a listener and called as a method without
|
|
148
|
+
* either losing `this`.
|
|
149
|
+
*/
|
|
150
|
+
readonly dismiss: () => void;
|
|
151
|
+
}
|
|
152
|
+
declare global {
|
|
153
|
+
interface HTMLElementTagNameMap {
|
|
154
|
+
'ui-toaster': UiToaster;
|
|
155
|
+
'ui-toast': UiToast;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=toast.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toast.d.ts","sourceRoot":"","sources":["../src/toast.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAa,KAAK,cAAc,EAAE,MAAM,KAAK,CAAC;AAGjE,gGAAgG;AAChG,MAAM,MAAM,YAAY,GAAG,MAAM,GAAG,SAAS,GAAG,SAAS,GAAG,QAAQ,CAAC;AAqBrE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,qBAAa,SAAU,SAAQ,UAAU;IACrC,gBAAyB,MAAM,0BAiD7B;IAEO,iBAAiB,IAAI,IAAI;IAazB,MAAM,IAAI,cAAc;CAMpC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,qBAAa,OAAQ,SAAQ,UAAU;;IACnC,gBAAyB,MAAM,0BAqH7B;IAEF,gBAAyB,UAAU;;;;;;;;;;;;MAIjC;IAEF;;;;;;;;OAQG;IACH,OAAO,EAAE,YAAY,CAAU;IAE/B;;;;;;;OAOG;IACH,QAAQ,SAAS;IAEjB;;;;;;;OAOG;IACH,YAAY,SAAa;IAoChB,iBAAiB,IAAI,IAAI;IAwBzB,oBAAoB,IAAI,IAAI;IAO5B,UAAU,IAAI,IAAI;IAQlB,MAAM,IAAI,cAAc;IAsBjC;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,QAAO,IAAI,CAEzB;CA0DL;AAWD,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,qBAAqB;QAC3B,YAAY,EAAE,SAAS,CAAC;QACxB,UAAU,EAAE,OAAO,CAAC;KACvB;CACJ"}
|
package/dist/toast.js
ADDED
|
@@ -0,0 +1,494 @@
|
|
|
1
|
+
import { LitElement, css, html } from 'lit';
|
|
2
|
+
import { reference } from './reference.js';
|
|
3
|
+
/** The class the exit is carried by, on the toast for exactly as long as the exit runs. */
|
|
4
|
+
const closing = 'closing';
|
|
5
|
+
/**
|
|
6
|
+
* How long a toast that is not an error stays, in milliseconds.
|
|
7
|
+
*
|
|
8
|
+
* **Deliberately not a token, and that is the sharpest thing in this file.** Every
|
|
9
|
+
* `--ui-duration-*` name is collapsed to `0.01ms` by `tokenStyleSheet()` when the reader
|
|
10
|
+
* has asked for less motion — which is right for a transition and catastrophic for a dwell
|
|
11
|
+
* time: a notice would vanish before it could be read, and only for the people least able
|
|
12
|
+
* to chase it. A duration a component *waits* is not motion, so it is an attribute with a
|
|
13
|
+
* default rather than a name in the scale.
|
|
14
|
+
*
|
|
15
|
+
* Five seconds is read off a rate rather than chosen: a short notice is eight or ten words,
|
|
16
|
+
* and 180 words a minute is the unhurried end of silent reading — about three seconds — with
|
|
17
|
+
* the rest of it spent noticing that something arrived at all.
|
|
18
|
+
*/
|
|
19
|
+
const dwell = 5000;
|
|
20
|
+
/**
|
|
21
|
+
* The live regions a toast is announced through, and the box the stack is drawn in.
|
|
22
|
+
*
|
|
23
|
+
* **One container, two regions, and the count is the number of politenesses rather than
|
|
24
|
+
* the number of messages.** A live region has to be in the document *before* the text is
|
|
25
|
+
* put into it — a region that arrives with its content already inside is the single most
|
|
26
|
+
* common way a toast is never announced — so the regions are rendered on connection and
|
|
27
|
+
* never removed, and a toast is added to whichever one its variant names.
|
|
28
|
+
*
|
|
29
|
+
* That is the whole reason there are two. `aria-live` cannot vary per message inside one
|
|
30
|
+
* region, and giving each toast its own `aria-live` would make every message its own
|
|
31
|
+
* region root, which is the shape this component exists to avoid. Two regions that outlive
|
|
32
|
+
* every message answer *politeness is per toast* without ever creating one.
|
|
33
|
+
*
|
|
34
|
+
* **Neither region carries `role="alert"` or `role="status"`**, and that is not a shortcut.
|
|
35
|
+
* Both roles imply `aria-atomic="true"`, so every arrival re-announces the whole stack —
|
|
36
|
+
* three toasts up means the third one reads all three. `aria-live` alone leaves
|
|
37
|
+
* `aria-atomic` at its `false` default, which announces the toast that arrived and nothing
|
|
38
|
+
* else. The semantics of `role="alert"` are `aria-live="assertive"` plus that atomicity;
|
|
39
|
+
* this keeps the half that is right for a stack.
|
|
40
|
+
*
|
|
41
|
+
* ## Where it sits
|
|
42
|
+
*
|
|
43
|
+
* A `popover`, for the reason `<ui-tooltip>` is one: the top layer escapes every stacking
|
|
44
|
+
* context and every `overflow: hidden` above it, so this package still names no `z-index`
|
|
45
|
+
* and opens no layering category — the third overlay in a row not to. `manual`, because an
|
|
46
|
+
* `auto` popover light-dismisses, and a toast that vanished on the next click somewhere
|
|
47
|
+
* else would be a notice the user never read.
|
|
48
|
+
*
|
|
49
|
+
* It is shown once, on connection, and never hidden — which costs the one thing promotion
|
|
50
|
+
* would have bought. A modal `<dialog>` opened *after* the toaster connects sits above it
|
|
51
|
+
* in the top layer, and re-promoting the stack per message would fix that ordering and
|
|
52
|
+
* break the announcement, by taking the region out of the tree and putting it back with
|
|
53
|
+
* content already in it. The trade is not close, and it is not the real limit anyway: a
|
|
54
|
+
* modal makes the rest of the document **inert**, so a toaster outside an open modal is out
|
|
55
|
+
* of the accessibility tree whichever layer it is in. `docs/toast.md` says where to put one
|
|
56
|
+
* for a page that toasts from inside a dialog.
|
|
57
|
+
*
|
|
58
|
+
* @example
|
|
59
|
+
* ```html
|
|
60
|
+
* <ui-toaster></ui-toaster>
|
|
61
|
+
* ```
|
|
62
|
+
*/
|
|
63
|
+
export class UiToaster extends LitElement {
|
|
64
|
+
static { this.styles = css `
|
|
65
|
+
:host {
|
|
66
|
+
/* The user agent's own popover box is a centred panel with a border and a
|
|
67
|
+
padding of its own. All of it is displaced, because what this is is a
|
|
68
|
+
corner of the viewport rather than a dialog. */
|
|
69
|
+
position: fixed;
|
|
70
|
+
inset-block: auto 0;
|
|
71
|
+
inset-inline: auto 0;
|
|
72
|
+
margin: 0;
|
|
73
|
+
border: none;
|
|
74
|
+
background: none;
|
|
75
|
+
/* The stack is wider than a phrase and narrower than the page. Capped in the
|
|
76
|
+
space token so it scales with everything else a host retunes, and floored
|
|
77
|
+
against the viewport so a narrow screen gets the margin rather than a
|
|
78
|
+
horizontal scrollbar. */
|
|
79
|
+
box-sizing: border-box;
|
|
80
|
+
inline-size: min(100%, calc(${reference('--ui-space')} * 44));
|
|
81
|
+
padding: calc(${reference('--ui-space')} * 2);
|
|
82
|
+
/* The box covers a corner of the page whether or not it holds anything, so it
|
|
83
|
+
takes no clicks; a toast puts them back on itself. Without this a page has a
|
|
84
|
+
dead zone in the corner for as long as a toaster is on it. */
|
|
85
|
+
pointer-events: none;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/* display is named under :popover-open and nowhere else, and that is the rule
|
|
89
|
+
src/dialog.ts states beside its own: the user agent hides a closed popover with
|
|
90
|
+
display: none, and a rule here that names display unconditionally outranks it —
|
|
91
|
+
so a toaster whose popover never opened would render in the page flow instead of
|
|
92
|
+
being invisible. */
|
|
93
|
+
:host(:popover-open) {
|
|
94
|
+
display: flex;
|
|
95
|
+
flex-direction: column;
|
|
96
|
+
gap: ${reference('--ui-space')};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/* The polite region is first and the assertive one second, so an error sits nearest
|
|
100
|
+
the corner the stack grows from — which is where the eye already is. The order is
|
|
101
|
+
a rendering decision and nothing else: what a screen reader does with either
|
|
102
|
+
region is decided by its aria-live, not by which came first. */
|
|
103
|
+
div {
|
|
104
|
+
display: flex;
|
|
105
|
+
flex-direction: column;
|
|
106
|
+
gap: ${reference('--ui-space')};
|
|
107
|
+
min-inline-size: 0;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
slot::slotted(*) {
|
|
111
|
+
pointer-events: auto;
|
|
112
|
+
}
|
|
113
|
+
`; }
|
|
114
|
+
connectedCallback() {
|
|
115
|
+
super.connectedCallback();
|
|
116
|
+
// Written here rather than in the template, because it is the host's own attribute
|
|
117
|
+
// and Lit renders into the shadow root. Set before it is shown, which is the order
|
|
118
|
+
// showPopover() requires: it throws on an element carrying no popover attribute.
|
|
119
|
+
this.setAttribute('popover', 'manual');
|
|
120
|
+
// No guard, and none is reachable: removing a showing popover from the document
|
|
121
|
+
// hides it, so an element arriving at connectedCallback is never already open.
|
|
122
|
+
this.showPopover();
|
|
123
|
+
}
|
|
124
|
+
render() {
|
|
125
|
+
return html `
|
|
126
|
+
<div aria-live="polite" part="polite"><slot name="polite"></slot></div>
|
|
127
|
+
<div aria-live="assertive" part="assertive"><slot name="assertive"></slot></div>
|
|
128
|
+
`;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* One message in a {@link UiToaster}.
|
|
133
|
+
*
|
|
134
|
+
* ## The variant decides three things, and that is the design
|
|
135
|
+
*
|
|
136
|
+
* `variant` is not only how the toast looks. It decides how urgently the message is
|
|
137
|
+
* announced and whether it expires, because those three answers are one answer: **an error
|
|
138
|
+
* is the message the reader has to see, hear, and keep.** So `danger` is announced
|
|
139
|
+
* assertively and never times out, and every other variant is polite and does.
|
|
140
|
+
*
|
|
141
|
+
* The alternative was a second attribute for politeness, and it was rejected for what it
|
|
142
|
+
* makes possible rather than for what it costs: two knobs can disagree, and a polite error
|
|
143
|
+
* or an assertive success is a defect nothing reports. The issue behind this component
|
|
144
|
+
* asked for `assertive` to be *reserved for errors* — a rule the API can hold is worth more
|
|
145
|
+
* than a rule the documentation states. What it gives up is stated in `docs/toast.md`:
|
|
146
|
+
* there is no way to write an assertive success.
|
|
147
|
+
*
|
|
148
|
+
* **The colour is redundant and must stay redundant.** WCAG 1.4.1 asks that colour never be
|
|
149
|
+
* the only carrier of information, and here it never is: the message says what happened and
|
|
150
|
+
* the edge agrees with it. That is also what makes the component correct under
|
|
151
|
+
* `forced-colors`, where the edge goes flat and nothing is lost.
|
|
152
|
+
*
|
|
153
|
+
* ## Dismissal
|
|
154
|
+
*
|
|
155
|
+
* Manual always, timed unless the toast is an error or `duration` is `0`. There is
|
|
156
|
+
* deliberately no way to remove the dismiss button: a toast that cannot be dismissed *and*
|
|
157
|
+
* does not expire is a permanent obstruction, and that combination is one attribute away in
|
|
158
|
+
* every kit that offers the knob.
|
|
159
|
+
*
|
|
160
|
+
* The timer stops while the pointer is over the toast or the focus is inside it, and starts
|
|
161
|
+
* again when both have left — a notice must not expire while it is being read, which is
|
|
162
|
+
* WCAG 2.2.1 aimed at the only time limit this component has.
|
|
163
|
+
*
|
|
164
|
+
* **A dismissed toast removes itself.** `ui-dismiss` is dispatched first, while the element
|
|
165
|
+
* is still in the tree so the event can reach a listener above it; a framework rendering a
|
|
166
|
+
* list of toasts drops the entry there rather than leaving the element to be put back.
|
|
167
|
+
*
|
|
168
|
+
* @example
|
|
169
|
+
* ```html
|
|
170
|
+
* <ui-toaster>
|
|
171
|
+
* <ui-toast variant="success">Saved.</ui-toast>
|
|
172
|
+
* </ui-toaster>
|
|
173
|
+
* ```
|
|
174
|
+
*/
|
|
175
|
+
export class UiToast extends LitElement {
|
|
176
|
+
constructor() {
|
|
177
|
+
super(...arguments);
|
|
178
|
+
/**
|
|
179
|
+
* What this toast is telling the reader.
|
|
180
|
+
*
|
|
181
|
+
* Reflected, because it is what the stylesheet selects on — and because it is the
|
|
182
|
+
* attribute a host reads back to find out how the toast will behave.
|
|
183
|
+
*
|
|
184
|
+
* A plain field rather than the `accessor` keyword, for the reason `src/button.ts`
|
|
185
|
+
* states beside its own.
|
|
186
|
+
*/
|
|
187
|
+
this.variant = 'info';
|
|
188
|
+
/**
|
|
189
|
+
* How long the toast waits before dismissing itself, in milliseconds; `0` never.
|
|
190
|
+
*
|
|
191
|
+
* Ignored when the variant is `danger`, which never expires. Not a token, for the
|
|
192
|
+
* reason the default carries: every duration name collapses under reduced motion, and
|
|
193
|
+
* a dwell time that collapsed would take the notice away from the reader who asked for
|
|
194
|
+
* less movement.
|
|
195
|
+
*/
|
|
196
|
+
this.duration = dwell;
|
|
197
|
+
/**
|
|
198
|
+
* The accessible name of the dismiss button.
|
|
199
|
+
*
|
|
200
|
+
* This package's one user-facing string, and an attribute precisely because it is one:
|
|
201
|
+
* a page that is not in English replaces it rather than forking the component. It names
|
|
202
|
+
* the button and never appears on screen, which is why there is no way to leave it
|
|
203
|
+
* empty — an unnamed control is the failure this default exists to prevent.
|
|
204
|
+
*/
|
|
205
|
+
this.dismissLabel = 'Dismiss';
|
|
206
|
+
/** The pending auto-dismissal; `0` when there is none, which is what `clearTimeout` reads. */
|
|
207
|
+
this.#timer = 0;
|
|
208
|
+
/**
|
|
209
|
+
* Takes every listener off at once, for the reason `src/tooltip.ts` gives beside its
|
|
210
|
+
* own: half of these leak invisibly if they are removed by name, and one `abort()` is
|
|
211
|
+
* one thing to get right.
|
|
212
|
+
*/
|
|
213
|
+
this.#listeners = new AbortController();
|
|
214
|
+
/** Holds the clock while the toast is being read, which is the whole of WCAG 2.2.1 here. */
|
|
215
|
+
this.#hold = () => {
|
|
216
|
+
this.#stop();
|
|
217
|
+
};
|
|
218
|
+
/** Starts it again once the pointer and the focus have both left. */
|
|
219
|
+
this.#resume = () => {
|
|
220
|
+
this.#start();
|
|
221
|
+
};
|
|
222
|
+
/**
|
|
223
|
+
* Dismisses on Escape.
|
|
224
|
+
*
|
|
225
|
+
* Bound to this element rather than to the document, which is the opposite of what
|
|
226
|
+
* `<ui-tooltip>` needed and for the opposite reason: a tooltip is shown by a pointer
|
|
227
|
+
* that leaves the focus elsewhere, and a toast is only reached by putting focus in it.
|
|
228
|
+
* A document listener here would dismiss a toast the reader was not looking at.
|
|
229
|
+
*/
|
|
230
|
+
this.#onKey = (event) => {
|
|
231
|
+
if (event.key === 'Escape') {
|
|
232
|
+
this.dismiss();
|
|
233
|
+
}
|
|
234
|
+
};
|
|
235
|
+
/**
|
|
236
|
+
* Runs the exit, announces it, and takes the toast off the page.
|
|
237
|
+
*
|
|
238
|
+
* Bound as a field so it can be handed to a listener and called as a method without
|
|
239
|
+
* either losing `this`.
|
|
240
|
+
*/
|
|
241
|
+
this.dismiss = () => {
|
|
242
|
+
void this.#exit();
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
static { this.styles = css `
|
|
246
|
+
:host {
|
|
247
|
+
display: flex;
|
|
248
|
+
align-items: flex-start;
|
|
249
|
+
gap: ${reference('--ui-space')};
|
|
250
|
+
box-sizing: border-box;
|
|
251
|
+
padding: ${reference('--ui-space')} calc(${reference('--ui-space')} * 1.5);
|
|
252
|
+
border: 1px solid ${reference('--ui-color-border')};
|
|
253
|
+
/* The edge, and the shorthand after the border above rather than a colour
|
|
254
|
+
beside it: the width and the style are this rule's as much as the hue is.
|
|
255
|
+
info reads the accent, which is the colour a page already answers with. */
|
|
256
|
+
border-inline-start: calc(${reference('--ui-space')} / 2) solid
|
|
257
|
+
${reference('--ui-color-accent')};
|
|
258
|
+
border-radius: ${reference('--ui-radius')};
|
|
259
|
+
background: ${reference('--ui-color-surface')};
|
|
260
|
+
color: ${reference('--ui-color-text')};
|
|
261
|
+
font-family: ${reference('--ui-font')};
|
|
262
|
+
/* Lifted, because it sits over the page rather than in it — and bounded as
|
|
263
|
+
well as lifted, for the reason src/card.ts gives: a shadow is one value in
|
|
264
|
+
both schemes and does almost nothing on a dark page, where the derived
|
|
265
|
+
boundary is what separates the surface from what is under it. */
|
|
266
|
+
box-shadow: ${reference('--ui-elevation-raised')};
|
|
267
|
+
/* The toaster takes no clicks so it does not steal a corner of the page. This
|
|
268
|
+
is the part that is not the corner. */
|
|
269
|
+
pointer-events: auto;
|
|
270
|
+
|
|
271
|
+
opacity: 1;
|
|
272
|
+
translate: 0 0;
|
|
273
|
+
transition:
|
|
274
|
+
opacity ${reference('--ui-duration-state')} ${reference('--ui-easing-enter')},
|
|
275
|
+
translate ${reference('--ui-duration-state')} ${reference('--ui-easing-enter')};
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
:host([variant='success']) {
|
|
279
|
+
border-inline-start-color: ${reference('--ui-color-success')};
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
:host([variant='warning']) {
|
|
283
|
+
border-inline-start-color: ${reference('--ui-color-warning')};
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
:host([variant='danger']) {
|
|
287
|
+
border-inline-start-color: ${reference('--ui-color-danger')};
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/* Where the entrance comes from. Without it there is nothing to transition out of:
|
|
291
|
+
a toast goes from not rendered to laid out in one frame, and a transition needs a
|
|
292
|
+
before-change style that an unrendered element does not have. */
|
|
293
|
+
@starting-style {
|
|
294
|
+
:host {
|
|
295
|
+
opacity: 0;
|
|
296
|
+
translate: 0 calc(${reference('--ui-space')} * 2);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
|
|
300
|
+
/* The exit, driven from a class rather than from the element leaving: the removal
|
|
301
|
+
is what this is waiting for, so an exit keyed on it would never run. */
|
|
302
|
+
:host(.closing) {
|
|
303
|
+
opacity: 0;
|
|
304
|
+
translate: 0 calc(${reference('--ui-space')} * 2);
|
|
305
|
+
transition-timing-function: ${reference('--ui-easing-exit')};
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
div {
|
|
309
|
+
/* The message takes the room the button does not, and may wrap inside it — a
|
|
310
|
+
flex item refuses to shrink below its content without this. */
|
|
311
|
+
flex: 1;
|
|
312
|
+
min-inline-size: 0;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
button {
|
|
316
|
+
flex: none;
|
|
317
|
+
display: grid;
|
|
318
|
+
place-items: center;
|
|
319
|
+
/* WCAG 2.2 2.5.8 asks 24 by 24, and an icon-only button is the shape that
|
|
320
|
+
lands under it: the glyph is drawn at 1.25em, which is 20 pixels at the
|
|
321
|
+
default text size. The platform floors nothing, so this does. */
|
|
322
|
+
min-inline-size: 24px;
|
|
323
|
+
min-block-size: 24px;
|
|
324
|
+
margin: 0;
|
|
325
|
+
padding: 0;
|
|
326
|
+
border: none;
|
|
327
|
+
border-radius: ${reference('--ui-radius')};
|
|
328
|
+
background: none;
|
|
329
|
+
/* Inherited so the glyph, sized in em, is the size of the text beside it. */
|
|
330
|
+
font: inherit;
|
|
331
|
+
color: ${reference('--ui-color-text-muted')};
|
|
332
|
+
cursor: pointer;
|
|
333
|
+
transition: background-color ${reference('--ui-duration-state')}
|
|
334
|
+
${reference('--ui-easing-state')};
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/* A hover and a focus ring, and no pressed step — which is where every component
|
|
338
|
+
here stops except ui-button. Pressing a button *is* the action, so its own
|
|
339
|
+
pressed colour is the feedback for the thing being done; dismissing a notice is
|
|
340
|
+
secondary, and a third colour for it would be a rule the suite cannot reach.
|
|
341
|
+
Measured: a scripted pointer cannot be driven onto a box in the top layer from
|
|
342
|
+
inside the frame the suite runs in, so an :active here would ship unmeasured. */
|
|
343
|
+
button:hover {
|
|
344
|
+
background: ${reference('--ui-color-hover')};
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/* A visible focus ring is not decoration: removing it is the single most common way
|
|
348
|
+
a component stops being usable by keyboard. */
|
|
349
|
+
button:focus-visible {
|
|
350
|
+
outline: 2px solid ${reference('--ui-color-focus')};
|
|
351
|
+
outline-offset: 2px;
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
/* One dimension, not two, and the mutation floor is what proved it: an svg carrying
|
|
355
|
+
a viewBox is a replaced element with an intrinsic ratio, so a square glyph given
|
|
356
|
+
a width takes the same height from the ratio. Writing both was the same fact
|
|
357
|
+
twice — and a fact written twice is a rule whose removal nothing can observe. */
|
|
358
|
+
svg {
|
|
359
|
+
inline-size: ${reference('--ui-icon-size')};
|
|
360
|
+
stroke-width: ${reference('--ui-icon-stroke')};
|
|
361
|
+
}
|
|
362
|
+
`; }
|
|
363
|
+
static { this.properties = {
|
|
364
|
+
variant: { type: String, reflect: true },
|
|
365
|
+
duration: { type: Number },
|
|
366
|
+
dismissLabel: { type: String, attribute: 'dismiss-label' },
|
|
367
|
+
}; }
|
|
368
|
+
/** The pending auto-dismissal; `0` when there is none, which is what `clearTimeout` reads. */
|
|
369
|
+
#timer;
|
|
370
|
+
/**
|
|
371
|
+
* Takes every listener off at once, for the reason `src/tooltip.ts` gives beside its
|
|
372
|
+
* own: half of these leak invisibly if they are removed by name, and one `abort()` is
|
|
373
|
+
* one thing to get right.
|
|
374
|
+
*/
|
|
375
|
+
#listeners;
|
|
376
|
+
/** Holds the clock while the toast is being read, which is the whole of WCAG 2.2.1 here. */
|
|
377
|
+
#hold;
|
|
378
|
+
/** Starts it again once the pointer and the focus have both left. */
|
|
379
|
+
#resume;
|
|
380
|
+
/**
|
|
381
|
+
* Dismisses on Escape.
|
|
382
|
+
*
|
|
383
|
+
* Bound to this element rather than to the document, which is the opposite of what
|
|
384
|
+
* `<ui-tooltip>` needed and for the opposite reason: a tooltip is shown by a pointer
|
|
385
|
+
* that leaves the focus elsewhere, and a toast is only reached by putting focus in it.
|
|
386
|
+
* A document listener here would dismiss a toast the reader was not looking at.
|
|
387
|
+
*/
|
|
388
|
+
#onKey;
|
|
389
|
+
connectedCallback() {
|
|
390
|
+
super.connectedCallback();
|
|
391
|
+
// Synchronously, and that is the point of doing it here as well as on update: a
|
|
392
|
+
// custom element upgrades with its attributes already read, so the toast is in the
|
|
393
|
+
// region its variant names in the same task it was inserted — nothing ever observes
|
|
394
|
+
// it in the other one, and no message is announced twice by being moved.
|
|
395
|
+
this.#route();
|
|
396
|
+
// A fresh one per connection: an aborted signal stays aborted, so a toast a
|
|
397
|
+
// framework moved in the tree would come back deaf.
|
|
398
|
+
this.#listeners = new AbortController();
|
|
399
|
+
const watched = { signal: this.#listeners.signal };
|
|
400
|
+
this.addEventListener('pointerenter', this.#hold, watched);
|
|
401
|
+
this.addEventListener('pointerleave', this.#resume, watched);
|
|
402
|
+
this.addEventListener('focusin', this.#hold, watched);
|
|
403
|
+
this.addEventListener('focusout', this.#resume, watched);
|
|
404
|
+
this.addEventListener('keydown', this.#onKey, watched);
|
|
405
|
+
this.#start();
|
|
406
|
+
}
|
|
407
|
+
disconnectedCallback() {
|
|
408
|
+
this.#stop();
|
|
409
|
+
this.#listeners.abort();
|
|
410
|
+
super.disconnectedCallback();
|
|
411
|
+
}
|
|
412
|
+
willUpdate() {
|
|
413
|
+
// Unconditionally rather than on a change to `variant`: routing is writing the
|
|
414
|
+
// value the variant already implies, so doing it every update and doing it only
|
|
415
|
+
// when the variant moved are the same write — and the guard would be a branch no
|
|
416
|
+
// input can tell apart from its absence.
|
|
417
|
+
this.#route();
|
|
418
|
+
}
|
|
419
|
+
render() {
|
|
420
|
+
return html `
|
|
421
|
+
<div part="message"><slot></slot></div>
|
|
422
|
+
<button
|
|
423
|
+
type="button"
|
|
424
|
+
part="dismiss"
|
|
425
|
+
aria-label=${this.dismissLabel}
|
|
426
|
+
@click=${this.dismiss}
|
|
427
|
+
>
|
|
428
|
+
<svg
|
|
429
|
+
viewBox="0 0 24 24"
|
|
430
|
+
fill="none"
|
|
431
|
+
stroke="currentColor"
|
|
432
|
+
stroke-linecap="round"
|
|
433
|
+
aria-hidden="true"
|
|
434
|
+
>
|
|
435
|
+
<path d="M18 6 6 18M6 6l12 12" />
|
|
436
|
+
</svg>
|
|
437
|
+
</button>
|
|
438
|
+
`;
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
441
|
+
* Puts the toast in the region its variant names.
|
|
442
|
+
*
|
|
443
|
+
* The `slot` attribute is the routing, which is what makes it observable: a host can
|
|
444
|
+
* read back which region a toast landed in without this component exporting a second
|
|
445
|
+
* name for it. The regions are `<ui-toaster>`'s, and a toast outside one simply carries
|
|
446
|
+
* an attribute that assigns it to nothing.
|
|
447
|
+
*/
|
|
448
|
+
#route() {
|
|
449
|
+
this.slot = this.variant === 'danger' ? 'assertive' : 'polite';
|
|
450
|
+
}
|
|
451
|
+
/** Starts the clock, unless this toast has none to start. */
|
|
452
|
+
#start() {
|
|
453
|
+
// An error is never taken away from the reader, and `0` is how a host asks for the
|
|
454
|
+
// same thing on any other variant.
|
|
455
|
+
if (this.variant === 'danger' || this.duration === 0) {
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
this.#stop();
|
|
459
|
+
this.#timer = window.setTimeout(this.dismiss, this.duration);
|
|
460
|
+
}
|
|
461
|
+
/** Stops it, whether or not one was running. */
|
|
462
|
+
#stop() {
|
|
463
|
+
window.clearTimeout(this.#timer);
|
|
464
|
+
this.#timer = 0;
|
|
465
|
+
}
|
|
466
|
+
/** Fades the toast out, tells whoever is listening, and then removes it. */
|
|
467
|
+
async #exit() {
|
|
468
|
+
// Dismissed twice — the button clicked while the clock was already up, say — is one
|
|
469
|
+
// dismissal. Without this the second pass fires a second `ui-dismiss` for a toast
|
|
470
|
+
// that has already left.
|
|
471
|
+
if (this.classList.contains(closing)) {
|
|
472
|
+
return;
|
|
473
|
+
}
|
|
474
|
+
this.#stop();
|
|
475
|
+
this.classList.add(closing);
|
|
476
|
+
// `finished` rejects when an animation is cancelled, so what this waits for is
|
|
477
|
+
// settlement rather than fulfilment. `getAnimations` flushes the pending style
|
|
478
|
+
// change before it answers, so the transition the line above started is in the list.
|
|
479
|
+
await Promise.allSettled(this.getAnimations().map((animation) => animation.finished));
|
|
480
|
+
// Before the removal, and that order is forced rather than preferred: a listener on
|
|
481
|
+
// the toaster or on anything above it hears a bubbling event only while the element
|
|
482
|
+
// is still in the tree.
|
|
483
|
+
this.dispatchEvent(new Event('ui-dismiss', { bubbles: true, composed: true }));
|
|
484
|
+
this.remove();
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
// Stryker disable next-line StringLiteral: the registration runs once, at import, inside
|
|
488
|
+
// the warm process Stryker switches mutants in — so by the time a mutant on this line is
|
|
489
|
+
// active the element is already defined under the original name, and no test can observe
|
|
490
|
+
// the change. Outside the runner's reach, not an equivalent mutant.
|
|
491
|
+
customElements.define('ui-toaster', UiToaster);
|
|
492
|
+
// Stryker disable next-line StringLiteral: as above.
|
|
493
|
+
customElements.define('ui-toast', UiToast);
|
|
494
|
+
//# sourceMappingURL=toast.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"toast.js","sourceRoot":"","sources":["../src/toast.ts"],"names":[],"mappings":"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"}
|
package/dist/tokens.d.ts
CHANGED
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
* it does break is code that **enumerates** the set, an exhaustive `Record<Token, string>`
|
|
32
32
|
* above all. The supported shape is the partial map, which is what a theme is anyway.
|
|
33
33
|
*/
|
|
34
|
-
export declare const tokens: readonly ["--ui-color-accent", "--ui-color-accent-contrast", "--ui-color-surface", "--ui-color-text", "--ui-color-focus", "--ui-color-danger", "--ui-color-scrim", "--ui-radius", "--ui-space", "--ui-font", "--ui-duration-100", "--ui-easing-state", "--ui-easing-enter", "--ui-easing-exit", "--ui-icon-size", "--ui-icon-stroke", "--ui-elevation-100"];
|
|
34
|
+
export declare const tokens: readonly ["--ui-color-accent", "--ui-color-accent-contrast", "--ui-color-surface", "--ui-color-text", "--ui-color-focus", "--ui-color-danger", "--ui-color-success", "--ui-color-warning", "--ui-color-scrim", "--ui-radius", "--ui-space", "--ui-font", "--ui-duration-100", "--ui-easing-state", "--ui-easing-enter", "--ui-easing-exit", "--ui-icon-size", "--ui-icon-stroke", "--ui-elevation-100"];
|
|
35
35
|
/** A CSS custom property this package defines and gives a default. */
|
|
36
36
|
export type Token = (typeof tokens)[number];
|
|
37
37
|
/**
|
package/dist/tokens.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,MAAM,
|
|
1
|
+
{"version":3,"file":"tokens.d.ts","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,MAAM,yYAsFT,CAAC;AAEX,sEAAsE;AACtE,MAAM,MAAM,KAAK,GAAG,CAAC,OAAO,MAAM,CAAC,CAAC,MAAM,CAAC,CAAC;AAE5C;;;;;;;;;GASG;AACH,eAAO,MAAM,aAAa,2MAwBhB,CAAC;AAEX,wEAAwE;AACxE,MAAM,MAAM,YAAY,GAAG,CAAC,OAAO,aAAa,CAAC,CAAC,MAAM,CAAC,CAAC;AAE1D;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CA2DpD,CAAC;AAqBF;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,eAAO,MAAM,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAwB3D,CAAC;AAEF;;;;;;;;;;;;;;;;;;GAkBG;AACH,eAAO,MAAM,UAAU,EAAE,QAAQ,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC,CAgB/D,CAAC;AAKF;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAsBxC"}
|
package/dist/tokens.js
CHANGED
|
@@ -38,6 +38,16 @@ export const tokens = [
|
|
|
38
38
|
'--ui-color-text',
|
|
39
39
|
'--ui-color-focus',
|
|
40
40
|
'--ui-color-danger',
|
|
41
|
+
// The other two outcomes, arriving with `ui-toast` — the component `ROADMAP.md` said
|
|
42
|
+
// would bring them. They complete a set `--ui-color-danger` has been half of since the
|
|
43
|
+
// first field: a form told you what went wrong and had no way to say that anything
|
|
44
|
+
// went right.
|
|
45
|
+
//
|
|
46
|
+
// Grounds rather than derivations, and for the reason `--ui-color-danger` is one: a
|
|
47
|
+
// hue cannot be mixed out of the grounds that exist. Both are values a host is
|
|
48
|
+
// expected to replace with their own brand's, which is what a ground is for.
|
|
49
|
+
'--ui-color-success',
|
|
50
|
+
'--ui-color-warning',
|
|
41
51
|
// The dim behind a modal, and a *ground* rather than a derivation even though every
|
|
42
52
|
// other neutral here is derived. A derived neutral mixes toward the text, which is
|
|
43
53
|
// what makes one formula right in both schemes — and it is exactly wrong for this
|
|
@@ -164,6 +174,18 @@ export const defaults = {
|
|
|
164
174
|
// because no axe rule does.
|
|
165
175
|
'--ui-color-focus': '#b45309',
|
|
166
176
|
'--ui-color-danger': '#b91c1c',
|
|
177
|
+
// Green-700 and amber-700, each the darkest step of its hue that still reads as that
|
|
178
|
+
// hue. Both clear **4.5:1** against the surface rather than the 3:1 a coloured edge
|
|
179
|
+
// would owe, because the floor a value has to clear is the strictest use it is put to
|
|
180
|
+
// and nothing stops a host using one as text — `--ui-color-danger` was chosen the same
|
|
181
|
+
// way and is text in `ui-field` today.
|
|
182
|
+
//
|
|
183
|
+
// The warning is the same amber as `--ui-color-focus`, and the two arrived at it
|
|
184
|
+
// independently: both are *the darkest amber that clears its floor in both schemes*,
|
|
185
|
+
// and that question has one answer. They stay separate names because they are separate
|
|
186
|
+
// knobs — a host who retunes the focus ring has said nothing about warnings.
|
|
187
|
+
'--ui-color-success': '#15803d',
|
|
188
|
+
'--ui-color-warning': '#b45309',
|
|
167
189
|
// Half black. Enough to push the page behind a modal out of the reading order for the
|
|
168
190
|
// eye as well as for the accessibility tree, and not so much that the context a modal
|
|
169
191
|
// is *about* stops being visible. The alpha is the whole point, so this is the one
|
|
@@ -295,6 +317,11 @@ export const darkScheme = {
|
|
|
295
317
|
// Red-700 is 2.74:1 on the dark surface — under the 4.5:1 floor for text, and error
|
|
296
318
|
// text is the one thing in this set that must never be hard to read. Red-400 is 6.41.
|
|
297
319
|
'--ui-color-danger': '#f87171',
|
|
320
|
+
// The same inversion, for the same reason: green-700 is 3.54:1 on the dark surface and
|
|
321
|
+
// amber-700 is 3.53, so both would clear a coloured edge and fail as text — which is
|
|
322
|
+
// the half of the pair a reader is most likely to need.
|
|
323
|
+
'--ui-color-success': '#4ade80',
|
|
324
|
+
'--ui-color-warning': '#fbbf24',
|
|
298
325
|
};
|
|
299
326
|
/** The category every duration name shares, which is what reduced motion collapses. */
|
|
300
327
|
const duration = '--ui-duration-';
|
package/dist/tokens.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tokens.js","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"tokens.js","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"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"}
|