@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
package/components/Tab.js
CHANGED
|
@@ -3,67 +3,102 @@
|
|
|
3
3
|
import './Icon.js';
|
|
4
4
|
|
|
5
5
|
import CustomElement from '../core/CustomElement.js';
|
|
6
|
+
import { CHROME_VERSION } from '../core/dom.js';
|
|
7
|
+
import DelegatesFocusMixin from '../mixins/DelegatesFocusMixin.js';
|
|
8
|
+
import HyperlinkMixin from '../mixins/HyperlinkMixin.js';
|
|
6
9
|
import RippleMixin from '../mixins/RippleMixin.js';
|
|
7
10
|
import ScrollListenerMixin from '../mixins/ScrollListenerMixin.js';
|
|
8
11
|
import ShapeMixin from '../mixins/ShapeMixin.js';
|
|
9
12
|
import StateMixin from '../mixins/StateMixin.js';
|
|
10
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Tabs organize content into separate views where only one view is visible
|
|
16
|
+
* at a time; tabs provide navigation between those views.
|
|
17
|
+
* @see https://m3.material.io/components/tabs/specs
|
|
18
|
+
*/
|
|
11
19
|
export default CustomElement
|
|
12
20
|
.extend()
|
|
13
21
|
.mixin(ShapeMixin)
|
|
14
22
|
.mixin(StateMixin)
|
|
15
23
|
.mixin(RippleMixin)
|
|
16
24
|
.mixin(ScrollListenerMixin)
|
|
25
|
+
.mixin(HyperlinkMixin)
|
|
26
|
+
.mixin(DelegatesFocusMixin)
|
|
17
27
|
.define({
|
|
18
28
|
stateTargetElement() { return this.refs.anchor; },
|
|
19
|
-
/**
|
|
20
|
-
* Used to compute primary indicator size.
|
|
21
|
-
* Default to 24.
|
|
22
|
-
*/
|
|
23
|
-
labelMetrics() {
|
|
24
|
-
const { slot, icon } = this.refs;
|
|
25
|
-
const target = slot.clientWidth ? slot : icon;
|
|
26
|
-
return {
|
|
27
|
-
width: target.clientWidth,
|
|
28
|
-
left: target.offsetLeft,
|
|
29
|
-
};
|
|
30
|
-
},
|
|
31
29
|
})
|
|
32
30
|
.set({
|
|
33
|
-
|
|
31
|
+
/** Enable state-layer visual treatment for pressed/hover states. */
|
|
34
32
|
stateLayer: true,
|
|
35
33
|
})
|
|
36
34
|
.observe({
|
|
35
|
+
/** Whether this tab is currently active/selected. */
|
|
37
36
|
active: 'boolean',
|
|
37
|
+
/** Named icon to display above the label. */
|
|
38
38
|
icon: 'string',
|
|
39
|
+
/** Image `src` for the icon when used instead of a named icon. */
|
|
39
40
|
src: 'string',
|
|
40
|
-
|
|
41
|
+
/** Optional aria-label for the tab's anchor element. */
|
|
41
42
|
ariaLabel: 'string',
|
|
42
43
|
})
|
|
43
44
|
.methods({
|
|
45
|
+
/** Move focus to the tab's anchor. */
|
|
44
46
|
/** @type {HTMLElement['focus']} */
|
|
45
47
|
focus(options) {
|
|
46
48
|
this.refs.anchor.focus(options);
|
|
47
49
|
},
|
|
50
|
+
/**
|
|
51
|
+
* Compute the label metrics used for indicator alignment.
|
|
52
|
+
* Returns an object with `width` and `left` in pixels.
|
|
53
|
+
*/
|
|
54
|
+
computeLabelMetrics() {
|
|
55
|
+
const { slot, icon } = this.refs;
|
|
56
|
+
const target = slot.clientWidth ? slot : icon;
|
|
57
|
+
return {
|
|
58
|
+
width: target.clientWidth,
|
|
59
|
+
left: target.offsetLeft,
|
|
60
|
+
};
|
|
61
|
+
},
|
|
62
|
+
})
|
|
63
|
+
.expressions({
|
|
64
|
+
/** Derive the `aria-controls` value from `href` if it references an id. */
|
|
65
|
+
anchorAriaControls({ href }) {
|
|
66
|
+
return href?.startsWith('#') ? href.slice(1) : null;
|
|
67
|
+
},
|
|
68
|
+
/** Stringified `aria-selected` for the anchor. */
|
|
69
|
+
anchorAriaSelected({ active }) {
|
|
70
|
+
return `${active}`;
|
|
71
|
+
},
|
|
72
|
+
/** Stringified `aria-disabled` for the anchor. */
|
|
73
|
+
anchorAriaDisabled({ disabledState }) {
|
|
74
|
+
return `${disabledState}`;
|
|
75
|
+
},
|
|
76
|
+
/** Ensure anchor `href` defaults to `#` when unset. */
|
|
77
|
+
anchorHref({ href }) {
|
|
78
|
+
return href ?? '#';
|
|
79
|
+
},
|
|
80
|
+
/** True when an icon or src is provided and should render. */
|
|
81
|
+
iconIf({ icon, src }) {
|
|
82
|
+
return icon || src;
|
|
83
|
+
},
|
|
84
|
+
/** Icon variation to use when active. */
|
|
85
|
+
iconVariation({ active }) {
|
|
86
|
+
return active ? 'filled' : null;
|
|
87
|
+
},
|
|
48
88
|
})
|
|
49
89
|
.html`
|
|
50
|
-
<
|
|
51
|
-
|
|
52
|
-
aria-controls=${({ href }) => (href?.startsWith('#') ? href.slice(1) : null)}
|
|
53
|
-
aria-selected=${({ active }) => (active ? 'true' : 'false')}
|
|
54
|
-
aria-disabled=${({ disabledState }) => `${disabledState}`}
|
|
55
|
-
disabled={disabledState}
|
|
56
|
-
href=${({ href }) => href ?? '#'}>
|
|
57
|
-
<mdw-icon mdw-if=${(data) => data.icon || data.src} id=icon aria-hidden=true src={src} active={active}>{icon}</mdw-icon>
|
|
58
|
-
<slot id=slot></slot>
|
|
59
|
-
</a>
|
|
90
|
+
<mdw-icon mdw-if={iconIf} id=icon aria-hidden=true src={src} active={active} icon={icon} variation={iconVariation}></mdw-icon>
|
|
91
|
+
<slot id=slot></slot>
|
|
60
92
|
`
|
|
61
|
-
.
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
}
|
|
93
|
+
.recompose(({ refs: { anchor, icon, slot, state } }) => {
|
|
94
|
+
anchor.setAttribute('role', 'tab');
|
|
95
|
+
anchor.setAttribute('aria-label', '{ariaLabel}');
|
|
96
|
+
anchor.setAttribute('aria-controls', '{anchorAriaControls}');
|
|
97
|
+
anchor.setAttribute('aria-selected', '{anchorAriaSelected}');
|
|
98
|
+
anchor.setAttribute('aria-disabled', '{anchorAriaDisabled}');
|
|
99
|
+
anchor.setAttribute('disabled', '{disabledState}');
|
|
100
|
+
anchor.append(icon, slot);
|
|
101
|
+
state.setAttribute('state-disabled', 'focus');
|
|
67
102
|
})
|
|
68
103
|
.events({
|
|
69
104
|
keydown(event) {
|
|
@@ -87,14 +122,24 @@ export default CustomElement
|
|
|
87
122
|
return;
|
|
88
123
|
}
|
|
89
124
|
if (href.startsWith('#')) {
|
|
90
|
-
const root = /** @type {HTMLElement} */ this.getRootNode();
|
|
125
|
+
const root = /** @type {HTMLElement} */ (this.getRootNode());
|
|
126
|
+
/** @type {HTMLElement} */
|
|
91
127
|
const el = root.querySelector(href);
|
|
92
128
|
if (!el) {
|
|
93
129
|
console.warn('Unknown element', href);
|
|
94
130
|
return;
|
|
95
131
|
}
|
|
96
132
|
event.preventDefault();
|
|
97
|
-
|
|
133
|
+
// Chrome does not support scrolling two elements at the same time
|
|
134
|
+
// https://bugs.chromium.org/p/chromium/issues/detail?id=1430426
|
|
135
|
+
const behavior = CHROME_VERSION ? 'instant' : 'smooth';
|
|
136
|
+
|
|
137
|
+
el.scrollTo({ top: 0, behavior });
|
|
138
|
+
el.offsetParent.scrollTo({
|
|
139
|
+
// Scroll-snap will adjust with subpixel precision
|
|
140
|
+
left: el.offsetLeft,
|
|
141
|
+
behavior: 'smooth',
|
|
142
|
+
});
|
|
98
143
|
}
|
|
99
144
|
},
|
|
100
145
|
},
|
|
@@ -106,6 +151,7 @@ export default CustomElement
|
|
|
106
151
|
display: inline-flex;
|
|
107
152
|
|
|
108
153
|
min-inline-size: 64px;
|
|
154
|
+
flex: none;
|
|
109
155
|
|
|
110
156
|
cursor: pointer;
|
|
111
157
|
}
|
|
@@ -136,8 +182,6 @@ export default CustomElement
|
|
|
136
182
|
padding-block: 4px;
|
|
137
183
|
|
|
138
184
|
font-size: 24px;
|
|
139
|
-
font-variation-settings: 'FILL' 0;
|
|
140
|
-
|
|
141
185
|
}
|
|
142
186
|
|
|
143
187
|
#shape[disabled],
|
|
@@ -152,10 +196,6 @@ export default CustomElement
|
|
|
152
196
|
color: rgb(var(--mdw-ink));
|
|
153
197
|
}
|
|
154
198
|
|
|
155
|
-
#icon[active] {
|
|
156
|
-
font-variation-settings: 'FILL' 1;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
199
|
#slot {
|
|
160
200
|
display: block;
|
|
161
201
|
overflow-x: hidden;
|
package/components/TabContent.js
CHANGED
|
@@ -4,25 +4,33 @@ import ResizeObserverMixin from '../mixins/ResizeObserverMixin.js';
|
|
|
4
4
|
|
|
5
5
|
import TabPanel from './TabPanel.js';
|
|
6
6
|
|
|
7
|
+
/**
|
|
8
|
+
* Tab content hosts tab panels and manages which panel is visible based on
|
|
9
|
+
* scroll position or selected tab.
|
|
10
|
+
* @see https://m3.material.io/components/tabs/specs
|
|
11
|
+
*/
|
|
7
12
|
export default CustomElement
|
|
8
13
|
.extend()
|
|
9
14
|
.mixin(ResizeObserverMixin)
|
|
10
15
|
.set({
|
|
11
|
-
/**
|
|
16
|
+
/**
|
|
17
|
+
* Internal list of `TabPanel` nodes currently assigned to the slot.
|
|
18
|
+
* @type {InstanceType<TabPanel>[]}
|
|
19
|
+
*/
|
|
12
20
|
_panelNodes: [],
|
|
13
21
|
/**
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* center: number,
|
|
19
|
-
* index: number,
|
|
20
|
-
* }[]}
|
|
22
|
+
* Cached metrics for each panel used to determine visibility and
|
|
23
|
+
* which panel is active based on scroll position. Each entry contains
|
|
24
|
+
* `{ left, width, right, center, index }` in pixels.
|
|
25
|
+
* @type {{left:number,width:number,right:number,center:number,index:number}[]|null}
|
|
21
26
|
*/
|
|
22
27
|
_panelMetrics: null,
|
|
23
28
|
})
|
|
24
29
|
.observe({
|
|
25
|
-
/**
|
|
30
|
+
/**
|
|
31
|
+
* Internal index of the currently selected panel. `-1` when none.
|
|
32
|
+
* This is maintained alongside panel `active` states.
|
|
33
|
+
*/
|
|
26
34
|
_selectedIndex: {
|
|
27
35
|
type: 'integer',
|
|
28
36
|
empty: -1,
|
|
@@ -44,7 +52,12 @@ export default CustomElement
|
|
|
44
52
|
},
|
|
45
53
|
})
|
|
46
54
|
.define({
|
|
55
|
+
/**
|
|
56
|
+
* Modifiable index of the currently-selected panel. 0-based index.
|
|
57
|
+
* Setting this updates panel `active` states accordingly.
|
|
58
|
+
*/
|
|
47
59
|
selectedIndex: {
|
|
60
|
+
|
|
48
61
|
get() {
|
|
49
62
|
let index = 0;
|
|
50
63
|
for (const panel of this.panels) {
|
|
@@ -68,16 +81,18 @@ export default CustomElement
|
|
|
68
81
|
},
|
|
69
82
|
})
|
|
70
83
|
.define({
|
|
71
|
-
selectedPanel: {
|
|
72
84
|
/**
|
|
73
|
-
*
|
|
85
|
+
* Modifiable currently selected panel.
|
|
86
|
+
* Setting this updates panel `active` states accordingly.
|
|
74
87
|
*/
|
|
88
|
+
selectedPanel: {
|
|
89
|
+
/** @return {InstanceType<TabPanel>|undefined} */
|
|
75
90
|
get() {
|
|
76
91
|
return this.panels.find((panel) => panel.active);
|
|
77
92
|
},
|
|
78
93
|
/**
|
|
79
94
|
* @param {InstanceType<TabPanel>} value
|
|
80
|
-
* @return {InstanceType<TabPanel
|
|
95
|
+
* @return {InstanceType<TabPanel>|null}
|
|
81
96
|
*/
|
|
82
97
|
set(value) {
|
|
83
98
|
const index = this.panels.indexOf(value);
|
|
@@ -89,11 +104,16 @@ export default CustomElement
|
|
|
89
104
|
})
|
|
90
105
|
.html`<slot id=slot></slot>`
|
|
91
106
|
.methods({
|
|
107
|
+
/** Called when the component observes a resize; clears cached metrics. */
|
|
92
108
|
onResizeObserved() {
|
|
93
109
|
this._panelMetrics = null;
|
|
94
110
|
this.updatePanels();
|
|
95
111
|
// Resize should not change panel visibility (Chrome Bug?)
|
|
96
112
|
},
|
|
113
|
+
/**
|
|
114
|
+
* Recompute which panels are visible based on scroll position and
|
|
115
|
+
* activate the panel whose visible percentage is >= 50%.
|
|
116
|
+
*/
|
|
97
117
|
updatePanels() {
|
|
98
118
|
const start = this.scrollLeft;
|
|
99
119
|
const width = this.clientWidth;
|
|
@@ -121,6 +141,7 @@ export default CustomElement
|
|
|
121
141
|
// @ts-ignore Skip cast
|
|
122
142
|
this._panelNodes = slot.assignedElements()
|
|
123
143
|
.filter((el) => el.tagName === TabPanel.elementName.toUpperCase());
|
|
144
|
+
this._panelMetrics = null;
|
|
124
145
|
this.updatePanels();
|
|
125
146
|
},
|
|
126
147
|
},
|
package/components/TabList.js
CHANGED
|
@@ -4,11 +4,17 @@ import CustomElement from '../core/CustomElement.js';
|
|
|
4
4
|
import KeyboardNavMixin from '../mixins/KeyboardNavMixin.js';
|
|
5
5
|
import RTLObserverMixin from '../mixins/RTLObserverMixin.js';
|
|
6
6
|
import ResizeObserverMixin from '../mixins/ResizeObserverMixin.js';
|
|
7
|
+
import SemiStickyMixin from '../mixins/SemiStickyMixin.js';
|
|
7
8
|
import ShapeMixin from '../mixins/ShapeMixin.js';
|
|
8
9
|
import ThemableMixin from '../mixins/ThemableMixin.js';
|
|
9
10
|
|
|
10
11
|
import Tab from './Tab.js';
|
|
11
12
|
|
|
13
|
+
/**
|
|
14
|
+
* Tab list is the container for `mdw-tab` elements and renders the active
|
|
15
|
+
* indicator and keyboard navigation behavior.
|
|
16
|
+
* @see https://m3.material.io/components/tabs/specs
|
|
17
|
+
*/
|
|
12
18
|
export default CustomElement
|
|
13
19
|
.extend()
|
|
14
20
|
.mixin(ThemableMixin)
|
|
@@ -16,9 +22,15 @@ export default CustomElement
|
|
|
16
22
|
.mixin(ResizeObserverMixin)
|
|
17
23
|
.mixin(RTLObserverMixin)
|
|
18
24
|
.mixin(ShapeMixin)
|
|
25
|
+
.mixin(SemiStickyMixin)
|
|
26
|
+
.observe({
|
|
27
|
+
/** When true the tablist is scrollable (renders differently). */
|
|
28
|
+
scrollable: 'boolean',
|
|
29
|
+
})
|
|
19
30
|
.set({
|
|
20
31
|
/** @type {WeakRef<HTMLElement>} */
|
|
21
32
|
_tabContentRef: null,
|
|
33
|
+
/** Listener function attached to the tab content's `scroll` event. */
|
|
22
34
|
_tabContentScrollListener: null,
|
|
23
35
|
/** @type {HTMLCollectionOf<InstanceType<Tab>>} */
|
|
24
36
|
_tabCollection: null,
|
|
@@ -29,6 +41,7 @@ export default CustomElement
|
|
|
29
41
|
* right:number,
|
|
30
42
|
* center: number,
|
|
31
43
|
* label: {left:number, width:number},
|
|
44
|
+
* tab: InstanceType<Tab>,
|
|
32
45
|
* index: number,
|
|
33
46
|
* }[]}
|
|
34
47
|
*/
|
|
@@ -48,8 +61,10 @@ export default CustomElement
|
|
|
48
61
|
}
|
|
49
62
|
if (value) {
|
|
50
63
|
this._tabContentRef = new WeakRef(value);
|
|
64
|
+
// @ts-expect-error this lacks forward declaration
|
|
51
65
|
this._tabContentScrollListener = this.observeTabContent.bind(this);
|
|
52
66
|
value.addEventListener('scroll', this._tabContentScrollListener);
|
|
67
|
+
// @ts-expect-error this lacks forward declaration
|
|
53
68
|
this.observeTabContent();
|
|
54
69
|
} else {
|
|
55
70
|
this._tabContentRef = null;
|
|
@@ -58,19 +73,15 @@ export default CustomElement
|
|
|
58
73
|
},
|
|
59
74
|
})
|
|
60
75
|
.observe({
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
* @param {string} newValue
|
|
65
|
-
*/
|
|
66
|
-
changedCallback(oldValue, newValue) {
|
|
67
|
-
// @ts-ignore Skip cast
|
|
68
|
-
this.tabContent = newValue ? document.getElementById(newValue) : null;
|
|
69
|
-
},
|
|
70
|
-
},
|
|
76
|
+
/** Id of an external `TabContent` element to bind and observe. */
|
|
77
|
+
tabContentId: 'string',
|
|
78
|
+
/** Whether the tablist is visually active (has a selected tab). */
|
|
71
79
|
active: 'boolean',
|
|
80
|
+
/** Render the secondary (label-width) indicator style when true. */
|
|
72
81
|
secondary: 'boolean',
|
|
82
|
+
/** Inline style used to position and size the indicator. */
|
|
73
83
|
_indicatorStyle: { value: 'opacity: 0' },
|
|
84
|
+
/** Color token used for the tab ink. */
|
|
74
85
|
color: { empty: 'surface-primary' },
|
|
75
86
|
})
|
|
76
87
|
.define({
|
|
@@ -108,15 +119,25 @@ export default CustomElement
|
|
|
108
119
|
},
|
|
109
120
|
tabMetrics() {
|
|
110
121
|
// eslint-disable-next-line no-return-assign
|
|
111
|
-
return this._tabMetrics ??= [...this.tabs].map((tab, index) =>
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
122
|
+
return this._tabMetrics ??= [...this.tabs].map((tab, index) => {
|
|
123
|
+
if (!(tab instanceof Tab)) {
|
|
124
|
+
customElements.upgrade(tab);
|
|
125
|
+
}
|
|
126
|
+
return {
|
|
127
|
+
left: tab.offsetLeft,
|
|
128
|
+
width: tab.offsetWidth,
|
|
129
|
+
right: tab.offsetLeft + tab.offsetWidth,
|
|
130
|
+
center: tab.offsetLeft + (tab.offsetWidth / 2),
|
|
131
|
+
label: tab.computeLabelMetrics(),
|
|
132
|
+
tab,
|
|
133
|
+
index,
|
|
134
|
+
};
|
|
135
|
+
});
|
|
119
136
|
},
|
|
137
|
+
/**
|
|
138
|
+
* Modifiable index of the currently selected tab. 0-based index.
|
|
139
|
+
* Setting this updates tab `active` states accordingly.
|
|
140
|
+
*/
|
|
120
141
|
selectedIndex: {
|
|
121
142
|
get() {
|
|
122
143
|
let index = 0;
|
|
@@ -141,6 +162,10 @@ export default CustomElement
|
|
|
141
162
|
},
|
|
142
163
|
})
|
|
143
164
|
.define({
|
|
165
|
+
/**
|
|
166
|
+
* Modifiable currently selected tab.
|
|
167
|
+
* Setting this updates tab `active` states accordingly.
|
|
168
|
+
*/
|
|
144
169
|
selectedItem: {
|
|
145
170
|
/**
|
|
146
171
|
* @return {InstanceType<Tab>}
|
|
@@ -169,24 +194,40 @@ export default CustomElement
|
|
|
169
194
|
},
|
|
170
195
|
})
|
|
171
196
|
.methods({
|
|
197
|
+
/** Clear cached tab metrics (widths/positions). */
|
|
172
198
|
clearCache() {
|
|
173
199
|
this._tabMetrics = null;
|
|
174
200
|
},
|
|
201
|
+
/** Find and bind to the external `TabContent` element by id. */
|
|
202
|
+
searchForTabContent() {
|
|
203
|
+
const { tabContentId, isConnected } = this;
|
|
204
|
+
if (!tabContentId) return;
|
|
205
|
+
if (!isConnected) return;
|
|
206
|
+
const root = /** @type {ShadowRoot|Document} */ (this.getRootNode());
|
|
207
|
+
this.tabContent = root.getElementById(tabContentId);
|
|
208
|
+
},
|
|
209
|
+
/** Update the indicator position based on a specific `Tab`. */
|
|
175
210
|
/** @param {InstanceType<Tab>} [tab] */
|
|
176
211
|
updateIndicatorByTab(tab) {
|
|
177
212
|
tab ??= this.selectedItem ?? this.tabs.item(0);
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
const
|
|
213
|
+
const metrics = this.tabMetrics.find((m) => m.tab === tab);
|
|
214
|
+
if (!metrics) return;
|
|
215
|
+
const width = this.secondary ? metrics.width : metrics.label.width;
|
|
216
|
+
const position = this.secondary ? metrics.left : metrics.left + metrics.label.left;
|
|
181
217
|
this._indicatorStyle = `--width: ${width}; --offset: ${position}px`;
|
|
182
218
|
},
|
|
219
|
+
/** Recompute and apply indicator; optionally disable animation when `animate` is false. */
|
|
183
220
|
updateIndicator(animate = false) {
|
|
184
221
|
this.updateIndicatorByTab();
|
|
185
222
|
if (!animate) {
|
|
186
223
|
this.refs.indicator.style.setProperty('--transition-ratio', '0');
|
|
187
224
|
}
|
|
188
225
|
},
|
|
189
|
-
/**
|
|
226
|
+
/**
|
|
227
|
+
* Update the indicator position by a floating `percentage` between 0..1
|
|
228
|
+
* representing the scroll progress across tab panels.
|
|
229
|
+
* @param {number} percentage
|
|
230
|
+
*/
|
|
190
231
|
updateIndicatorByPosition(percentage) {
|
|
191
232
|
const metrics = this.tabMetrics;
|
|
192
233
|
|
|
@@ -208,7 +249,7 @@ export default CustomElement
|
|
|
208
249
|
let center;
|
|
209
250
|
if (leftMetrics === rightMetrics) {
|
|
210
251
|
width = this.secondary ? leftMetrics.width : leftMetrics.label.width;
|
|
211
|
-
activeTab =
|
|
252
|
+
activeTab = leftMetrics.tab;
|
|
212
253
|
center = leftMetrics.center;
|
|
213
254
|
} else {
|
|
214
255
|
const leftRatio = 1 - (decimalIndex - leftIndex);
|
|
@@ -218,7 +259,7 @@ export default CustomElement
|
|
|
218
259
|
const activeIndex = leftRatio > rightRatio ? leftIndex : rightIndex;
|
|
219
260
|
const distance = rightMetrics.center - leftMetrics.center;
|
|
220
261
|
width = leftWidth + rightWidth;
|
|
221
|
-
activeTab = this.
|
|
262
|
+
activeTab = this.tabMetrics[activeIndex].tab;
|
|
222
263
|
center = leftMetrics.center + (distance * rightRatio);
|
|
223
264
|
}
|
|
224
265
|
|
|
@@ -232,10 +273,12 @@ export default CustomElement
|
|
|
232
273
|
this._indicatorStyle = `--width: ${width}; --offset: ${center - (width / 2)}px`;
|
|
233
274
|
this.refs.indicator.style.setProperty('--transition-ratio', '0');
|
|
234
275
|
},
|
|
276
|
+
/** Update the indicator using a discrete tab index. */
|
|
235
277
|
/** @param {number} index */
|
|
236
278
|
updateIndicatorByIndex(index) {
|
|
237
279
|
this.updateIndicatorByTab(this.tabs.item(index ?? this._selectedIndex));
|
|
238
280
|
},
|
|
281
|
+
/** Observe the bound TabContent scroll and update indicator accordingly. */
|
|
239
282
|
observeTabContent() {
|
|
240
283
|
const tabContent = this.tabContent;
|
|
241
284
|
if (!tabContent) return;
|
|
@@ -248,6 +291,7 @@ export default CustomElement
|
|
|
248
291
|
const percentage = max === 0 ? 0 : start / max;
|
|
249
292
|
this.updateIndicatorByPosition(percentage);
|
|
250
293
|
},
|
|
294
|
+
/** Handler called when the element is resized; refresh cache and indicator. */
|
|
251
295
|
onResizeObserved() {
|
|
252
296
|
this.clearCache();
|
|
253
297
|
this.updateIndicator();
|
|
@@ -258,7 +302,7 @@ export default CustomElement
|
|
|
258
302
|
ariaRole: 'tablist',
|
|
259
303
|
})
|
|
260
304
|
.html`
|
|
261
|
-
<slot id=slot ink={ink} type-style={typeStyle}></slot>
|
|
305
|
+
<slot id=slot ink={ink} type-style={typeStyle} scrollable={scrollable}></slot>
|
|
262
306
|
<div id=indicator aria-hidden=true style={_indicatorStyle} active={active} secondary={secondary}>
|
|
263
307
|
<div id=indicator-start class=indicator-piece></div>
|
|
264
308
|
<div id=indicator-center class=indicator-piece></div>
|
|
@@ -266,9 +310,11 @@ export default CustomElement
|
|
|
266
310
|
</div>
|
|
267
311
|
`
|
|
268
312
|
.on({
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
313
|
+
constructed() {
|
|
314
|
+
document.addEventListener('DOMContentLoaded', () => this.searchForTabContent(), { once: true });
|
|
315
|
+
},
|
|
316
|
+
connected() {
|
|
317
|
+
this.searchForTabContent();
|
|
272
318
|
},
|
|
273
319
|
pageIsRTLChanged() {
|
|
274
320
|
this.clearCache();
|
|
@@ -286,6 +332,9 @@ export default CustomElement
|
|
|
286
332
|
_selectedIndexChanged(oldValue, newValue) {
|
|
287
333
|
this.updateIndicatorByIndex(newValue);
|
|
288
334
|
},
|
|
335
|
+
tabContentIdChanged() {
|
|
336
|
+
this.searchForTabContent();
|
|
337
|
+
},
|
|
289
338
|
})
|
|
290
339
|
.events({
|
|
291
340
|
'~click'({ target }) {
|
|
@@ -301,6 +350,7 @@ export default CustomElement
|
|
|
301
350
|
slotchange() {
|
|
302
351
|
this.clearCache();
|
|
303
352
|
this.updateIndicator();
|
|
353
|
+
this.searchForTabContent();
|
|
304
354
|
},
|
|
305
355
|
},
|
|
306
356
|
})
|
|
@@ -309,9 +359,8 @@ export default CustomElement
|
|
|
309
359
|
|
|
310
360
|
:host {
|
|
311
361
|
--mdw-ink: var(--mdw-color__primary);
|
|
312
|
-
--mdw-
|
|
362
|
+
--mdw-bg: var(--mdw-color__surface);
|
|
313
363
|
position: relative;
|
|
314
|
-
position: sticky;
|
|
315
364
|
inset-block-start: 0;
|
|
316
365
|
inset-inline: 0;
|
|
317
366
|
|
|
@@ -327,6 +376,8 @@ export default CustomElement
|
|
|
327
376
|
inline-size: 100%;
|
|
328
377
|
flex:none;
|
|
329
378
|
|
|
379
|
+
z-index: 4;
|
|
380
|
+
|
|
330
381
|
color: inherit;
|
|
331
382
|
|
|
332
383
|
text-align: center;
|
|
@@ -334,6 +385,10 @@ export default CustomElement
|
|
|
334
385
|
will-change: transform;
|
|
335
386
|
}
|
|
336
387
|
|
|
388
|
+
:host(:where([color])) {
|
|
389
|
+
background-color: rgb(var(--mdw-bg));
|
|
390
|
+
}
|
|
391
|
+
|
|
337
392
|
#indicator {
|
|
338
393
|
--corner: 3;
|
|
339
394
|
--width: 24;
|
|
@@ -428,11 +483,17 @@ export default CustomElement
|
|
|
428
483
|
}
|
|
429
484
|
|
|
430
485
|
:host([scrollable]) {
|
|
431
|
-
|
|
432
|
-
justify-content:
|
|
433
|
-
|
|
486
|
+
display: flex;
|
|
487
|
+
justify-content: initial;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
#slot[scrollable] {
|
|
491
|
+
display: inline-flex;
|
|
492
|
+
|
|
493
|
+
inline-size: 0;
|
|
494
|
+
flex: 1;
|
|
434
495
|
|
|
435
|
-
padding-inline: 48px
|
|
496
|
+
padding-inline: 48px;
|
|
436
497
|
}
|
|
437
498
|
`
|
|
438
499
|
.autoRegister('mdw-tab-list');
|
package/components/TabPanel.js
CHANGED
|
@@ -2,19 +2,28 @@ import AriaReflectorMixin from '../mixins/AriaReflectorMixin.js';
|
|
|
2
2
|
|
|
3
3
|
import Box from './Box.js';
|
|
4
4
|
|
|
5
|
+
/**
|
|
6
|
+
* TabPanel represents the content area for a single tab and updates ARIA
|
|
7
|
+
* when activated.
|
|
8
|
+
* @see https://m3.material.io/components/tabs/specs
|
|
9
|
+
*/
|
|
5
10
|
export default Box
|
|
6
11
|
.extend()
|
|
7
12
|
.mixin(AriaReflectorMixin)
|
|
8
13
|
.set({
|
|
14
|
+
/** ARIA role applied by the AriaReflectorMixin (defaults to `tabpanel`). */
|
|
9
15
|
_ariaRole: 'tabpanel',
|
|
10
16
|
})
|
|
11
17
|
.observe({
|
|
18
|
+
/** Whether this panel is active/visible; updates ARIA `aria-hidden`. */
|
|
12
19
|
active: {
|
|
13
20
|
type: 'boolean',
|
|
21
|
+
/** Update `aria-hidden` when `active` changes. */
|
|
14
22
|
changedCallback(oldValue, newValue) {
|
|
15
23
|
this.updateAriaProperty('ariaHidden', newValue ? 'false' : 'true');
|
|
16
24
|
},
|
|
17
25
|
},
|
|
26
|
+
/** True when the panel is partially visible (peeking). */
|
|
18
27
|
peeking: 'boolean',
|
|
19
28
|
})
|
|
20
29
|
.css`
|
|
@@ -34,7 +43,7 @@ export default Box
|
|
|
34
43
|
|
|
35
44
|
:host(:is([active],[peeking])) {
|
|
36
45
|
/* Safari bug: Visiblity not changing without !important or layout reflow */
|
|
37
|
-
visibility:
|
|
46
|
+
visibility: inherit !important;
|
|
38
47
|
}
|
|
39
48
|
`
|
|
40
49
|
.autoRegister('mdw-tab-panel');
|