@shortfuse/materialdesignweb 0.5.0 → 0.7.1-0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +155 -77
- package/bin/generate-css.js +12 -0
- package/components/Badge.css +38 -0
- package/components/Badge.js +15 -0
- package/components/Body.css +14 -0
- package/components/Body.js +7 -0
- package/components/BottomAppBar.css +23 -0
- package/components/BottomAppBar.js +25 -0
- package/components/Box.css +31 -0
- package/components/Box.js +24 -0
- package/components/Button.css +147 -0
- package/components/Button.js +95 -0
- package/components/Button.md +61 -0
- package/components/Card.css +109 -0
- package/components/Card.js +82 -0
- package/components/Checkbox.css +89 -0
- package/components/Checkbox.js +59 -0
- package/components/CheckboxIcon.css +90 -0
- package/components/CheckboxIcon.js +41 -0
- package/components/Chip.css +35 -0
- package/components/Chip.js +22 -0
- package/components/Dialog.css +235 -0
- package/components/Dialog.js +327 -0
- package/components/DialogActions.js +13 -0
- package/components/Divider.css +41 -0
- package/components/Divider.js +13 -0
- package/components/ExtendedFab.css +24 -0
- package/components/ExtendedFab.js +11 -0
- package/components/Fab.css +23 -0
- package/components/Fab.js +26 -0
- package/components/FilterChip.css +80 -0
- package/components/FilterChip.js +51 -0
- package/components/Headline.css +14 -0
- package/components/Headline.js +33 -0
- package/components/Icon.css +76 -0
- package/components/Icon.js +174 -0
- package/components/IconButton.css +150 -0
- package/components/IconButton.js +65 -0
- package/components/Input.js +16 -0
- package/components/Label.css +14 -0
- package/components/Label.js +7 -0
- package/components/Layout.css +19 -0
- package/components/Layout.js +12 -0
- package/components/List.css +12 -0
- package/components/List.js +17 -0
- package/components/ListItem.css +224 -0
- package/components/ListItem.js +112 -0
- package/components/ListOption.css +34 -0
- package/components/ListOption.js +122 -0
- package/components/ListSelect.css +9 -0
- package/components/ListSelect.js +206 -0
- package/components/Menu.css +171 -0
- package/components/Menu.js +470 -0
- package/components/MenuItem.css +53 -0
- package/components/MenuItem.js +215 -0
- package/components/Nav.css +17 -0
- package/components/Nav.js +23 -0
- package/components/NavBar.css +34 -0
- package/components/NavBar.js +88 -0
- package/components/NavBarItem.css +41 -0
- package/components/NavBarItem.js +7 -0
- package/components/NavDrawer.css +31 -0
- package/components/NavDrawer.js +13 -0
- package/components/NavDrawerItem.css +42 -0
- package/components/NavDrawerItem.js +12 -0
- package/components/NavItem.css +181 -0
- package/components/NavItem.js +83 -0
- package/components/NavRail.css +47 -0
- package/components/NavRail.js +17 -0
- package/components/NavRailItem.css +25 -0
- package/components/NavRailItem.js +7 -0
- package/components/Option.js +91 -0
- package/components/Outline.css +138 -0
- package/components/Pane.css +261 -0
- package/components/Pane.js +21 -0
- package/components/Progress.css +75 -0
- package/components/Progress.js +67 -0
- package/components/ProgressCircle.css +226 -0
- package/components/ProgressLine.css +155 -0
- package/components/Radio.css +95 -0
- package/components/Radio.js +42 -0
- package/components/RadioIcon.css +73 -0
- package/components/RadioIcon.js +37 -0
- package/components/Ripple.css +74 -0
- package/components/Ripple.js +114 -0
- package/components/SegmentedButton.css +94 -0
- package/components/SegmentedButton.js +49 -0
- package/components/SegmentedButtonGroup.css +12 -0
- package/components/SegmentedButtonGroup.js +44 -0
- package/components/Select.css +52 -0
- package/components/Select.js +71 -0
- package/components/Shape.css +132 -0
- package/components/Shape.js +25 -0
- package/components/Slider.css +307 -0
- package/components/Slider.js +206 -0
- package/components/Snackbar.css +80 -0
- package/components/Snackbar.js +75 -0
- package/components/Surface.css +10 -0
- package/components/Surface.js +23 -0
- package/components/Switch.css +64 -0
- package/components/Switch.js +127 -0
- package/components/SwitchIcon.css +178 -0
- package/components/SwitchIcon.js +89 -0
- package/components/SwitchIconAnimations.css +89 -0
- package/components/Tab.css +85 -0
- package/components/Tab.js +103 -0
- package/components/TabContent.js +151 -0
- package/components/TabList.css +129 -0
- package/components/TabList.js +309 -0
- package/components/TabPanel.js +37 -0
- package/components/TextArea.css +93 -0
- package/components/TextArea.js +229 -0
- package/components/Title.css +14 -0
- package/components/Title.js +15 -0
- package/components/Tooltip.css +40 -0
- package/components/Tooltip.js +22 -0
- package/components/TopAppBar.css +209 -0
- package/components/TopAppBar.js +201 -0
- package/core/Composition.js +988 -0
- package/core/CustomElement.js +844 -0
- package/core/ICustomElement.d.ts +288 -0
- package/core/ICustomElement.js +1 -0
- package/core/css.js +51 -0
- package/core/customTypes.js +125 -0
- package/core/dom.js +56 -154
- package/core/identify.js +40 -0
- package/core/observe.js +410 -0
- package/core/template.js +121 -0
- package/core/typings.d.ts +135 -0
- package/core/typings.js +1 -0
- package/index.js +77 -0
- package/mixins/AriaReflectorMixin.js +42 -0
- package/mixins/AriaToolbarMixin.js +13 -0
- package/mixins/ControlMixin.css +57 -0
- package/mixins/ControlMixin.js +212 -0
- package/mixins/DensityMixin.css +40 -0
- package/mixins/DensityMixin.js +11 -0
- package/mixins/FlexableMixin.css +79 -0
- package/mixins/FlexableMixin.js +32 -0
- package/mixins/FormAssociatedMixin.js +170 -0
- package/mixins/InputMixin.js +335 -0
- package/mixins/KeyboardNavMixin.js +244 -0
- package/mixins/RTLObserverMixin.js +35 -0
- package/mixins/ResizeObserverMixin.js +38 -0
- package/mixins/RippleMixin.css +12 -0
- package/mixins/RippleMixin.js +115 -0
- package/mixins/ScrollListenerMixin.js +100 -0
- package/mixins/ShapeMixin.css +135 -0
- package/mixins/ShapeMixin.js +31 -0
- package/mixins/StateMixin.css +82 -0
- package/mixins/StateMixin.js +114 -0
- package/mixins/SurfaceMixin.css +150 -0
- package/mixins/SurfaceMixin.js +32 -0
- package/mixins/TextFieldMixin.css +657 -0
- package/mixins/TextFieldMixin.js +121 -0
- package/mixins/ThemableMixin.css +204 -0
- package/mixins/ThemableMixin.js +16 -0
- package/mixins/TooltipTriggerMixin.css +27 -0
- package/mixins/TooltipTriggerMixin.js +366 -0
- package/mixins/TouchTargetMixin.css +26 -0
- package/mixins/TouchTargetMixin.js +9 -0
- package/package.json +55 -49
- package/theming/index.js +473 -0
- package/theming/loader.js +24 -0
- package/utils/cli.js +11 -0
- package/utils/color_keywords.js +151 -0
- package/utils/hct/Cam16.js +298 -0
- package/utils/hct/CorePalette.js +84 -0
- package/utils/hct/Hct.js +172 -0
- package/utils/hct/Scheme.js +587 -0
- package/utils/hct/TonalPalette.js +68 -0
- package/utils/hct/ViewingConditions.js +136 -0
- package/utils/hct/blend.js +93 -0
- package/utils/hct/colorUtils.js +302 -0
- package/utils/hct/hctSolver.js +559 -0
- package/utils/hct/helper.js +182 -0
- package/utils/hct/mathUtils.js +153 -0
- package/utils/jsonMergePatch.js +100 -0
- package/utils/jsx-runtime.js +101 -0
- package/utils/popup.js +117 -0
- package/utils/svg.js +12 -0
- package/.browserslistrc +0 -4
- package/.eslintrc.json +0 -204
- package/.stylelintrc.json +0 -645
- package/.vscode/launch.json +0 -31
- package/.vscode/settings.json +0 -3
- package/.vscode/tasks.json +0 -32
- package/CHANGELOG.md +0 -36
- package/CODE_OF_CONDUCT.md +0 -46
- package/adapters/datatable/column.js +0 -176
- package/adapters/datatable/index.js +0 -960
- package/adapters/dom/index.js +0 -586
- package/adapters/list/index.js +0 -69
- package/adapters/search/index.js +0 -495
- package/components/appbar/_spec.scss +0 -165
- package/components/appbar/_theme.scss +0 -0
- package/components/appbar/index.scss +0 -2
- package/components/banner/_spec.scss +0 -83
- package/components/banner/_theme.scss +0 -0
- package/components/banner/index.scss +0 -2
- package/components/bottomnav/README.md +0 -85
- package/components/bottomnav/_spec.scss +0 -149
- package/components/bottomnav/_theme.scss +0 -0
- package/components/bottomnav/index.js +0 -117
- package/components/bottomnav/index.scss +0 -2
- package/components/bottomnav/item.js +0 -88
- package/components/button/README.md +0 -61
- package/components/button/_spec.scss +0 -162
- package/components/button/_theme.scss +0 -42
- package/components/button/index.eta +0 -32
- package/components/button/index.js +0 -43
- package/components/button/index.pug +0 -18
- package/components/button/index.scss +0 -2
- package/components/card/_spec.scss +0 -241
- package/components/card/_theme.scss +0 -0
- package/components/card/index.scss +0 -2
- package/components/chip/_spec.scss +0 -111
- package/components/chip/_theme.scss +0 -105
- package/components/chip/index.js +0 -23
- package/components/chip/index.scss +0 -2
- package/components/chip/item.js +0 -20
- package/components/datatable/_spec.scss +0 -225
- package/components/datatable/_theme.scss +0 -128
- package/components/datatable/cell.js +0 -44
- package/components/datatable/columnheader.js +0 -46
- package/components/datatable/index.js +0 -374
- package/components/datatable/index.scss +0 -2
- package/components/datatable/row.js +0 -48
- package/components/datatable/rowheader.js +0 -18
- package/components/dialog/_spec.scss +0 -203
- package/components/dialog/_theme.scss +0 -7
- package/components/dialog/index.js +0 -601
- package/components/dialog/index.scss +0 -2
- package/components/divider/_spec.scss +0 -11
- package/components/divider/_theme.scss +0 -0
- package/components/divider/index.scss +0 -2
- package/components/elevation/_spec.scss +0 -9
- package/components/elevation/_theme.scss +0 -0
- package/components/elevation/index.scss +0 -2
- package/components/fab/_spec.scss +0 -210
- package/components/fab/_theme.scss +0 -0
- package/components/fab/index.js +0 -99
- package/components/fab/index.scss +0 -2
- package/components/grid/_spec.scss +0 -169
- package/components/grid/_theme.scss +0 -0
- package/components/grid/index.scss +0 -2
- package/components/layout/_mixins.scss +0 -11
- package/components/layout/_spec.scss +0 -916
- package/components/layout/_theme.scss +0 -19
- package/components/layout/index.js +0 -454
- package/components/layout/index.scss +0 -2
- package/components/list/_spec.scss +0 -363
- package/components/list/_theme.scss +0 -102
- package/components/list/content.js +0 -106
- package/components/list/index.js +0 -256
- package/components/list/index.scss +0 -2
- package/components/list/item.js +0 -167
- package/components/list/secondary.js +0 -45
- package/components/menu/_spec.scss +0 -329
- package/components/menu/_theme.scss +0 -0
- package/components/menu/index.js +0 -705
- package/components/menu/index.scss +0 -2
- package/components/menu/item.js +0 -231
- package/components/progress/_spec.scss +0 -156
- package/components/progress/_theme.scss +0 -0
- package/components/progress/index.js +0 -36
- package/components/progress/index.scss +0 -2
- package/components/selection/_spec.scss +0 -376
- package/components/selection/_theme.scss +0 -134
- package/components/selection/index.eta +0 -60
- package/components/selection/index.js +0 -70
- package/components/selection/index.pug +0 -30
- package/components/selection/index.scss +0 -2
- package/components/selection/input.js +0 -54
- package/components/selection/radiogroup.js +0 -40
- package/components/slider/_spec.scss +0 -59
- package/components/slider/_theme.scss +0 -0
- package/components/slider/index.scss +0 -2
- package/components/snackbar/_spec.scss +0 -150
- package/components/snackbar/_theme.scss +0 -0
- package/components/snackbar/index.js +0 -338
- package/components/snackbar/index.scss +0 -2
- package/components/tab/_spec.scss +0 -220
- package/components/tab/_theme.scss +0 -0
- package/components/tab/content.js +0 -210
- package/components/tab/index.js +0 -257
- package/components/tab/index.scss +0 -2
- package/components/tab/item.js +0 -88
- package/components/tab/list.js +0 -196
- package/components/tab/panel.js +0 -54
- package/components/textfield/README.md +0 -179
- package/components/textfield/_spec.scss +0 -763
- package/components/textfield/_theme.scss +0 -264
- package/components/textfield/index.eta +0 -74
- package/components/textfield/index.js +0 -160
- package/components/textfield/index.pug +0 -30
- package/components/textfield/index.scss +0 -2
- package/components/tooltip/_spec.scss +0 -185
- package/components/tooltip/_theme.scss +0 -0
- package/components/tooltip/index.scss +0 -2
- package/components/type/_spec.scss +0 -227
- package/components/type/_theme.scss +0 -0
- package/components/type/index.scss +0 -2
- package/core/_breakpoint.scss +0 -189
- package/core/_elevation.scss +0 -78
- package/core/_length.scss +0 -8
- package/core/_motion.scss +0 -31
- package/core/_platform.scss +0 -12
- package/core/_type.scss +0 -128
- package/core/aria/attributes.js +0 -141
- package/core/aria/button.js +0 -49
- package/core/aria/keyboard.js +0 -92
- package/core/aria/rovingtabindex.js +0 -175
- package/core/aria/tab.js +0 -59
- package/core/document/index.js +0 -39
- package/core/overlay/_spec.scss +0 -28
- package/core/overlay/_theme.scss +0 -147
- package/core/overlay/index.js +0 -95
- package/core/overlay/index.scss +0 -2
- package/core/ripple/_spec.scss +0 -196
- package/core/ripple/_theme.scss +0 -20
- package/core/ripple/index.js +0 -286
- package/core/ripple/index.scss +0 -2
- package/core/theme/_aliases.scss +0 -15
- package/core/theme/_config.scss +0 -8
- package/core/theme/_functions.scss +0 -22
- package/core/theme/_palettes.scss +0 -405
- package/core/theme/_spec.scss +0 -0
- package/core/theme/_theme.scss +0 -268
- package/core/theme/index.js +0 -50
- package/core/theme/index.scss +0 -4
- package/core/throttler.js +0 -42
- package/core/transition/index.js +0 -465
- package/docs/_flex.scss +0 -28
- package/docs/_menuoptions.js +0 -183
- package/docs/_partials/_androidnavbar.eta +0 -5
- package/docs/_partials/_androidstatusbar.eta +0 -13
- package/docs/_partials/_appbar.eta +0 -27
- package/docs/_partials/_buttontest.eta +0 -31
- package/docs/_partials/_header.eta +0 -146
- package/docs/_partials/_navlistitem.eta +0 -16
- package/docs/_partials/_target.eta +0 -1
- package/docs/_sample-utils.js +0 -88
- package/docs/_storage.js +0 -33
- package/docs/docs.scss +0 -331
- package/docs/framework.scss +0 -26
- package/docs/index.eta +0 -12
- package/docs/index.js +0 -7
- package/docs/pages/appbar.eta +0 -108
- package/docs/pages/appbar.js +0 -0
- package/docs/pages/bottomnav.eta +0 -188
- package/docs/pages/bottomnav.js +0 -118
- package/docs/pages/button.eta +0 -124
- package/docs/pages/button.js +0 -224
- package/docs/pages/card.eta +0 -90
- package/docs/pages/card.js +0 -175
- package/docs/pages/chip.eta +0 -122
- package/docs/pages/chip.js +0 -80
- package/docs/pages/color.eta +0 -143
- package/docs/pages/color.js +0 -261
- package/docs/pages/datatable.eta +0 -323
- package/docs/pages/datatable.js +0 -160
- package/docs/pages/dialog.eta +0 -184
- package/docs/pages/dialog.js +0 -174
- package/docs/pages/dom.eta +0 -26
- package/docs/pages/dom.js +0 -140
- package/docs/pages/elevation.eta +0 -35
- package/docs/pages/elevation.js +0 -0
- package/docs/pages/fab.eta +0 -99
- package/docs/pages/fab.js +0 -43
- package/docs/pages/grid.eta +0 -135
- package/docs/pages/grid.js +0 -128
- package/docs/pages/layout.eta +0 -8
- package/docs/pages/layout.js +0 -0
- package/docs/pages/list.eta +0 -465
- package/docs/pages/list.js +0 -8
- package/docs/pages/menu.eta +0 -274
- package/docs/pages/menu.js +0 -213
- package/docs/pages/overlay.eta +0 -69
- package/docs/pages/overlay.js +0 -3
- package/docs/pages/progress.eta +0 -23
- package/docs/pages/progress.js +0 -12
- package/docs/pages/ripple.eta +0 -27
- package/docs/pages/ripple.js +0 -3
- package/docs/pages/search.eta +0 -242
- package/docs/pages/search.js +0 -226
- package/docs/pages/selection.eta +0 -107
- package/docs/pages/selection.js +0 -12
- package/docs/pages/slider.eta +0 -23
- package/docs/pages/slider.js +0 -0
- package/docs/pages/snackbar.eta +0 -83
- package/docs/pages/snackbar.js +0 -157
- package/docs/pages/tab.eta +0 -407
- package/docs/pages/tab.js +0 -152
- package/docs/pages/textfield.eta +0 -487
- package/docs/pages/textfield.js +0 -257
- package/docs/pages/tooltip.eta +0 -92
- package/docs/pages/tooltip.js +0 -0
- package/docs/pages/transition.eta +0 -117
- package/docs/pages/transition.js +0 -52
- package/docs/pages/type.eta +0 -31
- package/docs/pages/type.js +0 -0
- package/docs/postrender.js +0 -41
- package/docs/prerender.js +0 -16
- package/docs/pwa/_dialogs.eta +0 -143
- package/docs/pwa/_menus.eta +0 -16
- package/docs/pwa/pwa-prerender.js +0 -3
- package/docs/pwa/pwa.eta +0 -478
- package/docs/pwa/pwa.js +0 -298
- package/docs/pwa/pwa.scss +0 -31
- package/docs/themes/theme-colored.scss +0 -15
- package/docs/themes/theme-default.scss +0 -3
- package/index.scss +0 -27
- package/jsconfig.json +0 -16
- package/scripts/deploy-docs.sh +0 -9
- package/templates/index.eta +0 -2
- package/templates/index.pug +0 -3
- package/tsconfig.json +0 -16
- package/webpack.config.js +0 -304
package/core/template.js
ADDED
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { generateUID } from './identify.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Property are bound to an ID+Node
|
|
5
|
+
* Values are either getter or via an function
|
|
6
|
+
* @template {any} T
|
|
7
|
+
* @typedef {Object} InlineFunctionEntry
|
|
8
|
+
* @prop {(data:T) => any} fn
|
|
9
|
+
* @prop {Set<keyof T & string>} [props]
|
|
10
|
+
* @prop {T} [defaultValue]
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
/** @type {Document} */
|
|
14
|
+
let _inactiveDocument;
|
|
15
|
+
|
|
16
|
+
/** @type {boolean} */
|
|
17
|
+
let _cssStyleSheetConstructable;
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @param {string} [fromString]
|
|
21
|
+
* @return {DocumentFragment}
|
|
22
|
+
*/
|
|
23
|
+
export function generateFragment(fromString) {
|
|
24
|
+
_inactiveDocument ??= document.implementation.createHTMLDocument();
|
|
25
|
+
if (fromString == null) {
|
|
26
|
+
return _inactiveDocument.createDocumentFragment();
|
|
27
|
+
}
|
|
28
|
+
return _inactiveDocument.createRange().createContextualFragment(fromString);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
/** @type {Map<string, InlineFunctionEntry<?>>} */
|
|
32
|
+
export const inlineFunctions = new Map();
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @template T
|
|
36
|
+
* @typedef {Object} RenderOptions
|
|
37
|
+
* @prop {Object} context
|
|
38
|
+
* @prop {ParentNode} root
|
|
39
|
+
* @prop {Object<string, HTMLElement>} refs
|
|
40
|
+
*/
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @param {(data: Partial<any>) => any} fn
|
|
44
|
+
* @return {string}
|
|
45
|
+
*/
|
|
46
|
+
export function addInlineFunction(fn) {
|
|
47
|
+
const internalName = `#${generateUID()}`;
|
|
48
|
+
inlineFunctions.set(internalName, { fn });
|
|
49
|
+
return `{${internalName}}`;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* @param {TemplateStringsArray} array
|
|
54
|
+
* @param {...(string)} substitutions
|
|
55
|
+
* @return {HTMLStyleElement|CSSStyleSheet}
|
|
56
|
+
*/
|
|
57
|
+
export function css(array, ...substitutions) {
|
|
58
|
+
const content = String.raw({ raw: array }, ...substitutions);
|
|
59
|
+
if (_cssStyleSheetConstructable == null) {
|
|
60
|
+
try {
|
|
61
|
+
const sheet = new CSSStyleSheet();
|
|
62
|
+
_cssStyleSheetConstructable = true;
|
|
63
|
+
sheet.replaceSync(content);
|
|
64
|
+
return sheet;
|
|
65
|
+
} catch {
|
|
66
|
+
_cssStyleSheetConstructable = false;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
if (_cssStyleSheetConstructable) {
|
|
70
|
+
const sheet = new CSSStyleSheet();
|
|
71
|
+
_cssStyleSheetConstructable = true;
|
|
72
|
+
sheet.replaceSync(content);
|
|
73
|
+
return sheet;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
_inactiveDocument ??= document.implementation.createHTMLDocument();
|
|
77
|
+
const style = _inactiveDocument.createElement('style');
|
|
78
|
+
style.textContent = content;
|
|
79
|
+
return style;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* @template T1
|
|
84
|
+
* @template T2
|
|
85
|
+
* @param {TemplateStringsArray} strings
|
|
86
|
+
* @param {...(string|DocumentFragment|Element|((this:T1, data:T2) => any))} substitutions
|
|
87
|
+
* @return {DocumentFragment}
|
|
88
|
+
*/
|
|
89
|
+
export function html(strings, ...substitutions) {
|
|
90
|
+
/** @type {Map<string, DocumentFragment|Element>} */
|
|
91
|
+
let tempSlots;
|
|
92
|
+
const replacements = substitutions.map((sub) => {
|
|
93
|
+
switch (typeof sub) {
|
|
94
|
+
case 'string': return sub;
|
|
95
|
+
case 'function': return addInlineFunction(sub);
|
|
96
|
+
case 'object': {
|
|
97
|
+
if (sub == null) {
|
|
98
|
+
console.warn(sub, 'is null', strings);
|
|
99
|
+
return '';
|
|
100
|
+
}
|
|
101
|
+
// Assume Element
|
|
102
|
+
const tempId = generateUID();
|
|
103
|
+
tempSlots ??= new Map();
|
|
104
|
+
tempSlots.set(tempId, sub);
|
|
105
|
+
return `<div id="${tempId}"></div>`;
|
|
106
|
+
}
|
|
107
|
+
default:
|
|
108
|
+
throw new Error(`Unexpected substitution: ${sub}`);
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
const compiledString = String.raw({ raw: strings }, ...replacements);
|
|
112
|
+
const fragment = generateFragment(compiledString);
|
|
113
|
+
if (tempSlots) {
|
|
114
|
+
for (const [id, element] of tempSlots) {
|
|
115
|
+
const slot = fragment.getElementById(id);
|
|
116
|
+
slot.replaceWith(element);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return fragment;
|
|
121
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
type ObserverPropertyType = 'string' | 'boolean' | 'map' | 'set' | 'float' | 'integer' | 'object' | 'function';
|
|
2
|
+
|
|
3
|
+
type InlineTemplate<T1, T2=T1> = (fn: (this:T1, data: T2) => any) => string;
|
|
4
|
+
|
|
5
|
+
type HTMLTemplater<T1, T2=T1> = ((
|
|
6
|
+
string: TemplateStringsArray, ...substitutions: (string|DocumentFragment|Element|((this:T1, data:T2) => any))[]
|
|
7
|
+
) => DocumentFragment);
|
|
8
|
+
|
|
9
|
+
type ParsedObserverPropertyType<T extends ObserverPropertyType> =
|
|
10
|
+
T extends 'boolean' ? boolean
|
|
11
|
+
: T extends 'string' ? string
|
|
12
|
+
: T extends 'float' | 'integer' ? number
|
|
13
|
+
: T extends 'object' ? any
|
|
14
|
+
: T extends 'function' ? (...args:any) => any
|
|
15
|
+
: unknown;
|
|
16
|
+
|
|
17
|
+
type ObserverOptions<
|
|
18
|
+
T1 extends ObserverPropertyType,
|
|
19
|
+
T2 = any,
|
|
20
|
+
C extends object = any
|
|
21
|
+
> = {
|
|
22
|
+
type?: T1;
|
|
23
|
+
attr?: string;
|
|
24
|
+
|
|
25
|
+
/** Default true */
|
|
26
|
+
readonly?: boolean
|
|
27
|
+
enumerable?: boolean;
|
|
28
|
+
|
|
29
|
+
/** Defaults to false if type is boolean */
|
|
30
|
+
nullable?: boolean;
|
|
31
|
+
|
|
32
|
+
/** Empty value when not nullable */
|
|
33
|
+
empty?: T2;
|
|
34
|
+
/** Initial value (empty value if not specified) */
|
|
35
|
+
value?: T2;
|
|
36
|
+
values?: WeakMap<C, T2>;
|
|
37
|
+
reflect?: boolean | 'write' | 'read';
|
|
38
|
+
/** Function used when null passed */
|
|
39
|
+
changedCallback?: (this:C, oldValue:T2, newValue:T2, changes:any)=>any;
|
|
40
|
+
nullParser?: (this:C, value:null|undefined)=>T2;
|
|
41
|
+
parser?: (this:C, value:any)=>T2;
|
|
42
|
+
/** Function used when comparing */
|
|
43
|
+
diff?: (this:C, a:T2, b:T2)=> any,
|
|
44
|
+
is?: (this:C, a:T2, b:T2)=>boolean
|
|
45
|
+
get?: (this:C, data:Partial<C>, fn?: () => T2) => T2
|
|
46
|
+
set?: (this:C, value: T2, fn?:(value2: T2) => any) => any,
|
|
47
|
+
attributeChangedCallback?: (this:C, name:string, oldValue: string, newValue: string) => any;
|
|
48
|
+
propChangedCallback?: (this:C, name:string, oldValue: T2, newValue: T2, changes:any) => any;
|
|
49
|
+
validValues?: WeakMap<C, T2>;
|
|
50
|
+
watchers?: [keyof C, (this:C, ...args:any[]) => any][];
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
type ObserverConfiguration<
|
|
54
|
+
T1 extends ObserverPropertyType,
|
|
55
|
+
T2 = any,
|
|
56
|
+
K = string,
|
|
57
|
+
C extends object = any> = ObserverOptions<T1, T2, C> & {
|
|
58
|
+
key: K,
|
|
59
|
+
values?: WeakMap<C, T2>;
|
|
60
|
+
attrValues?: WeakMap<C, string>;
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
type ParsedProps<T> = {
|
|
64
|
+
[P in keyof T]:
|
|
65
|
+
T[P] extends (...args:any[]) => infer T2 ? T2
|
|
66
|
+
: T[P] extends ObserverPropertyType
|
|
67
|
+
? ParsedObserverPropertyType<T[P]>
|
|
68
|
+
: T[P] extends {type: ObserverPropertyType}
|
|
69
|
+
? ParsedObserverPropertyType<T[P]['type']>
|
|
70
|
+
: T[P] extends ObserverOptions<null, infer T2>
|
|
71
|
+
? unknown extends T2 ? string : T2
|
|
72
|
+
: never
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
type HTMLElementCancellableEventMap = Pick<HTMLElementEventMap,
|
|
76
|
+
'auxclick' |
|
|
77
|
+
'beforeinput' |
|
|
78
|
+
// 'cancel' |
|
|
79
|
+
'click' |
|
|
80
|
+
'compositionstart' |
|
|
81
|
+
'contextmenu' |
|
|
82
|
+
'drag' |
|
|
83
|
+
'dragenter' |
|
|
84
|
+
'dragover' |
|
|
85
|
+
'dragstart' |
|
|
86
|
+
'drop' |
|
|
87
|
+
'invalid' |
|
|
88
|
+
'keydown' |
|
|
89
|
+
'keypress' |
|
|
90
|
+
'keyup' |
|
|
91
|
+
'mousedown' |
|
|
92
|
+
'mousemove' |
|
|
93
|
+
'mouseout' |
|
|
94
|
+
'mouseover' |
|
|
95
|
+
'mouseup' |
|
|
96
|
+
'pointerdown' |
|
|
97
|
+
'pointermove' |
|
|
98
|
+
'pointerout' |
|
|
99
|
+
'pointerover' |
|
|
100
|
+
'pointerup' |
|
|
101
|
+
'reset' |
|
|
102
|
+
'selectstart' |
|
|
103
|
+
'submit' |
|
|
104
|
+
'touchend' |
|
|
105
|
+
'touchmove' |
|
|
106
|
+
'touchstart' |
|
|
107
|
+
'wheel'
|
|
108
|
+
>
|
|
109
|
+
|
|
110
|
+
type CompositionEventMap = HTMLElementEventMap & {
|
|
111
|
+
[P in keyof HTMLElementCancellableEventMap as `~${P}`]: Omit<HTMLElementCancellableEventMap[P], 'preventDefault'>
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
type CompositionEventListener<T, K = keyof CompositionEventMap> = {
|
|
115
|
+
type?: K
|
|
116
|
+
id?: string,
|
|
117
|
+
capture?: boolean;
|
|
118
|
+
once?: boolean;
|
|
119
|
+
passive?: boolean;
|
|
120
|
+
signal?: AbortSignal;
|
|
121
|
+
handleEvent?: (
|
|
122
|
+
this: T,
|
|
123
|
+
event: (K extends keyof CompositionEventMap ? CompositionEventMap[K] : Event) & {currentTarget:HTMLElement}
|
|
124
|
+
) => any;
|
|
125
|
+
prop?: keyof T & string;
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
type CompositionEventListenerObject<T> =
|
|
129
|
+
{
|
|
130
|
+
[P in keyof CompositionEventMap]?: (keyof T & string)
|
|
131
|
+
| ((this: T, event: CompositionEventMap[P] & {currentTarget:HTMLElement}) => any)
|
|
132
|
+
| CompositionEventListener<T, P>
|
|
133
|
+
};
|
|
134
|
+
|
|
135
|
+
export type dummyObject = {};
|
package/core/typings.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
package/index.js
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
export { default as Badge } from './components/Badge.js';
|
|
2
|
+
export { default as Body } from './components/Body.js';
|
|
3
|
+
export { default as BottomAppBar } from './components/BottomAppBar.js';
|
|
4
|
+
export { default as Box } from './components/Box.js';
|
|
5
|
+
export { default as Button } from './components/Button.js';
|
|
6
|
+
export { default as Card } from './components/Card.js';
|
|
7
|
+
export { default as Checkbox } from './components/Checkbox.js';
|
|
8
|
+
export { default as Chip } from './components/Chip.js';
|
|
9
|
+
export { default as Dialog } from './components/Dialog.js';
|
|
10
|
+
export { default as Divider } from './components/Divider.js';
|
|
11
|
+
export { default as ExtendedFab } from './components/ExtendedFab.js';
|
|
12
|
+
export { default as Fab } from './components/Fab.js';
|
|
13
|
+
export { default as FilterChip } from './components/FilterChip.js';
|
|
14
|
+
export { default as Headline } from './components/Headline.js';
|
|
15
|
+
export { default as Icon } from './components/Icon.js';
|
|
16
|
+
export { default as IconButton } from './components/IconButton.js';
|
|
17
|
+
export { default as Input } from './components/Input.js';
|
|
18
|
+
export { default as Label } from './components/Label.js';
|
|
19
|
+
export { default as Layout } from './components/Layout.js';
|
|
20
|
+
export { default as List } from './components/List.js';
|
|
21
|
+
export { default as ListItem } from './components/ListItem.js';
|
|
22
|
+
export { default as ListOption } from './components/ListOption.js';
|
|
23
|
+
export { default as ListSelect } from './components/ListSelect.js';
|
|
24
|
+
export { default as Menu } from './components/Menu.js';
|
|
25
|
+
export { default as MenuItem } from './components/MenuItem.js';
|
|
26
|
+
export { default as NavBar } from './components/NavBar.js';
|
|
27
|
+
export { default as NavBarItem } from './components/NavBarItem.js';
|
|
28
|
+
export { default as NavDrawer } from './components/NavDrawer.js';
|
|
29
|
+
export { default as NavDrawerItem } from './components/NavDrawerItem.js';
|
|
30
|
+
export { default as NavItem } from './components/NavItem.js';
|
|
31
|
+
export { default as NavRail } from './components/NavRail.js';
|
|
32
|
+
export { default as NavRailItem } from './components/NavRailItem.js';
|
|
33
|
+
export { default as Pane } from './components/Pane.js';
|
|
34
|
+
export { default as Progress } from './components/Progress.js';
|
|
35
|
+
export { default as Radio } from './components/Radio.js';
|
|
36
|
+
export { default as SegmentedButton } from './components/SegmentedButton.js';
|
|
37
|
+
export { default as SegmentedButtonGroup } from './components/SegmentedButtonGroup.js';
|
|
38
|
+
export { default as Select } from './components/Select.js';
|
|
39
|
+
export { default as Slider } from './components/Slider.js';
|
|
40
|
+
export { default as Snackbar } from './components/Snackbar.js';
|
|
41
|
+
export { default as Surface } from './components/Surface.js';
|
|
42
|
+
export { default as Switch } from './components/Switch.js';
|
|
43
|
+
export { default as Tab } from './components/Tab.js';
|
|
44
|
+
export { default as TabContent } from './components/TabContent.js';
|
|
45
|
+
export { default as TabList } from './components/TabList.js';
|
|
46
|
+
export { default as TabPanel } from './components/TabPanel.js';
|
|
47
|
+
export { default as TextArea } from './components/TextArea.js';
|
|
48
|
+
export { default as Title } from './components/Title.js';
|
|
49
|
+
export { default as Tooltip } from './components/Tooltip.js';
|
|
50
|
+
export { default as TopAppBar } from './components/TopAppBar.js';
|
|
51
|
+
|
|
52
|
+
export { default as CustomElement } from './core/CustomElement.js';
|
|
53
|
+
export { default as Composition } from './core/Composition.js';
|
|
54
|
+
|
|
55
|
+
export { default as InputMixin } from './mixins/InputMixin.js';
|
|
56
|
+
export { default as AriaReflectorMixin } from './mixins/AriaReflectorMixin.js';
|
|
57
|
+
export { default as ControlMixin } from './mixins/ControlMixin.js';
|
|
58
|
+
export { default as RTLObserverMixin } from './mixins/RTLObserverMixin.js';
|
|
59
|
+
export { default as TouchTargetMixin } from './mixins/TouchTargetMixin.js';
|
|
60
|
+
export { default as ShapeMixin } from './mixins/ShapeMixin.js';
|
|
61
|
+
export { default as RippleMixin } from './mixins/RippleMixin.js';
|
|
62
|
+
export { default as FormAssociatedMixin } from './mixins/FormAssociatedMixin.js';
|
|
63
|
+
export { default as KeyboardNavMixin } from './mixins/KeyboardNavMixin.js';
|
|
64
|
+
export { default as ResizeObserverMixin } from './mixins/ResizeObserverMixin.js';
|
|
65
|
+
export { default as DensityMixin } from './mixins/DensityMixin.js';
|
|
66
|
+
export { default as TooltipTriggerMixin } from './mixins/TooltipTriggerMixin.js';
|
|
67
|
+
export { default as ScrollListenerMixin } from './mixins/ScrollListenerMixin.js';
|
|
68
|
+
export { default as FlexableMixin } from './mixins/FlexableMixin.js';
|
|
69
|
+
export { default as ThemableMixin } from './mixins/ThemableMixin.js';
|
|
70
|
+
export { default as AriaToolbarMixin } from './mixins/AriaToolbarMixin.js';
|
|
71
|
+
export { default as TextFieldMixin } from './mixins/TextFieldMixin.js';
|
|
72
|
+
export { default as SurfaceMixin } from './mixins/SurfaceMixin.js';
|
|
73
|
+
export { default as StateMixin } from './mixins/StateMixin.js';
|
|
74
|
+
|
|
75
|
+
export * as themeLoader from './theming/loader.js';
|
|
76
|
+
|
|
77
|
+
export * as theming from './theming/index.js';
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { attrNameFromPropName } from '../core/dom.js';
|
|
2
|
+
|
|
3
|
+
/** @param {typeof import('../core/CustomElement.js').default} Base */
|
|
4
|
+
export default function AriaReflectorMixin(Base) {
|
|
5
|
+
return Base
|
|
6
|
+
.extend()
|
|
7
|
+
.observe({
|
|
8
|
+
_ariaRole: 'string',
|
|
9
|
+
}).methods({
|
|
10
|
+
/**
|
|
11
|
+
* @param {keyof HTMLElement & keyof ElementInternals} name
|
|
12
|
+
* @param {string} value
|
|
13
|
+
*/
|
|
14
|
+
updateAriaProperty(name, value) {
|
|
15
|
+
if (this.elementInternals && name in this.elementInternals) {
|
|
16
|
+
this.elementInternals[name] = value;
|
|
17
|
+
} else if (name in this) {
|
|
18
|
+
this[name] = value;
|
|
19
|
+
} else {
|
|
20
|
+
console.warn('Unknown ARIA property', name);
|
|
21
|
+
/** @type {string} */
|
|
22
|
+
let attrName = name;
|
|
23
|
+
if (attrName.startsWith('aria')) {
|
|
24
|
+
attrName = `aria-${attrName.slice(4).toLowerCase()}`;
|
|
25
|
+
}
|
|
26
|
+
if (value == null) {
|
|
27
|
+
this.removeAttribute(name);
|
|
28
|
+
} else {
|
|
29
|
+
this.setAttribute(attrName, value);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
})
|
|
34
|
+
.on({
|
|
35
|
+
_ariaRoleChanged(oldValue, newValue) {
|
|
36
|
+
this.updateAriaProperty('role', newValue);
|
|
37
|
+
},
|
|
38
|
+
constructed() {
|
|
39
|
+
this.updateAriaProperty('role', this._ariaRole);
|
|
40
|
+
},
|
|
41
|
+
});
|
|
42
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import KbdNavWidgetMixin from './KeyboardNavMixin.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @param {typeof import('../core/CustomElement.js').default} Base
|
|
5
|
+
*/
|
|
6
|
+
export default function AriaToolbarMixin(Base) {
|
|
7
|
+
return Base
|
|
8
|
+
.mixin(KbdNavWidgetMixin)
|
|
9
|
+
.extend()
|
|
10
|
+
.set({
|
|
11
|
+
ariaOrientationDefault: 'horizontal',
|
|
12
|
+
});
|
|
13
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
:host {
|
|
2
|
+
display: inline-flex;
|
|
3
|
+
}
|
|
4
|
+
|
|
5
|
+
/* Remove Firefox inner */
|
|
6
|
+
:host(::-moz-focus-inner) {
|
|
7
|
+
border: 0;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
#label {
|
|
11
|
+
display: contents;
|
|
12
|
+
|
|
13
|
+
pointer-events: none;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
#control {
|
|
17
|
+
/* Control is the touch target */
|
|
18
|
+
/* Firefox requires at least 1px "visible" for screen reading */
|
|
19
|
+
/* Safari will not allow interaction with 0 opacity */
|
|
20
|
+
/* Chrome will not focus with visibility:hidden */
|
|
21
|
+
|
|
22
|
+
position: absolute;
|
|
23
|
+
inset: 50%;
|
|
24
|
+
/* --mdw-device-pixel-ratio: 1; */
|
|
25
|
+
|
|
26
|
+
block-size: 100%;
|
|
27
|
+
min-block-size: 48px;
|
|
28
|
+
inline-size:100%;
|
|
29
|
+
min-inline-size: 48px;
|
|
30
|
+
margin: 0;
|
|
31
|
+
border: 0;
|
|
32
|
+
padding: 0;
|
|
33
|
+
|
|
34
|
+
-webkit-appearance: none;
|
|
35
|
+
-moz-appearance: none;
|
|
36
|
+
appearance: none;
|
|
37
|
+
|
|
38
|
+
cursor: auto;
|
|
39
|
+
outline: none;
|
|
40
|
+
|
|
41
|
+
pointer-events: auto;
|
|
42
|
+
|
|
43
|
+
transform: translateX(-50%) translateY(-50%);
|
|
44
|
+
|
|
45
|
+
/* Safari and Chrome will emit two click events if not at top of stack */
|
|
46
|
+
/* Allows up to 3 other layers (eg: ripple, outline) */
|
|
47
|
+
z-index: 4;
|
|
48
|
+
|
|
49
|
+
background-color: transparent;
|
|
50
|
+
|
|
51
|
+
border-radius: 0;
|
|
52
|
+
color: transparent;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
#control::-moz-focus-inner {
|
|
56
|
+
border: 0;
|
|
57
|
+
}
|
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
/* https://html.spec.whatwg.org/multipage/form-control-infrastructure.html */
|
|
2
|
+
|
|
3
|
+
import styles from './ControlMixin.css' assert { type: 'css' };
|
|
4
|
+
import FormAssociatedMixin from './FormAssociatedMixin.js';
|
|
5
|
+
|
|
6
|
+
/** @typedef {import('../core/CustomElement.js').default} CustomElement */
|
|
7
|
+
|
|
8
|
+
/** @typedef {'align'|'useMap'} DeprecatedHTMLInputElementProperties */
|
|
9
|
+
|
|
10
|
+
/** @typedef {HTMLInputElement|HTMLTextAreaElement|HTMLSelectElement} HTMLControlElement */
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @param {ReturnType<import('./StateMixin.js').default>} Base
|
|
14
|
+
*/
|
|
15
|
+
export default function ControlMixin(Base) {
|
|
16
|
+
class Control extends Base.mixin(FormAssociatedMixin) {
|
|
17
|
+
/** @return {Iterable<string>} */
|
|
18
|
+
static get observedAttributes() {
|
|
19
|
+
return [
|
|
20
|
+
...super.observedAttributes,
|
|
21
|
+
'aria-label',
|
|
22
|
+
...this.valueChangingContentAttributes,
|
|
23
|
+
...this.clonedContentAttributes,
|
|
24
|
+
];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
static controlTagName = 'input';
|
|
28
|
+
|
|
29
|
+
static controlVoidElement = true;
|
|
30
|
+
|
|
31
|
+
/** @type {string[]} */
|
|
32
|
+
static clonedContentAttributes = [
|
|
33
|
+
'autocomplete', 'name', 'readonly', 'required',
|
|
34
|
+
];
|
|
35
|
+
|
|
36
|
+
/** @type {string[]} */
|
|
37
|
+
static valueChangingContentAttributes = [];
|
|
38
|
+
|
|
39
|
+
/** @param {any[]} args */
|
|
40
|
+
constructor(...args) {
|
|
41
|
+
super(...args);
|
|
42
|
+
/** @type {string} */
|
|
43
|
+
this._value = this._control.value;
|
|
44
|
+
// Expose this element as focusable
|
|
45
|
+
if (!this.hasAttribute('tabindex')) {
|
|
46
|
+
this.tabIndex = 0;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** @type {CustomElement['attributeChangedCallback']} */
|
|
51
|
+
attributeChangedCallback(name, oldValue, newValue) {
|
|
52
|
+
super.attributeChangedCallback(name, oldValue, newValue);
|
|
53
|
+
if (this.static.clonedContentAttributes.includes(name)) {
|
|
54
|
+
if (newValue == null) {
|
|
55
|
+
this._control.removeAttribute(name);
|
|
56
|
+
} else {
|
|
57
|
+
this._control.setAttribute(name, newValue);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
if (this.static.valueChangingContentAttributes.includes(name)) {
|
|
62
|
+
if (!this.hasAttribute('value')) {
|
|
63
|
+
// Force HTMLInputElement to recalculate default
|
|
64
|
+
// Unintended effect of incrementally changing attributes (eg: range)
|
|
65
|
+
this._control.setAttribute('value', '');
|
|
66
|
+
}
|
|
67
|
+
// Changing control attribute may change the value (eg: min/max)
|
|
68
|
+
this._value = this._control.value;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** @type {HTMLControlElement} */
|
|
73
|
+
get _control() { return this.refs.control; }
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* @param {Partial<this>} data
|
|
77
|
+
* @return {string}
|
|
78
|
+
*/
|
|
79
|
+
computeAriaLabelledBy({ ariaLabel }) {
|
|
80
|
+
if (ariaLabel) return null;
|
|
81
|
+
return '#slot';
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
get stateTargetElement() { return this._control; }
|
|
85
|
+
|
|
86
|
+
click() {
|
|
87
|
+
/** Redirect click requests to control itself */
|
|
88
|
+
this._control.click();
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
static {
|
|
92
|
+
this.css(styles);
|
|
93
|
+
this.on({
|
|
94
|
+
// Wait until controlTagName is settled before templating
|
|
95
|
+
composed({ template, html }) {
|
|
96
|
+
template.append(html`
|
|
97
|
+
<label id=label disabled={disabledState}>
|
|
98
|
+
<${this.static.controlTagName} id=control aria-labelledby={computeAriaLabelledBy} aria-label={ariaLabel}
|
|
99
|
+
>${this.static.controlVoidElement ? '' : `</${this.static.controlTagName}>`}
|
|
100
|
+
</label>
|
|
101
|
+
`);
|
|
102
|
+
},
|
|
103
|
+
disabledStateChanged(oldValue, newValue) {
|
|
104
|
+
this._control.setAttribute('aria-disabled', `${newValue}`);
|
|
105
|
+
if (!this.focusableOnDisabled) {
|
|
106
|
+
this._control.disabled = newValue;
|
|
107
|
+
if (newValue) {
|
|
108
|
+
this.tabIndex = 0;
|
|
109
|
+
} else {
|
|
110
|
+
this.removeAttribute('tabindex');
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
},
|
|
114
|
+
});
|
|
115
|
+
this.childEvents({
|
|
116
|
+
control: {
|
|
117
|
+
input({ currentTarget }) {
|
|
118
|
+
const control = /** @type {HTMLControlElement} */ (currentTarget);
|
|
119
|
+
if (this.validity.valid) {
|
|
120
|
+
// Track internally
|
|
121
|
+
control.checkValidity();
|
|
122
|
+
this._badInput = control.validity.badInput;
|
|
123
|
+
} else {
|
|
124
|
+
// Perform check in case user has validated
|
|
125
|
+
this.checkValidity();
|
|
126
|
+
}
|
|
127
|
+
this._value = control.value;
|
|
128
|
+
},
|
|
129
|
+
change({ currentTarget }) {
|
|
130
|
+
const control = /** @type {HTMLControlElement} */ (currentTarget);
|
|
131
|
+
this._value = control.value;
|
|
132
|
+
this.checkValidity();
|
|
133
|
+
// Change event is NOT composed. Needs to escape shadow DOM
|
|
134
|
+
this.dispatchEvent(new Event('change', { bubbles: true }));
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/** @type {HTMLElement['focus']} */
|
|
141
|
+
focus(...options) {
|
|
142
|
+
super.focus(...options);
|
|
143
|
+
this.refs.control.focus(...options);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* @template {typeof Control & ReturnType<import('./RippleMixin.js').default> & ReturnType<import('./FormAssociatedMixin.js').default>} T
|
|
148
|
+
* @return {T}
|
|
149
|
+
*/
|
|
150
|
+
get static() {
|
|
151
|
+
return /** @type {T} */ (/** @type {unknown} */ (super.static));
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
get form() { return this.elementInternals.form; }
|
|
155
|
+
|
|
156
|
+
// get name() { return this.getAttribute('name'); }
|
|
157
|
+
get value() {
|
|
158
|
+
return this._value;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
set value(v) {
|
|
162
|
+
this._valueDirty = true;
|
|
163
|
+
this._control.value = v;
|
|
164
|
+
this._value = this._control.value;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
get validity() { return this.elementInternals.validity; }
|
|
168
|
+
|
|
169
|
+
get validationMessage() { return this.elementInternals.validationMessage; }
|
|
170
|
+
|
|
171
|
+
get willValidate() { return this.elementInternals.willValidate; }
|
|
172
|
+
|
|
173
|
+
checkValidity() {
|
|
174
|
+
const validityState = this._control.checkValidity();
|
|
175
|
+
/** @type {Partial<ValidityState>} */
|
|
176
|
+
const newValidity = {};
|
|
177
|
+
|
|
178
|
+
// eslint-disable-next-line guard-for-in
|
|
179
|
+
for (const key in this._control.validity) {
|
|
180
|
+
// @ts-ignore Skip cast
|
|
181
|
+
newValidity[key] = this._control.validity[key];
|
|
182
|
+
}
|
|
183
|
+
this.elementInternals.setValidity(newValidity, this._control.validationMessage);
|
|
184
|
+
this._invalid = !validityState;
|
|
185
|
+
this._validationMessage = this._control.validationMessage;
|
|
186
|
+
this._badInput = this._control.validity.badInput;
|
|
187
|
+
return validityState;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
reportValidity() {
|
|
191
|
+
this.checkValidity();
|
|
192
|
+
this._control.reportValidity();
|
|
193
|
+
return this.elementInternals.reportValidity();
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/**
|
|
197
|
+
* @param {string} error
|
|
198
|
+
* @return {void}
|
|
199
|
+
*/
|
|
200
|
+
setCustomValidity(error) {
|
|
201
|
+
this._control.setCustomValidity(error);
|
|
202
|
+
this.checkValidity();
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
get labels() { return this.elementInternals.labels; }
|
|
206
|
+
}
|
|
207
|
+
Control.prototype.ariaLabel = Control.prop('ariaLabel');
|
|
208
|
+
Control.prototype.delegatesFocus = true;
|
|
209
|
+
Control.prototype.focusableOnDisabled = false;
|
|
210
|
+
|
|
211
|
+
return Control;
|
|
212
|
+
}
|