@shortfuse/materialdesignweb 0.9.0 → 0.9.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 +50 -206
- package/components/Badge.js +5 -2
- package/components/Body.js +4 -0
- package/components/BottomAppBar.js +6 -2
- package/components/BottomSheet.js +62 -14
- package/components/Button.js +20 -0
- package/components/Card.js +20 -3
- package/components/Checkbox.js +8 -0
- package/components/CheckboxIcon.js +9 -3
- package/components/Chip.js +5 -2
- package/components/Dialog.js +22 -3
- package/components/DialogActions.js +4 -0
- package/components/Display.js +9 -0
- package/components/Divider.js +5 -0
- package/components/Fab.js +11 -0
- package/components/FabContainer.js +9 -0
- package/components/FilterChip.js +9 -0
- package/components/Grid.js +11 -0
- package/components/Headline.js +4 -0
- package/components/Icon.js +27 -3
- package/components/IconButton.js +8 -2
- package/components/Input.js +87 -14
- package/components/InputChip.js +33 -1
- package/components/Label.js +4 -0
- package/components/List.js +10 -0
- package/components/ListItem.js +53 -0
- package/components/ListOption.js +62 -1
- package/components/Listbox.js +44 -13
- package/components/Menu.js +31 -9
- package/components/MenuItem.js +24 -10
- package/components/NavBar.js +14 -3
- package/components/NavBarItem.js +5 -0
- package/components/NavDrawer.js +17 -0
- package/components/NavDrawerItem.js +5 -0
- package/components/NavItem.js +22 -2
- package/components/NavRail.js +9 -0
- package/components/NavRailItem.js +5 -0
- package/components/Page.js +15 -1
- package/components/Pane.js +7 -1
- package/components/Popup.js +6 -0
- package/components/Progress.js +25 -5
- package/components/Radio.js +6 -2
- package/components/RadioIcon.js +14 -1
- package/components/Ripple.js +14 -0
- package/components/Root.js +16 -0
- package/components/Scrim.js +10 -2
- package/components/Search.js +18 -5
- package/components/SegmentedButton.js +22 -6
- package/components/SegmentedButtonGroup.js +7 -10
- package/components/Select.js +13 -3
- package/components/Shape.js +4 -0
- package/components/SideSheet.js +31 -2
- package/components/Slider.js +22 -2
- package/components/Snackbar.js +30 -4
- package/components/SnackbarContainer.js +9 -0
- package/components/Surface.js +5 -0
- package/components/Switch.js +18 -2
- package/components/SwitchIcon.js +22 -1
- package/components/Tab.js +21 -0
- package/components/TabContent.js +32 -12
- package/components/TabList.js +36 -3
- package/components/TabPanel.js +9 -0
- package/components/Table.js +38 -3
- package/components/TextArea.js +32 -1
- package/components/Title.js +4 -0
- package/components/Tooltip.js +9 -2
- package/components/TopAppBar.js +15 -0
- package/core/Composition.js +45 -16
- package/core/CompositionAdapter.js +24 -6
- package/core/CustomElement.js +77 -49
- package/core/customTypes.js +43 -26
- package/core/dom.js +1 -0
- package/core/jsonMergePatch.js +15 -1
- package/core/observe.js +28 -21
- package/dist/CustomElement.min.js +2 -0
- package/dist/CustomElement.min.js.map +7 -0
- package/dist/core/CustomElement.min.js +2 -0
- package/dist/core/CustomElement.min.js.map +7 -0
- package/dist/index.min.js +9 -9
- package/dist/index.min.js.map +3 -3
- package/dist/meta.json +1 -1
- package/dom/HTMLOptionsCollectionProxy.js +5 -3
- package/mixins/AriaReflectorMixin.js +22 -13
- package/mixins/AriaToolbarMixin.js +3 -0
- package/mixins/ControlMixin.js +3 -0
- package/mixins/DelegatesFocusMixin.js +9 -1
- package/mixins/DensityMixin.js +5 -1
- package/mixins/ElevationMixin.js +1 -2
- package/mixins/FlexableMixin.js +21 -2
- package/mixins/FormAssociatedMixin.js +19 -5
- package/mixins/HyperlinkMixin.js +11 -1
- package/mixins/InputMixin.js +22 -0
- package/mixins/KeyboardNavMixin.js +3 -1
- package/mixins/PopupMixin.js +41 -12
- package/mixins/RTLObserverMixin.js +2 -0
- package/mixins/ResizeObserverMixin.js +2 -0
- package/mixins/RippleMixin.js +3 -1
- package/mixins/ScrollListenerMixin.js +13 -1
- package/mixins/SemiStickyMixin.js +7 -0
- package/mixins/ShapeMaskedMixin.js +9 -1
- package/mixins/ShapeMixin.js +9 -0
- package/mixins/StateMixin.js +4 -0
- package/mixins/TextFieldMixin.js +21 -2
- package/mixins/ThemableMixin.js +13 -0
- package/mixins/TooltipTriggerMixin.js +17 -3
- package/mixins/TouchTargetMixin.js +4 -1
- package/mixins/TypographyMixin.js +8 -1
- package/package.json +53 -45
- package/services/theme.js +4 -5
- package/types/components/BottomAppBar.d.ts +3 -4
- package/types/components/BottomSheet.d.ts +33 -7
- package/types/components/BottomSheet.d.ts.map +1 -1
- package/types/components/Button.d.ts +3 -472
- package/types/components/Button.d.ts.map +1 -1
- package/types/components/Card.d.ts +9 -274
- package/types/components/Card.d.ts.map +1 -1
- package/types/components/Checkbox.d.ts +2 -0
- package/types/components/Checkbox.d.ts.map +1 -1
- package/types/components/Chip.d.ts +3 -1180
- package/types/components/Dialog.d.ts +8 -191
- package/types/components/Dialog.d.ts.map +1 -1
- package/types/components/Display.d.ts +5 -4
- package/types/components/Display.d.ts.map +1 -1
- package/types/components/Fab.d.ts +2 -470
- package/types/components/FilterChip.d.ts +5 -4032
- package/types/components/Grid.d.ts +1 -0
- package/types/components/Grid.d.ts.map +1 -1
- package/types/components/Headline.d.ts +3 -4
- package/types/components/Icon.d.ts +1 -49
- package/types/components/Icon.d.ts.map +1 -1
- package/types/components/IconButton.d.ts +3 -1205
- package/types/components/Input.d.ts +1485 -50245
- package/types/components/Input.d.ts.map +1 -1
- package/types/components/InputChip.d.ts +2 -160
- package/types/components/List.d.ts +8 -4
- package/types/components/List.d.ts.map +1 -1
- package/types/components/ListItem.d.ts +10 -235
- package/types/components/ListItem.d.ts.map +1 -1
- package/types/components/ListOption.d.ts +17 -1352
- package/types/components/ListOption.d.ts.map +1 -1
- package/types/components/Listbox.d.ts +199 -11448
- package/types/components/Listbox.d.ts.map +1 -1
- package/types/components/Menu.d.ts +21 -10
- package/types/components/Menu.d.ts.map +1 -1
- package/types/components/MenuItem.d.ts +17 -2894
- package/types/components/MenuItem.d.ts.map +1 -1
- package/types/components/NavBar.d.ts +2 -0
- package/types/components/NavBar.d.ts.map +1 -1
- package/types/components/NavBarItem.d.ts +1 -90
- package/types/components/NavDrawer.d.ts +3 -4
- package/types/components/NavDrawerItem.d.ts +1 -90
- package/types/components/NavItem.d.ts +1 -92
- package/types/components/NavItem.d.ts.map +1 -1
- package/types/components/NavRail.d.ts +3 -4
- package/types/components/NavRailItem.d.ts +1 -90
- package/types/components/Page.d.ts +1 -0
- package/types/components/Page.d.ts.map +1 -1
- package/types/components/Popup.d.ts +5 -3
- package/types/components/Popup.d.ts.map +1 -1
- package/types/components/Progress.d.ts +2 -0
- package/types/components/Progress.d.ts.map +1 -1
- package/types/components/Radio.d.ts +2 -0
- package/types/components/Radio.d.ts.map +1 -1
- package/types/components/Ripple.d.ts +1 -0
- package/types/components/Ripple.d.ts.map +1 -1
- package/types/components/Root.d.ts +1 -1
- package/types/components/Root.d.ts.map +1 -1
- package/types/components/Search.d.ts +502 -2
- package/types/components/Search.d.ts.map +1 -1
- package/types/components/SegmentedButton.d.ts +4 -470
- package/types/components/SegmentedButton.d.ts.map +1 -1
- package/types/components/SegmentedButtonGroup.d.ts +3 -4
- package/types/components/SegmentedButtonGroup.d.ts.map +1 -1
- package/types/components/Select.d.ts +5 -1208
- package/types/components/Select.d.ts.map +1 -1
- package/types/components/SideSheet.d.ts +9 -4
- package/types/components/SideSheet.d.ts.map +1 -1
- package/types/components/Slider.d.ts +10 -189
- package/types/components/Slider.d.ts.map +1 -1
- package/types/components/Snackbar.d.ts +13 -5
- package/types/components/Snackbar.d.ts.map +1 -1
- package/types/components/Switch.d.ts +4 -0
- package/types/components/Switch.d.ts.map +1 -1
- package/types/components/SwitchIcon.d.ts +2 -110
- package/types/components/SwitchIcon.d.ts.map +1 -1
- package/types/components/Tab.d.ts +12 -752
- package/types/components/Tab.d.ts.map +1 -1
- package/types/components/TabContent.d.ts +23 -21
- package/types/components/TabContent.d.ts.map +1 -1
- package/types/components/TabList.d.ts +646 -5801
- package/types/components/TabList.d.ts.map +1 -1
- package/types/components/TabPanel.d.ts +4 -4
- package/types/components/TabPanel.d.ts.map +1 -1
- package/types/components/Table.d.ts +24 -1
- package/types/components/Table.d.ts.map +1 -1
- package/types/components/TextArea.d.ts +15 -1208
- package/types/components/TextArea.d.ts.map +1 -1
- package/types/components/Title.d.ts +3 -4
- package/types/components/Tooltip.d.ts +4 -4
- package/types/components/Tooltip.d.ts.map +1 -1
- package/types/components/TopAppBar.d.ts +4 -5
- package/types/components/TopAppBar.d.ts.map +1 -1
- package/types/constants/shapes.d.ts.map +1 -1
- package/types/core/Composition.d.ts +19 -11
- package/types/core/Composition.d.ts.map +1 -1
- package/types/core/CompositionAdapter.d.ts +30 -8
- package/types/core/CompositionAdapter.d.ts.map +1 -1
- package/types/core/CustomElement.d.ts +27 -25
- package/types/core/CustomElement.d.ts.map +1 -1
- package/types/core/customTypes.d.ts +2 -6
- package/types/core/customTypes.d.ts.map +1 -1
- package/types/core/dom.d.ts.map +1 -1
- package/types/core/jsonMergePatch.d.ts.map +1 -1
- package/types/core/observe.d.ts +20 -19
- package/types/core/observe.d.ts.map +1 -1
- package/types/core/template.d.ts.map +1 -1
- package/types/dom/HTMLOptionsCollectionProxy.d.ts +4 -4
- package/types/dom/HTMLOptionsCollectionProxy.d.ts.map +1 -1
- package/types/mixins/AriaReflectorMixin.d.ts +18 -10
- package/types/mixins/AriaReflectorMixin.d.ts.map +1 -1
- package/types/mixins/AriaToolbarMixin.d.ts +6 -4
- package/types/mixins/AriaToolbarMixin.d.ts.map +1 -1
- package/types/mixins/ControlMixin.d.ts +1 -1
- package/types/mixins/ControlMixin.d.ts.map +1 -1
- package/types/mixins/DelegatesFocusMixin.d.ts +9 -1
- package/types/mixins/DelegatesFocusMixin.d.ts.map +1 -1
- package/types/mixins/DensityMixin.d.ts +4 -1
- package/types/mixins/DensityMixin.d.ts.map +1 -1
- package/types/mixins/ElevationMixin.d.ts +1 -2
- package/types/mixins/ElevationMixin.d.ts.map +1 -1
- package/types/mixins/FlexableMixin.d.ts +1 -0
- package/types/mixins/FlexableMixin.d.ts.map +1 -1
- package/types/mixins/FormAssociatedMixin.d.ts +3 -2
- package/types/mixins/FormAssociatedMixin.d.ts.map +1 -1
- package/types/mixins/HyperlinkMixin.d.ts +4 -1
- package/types/mixins/HyperlinkMixin.d.ts.map +1 -1
- package/types/mixins/InputMixin.d.ts +1 -7
- package/types/mixins/InputMixin.d.ts.map +1 -1
- package/types/mixins/KeyboardNavMixin.d.ts +4 -5
- package/types/mixins/KeyboardNavMixin.d.ts.map +1 -1
- package/types/mixins/PopupMixin.d.ts +22 -6
- package/types/mixins/PopupMixin.d.ts.map +1 -1
- package/types/mixins/RTLObserverMixin.d.ts +1 -0
- package/types/mixins/RTLObserverMixin.d.ts.map +1 -1
- package/types/mixins/ResizeObserverMixin.d.ts +1 -0
- package/types/mixins/ResizeObserverMixin.d.ts.map +1 -1
- package/types/mixins/RippleMixin.d.ts +3 -1
- package/types/mixins/RippleMixin.d.ts.map +1 -1
- package/types/mixins/ScrollListenerMixin.d.ts +7 -2
- package/types/mixins/ScrollListenerMixin.d.ts.map +1 -1
- package/types/mixins/SemiStickyMixin.d.ts +1 -1
- package/types/mixins/SemiStickyMixin.d.ts.map +1 -1
- package/types/mixins/ShapeMaskedMixin.d.ts +4 -1
- package/types/mixins/ShapeMaskedMixin.d.ts.map +1 -1
- package/types/mixins/ShapeMixin.d.ts +1 -0
- package/types/mixins/ShapeMixin.d.ts.map +1 -1
- package/types/mixins/StateMixin.d.ts +2 -0
- package/types/mixins/StateMixin.d.ts.map +1 -1
- package/types/mixins/TextFieldMixin.d.ts +7 -1208
- package/types/mixins/TextFieldMixin.d.ts.map +1 -1
- package/types/mixins/ThemableMixin.d.ts +1 -0
- package/types/mixins/ThemableMixin.d.ts.map +1 -1
- package/types/mixins/TooltipTriggerMixin.d.ts +12 -4
- package/types/mixins/TooltipTriggerMixin.d.ts.map +1 -1
- package/types/mixins/TouchTargetMixin.d.ts +4 -1
- package/types/mixins/TouchTargetMixin.d.ts.map +1 -1
- package/types/mixins/TypographyMixin.d.ts +4 -1
- package/types/mixins/TypographyMixin.d.ts.map +1 -1
- package/types/services/theme.d.ts.map +1 -1
- package/types/utils/jsx-runtime.d.ts +3 -3
- package/types/utils/jsx-runtime.d.ts.map +1 -1
- package/types/utils/material-color/hct/Hct.d.ts.map +1 -1
- package/types/utils/material-color/palettes/CorePalette.d.ts +1 -1
- package/types/utils/material-color/palettes/CorePalette.d.ts.map +1 -1
- package/types/utils/material-color/scheme/Scheme.d.ts.map +1 -1
- package/types/utils/pixelmatch.d.ts +3 -3
- package/types/utils/pixelmatch.d.ts.map +1 -1
- package/types/utils/searchParams.d.ts.map +1 -1
- package/utils/jsx-runtime.js +9 -4
- package/utils/pixelmatch.js +10 -7
- package/utils/searchParams.js +3 -0
- package/components/Button.md +0 -61
package/components/Progress.js
CHANGED
|
@@ -1,26 +1,38 @@
|
|
|
1
|
-
/* https://m3.material.io/components/progress-indicators/specs */
|
|
2
|
-
|
|
3
1
|
import CustomElement from '../core/CustomElement.js';
|
|
4
2
|
import ThemableMixin from '../mixins/ThemableMixin.js';
|
|
5
3
|
|
|
6
|
-
|
|
7
|
-
|
|
4
|
+
/**
|
|
5
|
+
* Progress indicators display the progress of an operation as a determinate
|
|
6
|
+
* bar or an indeterminate animation.
|
|
7
|
+
* @see https://m3.material.io/components/progress-indicators/specs
|
|
8
|
+
* @see https://html.spec.whatwg.org/multipage/form-elements.html#the-progress-element
|
|
9
|
+
*/
|
|
8
10
|
export default CustomElement
|
|
9
11
|
.extend()
|
|
10
12
|
.mixin(ThemableMixin)
|
|
11
13
|
.observe({
|
|
14
|
+
/** Render the circular variant when true; otherwise render a linear bar. */
|
|
12
15
|
circle: 'boolean',
|
|
16
|
+
/** Current progress value. When present the indicator is determinate. */
|
|
13
17
|
value: 'float',
|
|
18
|
+
/** Maximum progress value (defaults to 100 when not set). */
|
|
14
19
|
max: 'float',
|
|
20
|
+
/** When true, the progress will auto-hide when complete. */
|
|
15
21
|
autoHide: 'boolean',
|
|
22
|
+
/** Internal inline style string used to animate the determinate bar. */
|
|
16
23
|
_determinateStyle: 'string',
|
|
17
24
|
})
|
|
18
25
|
.observe({
|
|
26
|
+
/**
|
|
27
|
+
* Computed fractional progress (0.0–1.0) derived from `value` and `max`.
|
|
28
|
+
* Used to drive the determinate animation and CSS variables.
|
|
29
|
+
*/
|
|
19
30
|
_valueAsFraction: {
|
|
20
31
|
type: 'float',
|
|
21
32
|
get({ value, max }) {
|
|
22
33
|
return (value / (max || 100));
|
|
23
34
|
},
|
|
35
|
+
/** Update `_determinateStyle` CSS variables when the fraction changes. */
|
|
24
36
|
changedCallback(oldValue, newValue) {
|
|
25
37
|
this._determinateStyle = `
|
|
26
38
|
--previous:${oldValue ?? newValue ?? 0};
|
|
@@ -29,10 +41,18 @@ export default CustomElement
|
|
|
29
41
|
},
|
|
30
42
|
},
|
|
31
43
|
})
|
|
44
|
+
.expressions({
|
|
45
|
+
/** True when `value` is provided, indicating a determinate progress state. */
|
|
46
|
+
isDeterminate({ value }) {
|
|
47
|
+
return value != null;
|
|
48
|
+
},
|
|
49
|
+
})
|
|
32
50
|
.define({
|
|
51
|
+
/** Proxy to the internal `<progress>` element's `position` property. */
|
|
33
52
|
position() {
|
|
34
53
|
return /** @type {HTMLProgressElement} */ (this.refs.progress).position;
|
|
35
54
|
},
|
|
55
|
+
/** Proxy to the internal `<progress>` element's `labels` collection. */
|
|
36
56
|
labels() {
|
|
37
57
|
return /** @type {HTMLProgressElement} */ (this.refs.progress).labels;
|
|
38
58
|
},
|
|
@@ -45,7 +65,7 @@ export default CustomElement
|
|
|
45
65
|
<div id=semi2 class=semi></div>
|
|
46
66
|
</div>
|
|
47
67
|
</div>
|
|
48
|
-
<div mdw-if={!
|
|
68
|
+
<div mdw-if={!isDeterminate} id=indeterminate>
|
|
49
69
|
<div mdw-if={!circle} id=indeterminate-line>
|
|
50
70
|
<div id=line1 class=line value={value}></div>
|
|
51
71
|
<div id=line2 class=line value={value}></div>
|
package/components/Radio.js
CHANGED
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
/* https://m3.material.io/components/radio/specs */
|
|
2
|
-
|
|
3
1
|
import './RadioIcon.js';
|
|
4
2
|
|
|
5
3
|
import CustomElement from '../core/CustomElement.js';
|
|
@@ -9,6 +7,10 @@ import StateMixin from '../mixins/StateMixin.js';
|
|
|
9
7
|
import ThemableMixin from '../mixins/ThemableMixin.js';
|
|
10
8
|
import TouchTargetMixin from '../mixins/TouchTargetMixin.js';
|
|
11
9
|
|
|
10
|
+
/**
|
|
11
|
+
* Radio buttons allow selection of a single option within a set.
|
|
12
|
+
* @see https://m3.material.io/components/radio-button/overview
|
|
13
|
+
*/
|
|
12
14
|
export default CustomElement
|
|
13
15
|
.extend()
|
|
14
16
|
.mixin(ThemableMixin)
|
|
@@ -17,7 +19,9 @@ export default CustomElement
|
|
|
17
19
|
.mixin(InputMixin)
|
|
18
20
|
.mixin(TouchTargetMixin)
|
|
19
21
|
.set({
|
|
22
|
+
/** Native control `type` used for the underlying input; always 'radio'. */
|
|
20
23
|
type: 'radio',
|
|
24
|
+
/** Forces Material state-layer overlay for pressed/hover states. */
|
|
21
25
|
stateLayer: true,
|
|
22
26
|
})
|
|
23
27
|
.html`
|
package/components/RadioIcon.js
CHANGED
|
@@ -4,20 +4,33 @@ import CustomElement from '../core/CustomElement.js';
|
|
|
4
4
|
import ShapeMixin from '../mixins/ShapeMixin.js';
|
|
5
5
|
import ThemableMixin from '../mixins/ThemableMixin.js';
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Visual helper for radio buttons, rendering the outer and inner rings.
|
|
9
|
+
* @see https://m3.material.io/components/radio-button/overview
|
|
10
|
+
*/
|
|
7
11
|
export default CustomElement
|
|
8
12
|
.extend()
|
|
9
13
|
.mixin(ThemableMixin)
|
|
10
14
|
.mixin(ShapeMixin)
|
|
11
15
|
.observe({
|
|
16
|
+
/** Whether the radio icon is selected (checked). */
|
|
12
17
|
selected: 'boolean',
|
|
18
|
+
/** Optional icon name to render inside the control (not normally used). */
|
|
13
19
|
icon: 'string',
|
|
20
|
+
/** When true the control is shown in an error state. */
|
|
14
21
|
errored: 'boolean',
|
|
22
|
+
/** When true the control is disabled. */
|
|
15
23
|
disabled: 'boolean',
|
|
24
|
+
/** Hover state used for styling. */
|
|
16
25
|
hovered: 'boolean',
|
|
26
|
+
/** Focus state used for styling. */
|
|
17
27
|
focused: 'boolean',
|
|
18
28
|
})
|
|
19
29
|
.define({
|
|
20
|
-
/**
|
|
30
|
+
/**
|
|
31
|
+
* Alias for `selected` to match common form terminology (`checked`).
|
|
32
|
+
* Reading/writing `checked` proxies to the `selected` state.
|
|
33
|
+
*/
|
|
21
34
|
checked: {
|
|
22
35
|
get() { return this.selected; },
|
|
23
36
|
set(value) { this.selected = value; },
|
package/components/Ripple.js
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import CustomElement from '../core/CustomElement.js';
|
|
2
2
|
import { ELEMENT_ANIMATION_TYPE } from '../core/customTypes.js';
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Ripple is a visual touch feedback effect used by controls to indicate
|
|
6
|
+
* pointer/touch interaction. It renders and animates a circular ink ripple
|
|
7
|
+
* and exposes properties to control its position, size, and lifecycle.
|
|
8
|
+
* @see https://m3.material.io/foundations/interaction/states/applying-states
|
|
9
|
+
*/
|
|
4
10
|
export default CustomElement
|
|
5
11
|
.extend()
|
|
6
12
|
.set({
|
|
@@ -9,11 +15,17 @@ export default CustomElement
|
|
|
9
15
|
rippleStarted: false,
|
|
10
16
|
})
|
|
11
17
|
.observe({
|
|
18
|
+
/** Current lifecycle state for the ripple (e.g. 'filled', 'complete'). */
|
|
12
19
|
rippleState: 'string',
|
|
20
|
+
/** When true, keep the ripple in the DOM after animation ends. */
|
|
13
21
|
keepAlive: 'boolean',
|
|
22
|
+
/** X offset (px) from center used to position the ripple. */
|
|
14
23
|
_positionX: 'float',
|
|
24
|
+
/** Y offset (px) from center used to position the ripple. */
|
|
15
25
|
_positionY: 'float',
|
|
26
|
+
/** Computed ripple radius (px) used for sizing/animation. */
|
|
16
27
|
_radius: 'float',
|
|
28
|
+
/** Hold the ripple (e.g. for long-press); triggers hold/release tracking. */
|
|
17
29
|
holdRipple: {
|
|
18
30
|
type: 'boolean',
|
|
19
31
|
changedCallback(oldValue, newValue) {
|
|
@@ -26,6 +38,7 @@ export default CustomElement
|
|
|
26
38
|
},
|
|
27
39
|
})
|
|
28
40
|
.observe({
|
|
41
|
+
/** Computed animation/style object used to position and size the ripple. */
|
|
29
42
|
_positionStyle: {
|
|
30
43
|
...ELEMENT_ANIMATION_TYPE,
|
|
31
44
|
get({ _positionX, _positionY, _radius }) {
|
|
@@ -82,6 +95,7 @@ export default CustomElement
|
|
|
82
95
|
this._positionY = y - (parentHeight / 2);
|
|
83
96
|
this._radius = hypotenuse;
|
|
84
97
|
},
|
|
98
|
+
/** Complete the ripple lifecycle: either mark complete or remove. */
|
|
85
99
|
handleRippleComplete() {
|
|
86
100
|
if (this.keepAlive) {
|
|
87
101
|
this.setAttribute('ripple-state', 'complete');
|
package/components/Root.js
CHANGED
|
@@ -5,6 +5,11 @@ import { ELEMENT_ANIMATION_TYPE } from '../core/customTypes.js';
|
|
|
5
5
|
import DelegatesFocusMixin from '../mixins/DelegatesFocusMixin.js';
|
|
6
6
|
import ScrollListenerMixin from '../mixins/ScrollListenerMixin.js';
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Root is the application's top-level container that manages layout regions and
|
|
10
|
+
* shared floating areas such as bottom bars.
|
|
11
|
+
* @see https://m3.material.io/foundations/layout/applying-layout/window-size-classes
|
|
12
|
+
*/
|
|
8
13
|
export default CustomElement
|
|
9
14
|
.extend()
|
|
10
15
|
.mixin(ScrollListenerMixin)
|
|
@@ -25,12 +30,21 @@ export default CustomElement
|
|
|
25
30
|
<slot id=end name=end></slot>
|
|
26
31
|
`
|
|
27
32
|
.observe({
|
|
33
|
+
/** Measured height (px) of the bottom area used to compute reveal offsets. */
|
|
28
34
|
_bottomHeight: { type: 'float', empty: 0 },
|
|
35
|
+
/** Current vertical offset (px) applied to the bottom area for reveal/hide. */
|
|
29
36
|
_bottomOffsetY: { type: 'float', empty: 0 },
|
|
37
|
+
/** Animation duration (ms) used when adjusting bottom offset. */
|
|
30
38
|
_bottomDuration: { type: 'float', empty: 0 },
|
|
39
|
+
/** Animation easing name used when animating bottom reveal/hide. */
|
|
31
40
|
_bottomEasing: { empty: 'ease-in' },
|
|
32
41
|
})
|
|
33
42
|
.observe({
|
|
43
|
+
/**
|
|
44
|
+
* Computed shared animation/style object for bottom areas used to
|
|
45
|
+
* translate and time reveal/hide animations. Returns null when height
|
|
46
|
+
* is zero (no bottom content measured).
|
|
47
|
+
*/
|
|
34
48
|
_sharedBottomStyle({ _bottomOffsetY, _bottomDuration, _bottomEasing, _bottomHeight }) {
|
|
35
49
|
if (!_bottomHeight) return null;
|
|
36
50
|
return {
|
|
@@ -45,6 +59,7 @@ export default CustomElement
|
|
|
45
59
|
},
|
|
46
60
|
})
|
|
47
61
|
.observe({
|
|
62
|
+
/** Animation/style object targeting the bottom slot element. */
|
|
48
63
|
_bottomSlotStyle: {
|
|
49
64
|
...ELEMENT_ANIMATION_TYPE,
|
|
50
65
|
get({ _sharedBottomStyle }) {
|
|
@@ -55,6 +70,7 @@ export default CustomElement
|
|
|
55
70
|
};
|
|
56
71
|
},
|
|
57
72
|
},
|
|
73
|
+
/** Animation/style object targeting the bottom-fixed-slot element. */
|
|
58
74
|
_bottomFixedSlotStyle: {
|
|
59
75
|
...ELEMENT_ANIMATION_TYPE,
|
|
60
76
|
get({ _sharedBottomStyle }) {
|
package/components/Scrim.js
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
import CustomElement from '../core/CustomElement.js';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* A scrim can bring focus to specific elements by increasing the visual contrast of a large layered surface.
|
|
5
|
+
* Use the scrim beneath elements like modals and expanded navigation menus.
|
|
6
|
+
* @see https://m3.material.io/styles/elevation/applying-elevation
|
|
7
|
+
*/
|
|
3
8
|
export default CustomElement
|
|
4
9
|
.extend()
|
|
5
10
|
.observe({
|
|
11
|
+
/** When true the scrim is hidden and will be removed after its fade-out animation. */
|
|
6
12
|
hidden: 'boolean',
|
|
7
13
|
})
|
|
8
14
|
.html`<div id=scroll-blocker></div>`
|
|
@@ -19,7 +25,7 @@ export default CustomElement
|
|
|
19
25
|
scrollbar-color: transparent transparent;
|
|
20
26
|
scrollbar-width: none;
|
|
21
27
|
|
|
22
|
-
cursor:pointer;
|
|
28
|
+
cursor: pointer;
|
|
23
29
|
|
|
24
30
|
outline: none; /* Older Chromium Builds */
|
|
25
31
|
|
|
@@ -81,7 +87,9 @@ export default CustomElement
|
|
|
81
87
|
`
|
|
82
88
|
.events({
|
|
83
89
|
animationend() {
|
|
84
|
-
if (this.hidden)
|
|
90
|
+
if (this.hidden) {
|
|
91
|
+
this.remove();
|
|
92
|
+
}
|
|
85
93
|
},
|
|
86
94
|
})
|
|
87
95
|
.autoRegister('mdw-scrim');
|
package/components/Search.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import TopAppBar from './TopAppBar.js';
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
/**
|
|
4
|
+
* Search provides an app bar integrated search field for querying content.
|
|
5
|
+
* implements {HTMLSelectElement}
|
|
6
|
+
* @see https://m3.material.io/components/search/overview
|
|
7
|
+
*/
|
|
4
8
|
export default TopAppBar
|
|
5
9
|
.extend()
|
|
6
10
|
.undefine('headline')
|
|
@@ -8,18 +12,27 @@ export default TopAppBar
|
|
|
8
12
|
.undefine('size')
|
|
9
13
|
.undefine('_headlineStyle')
|
|
10
14
|
.observe({
|
|
15
|
+
/** Placeholder text shown in the search input. */
|
|
11
16
|
placeholder: { type: 'string', empty: 'Search' },
|
|
17
|
+
/** Visual color token to apply to the search surface. */
|
|
12
18
|
color: { empty: 'surface-container-high' },
|
|
19
|
+
/** Shape style token to apply (e.g. 'full', 'none'). */
|
|
13
20
|
shapeStyle: { empty: 'full' },
|
|
21
|
+
/** Enable keyboard navigation mode for search results when true. */
|
|
14
22
|
kbdNav: { empty: 'false' },
|
|
15
23
|
})
|
|
16
24
|
.define({
|
|
17
|
-
/**
|
|
18
|
-
input() {
|
|
25
|
+
/** Returns the current text value of the internal input. */
|
|
26
|
+
input() {
|
|
27
|
+
return /** @type {HTMLInputElement} */ (this.refs.input).value;
|
|
28
|
+
},
|
|
29
|
+
/** The `value` accessor proxies the internal input's value. */
|
|
19
30
|
value: {
|
|
20
|
-
get() {
|
|
31
|
+
get() {
|
|
32
|
+
return /** @type {HTMLInputElement} */ (this.refs.input).value;
|
|
33
|
+
},
|
|
21
34
|
set(value) {
|
|
22
|
-
this.refs.input.value = value;
|
|
35
|
+
/** @type {HTMLInputElement} */ (this.refs.input).value = value;
|
|
23
36
|
},
|
|
24
37
|
},
|
|
25
38
|
})
|
|
@@ -2,16 +2,24 @@ import './Icon.js';
|
|
|
2
2
|
|
|
3
3
|
import Button from './Button.js';
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
/**
|
|
6
|
+
* Segmented buttons group individual related actions or options where
|
|
7
|
+
* multiple choices are presented inline; each segment acts like a toggle
|
|
8
|
+
* or option within a set.
|
|
9
|
+
* @see https://m3.material.io/components/segmented-buttons/specs
|
|
10
|
+
*/
|
|
7
11
|
export default Button
|
|
8
12
|
.extend()
|
|
9
13
|
.observe({
|
|
14
|
+
/** Interaction model for the segment: 'radio' (single select) or 'checkbox' (multi-select). */
|
|
10
15
|
type: { empty: 'radio' },
|
|
16
|
+
/** When true this segment is rendered as an inner segment inside a segmented group. */
|
|
11
17
|
innerSegmentedButton: 'boolean',
|
|
12
18
|
})
|
|
13
19
|
.set({
|
|
20
|
+
/** Render the button with an outline style. */
|
|
14
21
|
outlined: true,
|
|
22
|
+
/** Allow the control to receive focus even when disabled. */
|
|
15
23
|
focusableOnDisabled: true,
|
|
16
24
|
})
|
|
17
25
|
.recompose(({ html, inline, refs: { icon, outline, control, slot, state } }) => {
|
|
@@ -41,7 +49,7 @@ export default Button
|
|
|
41
49
|
})
|
|
42
50
|
.css`
|
|
43
51
|
:host {
|
|
44
|
-
--mdw-shape__size:
|
|
52
|
+
--mdw-shape__size: 0;
|
|
45
53
|
--mdw-ink: var(--mdw-color__on-surface);
|
|
46
54
|
gap: 8px;
|
|
47
55
|
|
|
@@ -52,8 +60,16 @@ export default Button
|
|
|
52
60
|
color: rgb(var(--mdw-ink));
|
|
53
61
|
}
|
|
54
62
|
|
|
55
|
-
:host(
|
|
56
|
-
--mdw-shape__size:
|
|
63
|
+
:host(:first-of-type) {
|
|
64
|
+
--mdw-shape__size: var(--mdw-shape__full);
|
|
65
|
+
--mdw-shape__size__top-end-size: 0px;
|
|
66
|
+
--mdw-shape__size__bottom-end-size: 0px;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
:host(:last-of-type) {
|
|
70
|
+
--mdw-shape__size: var(--mdw-shape__full);
|
|
71
|
+
--mdw-shape__size__top-start-size: 0px;
|
|
72
|
+
--mdw-shape__size__bottom-start-size: 0px;
|
|
57
73
|
}
|
|
58
74
|
|
|
59
75
|
#outline {
|
|
@@ -62,7 +78,7 @@ export default Button
|
|
|
62
78
|
z-index: -1;
|
|
63
79
|
}
|
|
64
80
|
|
|
65
|
-
#outline
|
|
81
|
+
:host(:last-of-type) #outline {
|
|
66
82
|
inset-inline-end: 0;
|
|
67
83
|
}
|
|
68
84
|
|
|
@@ -5,6 +5,11 @@ import SegmentedButton from './SegmentedButton.js';
|
|
|
5
5
|
|
|
6
6
|
/** @typedef {'compact'} DeprecatedHTMLMenuElementProperties */
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* A segmented button group arranges multiple `mdw-segmented-button` items
|
|
10
|
+
* so they behave as a related set of choices or toggles.
|
|
11
|
+
* @see https://m3.material.io/components/segmented-buttons/specs
|
|
12
|
+
*/
|
|
8
13
|
export default Box
|
|
9
14
|
.extend()
|
|
10
15
|
.mixin(KeyboardNav)
|
|
@@ -18,15 +23,7 @@ export default Box
|
|
|
18
23
|
})
|
|
19
24
|
.childEvents({
|
|
20
25
|
slot: {
|
|
21
|
-
slotchange
|
|
22
|
-
this.refreshTabIndexes();
|
|
23
|
-
const list = /** @type {NodeListOf<InstanceType<SegmentedButton>>} */ (this.kbdNavChildren);
|
|
24
|
-
for (const [index, child] of list.entries()) {
|
|
25
|
-
child.shapeStart = index === 0;
|
|
26
|
-
child.innerSegmentedButton = index > 0 && index < list.length - 1;
|
|
27
|
-
child.shapeEnd = index === list.length - 1;
|
|
28
|
-
}
|
|
29
|
-
},
|
|
26
|
+
slotchange: 'refreshTabIndexes',
|
|
30
27
|
},
|
|
31
28
|
})
|
|
32
29
|
.css`
|
|
@@ -45,7 +42,7 @@ export default Box
|
|
|
45
42
|
|
|
46
43
|
box-sizing: border-box;
|
|
47
44
|
min-inline-size: 100%;
|
|
48
|
-
flex:none;
|
|
45
|
+
flex: none;
|
|
49
46
|
}
|
|
50
47
|
|
|
51
48
|
:host([color]) {
|
package/components/Select.js
CHANGED
|
@@ -4,7 +4,11 @@ import StateMixin from '../mixins/StateMixin.js';
|
|
|
4
4
|
import TextFieldMixin from '../mixins/TextFieldMixin.js';
|
|
5
5
|
import ThemableMixin from '../mixins/ThemableMixin.js';
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
/**
|
|
8
|
+
* Select provides a control for choosing an option from a list of options.
|
|
9
|
+
* implements {HTMLSelectElement}
|
|
10
|
+
* @see https://m3.material.io/components/text-fields/overview
|
|
11
|
+
*/
|
|
8
12
|
export default CustomElement
|
|
9
13
|
.extend()
|
|
10
14
|
.mixin(ThemableMixin)
|
|
@@ -12,6 +16,7 @@ export default CustomElement
|
|
|
12
16
|
.mixin(ControlMixin)
|
|
13
17
|
.mixin(TextFieldMixin)
|
|
14
18
|
.observe({
|
|
19
|
+
/** Name of the trailing icon to render (defaults to the dropdown arrow). */
|
|
15
20
|
trailingIcon: { empty: 'arrow_drop_down' },
|
|
16
21
|
})
|
|
17
22
|
.overrides({
|
|
@@ -20,11 +25,13 @@ export default CustomElement
|
|
|
20
25
|
type: 'select-one',
|
|
21
26
|
})
|
|
22
27
|
.define({
|
|
28
|
+
/** Return the internal native <select> element used as the control. */
|
|
23
29
|
_select() {
|
|
24
30
|
return /** @type {HTMLSelectElement} */ (this.refs.control);
|
|
25
31
|
},
|
|
26
|
-
/** Readonly
|
|
32
|
+
/** Readonly: whether the underlying control allows multiple selection. */
|
|
27
33
|
multiple: { value: false },
|
|
34
|
+
/** Readonly: the rendered size of the native select control. */
|
|
28
35
|
size: { value: 1 },
|
|
29
36
|
})
|
|
30
37
|
.html`<slot id=slot></slot>`
|
|
@@ -48,9 +55,12 @@ export default CustomElement
|
|
|
48
55
|
suffix.remove();
|
|
49
56
|
})
|
|
50
57
|
.on({
|
|
58
|
+
/** When the form resets, restore the select value from any option[selected]. */
|
|
51
59
|
_formResetChanged(oldValue, newValue) {
|
|
52
60
|
if (!newValue) return;
|
|
53
|
-
|
|
61
|
+
/** @type {HTMLSelectElement} */
|
|
62
|
+
const selectedOption = this.querySelector('option[selected]');
|
|
63
|
+
this._select.value = selectedOption?.value ?? '';
|
|
54
64
|
},
|
|
55
65
|
})
|
|
56
66
|
.css`
|
package/components/Shape.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
import CustomElement from '../core/CustomElement.js';
|
|
2
2
|
import ShapeMaskedMixin from '../mixins/ShapeMaskedMixin.js';
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Shape applies shape tokens (corner radius) to elements and surfaces.
|
|
6
|
+
* @see https://m3.material.io/styles/shape/overview-principles
|
|
7
|
+
*/
|
|
4
8
|
export default CustomElement
|
|
5
9
|
.extend()
|
|
6
10
|
.mixin(ShapeMaskedMixin)
|
package/components/SideSheet.js
CHANGED
|
@@ -28,6 +28,11 @@ const SUPPORTS_SCROLLEND = 'onscrollend' in window;
|
|
|
28
28
|
* Modal side sheets must become "dialog-like", blocking access to all other elements on the screen.
|
|
29
29
|
* Modal side sheets can display elevation
|
|
30
30
|
*/
|
|
31
|
+
/**
|
|
32
|
+
* Side sheets present content in a surface that slides in from an edge; they
|
|
33
|
+
* support modal and static modes and can be themed and shaped.
|
|
34
|
+
* @see https://m3.material.io/components/side-sheets/overview
|
|
35
|
+
*/
|
|
31
36
|
export default CustomElement
|
|
32
37
|
.extend()
|
|
33
38
|
.mixin(ThemableMixin)
|
|
@@ -38,40 +43,58 @@ export default CustomElement
|
|
|
38
43
|
.mixin(DelegatesFocusMixin)
|
|
39
44
|
.mixin(ResizeObserverMixin)
|
|
40
45
|
.observe({
|
|
46
|
+
/** When true the side sheet is fixed (non-modal/static), occupying layout space. */
|
|
41
47
|
fixed: 'boolean',
|
|
48
|
+
/** Whether the sheet is currently open (visible). */
|
|
42
49
|
open: 'boolean',
|
|
50
|
+
/** When true, position the sheet at the inline end edge. */
|
|
43
51
|
inlineEnd: 'boolean',
|
|
52
|
+
/** Last measured inline size (px) used for layout/translate calculations. */
|
|
44
53
|
_lastComputedInlineSize: {
|
|
45
54
|
type: 'float',
|
|
46
55
|
nullable: false,
|
|
47
56
|
},
|
|
57
|
+
/** Animation duration (ms) for sheet open/close transitions. */
|
|
48
58
|
_animationDuration: {
|
|
49
59
|
type: 'integer',
|
|
50
60
|
value: 0,
|
|
51
61
|
},
|
|
62
|
+
/** Animation easing keyword used for sheet transitions. */
|
|
52
63
|
_animationEasing: {
|
|
53
64
|
value: 'ease-out',
|
|
54
65
|
},
|
|
66
|
+
/** Current drag delta X (px) while user is swiping the sheet. */
|
|
55
67
|
_dragDeltaX: 'float',
|
|
68
|
+
/** Starting X coordinate (px) for a drag gesture. */
|
|
56
69
|
_dragStartX: 'float',
|
|
70
|
+
/** CSS translateX value used to animate the sheet position. */
|
|
57
71
|
_translateX: { value: '-100%' },
|
|
72
|
+
/** Timestamp of the last child scroll event (used to avoid gesture conflicts). */
|
|
58
73
|
_lastChildScrollTime: 'float',
|
|
74
|
+
/** Event handler invoked when the sheet toggles. */
|
|
59
75
|
ontoggle: EVENT_HANDLER_TYPE,
|
|
76
|
+
/** Event handler invoked when the sheet closes. */
|
|
60
77
|
onclose: EVENT_HANDLER_TYPE,
|
|
78
|
+
/** Optional auto-open minimum viewport inline-size (px); -1 disables. */
|
|
61
79
|
autoOpen: {
|
|
62
80
|
type: 'float',
|
|
63
81
|
empty: -1,
|
|
64
82
|
},
|
|
83
|
+
/** Optional auto-close maximum viewport inline-size (px); -1 disables. */
|
|
65
84
|
autoClose: {
|
|
66
85
|
type: 'float',
|
|
67
86
|
empty: -1,
|
|
68
87
|
},
|
|
88
|
+
/** Inline-size breakpoint (px) at which the sheet becomes `fixed`. */
|
|
69
89
|
fixedBreakpoint: {
|
|
70
90
|
type: 'float',
|
|
71
91
|
empty: 0,
|
|
72
92
|
},
|
|
93
|
+
/** Internal flag computed from directionality and `inlineEnd`. */
|
|
73
94
|
_isSideSheetRtl: 'boolean',
|
|
95
|
+
/** The theme color token used for the sheet background. */
|
|
74
96
|
color: 'string',
|
|
97
|
+
/** Optional fixed-mode color token applied when sheet is fixed. */
|
|
75
98
|
fixedColor: 'string',
|
|
76
99
|
})
|
|
77
100
|
.set({
|
|
@@ -79,6 +102,7 @@ export default CustomElement
|
|
|
79
102
|
_scrim: null,
|
|
80
103
|
})
|
|
81
104
|
.observe({
|
|
105
|
+
/** Computed host style when `fixed` and `fixedColor` are set. */
|
|
82
106
|
_styles: {
|
|
83
107
|
...ELEMENT_STYLE_TYPE,
|
|
84
108
|
get({ fixed, fixedColor }) {
|
|
@@ -87,6 +111,7 @@ export default CustomElement
|
|
|
87
111
|
}
|
|
88
112
|
},
|
|
89
113
|
},
|
|
114
|
+
/** Computed animation/style object applied to the host for open/close. */
|
|
90
115
|
hostStyles: {
|
|
91
116
|
...ELEMENT_ANIMATION_TYPE,
|
|
92
117
|
get({
|
|
@@ -110,6 +135,10 @@ export default CustomElement
|
|
|
110
135
|
})
|
|
111
136
|
.html`<slot id=slot></slot>`
|
|
112
137
|
.methods({
|
|
138
|
+
/**
|
|
139
|
+
* Ensure a scrim is present when the sheet is modal (open && !fixed).
|
|
140
|
+
* When `animate` is true, keep the scrim around to run its fade-out.
|
|
141
|
+
*/
|
|
113
142
|
checkForScrim(animate = false) {
|
|
114
143
|
let { open, fixed, _scrim } = this;
|
|
115
144
|
if (open && !fixed) {
|
|
@@ -133,6 +162,7 @@ export default CustomElement
|
|
|
133
162
|
_scrim.hidden = true;
|
|
134
163
|
}
|
|
135
164
|
},
|
|
165
|
+
/** Evaluate drag state and decide whether to close or snap open. */
|
|
136
166
|
checkDragFinished() {
|
|
137
167
|
const { open, _dragDeltaX, _lastComputedInlineSize, fixed, _isSideSheetRtl } = this;
|
|
138
168
|
if (!open || fixed || _dragDeltaX == null) return;
|
|
@@ -150,9 +180,8 @@ export default CustomElement
|
|
|
150
180
|
this._translateX = '0';
|
|
151
181
|
this._animationEasing = 'ease-in';
|
|
152
182
|
}
|
|
153
|
-
this._dragDeltaY = null;
|
|
154
|
-
this._dragStartY = null;
|
|
155
183
|
},
|
|
184
|
+
/** Recompute `fixed`/`open` state based on the window width and breakpoints. */
|
|
156
185
|
onWindowResize() {
|
|
157
186
|
const { autoOpen, fixedBreakpoint, autoClose } = this;
|
|
158
187
|
const containerWidth = window.innerWidth;
|
package/components/Slider.js
CHANGED
|
@@ -32,6 +32,10 @@ function valueAsFraction(value, min, max) {
|
|
|
32
32
|
return (nValue - nMin) / (nMax - nMin);
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
/**
|
|
36
|
+
* Slider allows users to select a value from a range by dragging a thumb.
|
|
37
|
+
* @see https://m3.material.io/components/sliders/specs
|
|
38
|
+
*/
|
|
35
39
|
export default CustomElement
|
|
36
40
|
.extend()
|
|
37
41
|
.mixin(ThemableMixin)
|
|
@@ -42,18 +46,26 @@ export default CustomElement
|
|
|
42
46
|
type: 'range',
|
|
43
47
|
})
|
|
44
48
|
.observe({
|
|
45
|
-
|
|
49
|
+
/** Number of tick marks to show along the track (integer). */
|
|
50
|
+
ticks: 'integer',
|
|
51
|
+
/** Internal string representation of the current value used for formatting. */
|
|
46
52
|
_valueAsText: { nullable: false },
|
|
53
|
+
/** Text to show in the thumb label; when null the numeric value is shown. */
|
|
47
54
|
thumbLabel: {
|
|
48
55
|
type: 'string',
|
|
49
56
|
reflect: 'read',
|
|
50
57
|
},
|
|
58
|
+
/** Rounded numeric value (used while dragging) tracked as a float. */
|
|
51
59
|
_roundedValue: 'float',
|
|
60
|
+
/** True while the pointer is hovering the thumb (used to show the label). */
|
|
52
61
|
_isHoveringThumb: 'boolean',
|
|
62
|
+
/** Last `value` string that produced a dispatched `change` event; used to avoid duplicates. */
|
|
53
63
|
_lastDispatchedChangeValue: 'string',
|
|
54
64
|
})
|
|
55
65
|
.methods({
|
|
56
66
|
/**
|
|
67
|
+
* Handle pointer or touch interactions on the native control to compute
|
|
68
|
+
* position and update the intermediate rounded value while dragging.
|
|
57
69
|
* @param {(MouseEvent|TouchEvent) & {currentTarget:HTMLInputElement}} event
|
|
58
70
|
* @return {void}
|
|
59
71
|
*/
|
|
@@ -155,13 +167,18 @@ export default CustomElement
|
|
|
155
167
|
this._isHoveringThumb = offsetX >= thumbMin && offsetX <= thumbMax;
|
|
156
168
|
},
|
|
157
169
|
|
|
158
|
-
/**
|
|
170
|
+
/**
|
|
171
|
+
* Pointer leave/blur handler for the control; hides the thumb label when focus is lost.
|
|
172
|
+
* @param {Event} event
|
|
173
|
+
*/
|
|
159
174
|
onLeaveEvent({ currentTarget }) {
|
|
160
175
|
if (isFocused(/** @type {Element} */ (currentTarget))) return;
|
|
161
176
|
this._isHoveringThumb = false;
|
|
162
177
|
},
|
|
163
178
|
|
|
164
179
|
/**
|
|
180
|
+
* Finalize interaction with the control: commit the rounded value to the
|
|
181
|
+
* native input and dispatch a `change` event if the value changed.
|
|
165
182
|
* @param {(MouseEvent|TouchEvent) & {currentTarget:HTMLInputElement}} event
|
|
166
183
|
* @return {void}
|
|
167
184
|
*/
|
|
@@ -206,15 +223,18 @@ export default CustomElement
|
|
|
206
223
|
},
|
|
207
224
|
})
|
|
208
225
|
.expressions({
|
|
226
|
+
/** Compute inline style variables for the track, including ticks and value fraction. */
|
|
209
227
|
computeTrackStyle({ ticks, _valueAsText, min, max }) {
|
|
210
228
|
return [
|
|
211
229
|
ticks ? `--ticks:${ticks}` : null,
|
|
212
230
|
`--value:${valueAsFraction(_valueAsText, min, max)}`,
|
|
213
231
|
].filter(Boolean).join(';') || null;
|
|
214
232
|
},
|
|
233
|
+
/** True when the thumb label should be hidden (not hovering and not focused). */
|
|
215
234
|
_thumbLabelHidden({ _isHoveringThumb, focusedState }) {
|
|
216
235
|
return (!_isHoveringThumb && !focusedState);
|
|
217
236
|
},
|
|
237
|
+
/** Compute the label text to show in the thumb: explicit `thumbLabel` or numeric value. */
|
|
218
238
|
_computedThumbLabel({ thumbLabel, _valueAsText }) {
|
|
219
239
|
return thumbLabel ?? _valueAsText;
|
|
220
240
|
},
|