@shortfuse/materialdesignweb 0.7.6 → 0.9.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 +87 -90
- package/bin/mdw-css.js +1 -1
- package/components/Badge.js +14 -7
- package/components/Body.js +3 -0
- package/components/BottomAppBar.js +4 -13
- package/components/BottomSheet.js +424 -0
- package/components/Box.js +20 -28
- package/components/Button.js +85 -79
- package/components/Button.md +9 -9
- package/components/Card.js +60 -72
- package/components/Checkbox.js +33 -42
- package/components/CheckboxIcon.js +11 -29
- package/components/Chip.js +13 -11
- package/components/Dialog.js +214 -394
- package/components/DialogActions.js +2 -2
- package/components/Display.js +55 -0
- package/components/Divider.js +3 -3
- package/components/Fab.js +83 -18
- package/components/FabContainer.js +48 -0
- package/components/FilterChip.js +35 -33
- package/components/Grid.js +176 -0
- package/components/Headline.js +5 -28
- package/components/Icon.js +61 -76
- package/components/IconButton.js +72 -126
- package/components/Input.js +859 -1
- package/components/InputChip.js +161 -0
- package/components/Label.js +3 -0
- package/components/List.js +4 -6
- package/components/ListItem.js +46 -30
- package/components/ListOption.js +86 -53
- package/components/Listbox.js +248 -0
- package/components/Menu.js +69 -528
- package/components/MenuItem.js +33 -36
- package/components/NavBar.js +49 -86
- package/components/NavDrawer.js +16 -15
- package/components/NavDrawerItem.js +4 -5
- package/components/NavItem.js +58 -41
- package/components/NavRail.js +30 -20
- package/components/NavRailItem.js +8 -3
- package/components/Page.js +105 -0
- package/components/Pane.js +11 -274
- package/components/Popup.js +29 -0
- package/components/Progress.js +24 -23
- package/components/Radio.js +40 -36
- package/components/RadioIcon.js +12 -16
- package/components/Ripple.js +13 -10
- package/components/Root.js +209 -0
- package/components/Scrim.js +87 -0
- package/components/Search.js +77 -0
- package/components/SegmentedButton.js +33 -45
- package/components/SegmentedButtonGroup.js +25 -13
- package/components/Select.js +10 -11
- package/components/Shape.js +5 -65
- package/components/SideSheet.js +308 -0
- package/components/Slider.js +108 -78
- package/components/Snackbar.js +26 -21
- package/components/SnackbarContainer.js +42 -0
- package/components/Surface.js +17 -12
- package/components/Switch.js +45 -24
- package/components/SwitchIcon.js +49 -39
- package/components/Tab.js +64 -43
- package/components/TabContent.js +5 -3
- package/components/TabList.js +62 -34
- package/components/TabPanel.js +11 -8
- package/components/Table.js +116 -0
- package/components/TextArea.js +54 -50
- package/components/Title.js +4 -9
- package/components/Tooltip.js +44 -22
- package/components/TopAppBar.js +68 -172
- package/constants/shapes.js +36 -0
- package/constants/typography.js +127 -0
- package/core/Composition.js +1164 -645
- package/core/CompositionAdapter.js +314 -0
- package/core/CustomElement.js +701 -286
- package/core/css.js +121 -15
- package/core/customTypes.js +157 -40
- package/core/dom.js +17 -11
- package/{utils → core}/jsonMergePatch.js +42 -18
- package/core/observe.js +343 -244
- package/core/optimizations.js +23 -0
- package/core/template.js +19 -56
- package/core/uid.js +13 -0
- package/dist/index.min.js +85 -184
- package/dist/index.min.js.map +4 -4
- package/dist/meta.json +1 -1
- package/dom/HTMLOptionsCollectionProxy.js +106 -0
- package/loaders/palette.js +13 -0
- package/loaders/theme.js +12 -0
- package/mixins/AriaReflectorMixin.js +53 -14
- package/mixins/AriaToolbarMixin.js +5 -3
- package/mixins/ControlMixin.js +92 -41
- package/mixins/DelegatesFocusMixin.js +54 -0
- package/mixins/DensityMixin.js +2 -3
- package/mixins/ElevationMixin.js +62 -0
- package/mixins/FlexableMixin.js +67 -39
- package/mixins/FormAssociatedMixin.js +71 -16
- package/mixins/HyperlinkMixin.js +66 -0
- package/mixins/InputMixin.js +205 -39
- package/mixins/KeyboardNavMixin.js +22 -7
- package/mixins/NavigationListenerMixin.js +33 -0
- package/mixins/PopupMixin.js +725 -0
- package/mixins/RTLObserverMixin.js +0 -1
- package/mixins/ResizeObserverMixin.js +16 -5
- package/mixins/RippleMixin.js +11 -10
- package/mixins/ScrollListenerMixin.js +42 -33
- package/mixins/SemiStickyMixin.js +97 -0
- package/mixins/ShapeMaskedMixin.js +117 -0
- package/mixins/ShapeMixin.js +17 -194
- package/mixins/StateMixin.js +80 -39
- package/mixins/TextFieldMixin.js +139 -183
- package/mixins/ThemableMixin.js +71 -161
- package/mixins/TooltipTriggerMixin.js +292 -366
- package/mixins/TouchTargetMixin.js +5 -4
- package/mixins/TypographyMixin.js +121 -0
- package/package.json +111 -71
- package/services/rtl.js +10 -0
- package/services/svgAlias.js +17 -0
- package/{theming/index.js → services/theme.js} +25 -175
- package/types/bin/mdw-css.d.ts +3 -0
- package/types/bin/mdw-css.d.ts.map +1 -0
- package/types/components/Badge.d.ts +39 -0
- package/types/components/Badge.d.ts.map +1 -0
- package/types/components/Body.d.ts +29 -0
- package/types/components/Body.d.ts.map +1 -0
- package/types/components/BottomAppBar.d.ts +73 -0
- package/types/components/BottomAppBar.d.ts.map +1 -0
- package/types/components/BottomSheet.d.ts +109 -0
- package/types/components/BottomSheet.d.ts.map +1 -0
- package/types/components/Box.d.ts +16 -0
- package/types/components/Box.d.ts.map +1 -0
- package/types/components/Button.d.ts +714 -0
- package/types/components/Button.d.ts.map +1 -0
- package/types/components/Card.d.ts +412 -0
- package/types/components/Card.d.ts.map +1 -0
- package/types/components/Checkbox.d.ts +205 -0
- package/types/components/Checkbox.d.ts.map +1 -0
- package/types/components/CheckboxIcon.d.ts +44 -0
- package/types/components/CheckboxIcon.d.ts.map +1 -0
- package/types/components/Chip.d.ts +1425 -0
- package/types/components/Chip.d.ts.map +1 -0
- package/types/components/Dialog.d.ts +286 -0
- package/types/components/Dialog.d.ts.map +1 -0
- package/types/components/DialogActions.d.ts +4 -0
- package/types/components/DialogActions.d.ts.map +1 -0
- package/types/components/Display.d.ts +45 -0
- package/types/components/Display.d.ts.map +1 -0
- package/types/components/Divider.d.ts +10 -0
- package/types/components/Divider.d.ts.map +1 -0
- package/types/components/Fab.d.ts +741 -0
- package/types/components/Fab.d.ts.map +1 -0
- package/types/components/FabContainer.d.ts +10 -0
- package/types/components/FabContainer.d.ts.map +1 -0
- package/types/components/FilterChip.d.ts +4283 -0
- package/types/components/FilterChip.d.ts.map +1 -0
- package/types/components/Grid.d.ts +37 -0
- package/types/components/Grid.d.ts.map +1 -0
- package/types/components/Headline.d.ts +47 -0
- package/types/components/Headline.d.ts.map +1 -0
- package/types/components/Icon.d.ts +103 -0
- package/types/components/Icon.d.ts.map +1 -0
- package/types/components/IconButton.d.ts +1486 -0
- package/types/components/IconButton.d.ts.map +1 -0
- package/types/components/Input.d.ts +51288 -0
- package/types/components/Input.d.ts.map +1 -0
- package/types/components/InputChip.d.ts +243 -0
- package/types/components/InputChip.d.ts.map +1 -0
- package/types/components/Label.d.ts +29 -0
- package/types/components/Label.d.ts.map +1 -0
- package/types/components/List.d.ts +31 -0
- package/types/components/List.d.ts.map +1 -0
- package/types/components/ListItem.d.ts +349 -0
- package/types/components/ListItem.d.ts.map +1 -0
- package/types/components/ListOption.d.ts +1493 -0
- package/types/components/ListOption.d.ts.map +1 -0
- package/types/components/Listbox.d.ts +12012 -0
- package/types/components/Listbox.d.ts.map +1 -0
- package/types/components/Menu.d.ts +119 -0
- package/types/components/Menu.d.ts.map +1 -0
- package/types/components/MenuItem.d.ts +3109 -0
- package/types/components/MenuItem.d.ts.map +1 -0
- package/types/components/NavBar.d.ts +18 -0
- package/types/components/NavBar.d.ts.map +1 -0
- package/types/components/NavBarItem.d.ts +186 -0
- package/types/components/NavBarItem.d.ts.map +1 -0
- package/types/components/NavDrawer.d.ts +108 -0
- package/types/components/NavDrawer.d.ts.map +1 -0
- package/types/components/NavDrawerItem.d.ts +186 -0
- package/types/components/NavDrawerItem.d.ts.map +1 -0
- package/types/components/NavItem.d.ts +190 -0
- package/types/components/NavItem.d.ts.map +1 -0
- package/types/components/NavRail.d.ts +109 -0
- package/types/components/NavRail.d.ts.map +1 -0
- package/types/components/NavRailItem.d.ts +186 -0
- package/types/components/NavRailItem.d.ts.map +1 -0
- package/types/components/Page.d.ts +24 -0
- package/types/components/Page.d.ts.map +1 -0
- package/types/components/Pane.d.ts +44 -0
- package/types/components/Pane.d.ts.map +1 -0
- package/types/components/Popup.d.ts +76 -0
- package/types/components/Popup.d.ts.map +1 -0
- package/types/components/Progress.d.ts +19 -0
- package/types/components/Progress.d.ts.map +1 -0
- package/types/components/Radio.d.ts +199 -0
- package/types/components/Radio.d.ts.map +1 -0
- package/types/components/RadioIcon.d.ts +46 -0
- package/types/components/RadioIcon.d.ts.map +1 -0
- package/types/components/Ripple.d.ts +34 -0
- package/types/components/Ripple.d.ts.map +1 -0
- package/types/components/Root.d.ts +68 -0
- package/types/components/Root.d.ts.map +1 -0
- package/types/components/Scrim.d.ts +6 -0
- package/types/components/Scrim.d.ts.map +1 -0
- package/types/components/Search.d.ts +16 -0
- package/types/components/Search.d.ts.map +1 -0
- package/types/components/SegmentedButton.d.ts +718 -0
- package/types/components/SegmentedButton.d.ts.map +1 -0
- package/types/components/SegmentedButtonGroup.d.ts +44 -0
- package/types/components/SegmentedButtonGroup.d.ts.map +1 -0
- package/types/components/Select.d.ts +1361 -0
- package/types/components/Select.d.ts.map +1 -0
- package/types/components/Shape.d.ts +10 -0
- package/types/components/Shape.d.ts.map +1 -0
- package/types/components/SideSheet.d.ts +106 -0
- package/types/components/SideSheet.d.ts.map +1 -0
- package/types/components/Slider.d.ts +382 -0
- package/types/components/Slider.d.ts.map +1 -0
- package/types/components/Snackbar.d.ts +65 -0
- package/types/components/Snackbar.d.ts.map +1 -0
- package/types/components/SnackbarContainer.d.ts +6 -0
- package/types/components/SnackbarContainer.d.ts.map +1 -0
- package/types/components/Surface.d.ts +45 -0
- package/types/components/Surface.d.ts.map +1 -0
- package/types/components/Switch.d.ts +183 -0
- package/types/components/Switch.d.ts.map +1 -0
- package/types/components/SwitchIcon.d.ts +169 -0
- package/types/components/SwitchIcon.d.ts.map +1 -0
- package/types/components/Tab.d.ts +879 -0
- package/types/components/Tab.d.ts.map +1 -0
- package/types/components/TabContent.d.ts +122 -0
- package/types/components/TabContent.d.ts.map +1 -0
- package/types/components/TabList.d.ts +6266 -0
- package/types/components/TabList.d.ts.map +1 -0
- package/types/components/TabPanel.d.ts +28 -0
- package/types/components/TabPanel.d.ts.map +1 -0
- package/types/components/Table.d.ts +2 -0
- package/types/components/Table.d.ts.map +1 -0
- package/types/components/TextArea.d.ts +1394 -0
- package/types/components/TextArea.d.ts.map +1 -0
- package/types/components/Title.d.ts +47 -0
- package/types/components/Title.d.ts.map +1 -0
- package/types/components/Tooltip.d.ts +49 -0
- package/types/components/Tooltip.d.ts.map +1 -0
- package/types/components/TopAppBar.d.ts +130 -0
- package/types/components/TopAppBar.d.ts.map +1 -0
- package/types/constants/colorKeywords.d.ts +2 -0
- package/types/constants/colorKeywords.d.ts.map +1 -0
- package/types/constants/shapes.d.ts +38 -0
- package/types/constants/shapes.d.ts.map +1 -0
- package/types/constants/typography.d.ts +212 -0
- package/types/constants/typography.d.ts.map +1 -0
- package/types/core/Composition.d.ts +252 -0
- package/types/core/Composition.d.ts.map +1 -0
- package/types/core/CompositionAdapter.d.ts +92 -0
- package/types/core/CompositionAdapter.d.ts.map +1 -0
- package/types/core/CustomElement.d.ts +302 -0
- package/types/core/CustomElement.d.ts.map +1 -0
- package/types/core/css.d.ts +44 -0
- package/types/core/css.d.ts.map +1 -0
- package/types/core/customTypes.d.ts +26 -0
- package/types/core/customTypes.d.ts.map +1 -0
- package/types/core/dom.d.ts +32 -0
- package/types/core/dom.d.ts.map +1 -0
- package/types/core/jsonMergePatch.d.ts +31 -0
- package/types/core/jsonMergePatch.d.ts.map +1 -0
- package/types/core/observe.d.ts +113 -0
- package/types/core/observe.d.ts.map +1 -0
- package/types/core/optimizations.d.ts +7 -0
- package/types/core/optimizations.d.ts.map +1 -0
- package/types/core/template.d.ts +47 -0
- package/types/core/template.d.ts.map +1 -0
- package/types/core/uid.d.ts +6 -0
- package/types/core/uid.d.ts.map +1 -0
- package/types/dom/HTMLOptionsCollectionProxy.d.ts +18 -0
- package/types/dom/HTMLOptionsCollectionProxy.d.ts.map +1 -0
- package/types/index.d.ts +88 -0
- package/types/index.d.ts.map +1 -0
- package/types/loaders/palette.d.ts +2 -0
- package/types/loaders/palette.d.ts.map +1 -0
- package/types/loaders/theme.d.ts +2 -0
- package/types/loaders/theme.d.ts.map +1 -0
- package/types/mixins/AriaReflectorMixin.d.ts +23 -0
- package/types/mixins/AriaReflectorMixin.d.ts.map +1 -0
- package/types/mixins/AriaToolbarMixin.d.ts +32 -0
- package/types/mixins/AriaToolbarMixin.d.ts.map +1 -0
- package/types/mixins/ControlMixin.d.ts +124 -0
- package/types/mixins/ControlMixin.d.ts.map +1 -0
- package/types/mixins/DelegatesFocusMixin.d.ts +5 -0
- package/types/mixins/DelegatesFocusMixin.d.ts.map +1 -0
- package/types/mixins/DensityMixin.d.ts +5 -0
- package/types/mixins/DensityMixin.d.ts.map +1 -0
- package/types/mixins/ElevationMixin.d.ts +33 -0
- package/types/mixins/ElevationMixin.d.ts.map +1 -0
- package/types/mixins/FlexableMixin.d.ts +13 -0
- package/types/mixins/FlexableMixin.d.ts.map +1 -0
- package/types/mixins/FormAssociatedMixin.d.ts +122 -0
- package/types/mixins/FormAssociatedMixin.d.ts.map +1 -0
- package/types/mixins/HyperlinkMixin.d.ts +22 -0
- package/types/mixins/HyperlinkMixin.d.ts.map +1 -0
- package/types/mixins/InputMixin.d.ts +179 -0
- package/types/mixins/InputMixin.d.ts.map +1 -0
- package/types/mixins/KeyboardNavMixin.d.ts +47 -0
- package/types/mixins/KeyboardNavMixin.d.ts.map +1 -0
- package/types/mixins/NavigationListenerMixin.d.ts +8 -0
- package/types/mixins/NavigationListenerMixin.d.ts.map +1 -0
- package/types/mixins/PopupMixin.d.ts +82 -0
- package/types/mixins/PopupMixin.d.ts.map +1 -0
- package/types/mixins/RTLObserverMixin.d.ts +7 -0
- package/types/mixins/RTLObserverMixin.d.ts.map +1 -0
- package/types/mixins/ResizeObserverMixin.d.ts +12 -0
- package/types/mixins/ResizeObserverMixin.d.ts.map +1 -0
- package/types/mixins/RippleMixin.d.ts +92 -0
- package/types/mixins/RippleMixin.d.ts.map +1 -0
- package/types/mixins/ScrollListenerMixin.d.ts +41 -0
- package/types/mixins/ScrollListenerMixin.d.ts.map +1 -0
- package/types/mixins/SemiStickyMixin.d.ts +50 -0
- package/types/mixins/SemiStickyMixin.d.ts.map +1 -0
- package/types/mixins/ShapeMaskedMixin.d.ts +9 -0
- package/types/mixins/ShapeMaskedMixin.d.ts.map +1 -0
- package/types/mixins/ShapeMixin.d.ts +38 -0
- package/types/mixins/ShapeMixin.d.ts.map +1 -0
- package/types/mixins/StateMixin.d.ts +27 -0
- package/types/mixins/StateMixin.d.ts.map +1 -0
- package/types/mixins/TextFieldMixin.d.ts +1354 -0
- package/types/mixins/TextFieldMixin.d.ts.map +1 -0
- package/types/mixins/ThemableMixin.d.ts +9 -0
- package/types/mixins/ThemableMixin.d.ts.map +1 -0
- package/types/mixins/TooltipTriggerMixin.d.ts +106 -0
- package/types/mixins/TooltipTriggerMixin.d.ts.map +1 -0
- package/types/mixins/TouchTargetMixin.d.ts +3 -0
- package/types/mixins/TouchTargetMixin.d.ts.map +1 -0
- package/types/mixins/TypographyMixin.d.ts +17 -0
- package/types/mixins/TypographyMixin.d.ts.map +1 -0
- package/types/services/rtl.d.ts +3 -0
- package/types/services/rtl.d.ts.map +1 -0
- package/types/services/svgAlias.d.ts +13 -0
- package/types/services/svgAlias.d.ts.map +1 -0
- package/types/services/theme.d.ts +45 -0
- package/types/services/theme.d.ts.map +1 -0
- package/types/utils/cli.d.ts +3 -0
- package/types/utils/cli.d.ts.map +1 -0
- package/types/utils/function.d.ts +3 -0
- package/types/utils/function.d.ts.map +1 -0
- package/types/utils/jsx-runtime.d.ts +20 -0
- package/types/utils/jsx-runtime.d.ts.map +1 -0
- package/types/utils/material-color/blend.d.ts +34 -0
- package/types/utils/material-color/blend.d.ts.map +1 -0
- package/types/utils/material-color/hct/Cam16.d.ts +142 -0
- package/types/utils/material-color/hct/Cam16.d.ts.map +1 -0
- package/types/utils/material-color/hct/Hct.d.ts +93 -0
- package/types/utils/material-color/hct/Hct.d.ts.map +1 -0
- package/types/utils/material-color/hct/ViewingConditions.d.ts +69 -0
- package/types/utils/material-color/hct/ViewingConditions.d.ts.map +1 -0
- package/types/utils/material-color/hct/hctSolver.d.ts +30 -0
- package/types/utils/material-color/hct/hctSolver.d.ts.map +1 -0
- package/types/utils/material-color/helper.d.ts +8 -0
- package/types/utils/material-color/helper.d.ts.map +1 -0
- package/types/utils/material-color/palettes/CorePalette.d.ts +75 -0
- package/types/utils/material-color/palettes/CorePalette.d.ts.map +1 -0
- package/types/utils/material-color/palettes/TonalPalette.d.ts +38 -0
- package/types/utils/material-color/palettes/TonalPalette.d.ts.map +1 -0
- package/types/utils/material-color/scheme/Scheme.d.ts +264 -0
- package/types/utils/material-color/scheme/Scheme.d.ts.map +1 -0
- package/types/utils/material-color/utils/color.d.ts +172 -0
- package/types/utils/material-color/utils/color.d.ts.map +1 -0
- package/types/utils/material-color/utils/math.d.ts +94 -0
- package/types/utils/material-color/utils/math.d.ts.map +1 -0
- package/types/utils/pixelmatch.d.ts +22 -0
- package/types/utils/pixelmatch.d.ts.map +1 -0
- package/types/utils/popup.d.ts +106 -0
- package/types/utils/popup.d.ts.map +1 -0
- package/types/utils/searchParams.d.ts +3 -0
- package/types/utils/searchParams.d.ts.map +1 -0
- package/types/utils/svg.d.ts +7 -0
- package/types/utils/svg.d.ts.map +1 -0
- package/utils/{hct → material-color}/blend.js +8 -10
- package/utils/{hct → material-color/hct}/Cam16.js +196 -69
- package/utils/{hct → material-color/hct}/Hct.js +61 -19
- package/utils/{hct → material-color/hct}/ViewingConditions.js +3 -3
- package/utils/{hct → material-color/hct}/hctSolver.js +9 -16
- package/utils/{hct → material-color}/helper.js +11 -18
- package/utils/{hct → material-color/palettes}/CorePalette.js +79 -19
- package/utils/{hct → material-color/palettes}/TonalPalette.js +12 -4
- package/utils/material-color/scheme/Scheme.js +376 -0
- package/utils/{hct/colorUtils.js → material-color/utils/color.js} +61 -1
- package/utils/pixelmatch.js +360 -0
- package/utils/popup.js +127 -30
- package/utils/searchParams.js +19 -0
- package/components/ExtendedFab.js +0 -36
- package/components/Layout.js +0 -35
- package/components/ListSelect.js +0 -220
- package/components/Nav.js +0 -40
- package/components/Option.js +0 -91
- package/core/ICustomElement.d.ts +0 -291
- package/core/ICustomElement.js +0 -1
- package/core/identify.js +0 -40
- package/core/typings.d.ts +0 -136
- package/core/typings.js +0 -1
- package/mixins/SurfaceMixin.js +0 -181
- package/theming/loader.js +0 -22
- package/utils/hct/Scheme.js +0 -587
- /package/{utils/color_keywords.js → constants/colorKeywords.js} +0 -0
- /package/utils/{hct/mathUtils.js → material-color/utils/math.js} +0 -0
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/* https://html.spec.whatwg.org/multipage/form-control-infrastructure.html */
|
|
2
2
|
|
|
3
|
+
import { CHROME_VERSION } from '../core/dom.js';
|
|
4
|
+
|
|
3
5
|
/** @typedef {HTMLElement & {value:string}} HTMLControlElement */
|
|
4
6
|
|
|
5
7
|
/** @typedef {import('../core/CustomElement.js').default} CustomElement */
|
|
@@ -13,7 +15,6 @@ const DOMString = { nullParser: String, value: '' };
|
|
|
13
15
|
*/
|
|
14
16
|
export default function FormAssociatedMixin(Base) {
|
|
15
17
|
return Base
|
|
16
|
-
.extend()
|
|
17
18
|
.setStatic({
|
|
18
19
|
formAssociated: true,
|
|
19
20
|
})
|
|
@@ -22,12 +23,15 @@ export default function FormAssociatedMixin(Base) {
|
|
|
22
23
|
_ipcListener: null,
|
|
23
24
|
/** @type {EventTarget} */
|
|
24
25
|
_ipcTarget: null,
|
|
26
|
+
/** @type {FileList} */
|
|
27
|
+
_files: null,
|
|
25
28
|
})
|
|
26
29
|
.observe({
|
|
27
30
|
ariaControls: 'string',
|
|
28
31
|
autocomplete: DOMString,
|
|
29
32
|
name: DOMString,
|
|
30
33
|
readOnly: { attr: 'readonly', type: 'boolean' },
|
|
34
|
+
formNoValidate: { attr: 'formnovalidate', type: 'boolean' },
|
|
31
35
|
defaultChecked: { attr: 'checked', type: 'boolean' },
|
|
32
36
|
_checkedDirty: 'boolean',
|
|
33
37
|
/* "Checkedness" */
|
|
@@ -38,6 +42,7 @@ export default function FormAssociatedMixin(Base) {
|
|
|
38
42
|
_defaultValue: { reflect: true, attr: 'value' },
|
|
39
43
|
_value: { empty: '' },
|
|
40
44
|
_valueDirty: 'boolean',
|
|
45
|
+
_userInteracted: 'boolean',
|
|
41
46
|
_invalid: 'boolean',
|
|
42
47
|
_badInput: 'boolean',
|
|
43
48
|
_validationMessage: 'string',
|
|
@@ -45,7 +50,7 @@ export default function FormAssociatedMixin(Base) {
|
|
|
45
50
|
_formReset: 'boolean',
|
|
46
51
|
})
|
|
47
52
|
.observe({
|
|
48
|
-
erroredState({ _invalid }) { return _invalid; },
|
|
53
|
+
erroredState({ _invalid, _userInteracted }) { return _userInteracted && _invalid; },
|
|
49
54
|
defaultValue: {
|
|
50
55
|
reflect: false,
|
|
51
56
|
get({ _defaultValue }) {
|
|
@@ -92,14 +97,13 @@ export default function FormAssociatedMixin(Base) {
|
|
|
92
97
|
reflect: false,
|
|
93
98
|
get({ _valueBehavior, _defaultValue, _value }) {
|
|
94
99
|
switch (_valueBehavior) {
|
|
100
|
+
case 'filename':
|
|
95
101
|
default:
|
|
96
102
|
return _value;
|
|
97
103
|
case 'default':
|
|
98
104
|
return _defaultValue ?? '';
|
|
99
105
|
case 'default/on':
|
|
100
106
|
return _defaultValue ?? 'on';
|
|
101
|
-
case 'filename':
|
|
102
|
-
throw new Error('Not supported!');
|
|
103
107
|
}
|
|
104
108
|
},
|
|
105
109
|
/** @param {string} v */
|
|
@@ -109,6 +113,14 @@ export default function FormAssociatedMixin(Base) {
|
|
|
109
113
|
this._valueDirty = true;
|
|
110
114
|
this._onSetValue(v);
|
|
111
115
|
break;
|
|
116
|
+
case 'filename':
|
|
117
|
+
if (v == null || v === '') {
|
|
118
|
+
this._files = null;
|
|
119
|
+
// Presume overriding class will interpet null as empty
|
|
120
|
+
} else {
|
|
121
|
+
throw new DOMException('InvalidStateError');
|
|
122
|
+
}
|
|
123
|
+
break;
|
|
112
124
|
default:
|
|
113
125
|
this.defaultValue = v;
|
|
114
126
|
}
|
|
@@ -121,8 +133,9 @@ export default function FormAssociatedMixin(Base) {
|
|
|
121
133
|
checked: {
|
|
122
134
|
reflect: false,
|
|
123
135
|
type: 'boolean',
|
|
124
|
-
get({ _checked }) {
|
|
125
|
-
return _checked;
|
|
136
|
+
get({ _checkedDirty, defaultChecked, _checked }) {
|
|
137
|
+
if (_checkedDirty) return _checked;
|
|
138
|
+
return defaultChecked;
|
|
126
139
|
},
|
|
127
140
|
/** @param {boolean} checked */
|
|
128
141
|
set(checked) {
|
|
@@ -135,7 +148,11 @@ export default function FormAssociatedMixin(Base) {
|
|
|
135
148
|
form() { return this.elementInternals.form; },
|
|
136
149
|
validity() { return this.elementInternals.validity; },
|
|
137
150
|
validationMessage() { return this.elementInternals.validationMessage; },
|
|
138
|
-
willValidate() {
|
|
151
|
+
willValidate() {
|
|
152
|
+
if (this.type === 'submit') return !this.formNoValidate;
|
|
153
|
+
if (this.type === 'button' || this.type === 'reset') return false;
|
|
154
|
+
return this.elementInternals.willValidate;
|
|
155
|
+
},
|
|
139
156
|
labels() { return this.elementInternals.labels; },
|
|
140
157
|
})
|
|
141
158
|
.observe({
|
|
@@ -195,8 +212,7 @@ export default function FormAssociatedMixin(Base) {
|
|
|
195
212
|
*/
|
|
196
213
|
formAssociatedCallback(form) {
|
|
197
214
|
this.refreshFormAssociation();
|
|
198
|
-
|
|
199
|
-
// Set value on association (not done by default?)
|
|
215
|
+
this.checkValidity();
|
|
200
216
|
},
|
|
201
217
|
|
|
202
218
|
/**
|
|
@@ -231,6 +247,7 @@ export default function FormAssociatedMixin(Base) {
|
|
|
231
247
|
this._formReset = true; // Fires Change Event
|
|
232
248
|
this._valueDirty = false;
|
|
233
249
|
this.checkValidity();
|
|
250
|
+
this._userInteracted = false; // Reset error states
|
|
234
251
|
this._formReset = false;
|
|
235
252
|
},
|
|
236
253
|
|
|
@@ -239,9 +256,8 @@ export default function FormAssociatedMixin(Base) {
|
|
|
239
256
|
* @param {'autocomplete'|'restore'} mode
|
|
240
257
|
*/
|
|
241
258
|
formStateRestoreCallback(state, mode) {
|
|
242
|
-
if (
|
|
243
|
-
|
|
244
|
-
// formStateRestoreCallback is broken on Edge
|
|
259
|
+
if (CHROME_VERSION < 115) {
|
|
260
|
+
// formStateRestoreCallback is broken on Chromium
|
|
245
261
|
// https://bugs.chromium.org/p/chromium/issues/detail?id=1429585
|
|
246
262
|
return;
|
|
247
263
|
}
|
|
@@ -275,21 +291,52 @@ export default function FormAssociatedMixin(Base) {
|
|
|
275
291
|
// Fallthrough
|
|
276
292
|
case 'checkbox':
|
|
277
293
|
if (this.checked) {
|
|
278
|
-
console.
|
|
294
|
+
// console.debug('FormAssociatedMixin: setFormValue', this.name, `(${this.value}, 'checked')`, this);
|
|
279
295
|
this.elementInternals.setFormValue(this.value, 'checked');
|
|
280
296
|
} else {
|
|
281
|
-
console.
|
|
297
|
+
// console.debug('FormAssociatedMixin: setFormValue', this.name, "(null, 'unchecked')", this);
|
|
282
298
|
this.elementInternals.setFormValue(null, 'unchecked');
|
|
283
299
|
}
|
|
284
300
|
break;
|
|
301
|
+
case 'button':
|
|
302
|
+
case 'reset':
|
|
303
|
+
this.elementInternals.setFormValue(null);
|
|
304
|
+
break;
|
|
305
|
+
case 'file': {
|
|
306
|
+
const { elementInternals, _files, name } = this;
|
|
307
|
+
if (!_files || _files.length) {
|
|
308
|
+
elementInternals.setFormValue(null);
|
|
309
|
+
} else {
|
|
310
|
+
const fd = new FormData();
|
|
311
|
+
for (const entry of _files) {
|
|
312
|
+
fd.append(name, entry);
|
|
313
|
+
}
|
|
314
|
+
elementInternals.setFormValue(fd);
|
|
315
|
+
}
|
|
316
|
+
break;
|
|
317
|
+
}
|
|
318
|
+
case 'select-multiple': {
|
|
319
|
+
const formData = new FormData();
|
|
320
|
+
if (this.name) {
|
|
321
|
+
for (const option of this.selectedOptions) {
|
|
322
|
+
formData.append(this.name, option.value);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
this.elementInternals.setFormValue(formData);
|
|
326
|
+
break;
|
|
327
|
+
}
|
|
328
|
+
// case 'select-one':
|
|
285
329
|
default:
|
|
286
|
-
console.
|
|
330
|
+
// console.debug('FormAssociatedMixin: setFormValue', this.name, this.value, this);
|
|
287
331
|
this.elementInternals.setFormValue(this.value);
|
|
288
332
|
}
|
|
289
333
|
},
|
|
290
334
|
})
|
|
291
335
|
.events({
|
|
292
|
-
blur() {
|
|
336
|
+
blur() {
|
|
337
|
+
this._userInteracted = true;
|
|
338
|
+
this.checkValidity();
|
|
339
|
+
},
|
|
293
340
|
})
|
|
294
341
|
.on({
|
|
295
342
|
connected() {
|
|
@@ -302,5 +349,13 @@ export default function FormAssociatedMixin(Base) {
|
|
|
302
349
|
valueChanged() {
|
|
303
350
|
this._updateFormAssociatedValue();
|
|
304
351
|
},
|
|
352
|
+
_valueBehaviorChanged(previous, current) {
|
|
353
|
+
if (previous !== 'filename' && current === 'filename') {
|
|
354
|
+
this.value = '';
|
|
355
|
+
}
|
|
356
|
+
},
|
|
357
|
+
typeChanged() {
|
|
358
|
+
this._updateFormAssociatedValue();
|
|
359
|
+
},
|
|
305
360
|
});
|
|
306
361
|
}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import NavigationListenerMixin from './NavigationListenerMixin.js';
|
|
2
|
+
|
|
3
|
+
// https://html.spec.whatwg.org/multipage/links.html#dom-hyperlink-protocol-dev
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* @template {keyof URL} T
|
|
7
|
+
* @param {T} name
|
|
8
|
+
* @return {ThisType<URL> & TypedPropertyDescriptor<URL[T]>}
|
|
9
|
+
*/
|
|
10
|
+
function buildHyperlinkDefinition(name) {
|
|
11
|
+
return {
|
|
12
|
+
get() {
|
|
13
|
+
return new URL(this.href, window.location.href)[name];
|
|
14
|
+
},
|
|
15
|
+
set(value) {
|
|
16
|
+
const { href } = this;
|
|
17
|
+
if (!href) return;
|
|
18
|
+
const url = new URL(href, window.location.href);
|
|
19
|
+
url[name] = value;
|
|
20
|
+
this.href = url.href;
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/** @param {typeof import('../core/CustomElement.js').default} Base */
|
|
26
|
+
export default function HyperlinkMixin(Base) {
|
|
27
|
+
return Base
|
|
28
|
+
.mixin(NavigationListenerMixin)
|
|
29
|
+
.observe({
|
|
30
|
+
href: 'string',
|
|
31
|
+
target: 'string',
|
|
32
|
+
download: 'string',
|
|
33
|
+
ping: 'string',
|
|
34
|
+
rel: 'string',
|
|
35
|
+
hreflang: 'string',
|
|
36
|
+
referrerPolicy: { type: 'string', attr: 'referrerpolicy' },
|
|
37
|
+
})
|
|
38
|
+
.define({
|
|
39
|
+
origin() { return new URL(this.href).origin; },
|
|
40
|
+
protocol: buildHyperlinkDefinition('protocol'),
|
|
41
|
+
username: buildHyperlinkDefinition('username'),
|
|
42
|
+
password: buildHyperlinkDefinition('password'),
|
|
43
|
+
host: buildHyperlinkDefinition('host'),
|
|
44
|
+
hostname: buildHyperlinkDefinition('hostname'),
|
|
45
|
+
port: buildHyperlinkDefinition('port'),
|
|
46
|
+
pathname: buildHyperlinkDefinition('pathname'),
|
|
47
|
+
search: buildHyperlinkDefinition('search'),
|
|
48
|
+
hash: buildHyperlinkDefinition('hash'),
|
|
49
|
+
})
|
|
50
|
+
.html`
|
|
51
|
+
<a id=anchor
|
|
52
|
+
href={href}
|
|
53
|
+
target={target}
|
|
54
|
+
download={download}
|
|
55
|
+
ping={ping}
|
|
56
|
+
rel={rel}
|
|
57
|
+
hreflang={hreflang}
|
|
58
|
+
referrerpolicy={referrerPolicy}
|
|
59
|
+
></a>
|
|
60
|
+
`
|
|
61
|
+
.methods({
|
|
62
|
+
toString() {
|
|
63
|
+
return this.href;
|
|
64
|
+
},
|
|
65
|
+
});
|
|
66
|
+
}
|
package/mixins/InputMixin.js
CHANGED
|
@@ -23,6 +23,11 @@ const IMPLICIT_SUBMISSION_BLOCKING_TYPES = new Set([
|
|
|
23
23
|
|
|
24
24
|
const DOMString = { nullParser: String, empty: '' };
|
|
25
25
|
|
|
26
|
+
/** Flag redispatched click events to know not to block them */
|
|
27
|
+
const redispatchedClickEvents = new WeakSet();
|
|
28
|
+
/** Flag root click events to know not to block them */
|
|
29
|
+
const rootClickEvents = new WeakSet();
|
|
30
|
+
|
|
26
31
|
/**
|
|
27
32
|
* @see https://html.spec.whatwg.org/multipage/input.html#htmlinputelement
|
|
28
33
|
* @param {ReturnType<import('./StateMixin.js').default>} Base
|
|
@@ -30,7 +35,6 @@ const DOMString = { nullParser: String, empty: '' };
|
|
|
30
35
|
export default function InputMixin(Base) {
|
|
31
36
|
return Base
|
|
32
37
|
.mixin(ControlMixin)
|
|
33
|
-
.extend()
|
|
34
38
|
.observe({
|
|
35
39
|
accept: DOMString,
|
|
36
40
|
alt: DOMString,
|
|
@@ -38,10 +42,9 @@ export default function InputMixin(Base) {
|
|
|
38
42
|
_formAction: { attr: 'formaction' },
|
|
39
43
|
formEnctype: { attr: 'formenctype', ...DOMString },
|
|
40
44
|
formMethod: { attr: 'formmethod', ...DOMString },
|
|
41
|
-
formNoValidate: { attr: 'formNoValidate', type: 'boolean' },
|
|
42
45
|
formTarget: { attr: 'formtarget', ...DOMString },
|
|
43
46
|
_height: { attr: 'height', type: 'integer' },
|
|
44
|
-
|
|
47
|
+
_indeterminate: 'boolean',
|
|
45
48
|
max: DOMString,
|
|
46
49
|
maxLength: { attr: 'maxlength', type: 'integer', empty: -1 },
|
|
47
50
|
min: DOMString,
|
|
@@ -55,31 +58,44 @@ export default function InputMixin(Base) {
|
|
|
55
58
|
// [CEReactions] attribute [LegacyNullToEmptyString] DOMString value;
|
|
56
59
|
_width: { attr: 'width', type: 'integer' },
|
|
57
60
|
})
|
|
61
|
+
.set({
|
|
62
|
+
_useFormImplicitSubmission: true,
|
|
63
|
+
})
|
|
58
64
|
.define({
|
|
59
65
|
// Alias for typescript
|
|
60
66
|
_input() { return /** @type {HTMLInputElement} */ (this.refs.control); },
|
|
61
67
|
})
|
|
68
|
+
.observe({
|
|
69
|
+
indeterminate: {
|
|
70
|
+
type: 'boolean',
|
|
71
|
+
get({ _indeterminate }) {
|
|
72
|
+
return _indeterminate;
|
|
73
|
+
},
|
|
74
|
+
/** @param {boolean} value */
|
|
75
|
+
set(value) {
|
|
76
|
+
this._input.indeterminate = value;
|
|
77
|
+
this._indeterminate = this._input.indeterminate;
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
})
|
|
62
81
|
.overrides({
|
|
63
82
|
controlTagName: 'input',
|
|
64
83
|
})
|
|
84
|
+
.recompose(({ refs: { control } }) => {
|
|
85
|
+
control.setAttribute('checked', '{defaultChecked}');
|
|
86
|
+
control.setAttribute('height', '{_height}');
|
|
87
|
+
control.setAttribute('width', '{_width}');
|
|
88
|
+
control.setAttribute('value', '{_defaultValue}');
|
|
89
|
+
})
|
|
65
90
|
.on({
|
|
66
|
-
composed({ inline }) {
|
|
67
|
-
const { label, control } = this.refs;
|
|
68
|
-
// Expose [selected] to .checked
|
|
69
|
-
label.setAttribute('selected', '{checked}');
|
|
70
|
-
label.setAttribute('invalid', '{_invalid}');
|
|
71
|
-
label.setAttribute('indeterminate', '{indeterminate}');
|
|
72
|
-
|
|
73
|
-
control.setAttribute('checked', '{defaultChecked}');
|
|
74
|
-
control.setAttribute('height', '{_height}');
|
|
75
|
-
control.setAttribute('width', '{_width}');
|
|
76
|
-
control.setAttribute('value', '{_defaultValue}');
|
|
77
|
-
},
|
|
78
|
-
|
|
79
91
|
// TODO: Bind multiple
|
|
80
92
|
typeChanged() { this.onValueChangingContentAttribute(); },
|
|
81
|
-
|
|
82
|
-
this.
|
|
93
|
+
checkedChanged() {
|
|
94
|
+
this._input.checked = this.checked;
|
|
95
|
+
this._input.indeterminate = this._indeterminate;
|
|
96
|
+
},
|
|
97
|
+
_indeterminateChanged(previous, current) {
|
|
98
|
+
this._input.indeterminate = current;
|
|
83
99
|
},
|
|
84
100
|
minChanged() { this.onValueChangingContentAttribute(); },
|
|
85
101
|
minLengthChanged() { this.onValueChangingContentAttribute(); },
|
|
@@ -91,11 +107,9 @@ export default function InputMixin(Base) {
|
|
|
91
107
|
defaultValueChanged() { this.onValueChangingContentAttribute(); },
|
|
92
108
|
_formResetChanged(oldValue, newValue) {
|
|
93
109
|
if (!newValue) return;
|
|
94
|
-
|
|
110
|
+
this._onSetValue(this.defaultValue);
|
|
95
111
|
const input = this._input;
|
|
96
|
-
input.value = this.defaultValue;
|
|
97
112
|
input.checked = this.defaultChecked;
|
|
98
|
-
this._value = input.value;
|
|
99
113
|
this._checked = input.checked;
|
|
100
114
|
this._checkedDirty = false;
|
|
101
115
|
},
|
|
@@ -124,6 +138,7 @@ export default function InputMixin(Base) {
|
|
|
124
138
|
// Apply user value to input and read back result to apply control to parse
|
|
125
139
|
this._input.checked = checked;
|
|
126
140
|
this._checked = this._input.checked;
|
|
141
|
+
this.indeterminate = false;
|
|
127
142
|
},
|
|
128
143
|
_onSetValue(value) {
|
|
129
144
|
// Apply user value to input and read back result to apply control to parse
|
|
@@ -138,6 +153,7 @@ export default function InputMixin(Base) {
|
|
|
138
153
|
* @return {void}
|
|
139
154
|
*/
|
|
140
155
|
performImplicitSubmission(event) {
|
|
156
|
+
if (!this._useFormImplicitSubmission) return;
|
|
141
157
|
const form = this.form;
|
|
142
158
|
if (!form) return;
|
|
143
159
|
/** @type {HTMLInputElement} */
|
|
@@ -154,13 +170,123 @@ export default function InputMixin(Base) {
|
|
|
154
170
|
}
|
|
155
171
|
}
|
|
156
172
|
if (defaultButton) {
|
|
157
|
-
defaultButton.
|
|
173
|
+
defaultButton.dispatchEvent(new PointerEvent(
|
|
174
|
+
'click',
|
|
175
|
+
{ bubbles: true, cancelable: true, composed: true },
|
|
176
|
+
));
|
|
158
177
|
return;
|
|
159
178
|
}
|
|
160
179
|
if (submissionBlockers.size > 1) return;
|
|
161
180
|
this.form.submit();
|
|
162
181
|
},
|
|
182
|
+
/** @param {Event} event */
|
|
183
|
+
_redispatchControlClickEvent(event) {
|
|
184
|
+
event.stopPropagation();
|
|
185
|
+
// Use constructor to match mouse/pointer properties
|
|
186
|
+
/** @type {Event} */
|
|
187
|
+
// @ts-ignore skip-cast
|
|
188
|
+
const newEvent = (new event.constructor(event.type, event));
|
|
189
|
+
redispatchedClickEvents.add(newEvent);
|
|
190
|
+
return this.dispatchEvent(newEvent);
|
|
191
|
+
},
|
|
192
|
+
/** @param {MouseEvent} event */
|
|
193
|
+
_handleInputClick(event) {
|
|
194
|
+
if (this.disabledState) return;
|
|
195
|
+
const input = this._input;
|
|
196
|
+
switch (input.type) {
|
|
197
|
+
case 'checkbox':
|
|
198
|
+
case 'radio': {
|
|
199
|
+
const { _checkedDirty, _checked, _indeterminate } = this;
|
|
200
|
+
this.checked = input.checked;
|
|
201
|
+
// Event needs to be rethrown and preventDefault inspected
|
|
202
|
+
if (this._redispatchControlClickEvent(event)) return;
|
|
203
|
+
event.preventDefault();
|
|
204
|
+
this._checkedDirty = _checkedDirty;
|
|
205
|
+
this._checked = _checked;
|
|
206
|
+
this._indeterminate = _indeterminate;
|
|
207
|
+
break;
|
|
208
|
+
}
|
|
209
|
+
case 'button':
|
|
210
|
+
case 'submit':
|
|
211
|
+
case 'reset': {
|
|
212
|
+
if (!this._redispatchControlClickEvent(event)) {
|
|
213
|
+
event.preventDefault();
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
const { type } = input;
|
|
217
|
+
if (type !== 'submit' && type !== 'reset') return;
|
|
218
|
+
// If in the composed path is another submit/reset button,
|
|
219
|
+
// Let that button take preference and ignore click.
|
|
220
|
+
|
|
221
|
+
for (const target of event.composedPath()) {
|
|
222
|
+
if (target === input || target === this) break;
|
|
223
|
+
if ((target instanceof HTMLInputElement || target instanceof HTMLButtonElement)
|
|
224
|
+
&& (target.type === 'submit' || target.type === 'reset')) {
|
|
225
|
+
// Inner Native Button
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
if ((target instanceof HTMLElement && target.form instanceof HTMLFormElement
|
|
229
|
+
&& (target.type === 'submit' || target.type === 'reset'))) {
|
|
230
|
+
// Inner FACE Button
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
if ((target instanceof HTMLAnchorElement && target.href)) {
|
|
234
|
+
// Inner Anchor Button
|
|
235
|
+
return;
|
|
236
|
+
}
|
|
237
|
+
}
|
|
163
238
|
|
|
239
|
+
const form = this.elementInternals?.form;
|
|
240
|
+
if (!form) return;
|
|
241
|
+
|
|
242
|
+
if (type === 'submit') {
|
|
243
|
+
const duplicatedButton = /** @type {HTMLInputElement} */ (input.cloneNode());
|
|
244
|
+
duplicatedButton.hidden = true;
|
|
245
|
+
form.append(duplicatedButton);
|
|
246
|
+
if ('requestSubmit' in form) {
|
|
247
|
+
form.requestSubmit(duplicatedButton);
|
|
248
|
+
} else {
|
|
249
|
+
duplicatedButton.click();
|
|
250
|
+
}
|
|
251
|
+
duplicatedButton.remove();
|
|
252
|
+
} else if (type === 'reset') {
|
|
253
|
+
form.reset();
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
break;
|
|
257
|
+
default:
|
|
258
|
+
}
|
|
259
|
+
},
|
|
260
|
+
})
|
|
261
|
+
.rootEvents({
|
|
262
|
+
click(event) {
|
|
263
|
+
rootClickEvents.add(event);
|
|
264
|
+
const { control } = this.refs;
|
|
265
|
+
if (event.target === control) return;
|
|
266
|
+
// Label-like click
|
|
267
|
+
if (!event.bubbles) return;
|
|
268
|
+
const { disabledState, type } = this;
|
|
269
|
+
if (disabledState) return;
|
|
270
|
+
if (type === 'checkbox' || type === 'radio') {
|
|
271
|
+
event.stopPropagation();
|
|
272
|
+
control.click();
|
|
273
|
+
} else {
|
|
274
|
+
this._handleInputClick(event);
|
|
275
|
+
}
|
|
276
|
+
},
|
|
277
|
+
})
|
|
278
|
+
.events({
|
|
279
|
+
click(event) {
|
|
280
|
+
// If click event came from own shadowRoot, let it through
|
|
281
|
+
if (rootClickEvents.has(event)) return;
|
|
282
|
+
// If click event is a redispatch, let it through
|
|
283
|
+
if (redispatchedClickEvents.has(event)) return;
|
|
284
|
+
if (event.target === this) {
|
|
285
|
+
// Support custom host.dispatchEvent(new Event('click'))
|
|
286
|
+
event.stopImmediatePropagation();
|
|
287
|
+
this.refs.control.click();
|
|
288
|
+
}
|
|
289
|
+
},
|
|
164
290
|
})
|
|
165
291
|
.childEvents({
|
|
166
292
|
control: {
|
|
@@ -170,6 +296,16 @@ export default function InputMixin(Base) {
|
|
|
170
296
|
if (/** @type {HTMLInputElement} */ (event.currentTarget).type === 'submit') return;
|
|
171
297
|
this.performImplicitSubmission(event);
|
|
172
298
|
},
|
|
299
|
+
click: '_handleInputClick',
|
|
300
|
+
input(event) {
|
|
301
|
+
if (this.disabledState) {
|
|
302
|
+
event.preventDefault();
|
|
303
|
+
event.stopImmediatePropagation();
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
const input = /** @type {HTMLInputElement} */ (event.currentTarget);
|
|
307
|
+
this.checked = input.checked;
|
|
308
|
+
},
|
|
173
309
|
change(event) {
|
|
174
310
|
if (this.disabledState) {
|
|
175
311
|
event.preventDefault();
|
|
@@ -177,16 +313,51 @@ export default function InputMixin(Base) {
|
|
|
177
313
|
return;
|
|
178
314
|
}
|
|
179
315
|
const input = /** @type {HTMLInputElement} */ (event.currentTarget);
|
|
180
|
-
|
|
181
|
-
this._checkedDirty = true;
|
|
182
|
-
this._checked = input.checked;
|
|
316
|
+
this.checked = input.checked;
|
|
183
317
|
},
|
|
184
318
|
},
|
|
185
319
|
})
|
|
186
|
-
.
|
|
187
|
-
|
|
320
|
+
.methods({
|
|
321
|
+
/** @type {HTMLInputElement['setRangeText']} */
|
|
322
|
+
// @ts-ignore Can't cast?
|
|
323
|
+
setRangeText(...args) { this._input.setRangeText(...args); },
|
|
324
|
+
|
|
325
|
+
/** @type {HTMLInputElement['setSelectionRange']} */
|
|
326
|
+
setSelectionRange(...args) { this._input.setSelectionRange(...args); },
|
|
327
|
+
|
|
328
|
+
/** @type {HTMLInputElement['showPicker']} */
|
|
329
|
+
showPicker(...args) { this._input.showPicker(...args); },
|
|
330
|
+
|
|
331
|
+
/** @type {HTMLInputElement['stepDown']} */
|
|
332
|
+
stepDown(...args) {
|
|
333
|
+
this._input.stepDown(...args);
|
|
334
|
+
this._value = this._input.value;
|
|
335
|
+
},
|
|
336
|
+
|
|
337
|
+
/** @type {HTMLInputElement['stepUp']} */
|
|
338
|
+
stepUp(...args) {
|
|
339
|
+
this._input.stepUp(...args);
|
|
340
|
+
this._value = this._input.value;
|
|
341
|
+
},
|
|
188
342
|
|
|
189
|
-
|
|
343
|
+
/** @type {HTMLInputElement['select']} */
|
|
344
|
+
select(...args) {
|
|
345
|
+
this._input.select(...args);
|
|
346
|
+
},
|
|
347
|
+
})
|
|
348
|
+
.define({
|
|
349
|
+
files: {
|
|
350
|
+
get() { return this._input.files; },
|
|
351
|
+
set(value) {
|
|
352
|
+
if (value == null && this.type === 'file') {
|
|
353
|
+
// TODO: Clean up single-loop recursion
|
|
354
|
+
this._input.value = ''; // Clears files
|
|
355
|
+
this.value = '';
|
|
356
|
+
} else {
|
|
357
|
+
this._input.files = value;
|
|
358
|
+
}
|
|
359
|
+
},
|
|
360
|
+
},
|
|
190
361
|
|
|
191
362
|
selectionDirection: {
|
|
192
363
|
get() { return this._input.selectionDirection; },
|
|
@@ -203,16 +374,6 @@ export default function InputMixin(Base) {
|
|
|
203
374
|
set(value) { this._input.selectionStart = value; },
|
|
204
375
|
},
|
|
205
376
|
|
|
206
|
-
setRangeText() { return this._input.setRangeText; },
|
|
207
|
-
|
|
208
|
-
setSelectionRange() { return this._input.setSelectionRange; },
|
|
209
|
-
|
|
210
|
-
showPicker() { return this._input.showPicker; },
|
|
211
|
-
|
|
212
|
-
stepDown() { return this._input.stepDown; },
|
|
213
|
-
|
|
214
|
-
stepUp() { return this._input.stepUp; },
|
|
215
|
-
|
|
216
377
|
valueAsDate: {
|
|
217
378
|
get() { return this._input.valueAsDate; },
|
|
218
379
|
set(value) {
|
|
@@ -252,5 +413,10 @@ export default function InputMixin(Base) {
|
|
|
252
413
|
this._width = value;
|
|
253
414
|
},
|
|
254
415
|
},
|
|
255
|
-
})
|
|
416
|
+
})
|
|
417
|
+
.css`
|
|
418
|
+
#control::-webkit-file-upload-button {
|
|
419
|
+
display: none;
|
|
420
|
+
}
|
|
421
|
+
`;
|
|
256
422
|
}
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import { attemptFocus, isRtl } from '../core/dom.js';
|
|
1
|
+
import { attemptFocus, isFocused, isRtl } from '../core/dom.js';
|
|
2
|
+
|
|
3
|
+
import AriaReflectorMixin from './AriaReflectorMixin.js';
|
|
2
4
|
|
|
3
5
|
const DEFAULT_ELEMENT_QUERY = [
|
|
4
6
|
'button',
|
|
@@ -14,7 +16,7 @@ const DEFAULT_ELEMENT_QUERY = [
|
|
|
14
16
|
*/
|
|
15
17
|
export default function KeyboardNavMixin(Base) {
|
|
16
18
|
return Base
|
|
17
|
-
.
|
|
19
|
+
.mixin(AriaReflectorMixin)
|
|
18
20
|
.observe({
|
|
19
21
|
/** Keyboard navigation attribute */
|
|
20
22
|
kbdNav: { empty: 'true' },
|
|
@@ -47,10 +49,23 @@ export default function KeyboardNavMixin(Base) {
|
|
|
47
49
|
})
|
|
48
50
|
.methods({
|
|
49
51
|
_ariaOrientationIsVertical() {
|
|
50
|
-
return (this.ariaOrientation
|
|
51
|
-
?? this.getAttribute('aria-orientation')
|
|
52
|
+
return (this.readAriaProperty('ariaOrientation')
|
|
52
53
|
?? this.ariaOrientationDefault) === 'vertical';
|
|
53
54
|
},
|
|
55
|
+
focusCurrentOrFirst() {
|
|
56
|
+
let current;
|
|
57
|
+
let first;
|
|
58
|
+
for (const candidate of this.kbdNavChildren) {
|
|
59
|
+
first = candidate;
|
|
60
|
+
if (candidate.tabIndex === 0) {
|
|
61
|
+
current = candidate;
|
|
62
|
+
break;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
if (attemptFocus(current)) return current;
|
|
66
|
+
if (attemptFocus(first)) return first;
|
|
67
|
+
return null;
|
|
68
|
+
},
|
|
54
69
|
/**
|
|
55
70
|
* Focuses next element participating in roving tab index list
|
|
56
71
|
* @param {HTMLElement} [current]
|
|
@@ -81,7 +96,7 @@ export default function KeyboardNavMixin(Base) {
|
|
|
81
96
|
}
|
|
82
97
|
|
|
83
98
|
if (!loop) {
|
|
84
|
-
if (
|
|
99
|
+
if (!isFocused(current) && current instanceof HTMLElement) {
|
|
85
100
|
current.focus();
|
|
86
101
|
}
|
|
87
102
|
return current;
|
|
@@ -145,7 +160,7 @@ export default function KeyboardNavMixin(Base) {
|
|
|
145
160
|
/** @type {HTMLElement} */
|
|
146
161
|
let firstFocusableChild = null;
|
|
147
162
|
for (const child of this.kbdNavChildren) {
|
|
148
|
-
if (!currentlyFocusedChild &&
|
|
163
|
+
if (!currentlyFocusedChild && isFocused(child)) {
|
|
149
164
|
currentlyFocusedChild = child;
|
|
150
165
|
} else if (!currentTabIndexChild && child.getAttribute('tabindex') === '0') {
|
|
151
166
|
currentTabIndexChild = child;
|
|
@@ -159,7 +174,7 @@ export default function KeyboardNavMixin(Base) {
|
|
|
159
174
|
}
|
|
160
175
|
// Bind
|
|
161
176
|
if (!child.hasAttribute('tabindex')) {
|
|
162
|
-
child.tabIndex = (
|
|
177
|
+
child.tabIndex = isFocused(child) ? 0 : -1;
|
|
163
178
|
}
|
|
164
179
|
// this.rtiBindChild(child);
|
|
165
180
|
}
|