@shortfuse/materialdesignweb 0.8.0 → 0.9.1
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 -198
- package/bin/mdw-css.js +1 -1
- package/components/Badge.js +15 -5
- package/components/Body.js +7 -0
- package/components/BottomAppBar.js +7 -10
- package/components/BottomSheet.js +472 -0
- package/components/Box.js +11 -49
- package/components/Button.js +81 -82
- package/components/Card.js +74 -62
- package/components/Checkbox.js +15 -25
- package/components/CheckboxIcon.js +19 -31
- package/components/Chip.js +18 -13
- package/components/Dialog.js +70 -100
- package/components/DialogActions.js +4 -0
- package/components/Display.js +64 -0
- package/components/Divider.js +5 -0
- package/components/Fab.js +94 -17
- package/components/FabContainer.js +57 -0
- package/components/FilterChip.js +43 -32
- package/components/Grid.js +187 -0
- package/components/Headline.js +9 -28
- package/components/Icon.js +80 -71
- package/components/IconButton.js +77 -120
- package/components/Input.js +745 -86
- package/components/InputChip.js +193 -0
- package/components/Label.js +7 -0
- package/components/List.js +11 -5
- package/components/ListItem.js +92 -23
- package/components/ListOption.js +143 -65
- package/components/Listbox.js +57 -17
- package/components/Menu.js +39 -27
- package/components/MenuItem.js +49 -36
- package/components/NavBar.js +66 -21
- package/components/NavBarItem.js +5 -0
- package/components/NavDrawer.js +33 -16
- package/components/NavDrawerItem.js +7 -4
- package/components/NavItem.js +61 -34
- package/components/NavRail.js +32 -21
- package/components/NavRailItem.js +10 -2
- package/components/Page.js +119 -0
- package/components/Pane.js +24 -0
- package/components/Popup.js +23 -8
- package/components/Progress.js +25 -5
- package/components/Radio.js +8 -7
- package/components/RadioIcon.js +24 -15
- package/components/Ripple.js +25 -7
- package/components/Root.js +225 -0
- package/components/Scrim.js +95 -0
- package/components/Search.js +30 -25
- package/components/SegmentedButton.js +53 -40
- package/components/SegmentedButtonGroup.js +15 -12
- package/components/Select.js +19 -10
- package/components/Shape.js +10 -66
- package/components/SideSheet.js +337 -0
- package/components/Slider.js +93 -36
- package/components/Snackbar.js +52 -20
- package/components/SnackbarContainer.js +51 -0
- package/components/Surface.js +20 -10
- package/components/Switch.js +21 -18
- package/components/SwitchIcon.js +62 -33
- package/components/Tab.js +78 -38
- package/components/TabContent.js +33 -12
- package/components/TabList.js +95 -34
- package/components/TabPanel.js +10 -1
- package/components/Table.js +151 -0
- package/components/TextArea.js +48 -16
- package/components/Title.js +8 -9
- package/components/Tooltip.js +51 -22
- package/components/TopAppBar.js +71 -78
- package/constants/shapes.js +36 -0
- package/constants/typography.js +127 -0
- package/core/Composition.js +391 -201
- package/core/CompositionAdapter.js +35 -18
- package/core/CustomElement.js +634 -254
- package/core/css.js +117 -12
- package/core/customTypes.js +161 -49
- package/core/dom.js +18 -11
- package/core/jsonMergePatch.js +27 -11
- package/core/observe.js +308 -256
- package/core/optimizations.js +9 -9
- package/core/template.js +14 -57
- 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 +85 -115
- package/dist/index.min.js.map +4 -4
- package/dist/meta.json +1 -1
- package/dom/HTMLOptionsCollectionProxy.js +108 -0
- package/{theming/themableMixinLoader.js → loaders/palette.js} +4 -3
- package/loaders/theme.js +12 -0
- package/mixins/AriaReflectorMixin.js +64 -15
- package/mixins/AriaToolbarMixin.js +6 -0
- package/mixins/ControlMixin.js +79 -33
- package/mixins/DelegatesFocusMixin.js +62 -0
- package/mixins/DensityMixin.js +7 -3
- package/mixins/ElevationMixin.js +61 -0
- package/mixins/FlexableMixin.js +87 -39
- package/mixins/FormAssociatedMixin.js +76 -10
- package/mixins/HyperlinkMixin.js +76 -0
- package/mixins/InputMixin.js +227 -32
- package/mixins/KeyboardNavMixin.js +11 -7
- package/mixins/NavigationListenerMixin.js +33 -0
- package/mixins/PopupMixin.js +216 -219
- package/mixins/RTLObserverMixin.js +2 -0
- package/mixins/ResizeObserverMixin.js +18 -4
- package/mixins/RippleMixin.js +11 -7
- package/mixins/ScrollListenerMixin.js +14 -2
- package/mixins/SemiStickyMixin.js +51 -98
- package/mixins/ShapeMaskedMixin.js +125 -0
- package/mixins/ShapeMixin.js +30 -203
- package/mixins/StateMixin.js +74 -34
- package/mixins/TextFieldMixin.js +128 -145
- package/mixins/ThemableMixin.js +57 -56
- package/mixins/TooltipTriggerMixin.js +305 -359
- package/mixins/TouchTargetMixin.js +5 -2
- package/mixins/TypographyMixin.js +128 -0
- package/package.json +125 -81
- package/services/rtl.js +10 -0
- package/services/svgAlias.js +17 -0
- package/{theming/index.js → services/theme.js} +25 -176
- 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 +72 -0
- package/types/components/BottomAppBar.d.ts.map +1 -0
- package/types/components/BottomSheet.d.ts +135 -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 +245 -0
- package/types/components/Button.d.ts.map +1 -0
- package/types/components/Card.d.ts +147 -0
- package/types/components/Card.d.ts.map +1 -0
- package/types/components/Checkbox.d.ts +207 -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 +248 -0
- package/types/components/Chip.d.ts.map +1 -0
- package/types/components/Dialog.d.ts +103 -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 +46 -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 +273 -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 +256 -0
- package/types/components/FilterChip.d.ts.map +1 -0
- package/types/components/Grid.d.ts +38 -0
- package/types/components/Grid.d.ts.map +1 -0
- package/types/components/Headline.d.ts +46 -0
- package/types/components/Headline.d.ts.map +1 -0
- package/types/components/Icon.d.ts +55 -0
- package/types/components/Icon.d.ts.map +1 -0
- package/types/components/IconButton.d.ts +284 -0
- package/types/components/IconButton.d.ts.map +1 -0
- package/types/components/Input.d.ts +2528 -0
- package/types/components/Input.d.ts.map +1 -0
- package/types/components/InputChip.d.ts +85 -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 +35 -0
- package/types/components/List.d.ts.map +1 -0
- package/types/components/ListItem.d.ts +124 -0
- package/types/components/ListItem.d.ts.map +1 -0
- package/types/components/ListOption.d.ts +158 -0
- package/types/components/ListOption.d.ts.map +1 -0
- package/types/components/Listbox.d.ts +763 -0
- package/types/components/Listbox.d.ts.map +1 -0
- package/types/components/Menu.d.ts +130 -0
- package/types/components/Menu.d.ts.map +1 -0
- package/types/components/MenuItem.d.ts +232 -0
- package/types/components/MenuItem.d.ts.map +1 -0
- package/types/components/NavBar.d.ts +20 -0
- package/types/components/NavBar.d.ts.map +1 -0
- package/types/components/NavBarItem.d.ts +97 -0
- package/types/components/NavBarItem.d.ts.map +1 -0
- package/types/components/NavDrawer.d.ts +107 -0
- package/types/components/NavDrawer.d.ts.map +1 -0
- package/types/components/NavDrawerItem.d.ts +97 -0
- package/types/components/NavDrawerItem.d.ts.map +1 -0
- package/types/components/NavItem.d.ts +99 -0
- package/types/components/NavItem.d.ts.map +1 -0
- package/types/components/NavRail.d.ts +108 -0
- package/types/components/NavRail.d.ts.map +1 -0
- package/types/components/NavRailItem.d.ts +97 -0
- package/types/components/NavRailItem.d.ts.map +1 -0
- package/types/components/Page.d.ts +25 -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 +78 -0
- package/types/components/Popup.d.ts.map +1 -0
- package/types/components/Progress.d.ts +21 -0
- package/types/components/Progress.d.ts.map +1 -0
- package/types/components/Radio.d.ts +201 -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 +35 -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 +516 -0
- package/types/components/Search.d.ts.map +1 -0
- package/types/components/SegmentedButton.d.ts +252 -0
- package/types/components/SegmentedButton.d.ts.map +1 -0
- package/types/components/SegmentedButtonGroup.d.ts +43 -0
- package/types/components/SegmentedButtonGroup.d.ts.map +1 -0
- package/types/components/Select.d.ts +158 -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 +111 -0
- package/types/components/SideSheet.d.ts.map +1 -0
- package/types/components/Slider.d.ts +203 -0
- package/types/components/Slider.d.ts.map +1 -0
- package/types/components/Snackbar.d.ts +73 -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 +187 -0
- package/types/components/Switch.d.ts.map +1 -0
- package/types/components/SwitchIcon.d.ts +61 -0
- package/types/components/SwitchIcon.d.ts.map +1 -0
- package/types/components/Tab.d.ts +139 -0
- package/types/components/Tab.d.ts.map +1 -0
- package/types/components/TabContent.d.ts +124 -0
- package/types/components/TabContent.d.ts.map +1 -0
- package/types/components/TabList.d.ts +1111 -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 +25 -0
- package/types/components/Table.d.ts.map +1 -0
- package/types/components/TextArea.d.ts +201 -0
- package/types/components/TextArea.d.ts.map +1 -0
- package/types/components/Title.d.ts +46 -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 +129 -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 +260 -0
- package/types/core/Composition.d.ts.map +1 -0
- package/types/core/CompositionAdapter.d.ts +114 -0
- package/types/core/CompositionAdapter.d.ts.map +1 -0
- package/types/core/CustomElement.d.ts +304 -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 +22 -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 +114 -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 +31 -0
- package/types/mixins/AriaReflectorMixin.d.ts.map +1 -0
- package/types/mixins/AriaToolbarMixin.d.ts +34 -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 +13 -0
- package/types/mixins/DelegatesFocusMixin.d.ts.map +1 -0
- package/types/mixins/DensityMixin.d.ts +8 -0
- package/types/mixins/DensityMixin.d.ts.map +1 -0
- package/types/mixins/ElevationMixin.d.ts +32 -0
- package/types/mixins/ElevationMixin.d.ts.map +1 -0
- package/types/mixins/FlexableMixin.d.ts +14 -0
- package/types/mixins/FlexableMixin.d.ts.map +1 -0
- package/types/mixins/FormAssociatedMixin.d.ts +123 -0
- package/types/mixins/FormAssociatedMixin.d.ts.map +1 -0
- package/types/mixins/HyperlinkMixin.d.ts +25 -0
- package/types/mixins/HyperlinkMixin.d.ts.map +1 -0
- package/types/mixins/InputMixin.d.ts +173 -0
- package/types/mixins/InputMixin.d.ts.map +1 -0
- package/types/mixins/KeyboardNavMixin.d.ts +46 -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 +98 -0
- package/types/mixins/PopupMixin.d.ts.map +1 -0
- package/types/mixins/RTLObserverMixin.d.ts +8 -0
- package/types/mixins/RTLObserverMixin.d.ts.map +1 -0
- package/types/mixins/ResizeObserverMixin.d.ts +13 -0
- package/types/mixins/ResizeObserverMixin.d.ts.map +1 -0
- package/types/mixins/RippleMixin.d.ts +94 -0
- package/types/mixins/RippleMixin.d.ts.map +1 -0
- package/types/mixins/ScrollListenerMixin.d.ts +46 -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 +12 -0
- package/types/mixins/ShapeMaskedMixin.d.ts.map +1 -0
- package/types/mixins/ShapeMixin.d.ts +39 -0
- package/types/mixins/ShapeMixin.d.ts.map +1 -0
- package/types/mixins/StateMixin.d.ts +29 -0
- package/types/mixins/StateMixin.d.ts.map +1 -0
- package/types/mixins/TextFieldMixin.d.ts +153 -0
- package/types/mixins/TextFieldMixin.d.ts.map +1 -0
- package/types/mixins/ThemableMixin.d.ts +10 -0
- package/types/mixins/ThemableMixin.d.ts.map +1 -0
- package/types/mixins/TooltipTriggerMixin.d.ts +114 -0
- package/types/mixins/TooltipTriggerMixin.d.ts.map +1 -0
- package/types/mixins/TouchTargetMixin.d.ts +6 -0
- package/types/mixins/TouchTargetMixin.d.ts.map +1 -0
- package/types/mixins/TypographyMixin.d.ts +20 -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/jsx-runtime.js +9 -4
- package/utils/material-color/scheme/Scheme.js +1 -1
- package/utils/pixelmatch.js +363 -0
- package/utils/popup.js +86 -10
- package/utils/searchParams.js +22 -0
- package/components/Button.md +0 -61
- package/components/ExtendedFab.js +0 -32
- package/components/Layout.js +0 -504
- package/components/Nav.js +0 -38
- package/core/DomAdapter.js +0 -586
- package/core/ICustomElement.d.ts +0 -291
- package/core/ICustomElement.js +0 -1
- package/core/test.js +0 -126
- package/core/typings.d.ts +0 -142
- package/core/typings.js +0 -1
- package/mixins/SurfaceMixin.js +0 -127
- package/theming/loader.js +0 -22
- /package/{utils/color_keywords.js → constants/colorKeywords.js} +0 -0
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/* https://m3.material.io/foundations/layout/applying-layout/window-size-classes */
|
|
2
|
+
|
|
3
|
+
import CustomElement from '../core/CustomElement.js';
|
|
4
|
+
import { ELEMENT_STYLE_TYPE } from '../core/customTypes.js';
|
|
5
|
+
import DelegatesFocusMixin from '../mixins/DelegatesFocusMixin.js';
|
|
6
|
+
import ResizeObserverMixin from '../mixins/ResizeObserverMixin.js';
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Page is a top-level layout container that manages single or multi-pane
|
|
10
|
+
* application layouts, adapting to viewport size to show one or two panes.
|
|
11
|
+
* @see https://m3.material.io/foundations/layout/applying-layout/window-size-classes
|
|
12
|
+
*/
|
|
13
|
+
export default CustomElement
|
|
14
|
+
.extend()
|
|
15
|
+
.mixin(DelegatesFocusMixin)
|
|
16
|
+
.mixin(ResizeObserverMixin)
|
|
17
|
+
.observe({
|
|
18
|
+
/** Layout behavior for the first pane: 'fixed' keeps a fixed width, 'flexible' grows. */
|
|
19
|
+
paneOne: {
|
|
20
|
+
value: /** @type {'fixed'|'flexible'} */ ('flexible'),
|
|
21
|
+
},
|
|
22
|
+
/** Layout behavior for the second pane; null disables the second pane. */
|
|
23
|
+
paneTwo: {
|
|
24
|
+
value: /** @type {'fixed'|'flexible'|null} */ (null),
|
|
25
|
+
},
|
|
26
|
+
/** Whether the second pane is currently active/visible. */
|
|
27
|
+
paneTwoActive: 'boolean',
|
|
28
|
+
/** Inline-size breakpoint (px) at which the second pane becomes visible. */
|
|
29
|
+
paneTwoBreakpoint: {
|
|
30
|
+
type: 'float',
|
|
31
|
+
empty: 720,
|
|
32
|
+
},
|
|
33
|
+
/** Internally tracked last measured inline size (pixels) used for layout decisions. */
|
|
34
|
+
_lastComputedInlineSize: {
|
|
35
|
+
type: 'float',
|
|
36
|
+
nullable: false,
|
|
37
|
+
},
|
|
38
|
+
})
|
|
39
|
+
.observe({
|
|
40
|
+
/** Computed: true when two-pane layout should be active based on measured size. */
|
|
41
|
+
_isMultipane({ _lastComputedInlineSize, paneTwo, paneTwoBreakpoint }) {
|
|
42
|
+
return Boolean(paneTwo && _lastComputedInlineSize >= paneTwoBreakpoint);
|
|
43
|
+
},
|
|
44
|
+
})
|
|
45
|
+
.observe({
|
|
46
|
+
/** Computed inline CSS string that adjusts grid columns for single/multi-pane layouts. */
|
|
47
|
+
_styles: {
|
|
48
|
+
...ELEMENT_STYLE_TYPE,
|
|
49
|
+
get({ _isMultipane, paneOne, paneTwoActive }) {
|
|
50
|
+
if (_isMultipane) {
|
|
51
|
+
return `:host{grid-template-columns:${paneOne === 'fixed' ? '360px' : '1fr'} ${this.paneTwo === 'fixed' ? '360px' : '1fr'}}`;
|
|
52
|
+
}
|
|
53
|
+
if (paneTwoActive) {
|
|
54
|
+
return ':host{grid-template-columns:1fr 0}#slot{display:none}';
|
|
55
|
+
}
|
|
56
|
+
return ':host{grid-template-columns:1fr 0}#two{display:none}';
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
})
|
|
60
|
+
.html`
|
|
61
|
+
<slot id=slot mutli-pane={_isMultipane}></slot>
|
|
62
|
+
<slot id=two name=two mutli-pane={_isMultipane}></slot>
|
|
63
|
+
`
|
|
64
|
+
.css`
|
|
65
|
+
:host {
|
|
66
|
+
--mdw-pane__max-width: 1040px;
|
|
67
|
+
--mdw-pane__margin-inline: 16px;
|
|
68
|
+
--mdw-pane__padding-inline: max(var(--mdw-pane__margin-inline), calc((100% - var(--mdw-pane__max-width)) / 2));
|
|
69
|
+
--mdw-pane__shape__size: 0;
|
|
70
|
+
display: grid;
|
|
71
|
+
column-gap: var(--mdw-page__margin);
|
|
72
|
+
grid-auto-columns: 1fr;
|
|
73
|
+
grid-auto-flow: column;
|
|
74
|
+
|
|
75
|
+
block-size: 100%;
|
|
76
|
+
|
|
77
|
+
padding: 0;
|
|
78
|
+
|
|
79
|
+
font: var(--mdw-typescale__body-large__font);
|
|
80
|
+
letter-spacing: var(--mdw-typescale__body-large__letter-spacing);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
@media (min-width: 648px) {
|
|
84
|
+
:host {
|
|
85
|
+
--mdw-pane__margin-inline: 24px;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
@media (min-width: 728px) {
|
|
90
|
+
:host {
|
|
91
|
+
--mdw-pane__shape__size: var(--mdw-shape__large);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
#slot[multi-pane] {
|
|
96
|
+
--mdw-pane__padding-inline: 24px;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
#two[mutli-pane] {
|
|
100
|
+
--mdw-pane__padding-inline: 0 24px;
|
|
101
|
+
position: sticky;
|
|
102
|
+
inset-block:0;
|
|
103
|
+
|
|
104
|
+
display: flex;
|
|
105
|
+
flex-direction: column;
|
|
106
|
+
|
|
107
|
+
overflow-y:auto;
|
|
108
|
+
|
|
109
|
+
block-size: 100vh;
|
|
110
|
+
block-size: 100dvh;
|
|
111
|
+
}
|
|
112
|
+
`
|
|
113
|
+
.overrides({
|
|
114
|
+
/** Handle resize observer entries; update measured inline size for layout logic. */
|
|
115
|
+
onResizeObserved(entry) {
|
|
116
|
+
this._lastComputedInlineSize = entry.borderBoxSize[0]?.inlineSize;
|
|
117
|
+
},
|
|
118
|
+
})
|
|
119
|
+
.autoRegister('mdw-page');
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import ShapeMixin from '../mixins/ShapeMixin.js';
|
|
2
|
+
|
|
3
|
+
import Box from './Box.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Pane is a layout surface used within `mdw-page` to provide shaped,
|
|
7
|
+
* padded content columns for app content. It is intended to be placed
|
|
8
|
+
* as a child of `mdw-page` to create consistent, shaped panes with the
|
|
9
|
+
* same padding and background surface used across the layout system.
|
|
10
|
+
* @see https://m3.material.io/foundations/layout/applying-layout/window-size-classes
|
|
11
|
+
*/
|
|
12
|
+
export default Box
|
|
13
|
+
.extend()
|
|
14
|
+
.mixin(ShapeMixin)
|
|
15
|
+
.css`
|
|
16
|
+
:host {
|
|
17
|
+
--mdw-shape__size: var(--mdw-pane__shape__size, 0);
|
|
18
|
+
--mdw-bg: var(--mdw-color__surface);
|
|
19
|
+
--mdw-ink: var(--mdw-color__on-surface);
|
|
20
|
+
background-color: rgb(var(--mdw-bg));
|
|
21
|
+
color: rgb(var(--mdw-ink));
|
|
22
|
+
}
|
|
23
|
+
`
|
|
24
|
+
.autoRegister('mdw-pane');
|
package/components/Popup.js
CHANGED
|
@@ -1,20 +1,35 @@
|
|
|
1
1
|
import CustomElement from '../core/CustomElement.js';
|
|
2
|
+
import ElevationMixin from '../mixins/ElevationMixin.js';
|
|
2
3
|
import PopupMixin from '../mixins/PopupMixin.js';
|
|
3
4
|
import ShapeMixin from '../mixins/ShapeMixin.js';
|
|
4
|
-
import SurfaceMixin from '../mixins/SurfaceMixin.js';
|
|
5
5
|
import ThemableMixin from '../mixins/ThemableMixin.js';
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Popup displays transient content such as menus or popovers and provides
|
|
9
|
+
* elevation, shape, and theming control for floating surfaces.
|
|
10
|
+
* @see https://m3.material.io/styles/elevation/overview
|
|
11
|
+
*/
|
|
7
12
|
export default CustomElement
|
|
8
13
|
.extend()
|
|
9
14
|
.mixin(ThemableMixin)
|
|
10
|
-
.mixin(
|
|
15
|
+
.mixin(ElevationMixin)
|
|
11
16
|
.mixin(ShapeMixin)
|
|
12
17
|
.mixin(PopupMixin)
|
|
13
|
-
.
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
surface.append(shape);
|
|
17
|
-
dialog.prepend(surface);
|
|
18
|
-
},
|
|
18
|
+
.observe({
|
|
19
|
+
/** Elevation level (0–5) controlling the drop-shadow depth of the popup. */
|
|
20
|
+
elevation: 'integer',
|
|
19
21
|
})
|
|
22
|
+
.css`
|
|
23
|
+
:host {
|
|
24
|
+
filter: var(--mdw-elevation__drop-shadow__0);
|
|
25
|
+
|
|
26
|
+
transition: filter 200ms;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
:host(:where([elevation="1"])) { filter: var(--mdw-elevation__drop-shadow__1); }
|
|
30
|
+
:host(:where([elevation="2"])) { filter: var(--mdw-elevation__drop-shadow__2); }
|
|
31
|
+
:host(:where([elevation="3"])) { filter: var(--mdw-elevation__drop-shadow__3); }
|
|
32
|
+
:host(:where([elevation="4"])) { filter: var(--mdw-elevation__drop-shadow__4); }
|
|
33
|
+
:host(:where([elevation="5"])) { filter: var(--mdw-elevation__drop-shadow__5); }
|
|
34
|
+
`
|
|
20
35
|
.autoRegister('mdw-popup');
|
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`
|
|
@@ -37,11 +41,8 @@ export default CustomElement
|
|
|
37
41
|
}
|
|
38
42
|
},
|
|
39
43
|
})
|
|
40
|
-
.
|
|
41
|
-
|
|
42
|
-
const { radio, rippleContainer, state } = this.refs;
|
|
43
|
-
radio.append(state, rippleContainer);
|
|
44
|
-
},
|
|
44
|
+
.recompose(({ refs: { radio, rippleContainer, state } }) => {
|
|
45
|
+
radio.append(state, rippleContainer);
|
|
45
46
|
})
|
|
46
47
|
.css`
|
|
47
48
|
/* stylelint-disable liberty/use-logical-spec */
|
package/components/RadioIcon.js
CHANGED
|
@@ -1,34 +1,47 @@
|
|
|
1
|
+
import './Shape.js';
|
|
2
|
+
|
|
1
3
|
import CustomElement from '../core/CustomElement.js';
|
|
2
4
|
import ShapeMixin from '../mixins/ShapeMixin.js';
|
|
3
5
|
import ThemableMixin from '../mixins/ThemableMixin.js';
|
|
4
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
|
+
*/
|
|
5
11
|
export default CustomElement
|
|
6
12
|
.extend()
|
|
7
13
|
.mixin(ThemableMixin)
|
|
8
14
|
.mixin(ShapeMixin)
|
|
9
15
|
.observe({
|
|
16
|
+
/** Whether the radio icon is selected (checked). */
|
|
10
17
|
selected: 'boolean',
|
|
18
|
+
/** Optional icon name to render inside the control (not normally used). */
|
|
11
19
|
icon: 'string',
|
|
20
|
+
/** When true the control is shown in an error state. */
|
|
12
21
|
errored: 'boolean',
|
|
22
|
+
/** When true the control is disabled. */
|
|
13
23
|
disabled: 'boolean',
|
|
24
|
+
/** Hover state used for styling. */
|
|
14
25
|
hovered: 'boolean',
|
|
26
|
+
/** Focus state used for styling. */
|
|
15
27
|
focused: 'boolean',
|
|
16
28
|
})
|
|
17
29
|
.define({
|
|
18
|
-
/**
|
|
30
|
+
/**
|
|
31
|
+
* Alias for `selected` to match common form terminology (`checked`).
|
|
32
|
+
* Reading/writing `checked` proxies to the `selected` state.
|
|
33
|
+
*/
|
|
19
34
|
checked: {
|
|
20
35
|
get() { return this.selected; },
|
|
21
36
|
set(value) { this.selected = value; },
|
|
22
37
|
},
|
|
23
38
|
})
|
|
24
39
|
.html`
|
|
25
|
-
<
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
outline.setAttribute('selected', '{selected}');
|
|
31
|
-
},
|
|
40
|
+
<mdw-shape id=inner-shape selected={selected}></div>
|
|
41
|
+
`
|
|
42
|
+
.recompose(({ refs: { outline } }) => {
|
|
43
|
+
outline.removeAttribute('mdw-if');
|
|
44
|
+
outline.setAttribute('selected', '{selected}');
|
|
32
45
|
})
|
|
33
46
|
.css`
|
|
34
47
|
/* https://m3.material.io/components/radio-button/specs */
|
|
@@ -52,16 +65,11 @@ export default CustomElement
|
|
|
52
65
|
}
|
|
53
66
|
|
|
54
67
|
#outline {
|
|
55
|
-
|
|
56
|
-
drop-shadow(1px 0px 0px var(--color))
|
|
57
|
-
drop-shadow(0px 1px 0px var(--color))
|
|
58
|
-
drop-shadow(-1px 0px 0px var(--color))
|
|
59
|
-
drop-shadow(0px -1px 0px var(--color))
|
|
60
|
-
;
|
|
68
|
+
border-width: 2px;
|
|
61
69
|
|
|
62
70
|
color: var(--color);
|
|
63
71
|
|
|
64
|
-
will-change:
|
|
72
|
+
will-change: color;
|
|
65
73
|
}
|
|
66
74
|
|
|
67
75
|
#inner-shape {
|
|
@@ -71,6 +79,7 @@ export default CustomElement
|
|
|
71
79
|
transform: scale(0);
|
|
72
80
|
|
|
73
81
|
background-color: var(--color);
|
|
82
|
+
border-radius: inherit;
|
|
74
83
|
|
|
75
84
|
transition: transform 200ms, background-color 100ms;
|
|
76
85
|
}
|
package/components/Ripple.js
CHANGED
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
import CustomElement from '../core/CustomElement.js';
|
|
2
|
-
import {
|
|
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,13 +38,16 @@ 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 }) {
|
|
45
|
+
// Skip if not measured
|
|
46
|
+
if (_radius == null) return null;
|
|
32
47
|
return {
|
|
33
48
|
styles: {
|
|
34
|
-
|
|
35
|
-
|
|
49
|
+
minHeight: `${_radius}px`,
|
|
50
|
+
minWidth: `${_radius}px`,
|
|
36
51
|
boxShadow: `0 0 calc(0.10 * ${_radius}px) calc(0.10 * ${_radius}px) currentColor`,
|
|
37
52
|
top: `calc(50% + ${_positionY}px)`,
|
|
38
53
|
left: `calc(50% + ${_positionX}px)`,
|
|
@@ -53,14 +68,16 @@ export default CustomElement
|
|
|
53
68
|
// Use offset to calculate parent size;
|
|
54
69
|
|
|
55
70
|
let hypotenuse = size;
|
|
56
|
-
const {
|
|
71
|
+
const { offsetParent } = this;
|
|
72
|
+
if (!offsetParent) return;
|
|
73
|
+
const { clientWidth: parentWidth, clientHeight: parentHeight } = offsetParent;
|
|
57
74
|
|
|
58
75
|
x ??= parentWidth / 2;
|
|
59
76
|
y ??= parentHeight / 2;
|
|
60
77
|
if (!hypotenuse) {
|
|
61
78
|
const width = (x >= parentWidth / 2) ? x : (parentWidth - x);
|
|
62
79
|
const height = (y >= parentHeight / 2) ? y : (parentHeight - y);
|
|
63
|
-
hypotenuse = 2 * Math.
|
|
80
|
+
hypotenuse = 2 * Math.hypot(width, height);
|
|
64
81
|
}
|
|
65
82
|
|
|
66
83
|
// const expandDuration = Math.min(
|
|
@@ -78,6 +95,7 @@ export default CustomElement
|
|
|
78
95
|
this._positionY = y - (parentHeight / 2);
|
|
79
96
|
this._radius = hypotenuse;
|
|
80
97
|
},
|
|
98
|
+
/** Complete the ripple lifecycle: either mark complete or remove. */
|
|
81
99
|
handleRippleComplete() {
|
|
82
100
|
if (this.keepAlive) {
|
|
83
101
|
this.setAttribute('ripple-state', 'complete');
|
|
@@ -99,7 +117,7 @@ export default CustomElement
|
|
|
99
117
|
animationend({ animationName }) {
|
|
100
118
|
switch (animationName) {
|
|
101
119
|
case 'ripple-fade-in':
|
|
102
|
-
this.
|
|
120
|
+
this.rippleState = 'filled';
|
|
103
121
|
break;
|
|
104
122
|
case 'ripple-fade-out':
|
|
105
123
|
this.handleRippleComplete();
|
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
/* https://m3.material.io/foundations/layout/applying-layout/window-size-classes */
|
|
2
|
+
|
|
3
|
+
import CustomElement from '../core/CustomElement.js';
|
|
4
|
+
import { ELEMENT_ANIMATION_TYPE } from '../core/customTypes.js';
|
|
5
|
+
import DelegatesFocusMixin from '../mixins/DelegatesFocusMixin.js';
|
|
6
|
+
import ScrollListenerMixin from '../mixins/ScrollListenerMixin.js';
|
|
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
|
+
*/
|
|
13
|
+
export default CustomElement
|
|
14
|
+
.extend()
|
|
15
|
+
.mixin(ScrollListenerMixin)
|
|
16
|
+
.mixin(DelegatesFocusMixin)
|
|
17
|
+
.set({
|
|
18
|
+
/** @type {ResizeObserver} */
|
|
19
|
+
_bottomResizeObserver: null,
|
|
20
|
+
})
|
|
21
|
+
.html`
|
|
22
|
+
<slot id=start name=start></slot>
|
|
23
|
+
<div id=bottom>
|
|
24
|
+
<slot id=bottom-slot name=bottom></slot>
|
|
25
|
+
</div>
|
|
26
|
+
<div id=bottom-fixed>
|
|
27
|
+
<slot id=bottom-fixed-slot name=bottom-fixed></slot>
|
|
28
|
+
</div>
|
|
29
|
+
<slot id=slot></slot>
|
|
30
|
+
<slot id=end name=end></slot>
|
|
31
|
+
`
|
|
32
|
+
.observe({
|
|
33
|
+
/** Measured height (px) of the bottom area used to compute reveal offsets. */
|
|
34
|
+
_bottomHeight: { type: 'float', empty: 0 },
|
|
35
|
+
/** Current vertical offset (px) applied to the bottom area for reveal/hide. */
|
|
36
|
+
_bottomOffsetY: { type: 'float', empty: 0 },
|
|
37
|
+
/** Animation duration (ms) used when adjusting bottom offset. */
|
|
38
|
+
_bottomDuration: { type: 'float', empty: 0 },
|
|
39
|
+
/** Animation easing name used when animating bottom reveal/hide. */
|
|
40
|
+
_bottomEasing: { empty: 'ease-in' },
|
|
41
|
+
})
|
|
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
|
+
*/
|
|
48
|
+
_sharedBottomStyle({ _bottomOffsetY, _bottomDuration, _bottomEasing, _bottomHeight }) {
|
|
49
|
+
if (!_bottomHeight) return null;
|
|
50
|
+
return {
|
|
51
|
+
styles: {
|
|
52
|
+
transform: `translateY(${_bottomOffsetY}px)`,
|
|
53
|
+
},
|
|
54
|
+
timing: {
|
|
55
|
+
duration: _bottomDuration,
|
|
56
|
+
easing: _bottomEasing,
|
|
57
|
+
},
|
|
58
|
+
};
|
|
59
|
+
},
|
|
60
|
+
})
|
|
61
|
+
.observe({
|
|
62
|
+
/** Animation/style object targeting the bottom slot element. */
|
|
63
|
+
_bottomSlotStyle: {
|
|
64
|
+
...ELEMENT_ANIMATION_TYPE,
|
|
65
|
+
get({ _sharedBottomStyle }) {
|
|
66
|
+
if (!_sharedBottomStyle) return null;
|
|
67
|
+
return {
|
|
68
|
+
target: 'bottom-slot',
|
|
69
|
+
..._sharedBottomStyle,
|
|
70
|
+
};
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
/** Animation/style object targeting the bottom-fixed-slot element. */
|
|
74
|
+
_bottomFixedSlotStyle: {
|
|
75
|
+
...ELEMENT_ANIMATION_TYPE,
|
|
76
|
+
get({ _sharedBottomStyle }) {
|
|
77
|
+
if (!_sharedBottomStyle) return null;
|
|
78
|
+
return {
|
|
79
|
+
target: 'bottom-fixed-slot',
|
|
80
|
+
..._sharedBottomStyle,
|
|
81
|
+
};
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
})
|
|
85
|
+
.on({
|
|
86
|
+
_scrollListenerPositionYChanged(oldValue, newValue) {
|
|
87
|
+
const delta = newValue - oldValue;
|
|
88
|
+
|
|
89
|
+
this._bottomDuration = 0;
|
|
90
|
+
// 0 if disabled or has scrolled upto element
|
|
91
|
+
// Valid range : 0 > x > (100% - required)
|
|
92
|
+
const bottomStartsAt = (document.documentElement.scrollHeight - window.innerHeight - 1);
|
|
93
|
+
const distanceFromBottom = bottomStartsAt - newValue;
|
|
94
|
+
const scrollVisible = this._bottomHeight - distanceFromBottom;
|
|
95
|
+
let mustIncludeSpace = 0;
|
|
96
|
+
if (scrollVisible > 0) {
|
|
97
|
+
mustIncludeSpace = scrollVisible;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
this._bottomOffsetY = (newValue === 0 || distanceFromBottom < 0)
|
|
101
|
+
? 0
|
|
102
|
+
: Math.max(0, Math.min(
|
|
103
|
+
this._bottomOffsetY + delta,
|
|
104
|
+
this._bottomHeight - mustIncludeSpace,
|
|
105
|
+
));
|
|
106
|
+
},
|
|
107
|
+
_scrollListenerLastIdleChanged() {
|
|
108
|
+
const { _bottomHeight, _bottomOffsetY } = this;
|
|
109
|
+
const visibility = (_bottomHeight - _bottomOffsetY) / _bottomHeight;
|
|
110
|
+
if (visibility <= 0) return;
|
|
111
|
+
if (visibility >= 1) return;
|
|
112
|
+
if (visibility < 0.5) {
|
|
113
|
+
const bottomStartsAt = (document.documentElement.scrollHeight - window.innerHeight - 1);
|
|
114
|
+
const { _scrollListenerPositionY } = this;
|
|
115
|
+
const distanceFromBottom = bottomStartsAt - _scrollListenerPositionY;
|
|
116
|
+
const scrollVisible = _bottomHeight - distanceFromBottom;
|
|
117
|
+
|
|
118
|
+
if (_scrollListenerPositionY !== 0 && distanceFromBottom >= 0 && scrollVisible <= 0) {
|
|
119
|
+
this._bottomDuration = 200;
|
|
120
|
+
this._bottomEasing = 'ease-out';
|
|
121
|
+
this._bottomOffsetY = _bottomHeight;
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
// Reveal all
|
|
127
|
+
this._bottomDuration = 250;
|
|
128
|
+
this._bottomEasing = 'ease-in';
|
|
129
|
+
this._bottomOffsetY = 0;
|
|
130
|
+
},
|
|
131
|
+
connected() {
|
|
132
|
+
// eslint-disable-next-line no-multi-assign
|
|
133
|
+
const observer = (this._bottomResizeObserver ??= new ResizeObserver((entries) => {
|
|
134
|
+
for (const { borderBoxSize } of entries) {
|
|
135
|
+
this._bottomHeight = borderBoxSize[0].blockSize;
|
|
136
|
+
}
|
|
137
|
+
}));
|
|
138
|
+
observer.observe(this.refs.bottom);
|
|
139
|
+
this.startScrollListener(window);
|
|
140
|
+
},
|
|
141
|
+
disconnected() {
|
|
142
|
+
this._scrollListenerClear();
|
|
143
|
+
this._bottomResizeObserver.unobserve(this.refs.bottom);
|
|
144
|
+
},
|
|
145
|
+
})
|
|
146
|
+
.css`
|
|
147
|
+
:host {
|
|
148
|
+
position: relative;
|
|
149
|
+
|
|
150
|
+
display: grid;
|
|
151
|
+
grid-template:
|
|
152
|
+
"start top end" auto
|
|
153
|
+
"start content end" minmax(auto, 1fr)
|
|
154
|
+
"start bottom end" auto
|
|
155
|
+
/ minmax(0px, auto) minmax(0px, 100%) minmax(0px, auto);
|
|
156
|
+
|
|
157
|
+
min-block-size: 100vh;
|
|
158
|
+
min-block-size: 100dvh;
|
|
159
|
+
|
|
160
|
+
font: var(--mdw-typescale__body-large__font);
|
|
161
|
+
letter-spacing: var(--mdw-typescale__body-large__letter-spacing);
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
#start {
|
|
165
|
+
display: flex;
|
|
166
|
+
grid-area: start;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
#slot {
|
|
170
|
+
display: block;
|
|
171
|
+
grid-area: content;
|
|
172
|
+
overflow-x: clip;
|
|
173
|
+
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
#end {
|
|
177
|
+
display: none;
|
|
178
|
+
|
|
179
|
+
grid-area: end;
|
|
180
|
+
|
|
181
|
+
block-size: 0;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
#bottom {
|
|
185
|
+
position: sticky;
|
|
186
|
+
inset-block-end: 0;
|
|
187
|
+
|
|
188
|
+
display: block;
|
|
189
|
+
grid-area: bottom;
|
|
190
|
+
overflow-y: hidden;
|
|
191
|
+
|
|
192
|
+
pointer-events: none;
|
|
193
|
+
|
|
194
|
+
z-index: 1;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
#bottom-slot {
|
|
198
|
+
position: sticky;
|
|
199
|
+
inset-block-end: 0;
|
|
200
|
+
|
|
201
|
+
display: flex;
|
|
202
|
+
/* Tab order flows from bottom-up */
|
|
203
|
+
flex-direction: column-reverse;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
#bottom-fixed {
|
|
207
|
+
position: sticky;
|
|
208
|
+
inset-block-end: 0;
|
|
209
|
+
|
|
210
|
+
display: block;
|
|
211
|
+
grid-area: bottom; /* Takes but does not dictate size of bottom area */
|
|
212
|
+
|
|
213
|
+
pointer-events: none;
|
|
214
|
+
|
|
215
|
+
z-index: 2;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
#bottom-fixed-slot {
|
|
219
|
+
position: absolute;
|
|
220
|
+
inset-block-end: 100%;
|
|
221
|
+
|
|
222
|
+
display: block;
|
|
223
|
+
}
|
|
224
|
+
`
|
|
225
|
+
.autoRegister('mdw-root');
|