@m3e/snackbar 1.0.0-rc.1 → 1.0.0-rc.2
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 +1 -2
- package/dist/custom-elements.json +2547 -0
- package/package.json +6 -6
- package/cem.config.mjs +0 -16
- package/demo/index.html +0 -49
- package/dist/src/Snackbar.d.ts +0 -62
- package/dist/src/Snackbar.d.ts.map +0 -1
- package/dist/src/SnackbarElement.d.ts +0 -77
- package/dist/src/SnackbarElement.d.ts.map +0 -1
- package/dist/src/index.d.ts +0 -3
- package/dist/src/index.d.ts.map +0 -1
- package/eslint.config.mjs +0 -13
- package/rollup.config.js +0 -32
- package/src/Snackbar.ts +0 -135
- package/src/SnackbarElement.ts +0 -318
- package/src/index.ts +0 -2
- package/tsconfig.json +0 -9
package/src/SnackbarElement.ts
DELETED
|
@@ -1,318 +0,0 @@
|
|
|
1
|
-
/* eslint-disable @typescript-eslint/no-unsafe-declaration-merging */
|
|
2
|
-
|
|
3
|
-
import { css, CSSResultGroup, html, LitElement, nothing, unsafeCSS } from "lit";
|
|
4
|
-
import { customElement, property } from "lit/decorators.js";
|
|
5
|
-
|
|
6
|
-
import { DesignToken, ResizeController, Role } from "@m3e/core";
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Presents short updates about application processes at the bottom of the screen.
|
|
10
|
-
* @tag m3e-snackbar
|
|
11
|
-
*
|
|
12
|
-
* @slot - Renders the content of the snackbar.
|
|
13
|
-
* @slot close-icon - Renders the icon of the button used to close the snackbar.
|
|
14
|
-
*
|
|
15
|
-
* @attr action - The label of the snackbar's action.
|
|
16
|
-
* @attr close-label - The accessible label given to the button used to dismiss the snackbar.
|
|
17
|
-
* @attr dismissible - Whether a button is presented that can be used to close the snackbar.
|
|
18
|
-
* @attr duration - The length of time, in milliseconds, to wait before automatically dismissing the snackbar.
|
|
19
|
-
*
|
|
20
|
-
* @fires toggle - Emitted when the opened state of the snackbar changes.
|
|
21
|
-
*
|
|
22
|
-
* @cssprop --m3e-snackbar-margin - Vertical offset from the bottom of the viewport.
|
|
23
|
-
* @cssprop --m3e-snackbar-container-shape - Border radius of the snackbar container.
|
|
24
|
-
* @cssprop --m3e-snackbar-container-color - Background color of the snackbar.
|
|
25
|
-
* @cssprop --m3e-snackbar-padding - Internal spacing of the snackbar container.
|
|
26
|
-
* @cssprop --m3e-snackbar-min-width - Minimum width of the snackbar.
|
|
27
|
-
* @cssprop --m3e-snackbar-max-width - Maximum width of the snackbar.
|
|
28
|
-
*/
|
|
29
|
-
@customElement("m3e-snackbar")
|
|
30
|
-
export class M3eSnackbarElement extends Role(LitElement, "status") {
|
|
31
|
-
/** The styles of the element. */
|
|
32
|
-
static override styles: CSSResultGroup = css`
|
|
33
|
-
:host {
|
|
34
|
-
position: fixed;
|
|
35
|
-
top: calc(100vh - var(--_snackbar-height, 0px) - var(--m3e-snackbar-margin, 1rem));
|
|
36
|
-
display: inline-flex;
|
|
37
|
-
align-items: center;
|
|
38
|
-
padding: unset;
|
|
39
|
-
margin: unset;
|
|
40
|
-
margin-inline: auto;
|
|
41
|
-
border: unset;
|
|
42
|
-
border-radius: var(--m3e-snackbar-container-shape, ${DesignToken.shape.corner.extraSmall});
|
|
43
|
-
background-color: var(--m3e-snackbar-container-color, ${DesignToken.color.inverseSurface});
|
|
44
|
-
padding: var(--m3e-snackbar-padding, 0.75rem 1rem 0.75rem 1rem);
|
|
45
|
-
min-width: var(--m3e-snackbar-min-width, 21.5rem);
|
|
46
|
-
max-width: var(--m3e-snackbar-max-width, 42rem);
|
|
47
|
-
visibility: hidden;
|
|
48
|
-
opacity: 0;
|
|
49
|
-
transform: scale(0.8);
|
|
50
|
-
transition: ${unsafeCSS(
|
|
51
|
-
`opacity ${DesignToken.motion.duration.short3} ${DesignToken.motion.easing.standard},
|
|
52
|
-
transform ${DesignToken.motion.duration.short3} ${DesignToken.motion.easing.standard},
|
|
53
|
-
overlay ${DesignToken.motion.duration.short3} ${DesignToken.motion.easing.standard} allow-discrete,
|
|
54
|
-
visibility ${DesignToken.motion.duration.short3} ${DesignToken.motion.easing.standard} allow-discrete`
|
|
55
|
-
)};
|
|
56
|
-
}
|
|
57
|
-
:host::backdrop {
|
|
58
|
-
background-color: transparent;
|
|
59
|
-
}
|
|
60
|
-
:host(:popover-open) {
|
|
61
|
-
visibility: visible;
|
|
62
|
-
opacity: 1;
|
|
63
|
-
transform: scale(1);
|
|
64
|
-
}
|
|
65
|
-
@starting-style {
|
|
66
|
-
:host(:popover-open) {
|
|
67
|
-
opacity: 0;
|
|
68
|
-
transform: scale(0.8);
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
:host([dismissible]) {
|
|
72
|
-
padding-inline-end: 0.5rem;
|
|
73
|
-
}
|
|
74
|
-
.contents {
|
|
75
|
-
display: contents;
|
|
76
|
-
font-size: var(--m3e-snackbar-supporting-text-font-size, ${DesignToken.typescale.standard.label.large.fontSize});
|
|
77
|
-
font-weight: var(
|
|
78
|
-
--m3e-snackbar-supporting-text-font-weight,
|
|
79
|
-
${DesignToken.typescale.standard.label.large.fontWeight}
|
|
80
|
-
);
|
|
81
|
-
line-height: var(
|
|
82
|
-
--m3e-snackbar-supporting-text-line-height,
|
|
83
|
-
${DesignToken.typescale.standard.label.large.lineHeight}
|
|
84
|
-
);
|
|
85
|
-
letter-spacing: var(
|
|
86
|
-
--m3e-snackbar-supporting-text-tracking,
|
|
87
|
-
${DesignToken.typescale.standard.label.large.tracking}
|
|
88
|
-
);
|
|
89
|
-
color: var(--m3e-snackbar-supporting-text-color, ${DesignToken.color.inverseOnSurface});
|
|
90
|
-
|
|
91
|
-
--m3e-text-button-label-text-color: var(--m3e-snackbar-action-text-color, ${DesignToken.color.inversePrimary});
|
|
92
|
-
--m3e-text-button-hover-label-text-color: var(
|
|
93
|
-
--m3e-snackbar-action-text-color,
|
|
94
|
-
${DesignToken.color.inversePrimary}
|
|
95
|
-
);
|
|
96
|
-
--m3e-text-button-hover-state-layer-color: var(
|
|
97
|
-
--m3e-snackbar-action-text-color,
|
|
98
|
-
${DesignToken.color.inversePrimary}
|
|
99
|
-
);
|
|
100
|
-
--m3e-text-button-focus-label-text-color: var(
|
|
101
|
-
--m3e-snackbar-action-text-color,
|
|
102
|
-
${DesignToken.color.inversePrimary}
|
|
103
|
-
);
|
|
104
|
-
--m3e-text-button-focus-state-layer-color: var(
|
|
105
|
-
--m3e-snackbar-action-text-color,
|
|
106
|
-
${DesignToken.color.inversePrimary}
|
|
107
|
-
);
|
|
108
|
-
--m3e-text-button-pressed-label-text-color: var(
|
|
109
|
-
--m3e-snackbar-action-text-color,
|
|
110
|
-
${DesignToken.color.inversePrimary}
|
|
111
|
-
);
|
|
112
|
-
--m3e-text-button-pressed-state-layer-color: var(
|
|
113
|
-
--m3e-snackbar-action-text-color,
|
|
114
|
-
${DesignToken.color.inversePrimary}
|
|
115
|
-
);
|
|
116
|
-
--m3e-standard-icon-button-icon-color: var(
|
|
117
|
-
--m3e-snackbar-close-icon-color,
|
|
118
|
-
${DesignToken.color.inverseOnSurface}
|
|
119
|
-
);
|
|
120
|
-
--m3e-standard-icon-button-hover-icon-color: var(
|
|
121
|
-
--m3e-snackbar-close-icon-color,
|
|
122
|
-
${DesignToken.color.inverseOnSurface}
|
|
123
|
-
);
|
|
124
|
-
--m3e-standard-icon-button-hover-state-layer-color: var(
|
|
125
|
-
--m3e-snackbar-close-icon-color,
|
|
126
|
-
${DesignToken.color.inverseOnSurface}
|
|
127
|
-
);
|
|
128
|
-
--m3e-standard-icon-button-focus-icon-color: var(
|
|
129
|
-
--m3e-snackbar-close-icon-color,
|
|
130
|
-
${DesignToken.color.inverseOnSurface}
|
|
131
|
-
);
|
|
132
|
-
--m3e-standard-icon-button-focus-state-layer-color: var(
|
|
133
|
-
--m3e-snackbar-close-icon-color,
|
|
134
|
-
${DesignToken.color.inverseOnSurface}
|
|
135
|
-
);
|
|
136
|
-
--m3e-standard-icon-button-pressed-icon-color: var(
|
|
137
|
-
--m3e-snackbar-close-icon-color,
|
|
138
|
-
${DesignToken.color.inverseOnSurface}
|
|
139
|
-
);
|
|
140
|
-
--m3e-standard-icon-button-pressed-state-layer-color: var(
|
|
141
|
-
--m3e-snackbar-close-icon-color,
|
|
142
|
-
${DesignToken.color.inverseOnSurface}
|
|
143
|
-
);
|
|
144
|
-
}
|
|
145
|
-
.supporting-text {
|
|
146
|
-
flex: 1 1 auto;
|
|
147
|
-
}
|
|
148
|
-
::slotted([slot="close-icon"]),
|
|
149
|
-
.close-icon {
|
|
150
|
-
width: 1em;
|
|
151
|
-
font-size: var(--m3e-icon-button-icon-size, 1.5rem) !important;
|
|
152
|
-
}
|
|
153
|
-
@media (forced-colors: active) {
|
|
154
|
-
:host {
|
|
155
|
-
background-color: Canvas;
|
|
156
|
-
color: CanvasText;
|
|
157
|
-
border-radius: ${DesignToken.shape.corner.small};
|
|
158
|
-
box-sizing: border-box;
|
|
159
|
-
border: 1px solid CanvasText;
|
|
160
|
-
}
|
|
161
|
-
}
|
|
162
|
-
`;
|
|
163
|
-
|
|
164
|
-
/** @private */ static __current: M3eSnackbarElement | null = null;
|
|
165
|
-
|
|
166
|
-
/** @private */ #timeoutId = -1;
|
|
167
|
-
/** @private */ #actionTaken = false;
|
|
168
|
-
/** @private */ readonly #beforeToggleHandler = (e: ToggleEvent) => this.#handleBeforeToggle(e);
|
|
169
|
-
|
|
170
|
-
constructor() {
|
|
171
|
-
super();
|
|
172
|
-
|
|
173
|
-
new ResizeController(this, {
|
|
174
|
-
callback: () => {
|
|
175
|
-
this.style.setProperty("--_snackbar-height", `${this.getBoundingClientRect().height}px`);
|
|
176
|
-
},
|
|
177
|
-
});
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
/** The currently open snackbar. */
|
|
181
|
-
static get current(): M3eSnackbarElement | null {
|
|
182
|
-
return M3eSnackbarElement.__current;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
/**
|
|
186
|
-
* The length of time, in milliseconds, to wait before automatically dismissing the snackbar.
|
|
187
|
-
* @default 3000
|
|
188
|
-
*/
|
|
189
|
-
@property({ type: Number }) duration = 3000;
|
|
190
|
-
|
|
191
|
-
/**
|
|
192
|
-
* The label of the snackbar's action.
|
|
193
|
-
* @default ""
|
|
194
|
-
*/
|
|
195
|
-
@property() action = "";
|
|
196
|
-
|
|
197
|
-
/**
|
|
198
|
-
* Whether a button is presented that can be used to close the snackbar.
|
|
199
|
-
* @default false
|
|
200
|
-
*/
|
|
201
|
-
@property({ type: Boolean, reflect: true }) dismissible = false;
|
|
202
|
-
|
|
203
|
-
/**
|
|
204
|
-
* The accessible label given to the button used to dismiss the snackbar.
|
|
205
|
-
* @default "Close"
|
|
206
|
-
*/
|
|
207
|
-
@property({ attribute: "close-label" }) closeLabel = "Close";
|
|
208
|
-
|
|
209
|
-
/** Whether the user clicked the action. */
|
|
210
|
-
get isActionTaken(): boolean {
|
|
211
|
-
return this.#actionTaken;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
/** @inheritdoc */
|
|
215
|
-
override connectedCallback(): void {
|
|
216
|
-
super.connectedCallback();
|
|
217
|
-
|
|
218
|
-
this.addEventListener("beforetoggle", this.#beforeToggleHandler);
|
|
219
|
-
this.setAttribute("popover", "manual");
|
|
220
|
-
this.ariaLive = "polite";
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
/** @inheritdoc */
|
|
224
|
-
override disconnectedCallback(): void {
|
|
225
|
-
super.disconnectedCallback();
|
|
226
|
-
|
|
227
|
-
this.removeEventListener("beforetoggle", this.#beforeToggleHandler);
|
|
228
|
-
}
|
|
229
|
-
|
|
230
|
-
/** @inheritdoc */
|
|
231
|
-
protected override render() {
|
|
232
|
-
return html`<div class="contents">
|
|
233
|
-
<span class="supporting-text"><slot></slot></span>
|
|
234
|
-
${this.#renderActionButton()} ${this.#renderCloseButton()}
|
|
235
|
-
</div>`;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
/** @private */
|
|
239
|
-
#renderActionButton(): unknown {
|
|
240
|
-
return !this.action ? nothing : html`<m3e-button @click="${this.#handleActionClick}">${this.action}</m3e-button>`;
|
|
241
|
-
}
|
|
242
|
-
|
|
243
|
-
/** @private */
|
|
244
|
-
#renderCloseButton(): unknown {
|
|
245
|
-
return !this.dismissible
|
|
246
|
-
? nothing
|
|
247
|
-
: html`<m3e-icon-button aria-label="${this.closeLabel}" @click="${this.hidePopover}">
|
|
248
|
-
<slot name="close-icon">
|
|
249
|
-
<svg class="close-icon" viewBox="0 -960 960 960" fill="currentColor">
|
|
250
|
-
<path
|
|
251
|
-
d="m256-200-56-56 224-224-224-224 56-56 224 224 224-224 56 56-224 224 224 224-56 56-224-224-224 224Z"
|
|
252
|
-
/>
|
|
253
|
-
</svg>
|
|
254
|
-
</slot>
|
|
255
|
-
</m3e-icon-button>`;
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
/** @private */
|
|
259
|
-
#handleActionClick(): void {
|
|
260
|
-
this.#actionTaken = true;
|
|
261
|
-
this.hidePopover();
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
/** @private */
|
|
265
|
-
#handleBeforeToggle(e: ToggleEvent): void {
|
|
266
|
-
if (e.newState == "open") {
|
|
267
|
-
M3eSnackbarElement.__current?.hidePopover();
|
|
268
|
-
M3eSnackbarElement.__current = this;
|
|
269
|
-
|
|
270
|
-
if (this.duration > 0) {
|
|
271
|
-
this.#timeoutId = setTimeout(() => this.hidePopover(), this.duration);
|
|
272
|
-
}
|
|
273
|
-
} else {
|
|
274
|
-
if (M3eSnackbarElement.__current === this) {
|
|
275
|
-
M3eSnackbarElement.__current = null;
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
clearTimeout(this.#timeoutId);
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
interface M3eSnackbarElementEventMap extends HTMLElementEventMap {
|
|
284
|
-
beforetoggle: ToggleEvent;
|
|
285
|
-
toggle: ToggleEvent;
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
export interface M3eSnackbarElement {
|
|
289
|
-
addEventListener<K extends keyof M3eSnackbarElementEventMap>(
|
|
290
|
-
type: K,
|
|
291
|
-
listener: (this: M3eSnackbarElement, ev: M3eSnackbarElementEventMap[K]) => void,
|
|
292
|
-
options?: boolean | AddEventListenerOptions
|
|
293
|
-
): void;
|
|
294
|
-
|
|
295
|
-
addEventListener(
|
|
296
|
-
type: string,
|
|
297
|
-
listener: EventListenerOrEventListenerObject,
|
|
298
|
-
options?: boolean | AddEventListenerOptions
|
|
299
|
-
): void;
|
|
300
|
-
|
|
301
|
-
removeEventListener<K extends keyof M3eSnackbarElementEventMap>(
|
|
302
|
-
type: K,
|
|
303
|
-
listener: (this: M3eSnackbarElement, ev: M3eSnackbarElementEventMap[K]) => void,
|
|
304
|
-
options?: boolean | EventListenerOptions
|
|
305
|
-
): void;
|
|
306
|
-
|
|
307
|
-
removeEventListener(
|
|
308
|
-
type: string,
|
|
309
|
-
listener: EventListenerOrEventListenerObject,
|
|
310
|
-
options?: boolean | EventListenerOptions
|
|
311
|
-
): void;
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
declare global {
|
|
315
|
-
interface HTMLElementTagNameMap {
|
|
316
|
-
"m3e-snackbar": M3eSnackbarElement;
|
|
317
|
-
}
|
|
318
|
-
}
|
package/src/index.ts
DELETED