@vollowx/seele 0.13.3 → 0.13.4
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 +5 -3
- package/package.json +2 -3
- package/src/all.js +33 -34
- package/src/base/button.js +4 -0
- package/src/base/checkbox.js +7 -1
- package/src/base/list.js +4 -4
- package/src/base/tabs.js +3 -5
- package/src/base/toggle-button.js +15 -7
- package/src/core/decorators.js +1 -1
- package/src/m3/button/common-button-styles.css.js +1 -1
- package/src/m3/button/common-button-toggle.js +4 -3
- package/src/m3/button/common-button.js +4 -3
- package/src/m3/button/icon-button-styles.css.js +1 -1
- package/src/m3/button/icon-button-toggle.js +1 -1
- package/src/m3/button/icon-button.js +1 -1
- package/src/m3/button/shared-button-styles.css.js +1 -1
- package/src/m3/button/shared-button-toggle-styles.css.js +1 -1
- package/src/m3/button-group/connected-button-group-styles.css.js +2 -0
- package/src/m3/button-group/connected-button-group.js +37 -0
- package/src/m3/button-group/standard-button-group-styles.css.js +1 -1
- package/src/m3/button-group/standard-button-group.js +10 -9
- package/src/m3/checkbox/checkbox.js +11 -1
- package/src/m3/dialog/dialog-spring.js +179 -0
- package/src/m3/dialog/dialog.js +5 -4
- package/src/m3/fab/fab-styles.css.js +1 -1
- package/src/m3/fab/fab.js +2 -1
- package/src/m3/system/motion.js +27 -0
package/README.md
CHANGED
|
@@ -51,20 +51,22 @@ Check out [Overview](./docs/00-Overview.md).
|
|
|
51
51
|
seele relies on the following modern web standards:
|
|
52
52
|
|
|
53
53
|
- [`ElementInternals`](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals), Baseline 2023
|
|
54
|
-
- [Constructable Stylesheets](https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet/CSSStyleSheet), Baseline 2024, C[^1] 90, F 126
|
|
55
54
|
- [`:dir()`](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Selectors/:dir), Baseline 2023, C 120, F 49
|
|
55
|
+
- [Constructable Stylesheets](https://developer.mozilla.org/en-US/docs/Web/API/CSSStyleSheet/CSSStyleSheet), Baseline 2024, C[^1] 90, F 126
|
|
56
56
|
- [`:state()`](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Selectors/:state), Baseline 2024, C 125, F 126
|
|
57
|
+
- [`ariaActiveDescendantElement`](https://developer.mozilla.org/en-US/docs/Web/API/ElementInternals/ariaActiveDescendantElement) and other similar ones, Baseline 2025, C 135, F 136
|
|
57
58
|
|
|
58
59
|
And all that result in:
|
|
59
60
|
|
|
60
|
-
- Chromium: >=
|
|
61
|
-
- Firefox: >=
|
|
61
|
+
- Chromium: >= 135
|
|
62
|
+
- Firefox: >= 136
|
|
62
63
|
|
|
63
64
|
It is 2026 now, you don't really need to worry about this. But in the future,
|
|
64
65
|
these following web features might be used and require higher browser versions:
|
|
65
66
|
|
|
66
67
|
- [anchor()](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Values/anchor), Baseline 2026, C 125, F 147, will remove the dependency `floating-dom`
|
|
67
68
|
- [`::view-*`](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Selectors/::view-transition), Baseline 2025, C 111, F 144, will optimize some animations for menu, dialog, etc
|
|
69
|
+
- [`CSSNumericValue`](https://developer.mozilla.org/en-US/docs/Web/API/CSSNumericValue), not Baseline, C 66, F Nightly, worked around currently
|
|
68
70
|
|
|
69
71
|
[^1]: C = Chromium, F = Firefox.
|
|
70
72
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vollowx/seele",
|
|
3
|
-
"version": "0.13.
|
|
3
|
+
"version": "0.13.4",
|
|
4
4
|
"description": "A extensible Web Components library, with Material Design 3 components pre-provided.",
|
|
5
5
|
"author": "vollowx",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -9,8 +9,7 @@
|
|
|
9
9
|
"module": "./src/all.js",
|
|
10
10
|
"exports": {
|
|
11
11
|
".": "./src/all.js",
|
|
12
|
-
"
|
|
13
|
-
"./m3/*": "./src/m3/*"
|
|
12
|
+
"./*.js": "./src/*.js"
|
|
14
13
|
},
|
|
15
14
|
"files": [
|
|
16
15
|
"src/**/*.js",
|
package/src/all.js
CHANGED
|
@@ -1,34 +1,33 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
export { Win98Button } from './win98/button/button.js';
|
|
1
|
+
import './m3/autocomplete/autocomplete.js';
|
|
2
|
+
import './m3/badge/badge.js';
|
|
3
|
+
import './m3/button/common-button.js';
|
|
4
|
+
import './m3/button/common-button-toggle.js';
|
|
5
|
+
import './m3/button/icon-button.js';
|
|
6
|
+
import './m3/button/icon-button-toggle.js';
|
|
7
|
+
import './m3/button-group/standard-button-group.js';
|
|
8
|
+
import './m3/button-group/connected-button-group.js';
|
|
9
|
+
import './m3/checkbox/checkbox.js';
|
|
10
|
+
import './m3/dialog/dialog.js';
|
|
11
|
+
import './m3/divider/divider.js';
|
|
12
|
+
import './m3/fab/fab.js';
|
|
13
|
+
import './m3/focus-ring/focus-ring.js';
|
|
14
|
+
import './m3/item/item.js';
|
|
15
|
+
import './m3/list/list.js';
|
|
16
|
+
import './m3/list/list-item.js';
|
|
17
|
+
import './m3/loading-indicator/loading-indicator.js';
|
|
18
|
+
import './m3/menu/menu.js';
|
|
19
|
+
import './m3/menu/menu-item.js';
|
|
20
|
+
import './m3/ripple/ripple.js';
|
|
21
|
+
import './m3/select/filled-select.js';
|
|
22
|
+
import './m3/select/outlined-select.js';
|
|
23
|
+
import './m3/select/option.js';
|
|
24
|
+
import './m3/slider/slider.js';
|
|
25
|
+
import './m3/switch/switch.js';
|
|
26
|
+
import './m3/tab/tabs.js';
|
|
27
|
+
import './m3/tab/tab.js';
|
|
28
|
+
import './m3/tab/tab-panel.js';
|
|
29
|
+
import './m3/text-field/filled-text-field.js';
|
|
30
|
+
import './m3/text-field/outlined-text-field.js';
|
|
31
|
+
import './m3/toolbar/toolbar.js';
|
|
32
|
+
import './m3/tooltip/tooltip.js';
|
|
33
|
+
import './win98/button/button.js';
|
package/src/base/button.js
CHANGED
|
@@ -34,6 +34,10 @@ export class Button extends Base {
|
|
|
34
34
|
this.addEventListener('keydown', this.#handleKeyDown);
|
|
35
35
|
this.addEventListener('keyup', this.#handleKeyUp);
|
|
36
36
|
this.addEventListener('click', this.#handleClick);
|
|
37
|
+
// This is set to prevent a first-paint-time transition for styles like
|
|
38
|
+
// `border-radius` on `:host`. Also in `ToggleButton`.
|
|
39
|
+
this.setAttribute('notransition', '');
|
|
40
|
+
requestAnimationFrame(()=>this.removeAttribute('notransition'));
|
|
37
41
|
}
|
|
38
42
|
disconnectedCallback() {
|
|
39
43
|
super.disconnectedCallback();
|
package/src/base/checkbox.js
CHANGED
|
@@ -45,10 +45,10 @@ export class Checkbox extends Base {
|
|
|
45
45
|
this.addEventListener('keyup', this.#handleKeyUp);
|
|
46
46
|
}
|
|
47
47
|
disconnectedCallback() {
|
|
48
|
-
super.disconnectedCallback();
|
|
49
48
|
this.removeEventListener('click', this.#handleClick);
|
|
50
49
|
this.removeEventListener('keydown', this.#handleKeyDown);
|
|
51
50
|
this.removeEventListener('keyup', this.#handleKeyUp);
|
|
51
|
+
super.disconnectedCallback();
|
|
52
52
|
}
|
|
53
53
|
updated(changed) {
|
|
54
54
|
if (changed.has('checked') || changed.has('disabled') || changed.has('indeterminate') || changed.has('required')) {
|
|
@@ -94,6 +94,12 @@ export class Checkbox extends Base {
|
|
|
94
94
|
detail: this.checked
|
|
95
95
|
}));
|
|
96
96
|
}
|
|
97
|
+
formResetCallback() {
|
|
98
|
+
this.checked = this.hasAttribute('checked');
|
|
99
|
+
}
|
|
100
|
+
formStateRestoreCallback(state, _reason) {
|
|
101
|
+
this.checked = state === 'on';
|
|
102
|
+
}
|
|
97
103
|
}
|
|
98
104
|
_ts_decorate([
|
|
99
105
|
property({
|
package/src/base/list.js
CHANGED
|
@@ -45,11 +45,11 @@ const Base = InternalsAttached(LitElement);
|
|
|
45
45
|
},
|
|
46
46
|
wrapNavigation: ()=>false
|
|
47
47
|
});
|
|
48
|
+
this[internals].role = 'listbox';
|
|
49
|
+
if (!this.hasAttribute('tabindex')) {
|
|
50
|
+
this.setAttribute('tabindex', '0');
|
|
51
|
+
}
|
|
48
52
|
if (!isServer) {
|
|
49
|
-
this[internals].role = 'listbox';
|
|
50
|
-
if (!this.hasAttribute('tabindex')) {
|
|
51
|
-
this.setAttribute('tabindex', '0');
|
|
52
|
-
}
|
|
53
53
|
this.addEventListener('keydown', (e)=>this.#handleKeyDown(e));
|
|
54
54
|
this.addEventListener('focusin', ()=>this.#handleFocusIn());
|
|
55
55
|
this.addEventListener('focusout', ()=>this.#handleFocusOut());
|
package/src/base/tabs.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { _ as _ts_decorate } from "@swc/helpers/_/_ts_decorate";
|
|
2
|
-
import { LitElement, html
|
|
2
|
+
import { LitElement, html } from 'lit';
|
|
3
3
|
import { property, queryAssignedElements } from 'lit/decorators.js';
|
|
4
4
|
import { internals } from './mixins/internals-attached.js';
|
|
5
5
|
/**
|
|
@@ -16,10 +16,8 @@ import { internals } from './mixins/internals-attached.js';
|
|
|
16
16
|
}
|
|
17
17
|
connectedCallback() {
|
|
18
18
|
super.connectedCallback();
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
this.addEventListener('click', this.#handleClick.bind(this));
|
|
22
|
-
}
|
|
19
|
+
this.addEventListener('keydown', this.#handleKeyDown.bind(this));
|
|
20
|
+
this.addEventListener('click', this.#handleClick.bind(this));
|
|
23
21
|
}
|
|
24
22
|
updated(changed) {
|
|
25
23
|
if (changed.has('selected') && this.selected) {
|
|
@@ -17,18 +17,18 @@ export class ToggleButton extends Base {
|
|
|
17
17
|
}
|
|
18
18
|
constructor(){
|
|
19
19
|
super(), this.checked = false, /**
|
|
20
|
-
*
|
|
20
|
+
* --> Drag-and-drop to the other side
|
|
21
21
|
*
|
|
22
|
-
*
|
|
22
|
+
* `checked` is supposed to be changed once
|
|
23
23
|
*
|
|
24
24
|
* 1. `pointerdown`: _ignoreClick = false
|
|
25
25
|
* 2. `pointermove`: _ignoreClick = true
|
|
26
26
|
* 3. `pointerup`: `checked` changed
|
|
27
27
|
* 4. `click`: ignored, _ignoreClick = false
|
|
28
28
|
*
|
|
29
|
-
*
|
|
29
|
+
* --> Drag-and-drop to the other side, then click
|
|
30
30
|
*
|
|
31
|
-
*
|
|
31
|
+
* `checked` is supposed to be changed twice
|
|
32
32
|
*
|
|
33
33
|
* 1. `pointerdown`: _ignoreClick = false
|
|
34
34
|
* 2. `pointermove`: _ignoreClick = true
|
|
@@ -36,9 +36,9 @@ export class ToggleButton extends Base {
|
|
|
36
36
|
* 4. `click`: ignored, _ignoreClick = false
|
|
37
37
|
* 5. `click`: `checked` changed(2)
|
|
38
38
|
*
|
|
39
|
-
*
|
|
39
|
+
* --> Drag-and-drop to the other side, then click the label
|
|
40
40
|
*
|
|
41
|
-
*
|
|
41
|
+
* `checked` is supposed to be changed twice
|
|
42
42
|
*
|
|
43
43
|
* 1. `pointerdown`: _ignoreClick = false
|
|
44
44
|
* 2. `pointermove`: _ignoreClick = true
|
|
@@ -79,15 +79,17 @@ export class ToggleButton extends Base {
|
|
|
79
79
|
this.labels.forEach((label)=>{
|
|
80
80
|
label.addEventListener('click', this.#handleLabelClick);
|
|
81
81
|
});
|
|
82
|
+
this.setAttribute('notransition', '');
|
|
83
|
+
requestAnimationFrame(()=>this.removeAttribute('notransition'));
|
|
82
84
|
}
|
|
83
85
|
disconnectedCallback() {
|
|
84
|
-
super.disconnectedCallback();
|
|
85
86
|
this.removeEventListener('click', this.#handleClick);
|
|
86
87
|
this.removeEventListener('keydown', this.#handleKeyDown);
|
|
87
88
|
this.removeEventListener('keyup', this.#handleKeyUp);
|
|
88
89
|
this.labels.forEach((label)=>{
|
|
89
90
|
label.removeEventListener('click', this.#handleLabelClick);
|
|
90
91
|
});
|
|
92
|
+
super.disconnectedCallback();
|
|
91
93
|
}
|
|
92
94
|
updated(changed) {
|
|
93
95
|
if (changed.has('checked') || changed.has('disabled')) {
|
|
@@ -116,6 +118,12 @@ export class ToggleButton extends Base {
|
|
|
116
118
|
detail: this.checked
|
|
117
119
|
}));
|
|
118
120
|
}
|
|
121
|
+
formResetCallback() {
|
|
122
|
+
this.checked = this.hasAttribute('checked');
|
|
123
|
+
}
|
|
124
|
+
formStateRestoreCallback(state, _reason) {
|
|
125
|
+
this.checked = state === 'on';
|
|
126
|
+
}
|
|
119
127
|
}
|
|
120
128
|
_ts_decorate([
|
|
121
129
|
property({
|
package/src/core/decorators.js
CHANGED
|
@@ -2,7 +2,7 @@ import { isServer } from 'lit';
|
|
|
2
2
|
import { customElement } from 'lit/decorators.js';
|
|
3
3
|
const wrappedCustomElement = (tagName, allowSSR = true)=>{
|
|
4
4
|
if (isServer && !allowSSR) {
|
|
5
|
-
console.log(`[
|
|
5
|
+
console.log(`[seele]: <${tagName}> will not be rendered server-side.`);
|
|
6
6
|
return (cls)=>cls;
|
|
7
7
|
} else {
|
|
8
8
|
return customElement(tagName);
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { css } from 'lit';
|
|
2
|
-
export const commonButtonStyles = css`@layer common-button{:host{--_padding:16px;--md-focus-ring-shape:calc(var(--_h) / 2);background-color:color-mix(in srgb, var(--_background-color) var(--_background-opacity,100%), transparent);
|
|
2
|
+
export const commonButtonStyles = css`@layer common-button{:host{--_padding:16px;--md-focus-ring-shape:calc(var(--_h) / 2);background-color:color-mix(in srgb, var(--_background-color) var(--_background-opacity,100%), transparent);color:color-mix(in srgb, var(--_text-color) var(--_text-opacity,100%), transparent);font:var(--md-sys-typography-label-large);min-width:64px;padding-inline:var(--_padding);transition:box-shadow var(--md-sys-motion-effects-default-duration) var(--md-sys-motion-effects-default), border-radius var(--md-sys-motion-spatial-fast-duration) var(--md-sys-motion-spatial-fast);gap:8px}:host([size=xs]){--_padding:12px;gap:4px}:host([size=m]){--_padding:24px;font:var(--md-sys-typography-title-medium);gap:8px}:host([size=l]){--_padding:48px;font:var(--md-sys-typography-headline-small);gap:12px}:host([size=xl]){--_padding:64px;font:var(--md-sys-typography-headline-medium);gap:16px}:host([trailing-icon]){flex-direction:row-reverse}:host([variant=outlined]){padding-inline:calc(var(--_padding) - 1px)}:host([variant=text]){padding-inline:calc(var(--_padding) / 4 * 3)}::slotted([slot=icon]),::slotted([slot=icon-checked]){fill:currentColor;block-size:1em;font-size:var(--_icon-size);inline-size:1em}}@layer override{:host([variant=elevated]){--_background-color:var(--md-sys-color-surface-container-low);--_text-color:var(--_color);box-shadow:var(--md-sys-elevation-shadow-1)}@media (hover:hover) and (pointer:fine){:host([variant=filled]:hover:not(:active)),:host([variant=tonal]:hover:not(:active)){box-shadow:var(--md-sys-elevation-shadow-1)}:host([variant=elevated]:hover:not(:active)){box-shadow:var(--md-sys-elevation-shadow-2)}}}`;
|
|
@@ -22,7 +22,7 @@ export class M3ButtonToggle extends ToggleButton {
|
|
|
22
22
|
return html`<md-focus-ring></md-focus-ring><md-ripple></md-ripple><span part="target"></span><slot part="icon unchecked" name="icon" aria-hidden="true"></slot><slot part="icon checked" name="icon-checked" aria-hidden="true"></slot><slot part="label unchecked"></slot><slot part="label checked" name="checked"></slot>`;
|
|
23
23
|
}
|
|
24
24
|
constructor(...args){
|
|
25
|
-
super(...args), this.size = '
|
|
25
|
+
super(...args), this.size = 's', this.square = false, this.color = 'primary', this.variant = 'filled', /**
|
|
26
26
|
* Whether to show the icon at the end of the button.
|
|
27
27
|
*/ this.trailingIcon = false;
|
|
28
28
|
}
|
|
@@ -34,9 +34,10 @@ _ts_decorate([
|
|
|
34
34
|
], M3ButtonToggle.prototype, "size", void 0);
|
|
35
35
|
_ts_decorate([
|
|
36
36
|
property({
|
|
37
|
-
reflect: true
|
|
37
|
+
reflect: true,
|
|
38
|
+
type: Boolean
|
|
38
39
|
})
|
|
39
|
-
], M3ButtonToggle.prototype, "
|
|
40
|
+
], M3ButtonToggle.prototype, "square", void 0);
|
|
40
41
|
_ts_decorate([
|
|
41
42
|
property({
|
|
42
43
|
reflect: true
|
|
@@ -20,7 +20,7 @@ export class M3Button extends Button {
|
|
|
20
20
|
return html`<md-focus-ring></md-focus-ring><md-ripple></md-ripple><span part="target"></span><slot part="icon" name="icon" aria-hidden="true"></slot><slot part="label"></slot>`;
|
|
21
21
|
}
|
|
22
22
|
constructor(...args){
|
|
23
|
-
super(...args), this.size = '
|
|
23
|
+
super(...args), this.size = 's', this.color = 'primary', this.variant = 'filled', /**
|
|
24
24
|
* Whether to show the icon at the end of the button.
|
|
25
25
|
*/ this.trailingIcon = false;
|
|
26
26
|
}
|
|
@@ -32,9 +32,10 @@ _ts_decorate([
|
|
|
32
32
|
], M3Button.prototype, "size", void 0);
|
|
33
33
|
_ts_decorate([
|
|
34
34
|
property({
|
|
35
|
-
reflect: true
|
|
35
|
+
reflect: true,
|
|
36
|
+
type: Boolean
|
|
36
37
|
})
|
|
37
|
-
], M3Button.prototype, "
|
|
38
|
+
], M3Button.prototype, "square", void 0);
|
|
38
39
|
_ts_decorate([
|
|
39
40
|
property({
|
|
40
41
|
reflect: true
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { css } from 'lit';
|
|
2
|
-
export const iconButtonStyles = css`@layer icon-button{:host{--_wn:32px;--_ww:52px;background-color:color-mix(in srgb, var(--_background-color) var(--_background-opacity,100%), transparent);
|
|
2
|
+
export const iconButtonStyles = css`@layer icon-button{:host{--_wn:32px;--_ww:52px;background-color:color-mix(in srgb, var(--_background-color) var(--_background-opacity,100%), transparent);color:color-mix(in srgb, var(--_text-color) var(--_text-opacity,100%), transparent);transition:border-radius var(--md-sys-motion-spatial-fast-duration) var(--md-sys-motion-spatial-fast);width:var(--_h)}:host([size=xs]){--_wn:28px;--_ww:40px}:host([size=m]){--_wn:48px;--_ww:72px}:host([size=l]){--_wn:64px;--_ww:128px}:host([size=xl]){--_wn:104px;--_ww:184px}:host([width=narrow]){width:var(--_wn)}:host([width=wide]){width:var(--_ww)}::slotted(*){fill:currentColor;block-size:1em;font-size:var(--_icon-size);inline-size:1em}}@layer override{:host([size=small]){--_icon-size:24px}:host([variant=text]){--_text-color:var(--md-sys-color-on-surface-variant)}:host([variant=text]:state(checked)){--_text-color:var(--_color)}}`;
|
|
@@ -22,7 +22,7 @@ export class M3IconButtonToggle extends ToggleButton {
|
|
|
22
22
|
return html`<md-focus-ring></md-focus-ring><md-ripple enterbehavior="always"></md-ripple><span part="target"></span><slot part="icon unchecked"></slot><slot part="icon checked" name="checked"></slot>`;
|
|
23
23
|
}
|
|
24
24
|
constructor(...args){
|
|
25
|
-
super(...args), this.size = '
|
|
25
|
+
super(...args), this.size = 's', this.color = 'primary', this.variant = 'text', this.width = 'standard';
|
|
26
26
|
}
|
|
27
27
|
}
|
|
28
28
|
_ts_decorate([
|
|
@@ -20,7 +20,7 @@ export class M3IconButton extends Button {
|
|
|
20
20
|
return html`<md-focus-ring></md-focus-ring><md-ripple></md-ripple><span part="target"></span><slot part="icon"></slot>`;
|
|
21
21
|
}
|
|
22
22
|
constructor(...args){
|
|
23
|
-
super(...args), this.size = '
|
|
23
|
+
super(...args), this.size = 's', this.color = 'primary', this.variant = 'text', this.width = 'standard';
|
|
24
24
|
}
|
|
25
25
|
}
|
|
26
26
|
_ts_decorate([
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { css } from 'lit';
|
|
2
|
-
export const sharedButtonStyles = css`@layer common-button,icon-button;@layer shared{:host{--_on-color:var(--md-sys-color-on-primary);--_color:var(--md-sys-color-primary);--_h:40px;--_icon-size:20px;--
|
|
2
|
+
export const sharedButtonStyles = css`@layer common-button,icon-button;@layer shared{:host{--_on-color:var(--md-sys-color-on-primary);--_color:var(--md-sys-color-primary);--_h:40px;--_icon-size:20px;--_rs:12px;--_rp:8px;--_text-color:var(--_on-color);--_background-color:var(--_color);box-sizing:border-box;cursor:pointer;height:var(--_h);-webkit-tap-highlight-color:transparent;-webkit-user-select:none;user-select:none;vertical-align:top;border-start-start-radius:var(--_inner-left-radius,calc(var(--_h) / 2));border-start-end-radius:var(--_inner-right-radius,calc(var(--_h) / 2));border-end-end-radius:var(--_inner-right-radius,calc(var(--_h) / 2));border-end-start-radius:var(--_inner-left-radius,calc(var(--_h) / 2));outline:0;flex-shrink:0;justify-content:center;align-items:center;display:inline-flex;position:relative}:host([notransition]){transition:none!important}md-ripple,md-focus-ring{position:absolute}:host([size=xs]){--_h:32px}:host([size=m]){--_h:56px;--_icon-size:24px;--_rs:16px;--_rp:12px}:host([size=l]){--_h:96px;--_icon-size:32px;--_rs:28px;--_rp:16px}:host([size=xl]){--_h:136px;--_icon-size:40px;--_rs:28px;--_rp:16px}:host([color=secondary]){--_on-color:var(--md-sys-color-on-secondary);--_color:var(--md-sys-color-secondary)}:host([color=tertiary]){--_on-color:var(--md-sys-color-on-tertiary);--_color:var(--md-sys-color-tertiary)}:host([variant=tonal]){--_background-color:var(--md-sys-color-secondary-container);--_text-color:var(--md-sys-color-on-secondary-container)}:host([variant=outlined]){--_background-color:transparent;--_text-color:var(--md-sys-color-on-surface-variant);--md-focus-ring-offset:3px;border-color:color-mix(in srgb, var(--md-sys-color-outline-variant) 100%, transparent);border-style:solid;border-width:1px}:host([variant=text]){--_text-color:var(--_color);--_background-color:transparent!important}:host([square]){--md-focus-ring-shape:var(--_rs);border-radius:var(--_rs)}}@layer shared-toggle,override;@layer active{:host(:active){--md-focus-ring-shape:var(--_rp);border-radius:var(--_rp)}}@layer disabled{:host([variant=outlined]:disabled){--_background-color:var(--md-sys-color-outline)}:host(:disabled),:host([variant=outlined]:state(checked):disabled){--_background-color:var(--md-sys-color-on-surface);--_background-opacity:10%;--_text-color:var(--md-sys-color-on-surface);--_text-opacity:38%;border-color:color-mix(in srgb, var(--md-sys-color-on-surface) 10%, transparent);box-shadow:none;pointer-events:none}}`;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { css } from 'lit';
|
|
2
|
-
export const sharedButtonToggleStyles = css`@layer shared-toggle{:host{transition:border-radius var(--md-sys-motion-spatial-fast-duration) var(--md-sys-motion-spatial-fast), box-shadow var(--md-sys-motion-effects-default-duration) var(--md-sys-motion-effects-default), background-color var(--md-sys-motion-effects-fast-duration) var(--md-sys-motion-effects-fast), color var(--md-sys-motion-effects-fast-duration) var(--md-sys-motion-effects-fast)}:host(:state(checked)){--md-focus-ring-shape:var(--
|
|
2
|
+
export const sharedButtonToggleStyles = css`@layer shared-toggle{:host{transition:border-radius var(--md-sys-motion-spatial-fast-duration) var(--md-sys-motion-spatial-fast), box-shadow var(--md-sys-motion-effects-default-duration) var(--md-sys-motion-effects-default), background-color var(--md-sys-motion-effects-fast-duration) var(--md-sys-motion-effects-fast), color var(--md-sys-motion-effects-fast-duration) var(--md-sys-motion-effects-fast)}:host(:state(checked)){--md-focus-ring-shape:var(--_rs);border-radius:var(--_rs)}:host(:state(checked)) [part~=unchecked],:host(:not(:state(checked))) [part~=checked]{display:none}:host([variant=filled]:not(:state(checked))){--_background-color:var(--md-sys-color-surface-container);--_text-color:var(--md-sys-color-on-surface-variant)}:host([variant=tonal]:not(:state(checked))){--_background-color:var(--md-sys-color-surface-container-highest);--_text-color:var(--md-sys-color-on-surface-variant)}:host([variant=outlined]:state(checked)){--_background-color:var(--md-sys-color-inverse-surface);--_text-color:var(--md-sys-color-inverse-on-surface);border-width:0}}`;
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { css } from 'lit';
|
|
2
|
+
export const connectedButtonGroupStyles = css`:host{gap:2px;display:inline-flex}::slotted(*){flex:1}::slotted(:not(:first-child)[size=xs]){--_inner-left-radius:4px}::slotted(:not(:last-child)[size=xs]){--_inner-right-radius:4px}::slotted(:not(:first-child)){--_inner-left-radius:8px}::slotted(:not(:last-child)){--_inner-right-radius:8px}::slotted(:not(:first-child)[size=l]){--_inner-left-radius:16px}::slotted(:not(:last-child)[size=l]){--_inner-right-radius:16px}::slotted(:not(:first-child)[size=xl]){--_inner-left-radius:20px}::slotted(:not(:last-child)[size=xl]){--_inner-right-radius:20px}::slotted(:first-child:state(checked):not(:active,[square])){border-start-start-radius:calc(var(--_h) / 2);border-end-start-radius:calc(var(--_h) / 2)}::slotted(:last-child:state(checked):not(:active,[square])){border-start-end-radius:calc(var(--_h) / 2);border-end-end-radius:calc(var(--_h) / 2)}`;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { _ as _ts_decorate } from "@swc/helpers/_/_ts_decorate";
|
|
2
|
+
import { LitElement, html } from 'lit';
|
|
3
|
+
import { property, queryAssignedElements } from 'lit/decorators.js';
|
|
4
|
+
import { customElement } from '../../core/decorators.js';
|
|
5
|
+
import { connectedButtonGroupStyles } from './connected-button-group-styles.css.js';
|
|
6
|
+
export class M3StandardButtonGroup extends LitElement {
|
|
7
|
+
static{
|
|
8
|
+
this.styles = [
|
|
9
|
+
connectedButtonGroupStyles
|
|
10
|
+
];
|
|
11
|
+
}
|
|
12
|
+
render() {
|
|
13
|
+
return html`<slot @change="${this.#handleChange}"></slot>`;
|
|
14
|
+
}
|
|
15
|
+
#handleChange;
|
|
16
|
+
constructor(...args){
|
|
17
|
+
super(...args), this.multiple = false, this.#handleChange = (e)=>{
|
|
18
|
+
console.log('Boom!', e);
|
|
19
|
+
this.$buttons.forEach((btn, _)=>{
|
|
20
|
+
if (btn !== e.target && !this.multiple) // NOTE: there will not be an event dispatched and user should listen on
|
|
21
|
+
// the button group directly.
|
|
22
|
+
btn.checked = false;
|
|
23
|
+
});
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
_ts_decorate([
|
|
28
|
+
property({
|
|
29
|
+
type: Boolean
|
|
30
|
+
})
|
|
31
|
+
], M3StandardButtonGroup.prototype, "multiple", void 0);
|
|
32
|
+
_ts_decorate([
|
|
33
|
+
queryAssignedElements()
|
|
34
|
+
], M3StandardButtonGroup.prototype, "$buttons", void 0);
|
|
35
|
+
M3StandardButtonGroup = _ts_decorate([
|
|
36
|
+
customElement('md-connected-button-group', false)
|
|
37
|
+
], M3StandardButtonGroup);
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { css } from 'lit';
|
|
2
|
-
export const standardButtonGroupStyles = css`:host{gap:8px;display:inline-flex}`;
|
|
2
|
+
export const standardButtonGroupStyles = css`:host{gap:8px;display:inline-flex}:host([size=s]){gap:12px}:host([size=ss]){gap:18px}`;
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { _ as _ts_decorate } from "@swc/helpers/_/_ts_decorate";
|
|
2
2
|
import { LitElement, html } from 'lit';
|
|
3
|
+
import { property, queryAssignedElements } from 'lit/decorators.js';
|
|
3
4
|
import { customElement } from '../../core/decorators.js';
|
|
4
|
-
import {
|
|
5
|
+
import { getSpring } from '../system/motion.js';
|
|
5
6
|
import { standardButtonGroupStyles } from './standard-button-group-styles.css.js';
|
|
6
7
|
const EXPAND_FACTOR = 1.15;
|
|
7
8
|
const shapeAnimation = Symbol('shapeAnimation');
|
|
@@ -74,11 +75,7 @@ export class M3StandardButtonGroup extends LitElement {
|
|
|
74
75
|
else targetWidth = this.#baseWidths[i] - expansionDelta / 2;
|
|
75
76
|
}
|
|
76
77
|
}
|
|
77
|
-
const
|
|
78
|
-
const rawDuration = styles.getPropertyValue('--md-sys-motion-spatial-fast-duration');
|
|
79
|
-
const rawEasing = styles.getPropertyValue('--md-sys-motion-spatial-fast');
|
|
80
|
-
const duration = parseInt(rawDuration.substring(0, rawDuration.length - 2)) || 0;
|
|
81
|
-
const easing = rawEasing || 'ease';
|
|
78
|
+
const spring = getSpring(this, 'spatial', 'fast');
|
|
82
79
|
if (btn[shapeAnimation]) btn[shapeAnimation].cancel();
|
|
83
80
|
btn[shapeAnimation] = btn.animate([
|
|
84
81
|
{
|
|
@@ -88,8 +85,7 @@ export class M3StandardButtonGroup extends LitElement {
|
|
|
88
85
|
width: `${targetWidth}px`
|
|
89
86
|
}
|
|
90
87
|
], {
|
|
91
|
-
|
|
92
|
-
easing,
|
|
88
|
+
...spring,
|
|
93
89
|
fill: 'forwards'
|
|
94
90
|
});
|
|
95
91
|
btn[shapeAnimation].onfinish = ()=>{
|
|
@@ -101,7 +97,7 @@ export class M3StandardButtonGroup extends LitElement {
|
|
|
101
97
|
});
|
|
102
98
|
}
|
|
103
99
|
constructor(...args){
|
|
104
|
-
super(...args), this.#activeIndex = -1, this.#baseWidths = [], this.#handleSlotChange = ()=>{
|
|
100
|
+
super(...args), this.size = '', this.#activeIndex = -1, this.#baseWidths = [], this.#handleSlotChange = ()=>{
|
|
105
101
|
this.#resizeObserver.disconnect();
|
|
106
102
|
this.$buttons.forEach((btn, i)=>{
|
|
107
103
|
this.#baseWidths[i] = btn.getBoundingClientRect().width;
|
|
@@ -122,6 +118,11 @@ export class M3StandardButtonGroup extends LitElement {
|
|
|
122
118
|
};
|
|
123
119
|
}
|
|
124
120
|
}
|
|
121
|
+
_ts_decorate([
|
|
122
|
+
property({
|
|
123
|
+
reflect: true
|
|
124
|
+
})
|
|
125
|
+
], M3StandardButtonGroup.prototype, "size", void 0);
|
|
125
126
|
_ts_decorate([
|
|
126
127
|
queryAssignedElements()
|
|
127
128
|
], M3StandardButtonGroup.prototype, "$buttons", void 0);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { _ as _ts_decorate } from "@swc/helpers/_/_ts_decorate";
|
|
2
2
|
import { html } from 'lit';
|
|
3
|
-
import { customElement, property } from 'lit/decorators.js';
|
|
3
|
+
import { customElement, property, query } from 'lit/decorators.js';
|
|
4
4
|
import { Checkbox } from '../../base/checkbox.js';
|
|
5
5
|
import '../focus-ring/focus-ring.js';
|
|
6
6
|
import { checkboxStyles } from './checkbox-styles.css.js';
|
|
@@ -19,6 +19,13 @@ export class M3Checkbox extends Checkbox {
|
|
|
19
19
|
renderIcon() {
|
|
20
20
|
return html`<svg part="icon" viewBox="0 0 18 18" aria-hidden="true"><rect part="mark mark-short"></rect><rect part="mark mark-long"></rect></svg>`;
|
|
21
21
|
}
|
|
22
|
+
connectedCallback() {
|
|
23
|
+
super.connectedCallback();
|
|
24
|
+
// SSR'd <md-checkbox> components don't have their labels set up on time
|
|
25
|
+
this.updateComplete.then(()=>{
|
|
26
|
+
this.$ripple.attach(this, true);
|
|
27
|
+
});
|
|
28
|
+
}
|
|
22
29
|
constructor(...args){
|
|
23
30
|
super(...args), this.error = false;
|
|
24
31
|
}
|
|
@@ -29,6 +36,9 @@ _ts_decorate([
|
|
|
29
36
|
reflect: true
|
|
30
37
|
})
|
|
31
38
|
], M3Checkbox.prototype, "error", void 0);
|
|
39
|
+
_ts_decorate([
|
|
40
|
+
query('md-ripple')
|
|
41
|
+
], M3Checkbox.prototype, "$ripple", void 0);
|
|
32
42
|
M3Checkbox = _ts_decorate([
|
|
33
43
|
customElement('md-checkbox')
|
|
34
44
|
], M3Checkbox);
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
import { _ as _ts_decorate } from "@swc/helpers/_/_ts_decorate";
|
|
2
|
+
import { html } from 'lit';
|
|
3
|
+
import { query, state, customElement } from 'lit/decorators.js';
|
|
4
|
+
import { Dialog } from '../../base/dialog.js';
|
|
5
|
+
import { getSpring } from '../system/motion.js';
|
|
6
|
+
import { dialogStyles } from './dialog-styles.css.js';
|
|
7
|
+
export class M3Dialog extends Dialog {
|
|
8
|
+
static{
|
|
9
|
+
this.styles = [
|
|
10
|
+
dialogStyles
|
|
11
|
+
];
|
|
12
|
+
}
|
|
13
|
+
render() {
|
|
14
|
+
return html`<dialog part="dialog" @click="${this.#handleClick}" @cancel="${this._handleCancel}"><div part="container"><div part="body"><div part="headline" class="${this.hasIcon ? 'has-icon' : ''}"><slot name="icon" @slotchange="${this.#handleIconSlotChange}"></slot><slot name="headline"></slot></div><div part="content"><slot></slot></div><div class="actions-placeholder"></div></div><div part="actions"><slot name="actions"></slot></div></div></dialog><div part="scrim"></div>`;
|
|
15
|
+
}
|
|
16
|
+
#activeAnimations;
|
|
17
|
+
#clearAnimations() {
|
|
18
|
+
this.#activeAnimations.forEach((anim)=>anim.cancel());
|
|
19
|
+
this.#activeAnimations = [];
|
|
20
|
+
this.#opening = this.#closing = false;
|
|
21
|
+
}
|
|
22
|
+
#handleClick;
|
|
23
|
+
#handleIconSlotChange;
|
|
24
|
+
get #springs() {
|
|
25
|
+
return {
|
|
26
|
+
spatialDefault: getSpring(this, 'spatial', 'default'),
|
|
27
|
+
spatialFast: getSpring(this, 'spatial', 'fast'),
|
|
28
|
+
effectsDefault: getSpring(this, 'effects', 'default'),
|
|
29
|
+
effectsFast: getSpring(this, 'effects', 'fast')
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
#opening;
|
|
33
|
+
show() {
|
|
34
|
+
if (this.#opening) return;
|
|
35
|
+
this.#clearAnimations();
|
|
36
|
+
this.#opening = true;
|
|
37
|
+
// Reset margins to allow browser centering
|
|
38
|
+
this.$dialog.style.marginTop = 'auto';
|
|
39
|
+
this.$dialog.style.marginBottom = 'auto';
|
|
40
|
+
super.show();
|
|
41
|
+
const actionsHeight = this.$actions.offsetHeight;
|
|
42
|
+
this.$actionsPlaceholder.style.height = `${actionsHeight}px`;
|
|
43
|
+
this.$container.style.height = 'auto';
|
|
44
|
+
const startHeight = 0;
|
|
45
|
+
const endHeight = this.$container.offsetHeight;
|
|
46
|
+
// Lock the position to prevent auto-centering during animation
|
|
47
|
+
const rect = this.$container.getBoundingClientRect();
|
|
48
|
+
this.$dialog.style.marginTop = `${rect.top}px`;
|
|
49
|
+
this.$dialog.style.marginBottom = 'auto';
|
|
50
|
+
this.$container.style.minHeight = '0px';
|
|
51
|
+
const container = this.$container.animate([
|
|
52
|
+
{
|
|
53
|
+
height: `${startHeight}px`,
|
|
54
|
+
transform: `translateY(-40px)`
|
|
55
|
+
},
|
|
56
|
+
{
|
|
57
|
+
height: `${endHeight}px`,
|
|
58
|
+
transform: 'translateY(0px)'
|
|
59
|
+
}
|
|
60
|
+
], this.#springs.spatialDefault);
|
|
61
|
+
const scrim = this.$scrim.animate([
|
|
62
|
+
{
|
|
63
|
+
opacity: 0
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
opacity: 0.32
|
|
67
|
+
}
|
|
68
|
+
], {
|
|
69
|
+
...this.#springs.effectsDefault,
|
|
70
|
+
fill: 'forwards'
|
|
71
|
+
});
|
|
72
|
+
const body = this.$body.animate([
|
|
73
|
+
{
|
|
74
|
+
opacity: 0.2
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
opacity: 1
|
|
78
|
+
}
|
|
79
|
+
], {
|
|
80
|
+
...this.#springs.effectsDefault,
|
|
81
|
+
fill: 'forwards'
|
|
82
|
+
});
|
|
83
|
+
const actions = this.$actions.animate([
|
|
84
|
+
{
|
|
85
|
+
opacity: 0.5
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
opacity: 1
|
|
89
|
+
}
|
|
90
|
+
], {
|
|
91
|
+
...this.#springs.effectsDefault,
|
|
92
|
+
fill: 'forwards'
|
|
93
|
+
});
|
|
94
|
+
this.#activeAnimations.push(container, scrim, body, actions);
|
|
95
|
+
container.onfinish = ()=>{
|
|
96
|
+
this.$container.style.minHeight = '';
|
|
97
|
+
this.#clearAnimations();
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
#closing;
|
|
101
|
+
close() {
|
|
102
|
+
if (this.#closing) return;
|
|
103
|
+
this.#clearAnimations();
|
|
104
|
+
this.#closing = true;
|
|
105
|
+
const startHeight = this.$container.offsetHeight;
|
|
106
|
+
const endHeight = startHeight * 0.35;
|
|
107
|
+
this.$container.style.minHeight = '0px';
|
|
108
|
+
const containerSpatial = this.$container.animate([
|
|
109
|
+
{
|
|
110
|
+
height: `${startHeight}px`,
|
|
111
|
+
transform: 'translateY(0px)'
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
height: `${endHeight}px`,
|
|
115
|
+
transform: `translateY(-40px)`
|
|
116
|
+
}
|
|
117
|
+
], this.#springs.spatialFast);
|
|
118
|
+
const containerEffects = this.$container.animate([
|
|
119
|
+
{
|
|
120
|
+
opacity: 1
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
opacity: 0
|
|
124
|
+
}
|
|
125
|
+
], {
|
|
126
|
+
...this.#springs.effectsFast,
|
|
127
|
+
fill: 'forwards'
|
|
128
|
+
});
|
|
129
|
+
const scrim = this.$scrim.animate([
|
|
130
|
+
{
|
|
131
|
+
opacity: 0.32
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
opacity: 0
|
|
135
|
+
}
|
|
136
|
+
], {
|
|
137
|
+
...this.#springs.effectsFast,
|
|
138
|
+
fill: 'forwards'
|
|
139
|
+
});
|
|
140
|
+
this.#activeAnimations.push(containerSpatial, containerEffects, scrim);
|
|
141
|
+
containerEffects.onfinish = ()=>{
|
|
142
|
+
this.$container.style.minHeight = '';
|
|
143
|
+
super.close();
|
|
144
|
+
this.#clearAnimations();
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
constructor(...args){
|
|
148
|
+
super(...args), this.hasIcon = false, this.#activeAnimations = [], this.#handleClick = (e)=>{
|
|
149
|
+
const target = e.target;
|
|
150
|
+
if (!this.$container.contains(target) && !this.contains(target)) this.close();
|
|
151
|
+
}, this.#handleIconSlotChange = (e)=>{
|
|
152
|
+
const slot = e.target;
|
|
153
|
+
this.hasIcon = slot.assignedElements({
|
|
154
|
+
flatten: true
|
|
155
|
+
}).length > 0;
|
|
156
|
+
}, this.#opening = false, this.#closing = false;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
_ts_decorate([
|
|
160
|
+
state()
|
|
161
|
+
], M3Dialog.prototype, "hasIcon", void 0);
|
|
162
|
+
_ts_decorate([
|
|
163
|
+
query('[part=container]')
|
|
164
|
+
], M3Dialog.prototype, "$container", void 0);
|
|
165
|
+
_ts_decorate([
|
|
166
|
+
query('[part=body]')
|
|
167
|
+
], M3Dialog.prototype, "$body", void 0);
|
|
168
|
+
_ts_decorate([
|
|
169
|
+
query('[part=actions]')
|
|
170
|
+
], M3Dialog.prototype, "$actions", void 0);
|
|
171
|
+
_ts_decorate([
|
|
172
|
+
query('.actions-placeholder')
|
|
173
|
+
], M3Dialog.prototype, "$actionsPlaceholder", void 0);
|
|
174
|
+
_ts_decorate([
|
|
175
|
+
query('[part=scrim]')
|
|
176
|
+
], M3Dialog.prototype, "$scrim", void 0);
|
|
177
|
+
M3Dialog = _ts_decorate([
|
|
178
|
+
customElement('md-dialog')
|
|
179
|
+
], M3Dialog);
|
package/src/m3/dialog/dialog.js
CHANGED
|
@@ -172,16 +172,17 @@ export class M3Dialog extends Dialog {
|
|
|
172
172
|
};
|
|
173
173
|
}
|
|
174
174
|
constructor(...args){
|
|
175
|
-
super(...args),
|
|
175
|
+
super(...args), // Was based on https://m3.material.io/styles/motion/easing-and-duration/applying-easing-and-duration#e5b958f0-435d-4e84-aed4-8d1ea395fa5c
|
|
176
|
+
// TODO: use curves and durations from motion physics
|
|
177
|
+
this._config = {
|
|
176
178
|
openEase: 'cubic-bezier(0, 0, 0, 1)',
|
|
177
179
|
closeEase: 'cubic-bezier(0.3, 0, 1, 1)',
|
|
178
|
-
vertSlide:
|
|
180
|
+
vertSlide: 40,
|
|
179
181
|
openDur: 500,
|
|
180
182
|
closeDur: 200,
|
|
181
183
|
bodyFadeInDur: 200,
|
|
182
184
|
bodyFadeOutDur: 100
|
|
183
|
-
}
|
|
184
|
-
making classes inheriting this class... */ , this.hasIcon = false, this.#activeAnimations = [], this.#handleClick = (e)=>{
|
|
185
|
+
}, this.hasIcon = false, this.#activeAnimations = [], this.#handleClick = (e)=>{
|
|
185
186
|
const target = e.target;
|
|
186
187
|
if (!this.$container.contains(target) && !this.contains(target)) this.close();
|
|
187
188
|
}, this.#handleIconSlotChange = (e)=>{
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import { css } from 'lit';
|
|
2
|
-
export const fabStyles = css`:host{--md-focus-ring-shape:var(--_border-radius);--_text-color:var(--md-sys-color-on-primary);--_background-color:var(--md-sys-color-primary);--_size:56px;--_border-radius:16px;--_icon-size:24px;background-color:color-mix(in srgb, var(--_background-color) var(--_background-opacity,100%), transparent);border-radius:var(--_border-radius);box-shadow:var(--md-sys-elevation-shadow-3);box-sizing:border-box;color:color-mix(in srgb, var(--_text-color) var(--_text-opacity,100%), transparent);cursor:pointer;font:var(--md-sys-typography-label-large);height:var(--_size);min-width:var(--_size);padding-inline:calc((var(--_size) - var(--_icon-size)) / 2);-webkit-tap-highlight-color:transparent;transition:box-shadow var(--md-sys-motion-effects-default-duration) var(--md-sys-motion-effects-default);-webkit-user-select:none;user-select:none;vertical-align:middle;outline:0;justify-content:center;align-items:center;gap:8px;display:inline-flex;position:relative}:host([size=
|
|
2
|
+
export const fabStyles = css`:host{--md-focus-ring-shape:var(--_border-radius);--_text-color:var(--md-sys-color-on-primary);--_background-color:var(--md-sys-color-primary);--_size:56px;--_border-radius:16px;--_icon-size:24px;background-color:color-mix(in srgb, var(--_background-color) var(--_background-opacity,100%), transparent);border-radius:var(--_border-radius);box-shadow:var(--md-sys-elevation-shadow-3);box-sizing:border-box;color:color-mix(in srgb, var(--_text-color) var(--_text-opacity,100%), transparent);cursor:pointer;font:var(--md-sys-typography-label-large);height:var(--_size);min-width:var(--_size);padding-inline:calc((var(--_size) - var(--_icon-size)) / 2);-webkit-tap-highlight-color:transparent;transition:box-shadow var(--md-sys-motion-effects-default-duration) var(--md-sys-motion-effects-default);-webkit-user-select:none;user-select:none;vertical-align:middle;outline:0;justify-content:center;align-items:center;gap:8px;display:inline-flex;position:relative}md-ripple,md-focus-ring{position:absolute}:host([size=m]){--_size:80px;--_border-radius:20px;--_icon-size:28px}:host([size=l]){--_size:96px;--_border-radius:28px;--_icon-size:36px}:host([color=primary-container]){--_text-color:var(--md-sys-color-on-primary-container);--_background-color:var(--md-sys-color-primary-container)}:host([color=secondary-container]){--_text-color:var(--md-sys-color-on-secondary-container);--_background-color:var(--md-sys-color-secondary-container)}:host([color=tertiary-container]){--_text-color:var(--md-sys-color-on-tertiary-container);--_background-color:var(--md-sys-color-tertiary-container)}:host([color=secondary]){--_text-color:var(--md-sys-color-on-secondary);--_background-color:var(--md-sys-color-secondary)}:host([color=tertiary]){--_text-color:var(--md-sys-color-on-tertiary);--_background-color:var(--md-sys-color-tertiary)}:host([color=surface]){--_text-color:var(--md-sys-color-primary);--_background-color:var(--md-sys-color-surface-container-high)}:host(:disabled){--_background-color:var(--md-sys-color-on-surface);--_background-opacity:12%;--_text-color:var(--md-sys-color-on-surface);--_text-opacity:38%;box-shadow:none;pointer-events:none}@media (hover:hover) and (pointer:fine){:host(:hover:not(:active)){box-shadow:var(--md-sys-elevation-shadow-4)}}::slotted(:not([slot=label])){fill:currentColor;block-size:1em;font-size:var(--_icon-size);inline-size:1em}::slotted([slot=label]){margin-inline:4px}`;
|
package/src/m3/fab/fab.js
CHANGED
|
@@ -18,7 +18,8 @@ export class M3Fab extends Button {
|
|
|
18
18
|
return html`<md-focus-ring></md-focus-ring><md-ripple></md-ripple><span part="target"></span><slot part="icon" aria-hidden="true"></slot><slot part="label" name="label"></slot>`;
|
|
19
19
|
}
|
|
20
20
|
constructor(...args){
|
|
21
|
-
super(...args), this.size = '
|
|
21
|
+
super(...args), this.size = 's' // s for default
|
|
22
|
+
, this.color = 'primary';
|
|
22
23
|
}
|
|
23
24
|
}
|
|
24
25
|
_ts_decorate([
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Workaround for `CSSNumericValue.parse()` not being supported by Firefox
|
|
3
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/CSSNumericValue/parse_static
|
|
4
|
+
*/ export const parseCSSNum = (css)=>{
|
|
5
|
+
if (typeof CSSNumericValue !== 'undefined') {
|
|
6
|
+
try {
|
|
7
|
+
return CSSNumericValue.parse(css).to('ms').value;
|
|
8
|
+
} catch {
|
|
9
|
+
return 0;
|
|
10
|
+
}
|
|
11
|
+
} else {
|
|
12
|
+
css = css.trim().toLowerCase();
|
|
13
|
+
if (css.endsWith('ms')) return parseFloat(css.substring(0, css.length - 2)) | 0;
|
|
14
|
+
else if (css.endsWith('s')) return parseFloat(css.substring(0, css.length - 1)) * 1000 | 0;
|
|
15
|
+
else return 0;
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* https://m3.material.io/styles/motion/overview/specs
|
|
20
|
+
*/ export const getSpring = (element, type, duration)=>{
|
|
21
|
+
const styles = getComputedStyle(element);
|
|
22
|
+
const get = (suffix)=>styles.getPropertyValue(`--md-sys-motion-${type}-${duration}${suffix}`);
|
|
23
|
+
return {
|
|
24
|
+
easing: get('') || 'ease',
|
|
25
|
+
duration: parseCSSNum(get('-duration'))
|
|
26
|
+
};
|
|
27
|
+
};
|