@material/web 1.0.0-pre.15 → 1.0.0-pre.17
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 +26 -21
- package/all.d.ts +4 -2
- package/all.js +4 -2
- package/all.js.map +1 -1
- package/button/internal/_elevation.scss +4 -0
- package/button/internal/_filled-button.scss +0 -1
- package/button/internal/_outlined-button.scss +6 -0
- package/button/internal/_shared.scss +12 -2
- package/button/internal/button.d.ts +15 -14
- package/button/internal/button.js +41 -39
- package/button/internal/button.js.map +1 -1
- package/button/internal/elevated-styles.css.js +1 -1
- package/button/internal/elevated-styles.css.js.map +1 -1
- package/button/internal/filled-styles.css.js +1 -1
- package/button/internal/filled-styles.css.js.map +1 -1
- package/button/internal/filled-tonal-styles.css.js +1 -1
- package/button/internal/filled-tonal-styles.css.js.map +1 -1
- package/button/internal/outlined-styles.css.js +1 -1
- package/button/internal/outlined-styles.css.js.map +1 -1
- package/button/internal/shared-elevation-styles.css.js +1 -1
- package/button/internal/shared-elevation-styles.css.js.map +1 -1
- package/button/internal/shared-styles.css.js +1 -1
- package/button/internal/shared-styles.css.js.map +1 -1
- package/button/internal/text-styles.css.js +1 -1
- package/button/internal/text-styles.css.js.map +1 -1
- package/checkbox/internal/_checkbox.scss +2 -1
- package/checkbox/internal/checkbox-styles.css.js +1 -1
- package/checkbox/internal/checkbox-styles.css.js.map +1 -1
- package/checkbox/internal/checkbox.d.ts +2 -2
- package/checkbox/internal/checkbox.js +18 -14
- package/checkbox/internal/checkbox.js.map +1 -1
- package/chips/assist-chip.js +1 -2
- package/chips/assist-chip.js.map +1 -1
- package/chips/filter-chip.js +1 -3
- package/chips/filter-chip.js.map +1 -1
- package/chips/input-chip.js +1 -5
- package/chips/input-chip.js.map +1 -1
- package/chips/internal/_assist-chip.scss +6 -0
- package/chips/internal/_elevated.scss +1 -5
- package/chips/internal/_filter-chip.scss +6 -0
- package/chips/internal/_input-chip.scss +32 -0
- package/chips/internal/_selectable.scss +17 -13
- package/chips/internal/_shared.scss +27 -11
- package/chips/internal/_suggestion-chip.scss +6 -0
- package/chips/internal/_trailing-icon.scss +24 -24
- package/chips/internal/assist-chip.d.ts +3 -1
- package/chips/internal/assist-chip.js +11 -8
- package/chips/internal/assist-chip.js.map +1 -1
- package/chips/internal/assist-styles.css.js +1 -1
- package/chips/internal/assist-styles.css.js.map +1 -1
- package/chips/internal/chip.d.ts +18 -10
- package/chips/internal/chip.js +38 -33
- package/chips/internal/chip.js.map +1 -1
- package/chips/internal/elevated-styles.css.js +1 -1
- package/chips/internal/elevated-styles.css.js.map +1 -1
- package/chips/internal/filter-chip.d.ts +6 -7
- package/chips/internal/filter-chip.js +13 -14
- package/chips/internal/filter-chip.js.map +1 -1
- package/chips/internal/filter-styles.css.js +1 -1
- package/chips/internal/filter-styles.css.js.map +1 -1
- package/chips/internal/input-chip.d.ts +4 -2
- package/chips/internal/input-chip.js +16 -12
- package/chips/internal/input-chip.js.map +1 -1
- package/chips/internal/input-styles.css.js +1 -1
- package/chips/internal/input-styles.css.js.map +1 -1
- package/chips/internal/multi-action-chip.d.ts +2 -3
- package/chips/internal/multi-action-chip.js +3 -3
- package/chips/internal/multi-action-chip.js.map +1 -1
- package/chips/internal/selectable-styles.css.js +1 -1
- package/chips/internal/selectable-styles.css.js.map +1 -1
- package/chips/internal/shared-styles.css.js +1 -1
- package/chips/internal/shared-styles.css.js.map +1 -1
- package/chips/internal/suggestion-styles.css.js +1 -1
- package/chips/internal/suggestion-styles.css.js.map +1 -1
- package/chips/internal/trailing-icon-styles.css.js +1 -1
- package/chips/internal/trailing-icon-styles.css.js.map +1 -1
- package/chips/suggestion-chip.js +1 -2
- package/chips/suggestion-chip.js.map +1 -1
- package/color/_color.scss +193 -0
- package/common.d.ts +2 -2
- package/common.js +2 -2
- package/common.js.map +1 -1
- package/dialog/internal/_dialog.scss +19 -4
- package/dialog/internal/dialog-styles.css.js +1 -1
- package/dialog/internal/dialog-styles.css.js.map +1 -1
- package/dialog/internal/dialog.d.ts +6 -0
- package/dialog/internal/dialog.js +36 -4
- package/dialog/internal/dialog.js.map +1 -1
- package/elevation/internal/_elevation.scss +14 -7
- package/elevation/internal/elevation-styles.css.js +1 -1
- package/elevation/internal/elevation-styles.css.js.map +1 -1
- package/elevation/internal/elevation.d.ts +1 -0
- package/elevation/internal/elevation.js +6 -0
- package/elevation/internal/elevation.js.map +1 -1
- package/fab/branded-fab.d.ts +0 -1
- package/fab/internal/_fab.scss +11 -10
- package/fab/internal/_shared.scss +8 -2
- package/fab/internal/fab-branded-styles.css.js +1 -1
- package/fab/internal/fab-branded-styles.css.js.map +1 -1
- package/fab/internal/fab-styles.css.js +1 -1
- package/fab/internal/fab-styles.css.js.map +1 -1
- package/fab/internal/fab.d.ts +0 -1
- package/fab/internal/shared-styles.css.js +1 -1
- package/fab/internal/shared-styles.css.js.map +1 -1
- package/fab/internal/shared.d.ts +0 -9
- package/fab/internal/shared.js +2 -18
- package/fab/internal/shared.js.map +1 -1
- package/field/internal/_content.scss +9 -1
- package/field/internal/_filled-field.scss +12 -0
- package/field/internal/_label.scss +4 -1
- package/field/internal/_outlined-field.scss +33 -0
- package/field/internal/_shared.scss +14 -6
- package/field/internal/_supporting-text.scss +4 -1
- package/field/internal/field.d.ts +2 -0
- package/field/internal/field.js +19 -0
- package/field/internal/field.js.map +1 -1
- package/field/internal/filled-styles.css.js +1 -1
- package/field/internal/filled-styles.css.js.map +1 -1
- package/field/internal/outlined-styles.css.js +1 -1
- package/field/internal/outlined-styles.css.js.map +1 -1
- package/field/internal/shared-styles.css.js +1 -1
- package/field/internal/shared-styles.css.js.map +1 -1
- package/focus/internal/focus-ring.d.ts +3 -1
- package/focus/internal/focus-ring.js +9 -0
- package/focus/internal/focus-ring.js.map +1 -1
- package/icon/internal/_icon.scss +10 -5
- package/icon/internal/icon-styles.css.js +1 -1
- package/icon/internal/icon-styles.css.js.map +1 -1
- package/icon/internal/icon.js +4 -0
- package/icon/internal/icon.js.map +1 -1
- package/iconbutton/internal/_icon-button.scss +12 -0
- package/iconbutton/internal/_shared.scss +9 -0
- package/iconbutton/internal/icon-button.d.ts +19 -6
- package/iconbutton/internal/icon-button.js +35 -11
- package/iconbutton/internal/icon-button.js.map +1 -1
- package/iconbutton/internal/shared-styles.css.js +1 -1
- package/iconbutton/internal/shared-styles.css.js.map +1 -1
- package/iconbutton/internal/standard-styles.css.js +1 -1
- package/iconbutton/internal/standard-styles.css.js.map +1 -1
- package/internal/aria/aria.d.ts +52 -1
- package/internal/aria/aria.js +146 -0
- package/internal/aria/aria.js.map +1 -1
- package/internal/controller/attachable-controller.d.ts +5 -4
- package/internal/controller/attachable-controller.js +8 -0
- package/internal/controller/attachable-controller.js.map +1 -1
- package/internal/controller/form-submitter.d.ts +12 -0
- package/internal/controller/form-submitter.js +3 -1
- package/internal/controller/form-submitter.js.map +1 -1
- package/labs/badge/internal/_badge.scss +16 -9
- package/labs/badge/internal/badge-styles.css.js +1 -1
- package/labs/badge/internal/badge-styles.css.js.map +1 -1
- package/labs/navigationbar/internal/_navigation-bar.scss +11 -9
- package/labs/navigationbar/internal/navigation-bar-styles.css.js +1 -1
- package/labs/navigationbar/internal/navigation-bar-styles.css.js.map +1 -1
- package/labs/navigationdrawer/internal/_navigation-drawer-modal.scss +11 -8
- package/labs/navigationdrawer/internal/_navigation-drawer.scss +11 -8
- package/labs/navigationdrawer/internal/navigation-drawer-modal-styles.css.js +1 -1
- package/labs/navigationdrawer/internal/navigation-drawer-modal-styles.css.js.map +1 -1
- package/labs/navigationdrawer/internal/navigation-drawer-styles.css.js +1 -1
- package/labs/navigationdrawer/internal/navigation-drawer-styles.css.js.map +1 -1
- package/labs/navigationtab/internal/_navigation-tab.scss +14 -11
- package/labs/navigationtab/internal/navigation-tab-styles.css.js +1 -1
- package/labs/navigationtab/internal/navigation-tab-styles.css.js.map +1 -1
- package/labs/segmentedbutton/internal/_outlined-segmented-button.scss +1 -3
- package/labs/segmentedbutton/internal/_shared.scss +4 -1
- package/labs/segmentedbutton/internal/outlined-styles.css.js +1 -1
- package/labs/segmentedbutton/internal/outlined-styles.css.js.map +1 -1
- package/labs/segmentedbutton/internal/shared-styles.css.js +1 -1
- package/labs/segmentedbutton/internal/shared-styles.css.js.map +1 -1
- package/labs/segmentedbuttonset/internal/outlined-styles.css.js +1 -1
- package/labs/segmentedbuttonset/internal/outlined-styles.css.js.map +1 -1
- package/list/harness.js +1 -1
- package/list/harness.js.map +1 -1
- package/list/internal/_list.scss +7 -6
- package/list/internal/list-styles.css.js +1 -1
- package/list/internal/list-styles.css.js.map +1 -1
- package/list/internal/list.d.ts +1 -2
- package/list/internal/list.js +4 -6
- package/list/internal/list.js.map +1 -1
- package/list/internal/listitem/_list-item.scss +96 -94
- package/list/internal/listitem/forced-colors-styles.css.js +1 -1
- package/list/internal/listitem/forced-colors-styles.css.js.map +1 -1
- package/list/internal/listitem/forced-colors-styles.scss +6 -6
- package/list/internal/listitem/list-item-styles.css.js +1 -1
- package/list/internal/listitem/list-item-styles.css.js.map +1 -1
- package/menu/harness.d.ts +1 -1
- package/menu/harness.js +3 -4
- package/menu/harness.js.map +1 -1
- package/menu/internal/_menu.scss +37 -28
- package/menu/internal/menu-styles.css.js +1 -1
- package/menu/internal/menu-styles.css.js.map +1 -1
- package/menu/internal/menu.d.ts +15 -4
- package/menu/internal/menu.js +33 -10
- package/menu/internal/menu.js.map +1 -1
- package/menu/internal/menuitem/_menu-item.scss +7 -4
- package/menu/internal/menuitem/menu-item-styles.css.js +1 -1
- package/menu/internal/menuitem/menu-item-styles.css.js.map +1 -1
- package/menu/internal/menuitem/menu-item.js +1 -1
- package/menu/internal/menuitem/menu-item.js.map +1 -1
- package/menu/internal/submenuitem/sub-menu-item.d.ts +3 -0
- package/menu/internal/submenuitem/sub-menu-item.js +42 -12
- package/menu/internal/submenuitem/sub-menu-item.js.map +1 -1
- package/menu/internal/typeaheadController.js +2 -1
- package/menu/internal/typeaheadController.js.map +1 -1
- package/menu/menu.d.ts +12 -5
- package/menu/menu.js +12 -5
- package/menu/menu.js.map +1 -1
- package/menu/sub-menu-item.d.ts +3 -4
- package/menu/sub-menu-item.js +3 -4
- package/menu/sub-menu-item.js.map +1 -1
- package/package.json +10 -2
- package/progress/harness.js +2 -4
- package/progress/harness.js.map +1 -1
- package/progress/internal/_circular-progress.scss +8 -6
- package/progress/internal/_linear-progress.scss +95 -134
- package/progress/internal/circular-progress-styles.css.js +1 -1
- package/progress/internal/circular-progress-styles.css.js.map +1 -1
- package/progress/internal/circular-progress.js +1 -1
- package/progress/internal/circular-progress.js.map +1 -1
- package/progress/internal/linear-progress-styles.css.js +1 -1
- package/progress/internal/linear-progress-styles.css.js.map +1 -1
- package/progress/internal/linear-progress.d.ts +0 -11
- package/progress/internal/linear-progress.js +4 -48
- package/progress/internal/linear-progress.js.map +1 -1
- package/radio/harness.d.ts +1 -1
- package/radio/harness.js +1 -1
- package/radio/harness.js.map +1 -1
- package/radio/internal/_radio.scss +4 -4
- package/radio/internal/radio-styles.css.js +1 -1
- package/radio/internal/radio-styles.css.js.map +1 -1
- package/radio/internal/radio.d.ts +4 -6
- package/radio/internal/radio.js +37 -32
- package/radio/internal/radio.js.map +1 -1
- package/radio/internal/single-selection-controller.js +4 -3
- package/radio/internal/single-selection-controller.js.map +1 -1
- package/ripple/internal/_ripple.scss +1 -1
- package/ripple/internal/ripple-styles.css.js +1 -1
- package/ripple/internal/ripple-styles.css.js.map +1 -1
- package/ripple/internal/ripple.d.ts +3 -1
- package/ripple/internal/ripple.js +9 -0
- package/ripple/internal/ripple.js.map +1 -1
- package/select/harness.d.ts +1 -1
- package/select/harness.js +1 -3
- package/select/harness.js.map +1 -1
- package/select/internal/_filled-select.scss +13 -4
- package/select/internal/_outlined-select.scss +13 -4
- package/select/internal/_shared.scss +0 -1
- package/select/internal/filled-select-styles.css.js +1 -1
- package/select/internal/filled-select-styles.css.js.map +1 -1
- package/select/internal/outlined-select-styles.css.js +1 -1
- package/select/internal/outlined-select-styles.css.js.map +1 -1
- package/select/internal/select.d.ts +8 -2
- package/select/internal/select.js +21 -8
- package/select/internal/select.js.map +1 -1
- package/slider/internal/_slider.scss +42 -32
- package/slider/internal/forced-colors-styles.css.js +1 -1
- package/slider/internal/forced-colors-styles.css.js.map +1 -1
- package/slider/internal/forced-colors-styles.scss +31 -4
- package/slider/internal/slider-styles.css.js +1 -1
- package/slider/internal/slider-styles.css.js.map +1 -1
- package/slider/internal/slider.d.ts +22 -8
- package/slider/internal/slider.js +113 -22
- package/slider/internal/slider.js.map +1 -1
- package/switch/harness.d.ts +1 -1
- package/switch/harness.js +1 -1
- package/switch/harness.js.map +1 -1
- package/switch/internal/_handle.scss +22 -21
- package/switch/internal/_icon.scss +12 -12
- package/switch/internal/_switch.scss +17 -17
- package/switch/internal/_track.scss +12 -12
- package/switch/internal/forced-colors-styles.css.js +1 -1
- package/switch/internal/forced-colors-styles.css.js.map +1 -1
- package/switch/internal/forced-colors-styles.scss +1 -0
- package/switch/internal/switch-styles.css.js +1 -1
- package/switch/internal/switch-styles.css.js.map +1 -1
- package/switch/internal/switch.d.ts +73 -3
- package/switch/internal/switch.js +146 -32
- package/switch/internal/switch.js.map +1 -1
- package/tabs/{_tab.scss → _primary-tab.scss} +1 -1
- package/tabs/_secondary-tab.scss +6 -0
- package/tabs/harness.d.ts +2 -2
- package/tabs/harness.js +1 -2
- package/tabs/harness.js.map +1 -1
- package/tabs/internal/_primary-tab.scss +70 -0
- package/tabs/internal/_secondary-tab.scss +61 -0
- package/tabs/internal/_tab.scss +21 -114
- package/tabs/internal/_tabs.scss +9 -10
- package/tabs/internal/primary-tab-styles.css.js +9 -0
- package/tabs/internal/primary-tab-styles.css.js.map +1 -0
- package/tabs/internal/primary-tab-styles.scss +10 -0
- package/tabs/internal/primary-tab.d.ts +20 -0
- package/tabs/internal/primary-tab.js +30 -0
- package/tabs/internal/primary-tab.js.map +1 -0
- package/tabs/internal/secondary-tab-styles.css.js +9 -0
- package/tabs/internal/secondary-tab-styles.css.js.map +1 -0
- package/tabs/internal/secondary-tab-styles.scss +10 -0
- package/tabs/internal/secondary-tab.d.ts +12 -0
- package/tabs/internal/secondary-tab.js +16 -0
- package/tabs/internal/secondary-tab.js.map +1 -0
- package/tabs/internal/tab-styles.css.js +1 -1
- package/tabs/internal/tab-styles.css.js.map +1 -1
- package/tabs/internal/tab.d.ts +16 -34
- package/tabs/internal/tab.js +81 -81
- package/tabs/internal/tab.js.map +1 -1
- package/tabs/internal/tabs-styles.css.js +1 -1
- package/tabs/internal/tabs-styles.css.js.map +1 -1
- package/tabs/internal/tabs.d.ts +6 -20
- package/tabs/internal/tabs.js +33 -66
- package/tabs/internal/tabs.js.map +1 -1
- package/tabs/{tab.d.ts → primary-tab.d.ts} +3 -4
- package/tabs/primary-tab.js +23 -0
- package/tabs/primary-tab.js.map +1 -0
- package/tabs/secondary-tab.d.ts +18 -0
- package/tabs/secondary-tab.js +23 -0
- package/tabs/secondary-tab.js.map +1 -0
- package/tabs/tabs.d.ts +0 -2
- package/tabs/tabs.js +0 -2
- package/tabs/tabs.js.map +1 -1
- package/textfield/internal/_filled-text-field.scss +12 -3
- package/textfield/internal/_outlined-text-field.scss +12 -3
- package/textfield/internal/filled-styles.css.js +1 -1
- package/textfield/internal/filled-styles.css.js.map +1 -1
- package/textfield/internal/outlined-styles.css.js +1 -1
- package/textfield/internal/outlined-styles.css.js.map +1 -1
- package/textfield/internal/text-field.d.ts +30 -10
- package/textfield/internal/text-field.js +80 -32
- package/textfield/internal/text-field.js.map +1 -1
- package/tokens/_index.scss +5 -6
- package/tokens/_md-comp-assist-chip.scss +6 -14
- package/tokens/_md-comp-badge.scss +1 -14
- package/tokens/{_md-comp-circular-progress-indicator.scss → _md-comp-circular-progress.scss} +3 -1
- package/tokens/_md-comp-dialog.scss +10 -17
- package/tokens/_md-comp-elevated-button.scss +5 -13
- package/tokens/_md-comp-fab-branded.scss +9 -10
- package/tokens/_md-comp-fab.scss +9 -10
- package/tokens/_md-comp-filled-button.scss +5 -13
- package/tokens/_md-comp-filled-field.scss +27 -8
- package/tokens/_md-comp-filled-select.scss +18 -15
- package/tokens/_md-comp-filled-text-field.scss +17 -19
- package/tokens/_md-comp-filled-tonal-button.scss +5 -13
- package/tokens/_md-comp-filter-chip.scss +5 -13
- package/tokens/_md-comp-input-chip.scss +5 -13
- package/tokens/_md-comp-list-item.scss +117 -122
- package/tokens/_md-comp-menu-item.scss +3 -3
- package/tokens/_md-comp-outlined-button.scss +5 -13
- package/tokens/_md-comp-outlined-field.scss +27 -7
- package/tokens/_md-comp-outlined-segmented-button.scss +5 -13
- package/tokens/_md-comp-outlined-select.scss +23 -15
- package/tokens/_md-comp-outlined-text-field.scss +17 -19
- package/tokens/_md-comp-primary-tab.scss +132 -0
- package/tokens/_md-comp-secondary-tab.scss +139 -0
- package/tokens/_md-comp-slider.scss +16 -16
- package/tokens/_md-comp-suggestion-chip.scss +5 -13
- package/tokens/_md-comp-test-table.scss +13 -2
- package/tokens/_md-comp-text-button.scss +5 -13
- package/tokens/_md-ref-palette.scss +101 -1
- package/tokens/_md-ref-typeface.scss +3 -0
- package/tokens/_md-sys-color.scss +57 -2
- package/tokens/_md-sys-typescale.scss +66 -5
- package/chips/internal/assist-forced-colors-styles.css.js +0 -9
- package/chips/internal/assist-forced-colors-styles.css.js.map +0 -1
- package/chips/internal/assist-forced-colors-styles.scss +0 -27
- package/chips/internal/filter-forced-colors-styles.css.js +0 -9
- package/chips/internal/filter-forced-colors-styles.css.js.map +0 -1
- package/chips/internal/filter-forced-colors-styles.scss +0 -34
- package/chips/internal/input-forced-colors-styles.css.d.ts +0 -1
- package/chips/internal/input-forced-colors-styles.css.js +0 -9
- package/chips/internal/input-forced-colors-styles.css.js.map +0 -1
- package/chips/internal/input-forced-colors-styles.scss +0 -39
- package/chips/internal/suggestion-forced-colors-styles.css.d.ts +0 -1
- package/chips/internal/suggestion-forced-colors-styles.css.js +0 -9
- package/chips/internal/suggestion-forced-colors-styles.css.js.map +0 -1
- package/chips/internal/suggestion-forced-colors-styles.scss +0 -27
- package/internal/sass/_theme.scss +0 -249
- package/tabs/tab.js +0 -22
- package/tabs/tab.js.map +0 -1
- package/tokens/_md-comp-tab.scss +0 -285
- /package/{chips/internal/assist-forced-colors-styles.css.d.ts → tabs/internal/primary-tab-styles.css.d.ts} +0 -0
- /package/{chips/internal/filter-forced-colors-styles.css.d.ts → tabs/internal/secondary-tab-styles.css.d.ts} +0 -0
- /package/tokens/{_md-comp-linear-progress-indicator.scss → _md-comp-linear-progress.scss} +0 -0
- /package/tokens/{_md-comp-radio-button.scss → _md-comp-radio.scss} +0 -0
package/tabs/internal/tab.js
CHANGED
|
@@ -8,88 +8,75 @@ import '../../elevation/elevation.js';
|
|
|
8
8
|
import '../../focus/md-focus-ring.js';
|
|
9
9
|
import '../../ripple/ripple.js';
|
|
10
10
|
import { html, isServer, LitElement, nothing } from 'lit';
|
|
11
|
-
import { property, query } from 'lit/decorators.js';
|
|
11
|
+
import { property, query, queryAssignedElements, queryAssignedNodes, state } from 'lit/decorators.js';
|
|
12
12
|
import { classMap } from 'lit/directives/class-map.js';
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
13
|
+
import { polyfillElementInternalsAria, setupHostAria } from '../../internal/aria/aria.js';
|
|
14
|
+
import { EASING } from '../../internal/motion/animation.js';
|
|
15
15
|
/**
|
|
16
16
|
* Tab component.
|
|
17
17
|
*/
|
|
18
18
|
export class Tab extends LitElement {
|
|
19
19
|
constructor() {
|
|
20
20
|
super();
|
|
21
|
-
/**
|
|
22
|
-
* Styling variant to display, 'primary' (default) or 'secondary'.
|
|
23
|
-
*/
|
|
24
|
-
this.variant = 'primary';
|
|
25
|
-
/**
|
|
26
|
-
* Whether or not the tab is `disabled`.
|
|
27
|
-
*/
|
|
28
|
-
this.disabled = false;
|
|
29
21
|
/**
|
|
30
22
|
* Whether or not the tab is `selected`.
|
|
31
23
|
**/
|
|
32
24
|
this.selected = false;
|
|
33
25
|
/**
|
|
34
|
-
*
|
|
26
|
+
* In SSR, set this to true when an icon is present.
|
|
35
27
|
*/
|
|
36
|
-
this.
|
|
28
|
+
this.hasIcon = false;
|
|
37
29
|
/**
|
|
38
|
-
*
|
|
30
|
+
* In SSR, set this to true when there is no label and only an icon.
|
|
39
31
|
*/
|
|
40
|
-
this.
|
|
41
|
-
this.
|
|
42
|
-
|
|
43
|
-
return;
|
|
44
|
-
}
|
|
45
|
-
this.focus();
|
|
46
|
-
dispatchActivationClick(this.button);
|
|
47
|
-
};
|
|
32
|
+
this.iconOnly = false;
|
|
33
|
+
this.fullWidthIndicator = false;
|
|
34
|
+
this.internals = polyfillElementInternalsAria(this, this /* needed for closure */.attachInternals());
|
|
48
35
|
if (!isServer) {
|
|
49
|
-
this.
|
|
36
|
+
this.internals.role = 'tab';
|
|
37
|
+
this.addEventListener('keydown', this.handleKeydown.bind(this));
|
|
50
38
|
}
|
|
51
39
|
}
|
|
52
|
-
focus() {
|
|
53
|
-
this.button?.focus();
|
|
54
|
-
}
|
|
55
|
-
blur() {
|
|
56
|
-
this.button?.blur();
|
|
57
|
-
}
|
|
58
40
|
render() {
|
|
59
|
-
const
|
|
60
|
-
'inline-icon': this.inlineIcon,
|
|
61
|
-
};
|
|
62
|
-
// Needed for closure conformance
|
|
63
|
-
const { ariaLabel } = this;
|
|
41
|
+
const indicator = html `<div class="indicator"></div>`;
|
|
64
42
|
return html `
|
|
65
|
-
<button
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
.tabIndex=${this.focusable && !this.disabled ? 0 : -1}
|
|
69
|
-
aria-selected=${this.selected ? 'true' : 'false'}
|
|
70
|
-
?disabled=${this.disabled}
|
|
71
|
-
aria-label=${ariaLabel || nothing}
|
|
72
|
-
>
|
|
73
|
-
<md-focus-ring part="focus-ring" inward></md-focus-ring>
|
|
43
|
+
<div class="button" role="presentation">
|
|
44
|
+
<md-focus-ring part="focus-ring" inward
|
|
45
|
+
.control=${this}></md-focus-ring>
|
|
74
46
|
<md-elevation></md-elevation>
|
|
75
|
-
<md-ripple
|
|
76
|
-
<
|
|
77
|
-
|
|
78
|
-
<slot name="icon"></slot>
|
|
79
|
-
<
|
|
80
|
-
|
|
81
|
-
</span>
|
|
82
|
-
<div class="indicator"></div>
|
|
47
|
+
<md-ripple .control=${this}></md-ripple>
|
|
48
|
+
<div class="content ${classMap(this.getContentClasses())}"
|
|
49
|
+
role="presentation">
|
|
50
|
+
<slot name="icon" @slotchange=${this.handleIconSlotChange}></slot>
|
|
51
|
+
<slot @slotchange=${this.handleSlotChange}></slot>
|
|
52
|
+
${this.fullWidthIndicator ? nothing : indicator}
|
|
83
53
|
</div>
|
|
84
|
-
|
|
54
|
+
${this.fullWidthIndicator ? indicator : nothing}
|
|
55
|
+
</div>`;
|
|
56
|
+
}
|
|
57
|
+
getContentClasses() {
|
|
58
|
+
return {
|
|
59
|
+
'has-icon': this.hasIcon,
|
|
60
|
+
'has-label': !this.iconOnly,
|
|
61
|
+
};
|
|
85
62
|
}
|
|
86
63
|
updated(changed) {
|
|
87
|
-
if (changed.has('selected')
|
|
64
|
+
if (changed.has('selected')) {
|
|
65
|
+
this.internals.ariaSelected = String(this.selected);
|
|
88
66
|
this.animateSelected();
|
|
89
67
|
}
|
|
90
68
|
}
|
|
91
|
-
|
|
92
|
-
|
|
69
|
+
async handleKeydown(event) {
|
|
70
|
+
// Allow event to bubble.
|
|
71
|
+
await 0;
|
|
72
|
+
if (event.defaultPrevented) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
if (event.key === 'Enter' || event.key === ' ') {
|
|
76
|
+
// Prevent default behavior such as scrolling when pressing spacebar.
|
|
77
|
+
event.preventDefault();
|
|
78
|
+
this.click();
|
|
79
|
+
}
|
|
93
80
|
}
|
|
94
81
|
animateSelected() {
|
|
95
82
|
this.indicator.getAnimations().forEach(a => {
|
|
@@ -97,7 +84,7 @@ export class Tab extends LitElement {
|
|
|
97
84
|
});
|
|
98
85
|
const frames = this.getKeyframes();
|
|
99
86
|
if (frames !== null) {
|
|
100
|
-
this.indicator.animate(frames, { duration:
|
|
87
|
+
this.indicator.animate(frames, { duration: 250, easing: EASING.EMPHASIZED });
|
|
101
88
|
}
|
|
102
89
|
}
|
|
103
90
|
getKeyframes() {
|
|
@@ -105,21 +92,20 @@ export class Tab extends LitElement {
|
|
|
105
92
|
if (!this.selected) {
|
|
106
93
|
return reduceMotion ? [{ 'opacity': 1 }, { 'transform': 'none' }] : null;
|
|
107
94
|
}
|
|
95
|
+
// TODO(b/298105040): avoid hardcoding selector
|
|
96
|
+
const tabs = this.closest('md-tabs');
|
|
108
97
|
const from = {};
|
|
109
|
-
|
|
110
|
-
const isVertical = false;
|
|
111
|
-
const fromRect = (this.tabs?.previousSelectedItem?.indicator.getBoundingClientRect() ??
|
|
98
|
+
const fromRect = (tabs?.previousSelectedItem?.indicator.getBoundingClientRect() ??
|
|
112
99
|
{});
|
|
113
|
-
const fromPos =
|
|
114
|
-
const fromExtent =
|
|
100
|
+
const fromPos = fromRect.left;
|
|
101
|
+
const fromExtent = fromRect.width;
|
|
115
102
|
const toRect = this.indicator.getBoundingClientRect();
|
|
116
|
-
const toPos =
|
|
117
|
-
const toExtent =
|
|
118
|
-
const axis = isVertical ? 'Y' : 'X';
|
|
103
|
+
const toPos = toRect.left;
|
|
104
|
+
const toExtent = toRect.width;
|
|
119
105
|
const scale = fromExtent / toExtent;
|
|
120
106
|
if (!reduceMotion && fromPos !== undefined && toPos !== undefined &&
|
|
121
107
|
!isNaN(scale)) {
|
|
122
|
-
from['transform'] = `
|
|
108
|
+
from['transform'] = `translateX(${(fromPos - toPos).toFixed(4)}px) scaleX(${scale.toFixed(4)})`;
|
|
123
109
|
}
|
|
124
110
|
else {
|
|
125
111
|
from['opacity'] = 0;
|
|
@@ -128,33 +114,47 @@ export class Tab extends LitElement {
|
|
|
128
114
|
// that can hide the animation.
|
|
129
115
|
return [from, { 'transform': 'none' }];
|
|
130
116
|
}
|
|
117
|
+
handleSlotChange() {
|
|
118
|
+
this.iconOnly = false;
|
|
119
|
+
// Check if there's any label text or elements. If not, then there is only
|
|
120
|
+
// an icon.
|
|
121
|
+
for (const node of this.assignedDefaultNodes) {
|
|
122
|
+
const hasTextContent = node.nodeType === Node.TEXT_NODE &&
|
|
123
|
+
!!node.wholeText.match(/\S/);
|
|
124
|
+
if (node.nodeType === Node.ELEMENT_NODE || hasTextContent) {
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
this.iconOnly = true;
|
|
129
|
+
}
|
|
130
|
+
handleIconSlotChange() {
|
|
131
|
+
this.hasIcon = this.assignedIcons.length > 0;
|
|
132
|
+
}
|
|
131
133
|
}
|
|
132
134
|
(() => {
|
|
133
|
-
|
|
135
|
+
setupHostAria(Tab);
|
|
134
136
|
})();
|
|
135
|
-
/** @nocollapse */
|
|
136
|
-
Tab.shadowRootOptions = { mode: 'open', delegatesFocus: true };
|
|
137
|
-
__decorate([
|
|
138
|
-
property({ reflect: true })
|
|
139
|
-
], Tab.prototype, "variant", void 0);
|
|
140
|
-
__decorate([
|
|
141
|
-
property({ type: Boolean, reflect: true })
|
|
142
|
-
], Tab.prototype, "disabled", void 0);
|
|
143
137
|
__decorate([
|
|
144
138
|
property({ type: Boolean, reflect: true })
|
|
145
139
|
], Tab.prototype, "selected", void 0);
|
|
146
140
|
__decorate([
|
|
147
|
-
property({ type: Boolean })
|
|
148
|
-
], Tab.prototype, "
|
|
149
|
-
__decorate([
|
|
150
|
-
property({ type: Boolean, attribute: 'inline-icon' })
|
|
151
|
-
], Tab.prototype, "inlineIcon", void 0);
|
|
141
|
+
property({ type: Boolean, attribute: 'has-icon' })
|
|
142
|
+
], Tab.prototype, "hasIcon", void 0);
|
|
152
143
|
__decorate([
|
|
153
|
-
|
|
154
|
-
], Tab.prototype, "
|
|
144
|
+
property({ type: Boolean, attribute: 'icon-only' })
|
|
145
|
+
], Tab.prototype, "iconOnly", void 0);
|
|
155
146
|
__decorate([
|
|
156
147
|
query('.indicator')
|
|
157
148
|
], Tab.prototype, "indicator", void 0);
|
|
149
|
+
__decorate([
|
|
150
|
+
state()
|
|
151
|
+
], Tab.prototype, "fullWidthIndicator", void 0);
|
|
152
|
+
__decorate([
|
|
153
|
+
queryAssignedNodes({ flatten: true })
|
|
154
|
+
], Tab.prototype, "assignedDefaultNodes", void 0);
|
|
155
|
+
__decorate([
|
|
156
|
+
queryAssignedElements({ slot: 'icon', flatten: true })
|
|
157
|
+
], Tab.prototype, "assignedIcons", void 0);
|
|
158
158
|
function shouldReduceMotion() {
|
|
159
159
|
return window.matchMedia('(prefers-reduced-motion: reduce)').matches;
|
|
160
160
|
}
|
package/tabs/internal/tab.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tab.js","sourceRoot":"","sources":["tab.ts"],"names":[],"mappings":"AAAA;;;;GAIG;;AAEH,OAAO,8BAA8B,CAAC;AACtC,OAAO,8BAA8B,CAAC;AACtC,OAAO,wBAAwB,CAAC;AAEhC,OAAO,EAAC,IAAI,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAiB,MAAM,KAAK,CAAC;AACxE,OAAO,EAAC,QAAQ,EAAE,KAAK,EAAC,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"tab.js","sourceRoot":"","sources":["tab.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @license\n * Copyright 2023 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n\nimport '../../elevation/elevation.js';\nimport '../../focus/md-focus-ring.js';\nimport '../../ripple/ripple.js';\n\nimport {html, isServer, LitElement, nothing, PropertyValues} from 'lit';\nimport {property, query, queryAssignedElements, queryAssignedNodes, state} from 'lit/decorators.js';\nimport {classMap} from 'lit/directives/class-map.js';\n\nimport {polyfillElementInternalsAria, setupHostAria} from '../../internal/aria/aria.js';\nimport {EASING} from '../../internal/motion/animation.js';\n\ninterface Tabs extends HTMLElement {\n selected?: number;\n selectedItem?: Tab;\n previousSelectedItem?: Tab;\n}\n\n/**\n * Tab component.\n */\nexport class Tab extends LitElement {\n static {\n setupHostAria(Tab);\n }\n\n /**\n * Whether or not the tab is `selected`.\n **/\n @property({type: Boolean, reflect: true}) selected = false;\n\n /**\n * In SSR, set this to true when an icon is present.\n */\n @property({type: Boolean, attribute: 'has-icon'}) hasIcon = false;\n\n /**\n * In SSR, set this to true when there is no label and only an icon.\n */\n @property({type: Boolean, attribute: 'icon-only'}) iconOnly = false;\n\n // note, this is public so it can participate in selection animation.\n /** @private */\n @query('.indicator') readonly indicator!: HTMLElement;\n @state() protected fullWidthIndicator = false;\n @queryAssignedNodes({flatten: true})\n private readonly assignedDefaultNodes!: Node[];\n @queryAssignedElements({slot: 'icon', flatten: true})\n private readonly assignedIcons!: HTMLElement[];\n private readonly internals = polyfillElementInternalsAria(\n this, (this as HTMLElement /* needed for closure */).attachInternals());\n\n constructor() {\n super();\n if (!isServer) {\n this.internals.role = 'tab';\n this.addEventListener('keydown', this.handleKeydown.bind(this));\n }\n }\n\n protected override render() {\n const indicator = html`<div class=\"indicator\"></div>`;\n return html`\n <div class=\"button\" role=\"presentation\">\n <md-focus-ring part=\"focus-ring\" inward\n .control=${this}></md-focus-ring>\n <md-elevation></md-elevation>\n <md-ripple .control=${this}></md-ripple>\n <div class=\"content ${classMap(this.getContentClasses())}\"\n role=\"presentation\">\n <slot name=\"icon\" @slotchange=${this.handleIconSlotChange}></slot>\n <slot @slotchange=${this.handleSlotChange}></slot>\n ${this.fullWidthIndicator ? nothing : indicator}\n </div>\n ${this.fullWidthIndicator ? indicator : nothing}\n </div>`;\n }\n\n protected getContentClasses() {\n return {\n 'has-icon': this.hasIcon,\n 'has-label': !this.iconOnly,\n };\n }\n\n protected override updated(changed: PropertyValues) {\n if (changed.has('selected')) {\n this.internals.ariaSelected = String(this.selected);\n this.animateSelected();\n }\n }\n\n private async handleKeydown(event: KeyboardEvent) {\n // Allow event to bubble.\n await 0;\n if (event.defaultPrevented) {\n return;\n }\n\n if (event.key === 'Enter' || event.key === ' ') {\n // Prevent default behavior such as scrolling when pressing spacebar.\n event.preventDefault();\n this.click();\n }\n }\n\n private animateSelected() {\n this.indicator.getAnimations().forEach(a => {\n a.cancel();\n });\n const frames = this.getKeyframes();\n if (frames !== null) {\n this.indicator.animate(\n frames, {duration: 250, easing: EASING.EMPHASIZED});\n }\n }\n\n private getKeyframes() {\n const reduceMotion = shouldReduceMotion();\n if (!this.selected) {\n return reduceMotion ? [{'opacity': 1}, {'transform': 'none'}] : null;\n }\n\n // TODO(b/298105040): avoid hardcoding selector\n const tabs = this.closest<Tabs>('md-tabs');\n const from: Keyframe = {};\n const fromRect =\n (tabs?.previousSelectedItem?.indicator.getBoundingClientRect() ??\n ({} as DOMRect));\n const fromPos = fromRect.left;\n const fromExtent = fromRect.width;\n const toRect = this.indicator.getBoundingClientRect();\n const toPos = toRect.left;\n const toExtent = toRect.width;\n const scale = fromExtent / toExtent;\n if (!reduceMotion && fromPos !== undefined && toPos !== undefined &&\n !isNaN(scale)) {\n from['transform'] = `translateX(${\n (fromPos - toPos).toFixed(4)}px) scaleX(${scale.toFixed(4)})`;\n } else {\n from['opacity'] = 0;\n }\n // note, including `transform: none` avoids quirky Safari behavior\n // that can hide the animation.\n return [from, {'transform': 'none'}];\n }\n\n private handleSlotChange() {\n this.iconOnly = false;\n // Check if there's any label text or elements. If not, then there is only\n // an icon.\n for (const node of this.assignedDefaultNodes) {\n const hasTextContent = node.nodeType === Node.TEXT_NODE &&\n !!(node as Text).wholeText.match(/\\S/);\n if (node.nodeType === Node.ELEMENT_NODE || hasTextContent) {\n return;\n }\n }\n\n this.iconOnly = true;\n }\n\n private handleIconSlotChange() {\n this.hasIcon = this.assignedIcons.length > 0;\n }\n}\n\nfunction shouldReduceMotion() {\n return window.matchMedia('(prefers-reduced-motion: reduce)').matches;\n}\n"]}
|
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
import { css } from 'lit';
|
|
7
|
-
export const styles = css `:host{box-sizing:border-box;display:flex;
|
|
7
|
+
export const styles = css `:host{box-sizing:border-box;display:flex;flex-direction:column;overflow:auto;scroll-behavior:smooth;scrollbar-width:none;position:relative}:host([hidden]){display:none}:host::-webkit-scrollbar{display:none}.tabs{align-items:end;display:flex;height:100%;justify-content:space-between;width:100%}::slotted(*){flex:1}::slotted([selected]){z-index:1}/*# sourceMappingURL=tabs-styles.css.map */
|
|
8
8
|
`;
|
|
9
9
|
//# sourceMappingURL=tabs-styles.css.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tabs-styles.css.js","sourceRoot":"","sources":["tabs-styles.css.ts"],"names":[],"mappings":"AAAA;;;;IAII;AACH,OAAO,EAAC,GAAG,EAAC,MAAM,KAAK,CAAC;AACxB,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,CAAA;CACzB,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2022 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n import {css} from 'lit';\n export const styles = css`:host{box-sizing:border-box;display:flex;
|
|
1
|
+
{"version":3,"file":"tabs-styles.css.js","sourceRoot":"","sources":["tabs-styles.css.ts"],"names":[],"mappings":"AAAA;;;;IAII;AACH,OAAO,EAAC,GAAG,EAAC,MAAM,KAAK,CAAC;AACxB,MAAM,CAAC,MAAM,MAAM,GAAG,GAAG,CAAA;CACzB,CAAC","sourcesContent":["/**\n * @license\n * Copyright 2022 Google LLC\n * SPDX-License-Identifier: Apache-2.0\n */\n import {css} from 'lit';\n export const styles = css`:host{box-sizing:border-box;display:flex;flex-direction:column;overflow:auto;scroll-behavior:smooth;scrollbar-width:none;position:relative}:host([hidden]){display:none}:host::-webkit-scrollbar{display:none}.tabs{align-items:end;display:flex;height:100%;justify-content:space-between;width:100%}::slotted(*){flex:1}::slotted([selected]){z-index:1}/*# sourceMappingURL=tabs-styles.css.map */\n`;\n "]}
|
package/tabs/internal/tabs.d.ts
CHANGED
|
@@ -3,8 +3,9 @@
|
|
|
3
3
|
* Copyright 2023 Google LLC
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
|
+
import '../../divider/divider.js';
|
|
6
7
|
import { LitElement, PropertyValues } from 'lit';
|
|
7
|
-
import { Tab
|
|
8
|
+
import { Tab } from './tab.js';
|
|
8
9
|
/**
|
|
9
10
|
* @fires change Fired when the selected tab changes. The target's selected or
|
|
10
11
|
* selectedItem and previousSelected or previousSelectedItem provide information
|
|
@@ -30,20 +31,6 @@ import { Tab, TabVariant } from './tab.js';
|
|
|
30
31
|
*
|
|
31
32
|
*/
|
|
32
33
|
export declare class Tabs extends LitElement {
|
|
33
|
-
/** @nocollapse */
|
|
34
|
-
static readonly shadowRootOptions: {
|
|
35
|
-
delegatesFocus: boolean;
|
|
36
|
-
mode: ShadowRootMode;
|
|
37
|
-
slotAssignment?: SlotAssignmentMode;
|
|
38
|
-
};
|
|
39
|
-
/**
|
|
40
|
-
* Styling variant to display, 'primary' (default) or 'secondary'.
|
|
41
|
-
*/
|
|
42
|
-
variant: TabVariant;
|
|
43
|
-
/**
|
|
44
|
-
* Whether or not the item is `disabled`.
|
|
45
|
-
*/
|
|
46
|
-
disabled: boolean;
|
|
47
34
|
/**
|
|
48
35
|
* Index of the selected item.
|
|
49
36
|
*/
|
|
@@ -54,9 +41,9 @@ export declare class Tabs extends LitElement {
|
|
|
54
41
|
selectOnFocus: boolean;
|
|
55
42
|
private previousSelected;
|
|
56
43
|
private readonly scrollMargin;
|
|
57
|
-
private readonly
|
|
44
|
+
private readonly maybeTabItems;
|
|
45
|
+
private get items();
|
|
58
46
|
private itemsDirty;
|
|
59
|
-
private readonly selectedAttribute;
|
|
60
47
|
/**
|
|
61
48
|
* The item currently selected.
|
|
62
49
|
*/
|
|
@@ -68,13 +55,12 @@ export declare class Tabs extends LitElement {
|
|
|
68
55
|
/**
|
|
69
56
|
* The item currently focused.
|
|
70
57
|
*/
|
|
71
|
-
|
|
58
|
+
private get focusedItem();
|
|
59
|
+
private readonly internals;
|
|
72
60
|
constructor();
|
|
73
|
-
connectedCallback(): void;
|
|
74
61
|
private readonly handleKeydown;
|
|
75
62
|
private readonly handleKeyup;
|
|
76
63
|
private readonly handleFocusout;
|
|
77
|
-
private findFocusableItem;
|
|
78
64
|
private wasEventPrevented;
|
|
79
65
|
private dispatchInteraction;
|
|
80
66
|
protected willUpdate(changed: PropertyValues): void;
|
package/tabs/internal/tabs.js
CHANGED
|
@@ -4,13 +4,14 @@
|
|
|
4
4
|
* SPDX-License-Identifier: Apache-2.0
|
|
5
5
|
*/
|
|
6
6
|
import { __decorate } from "tslib";
|
|
7
|
+
import '../../divider/divider.js';
|
|
7
8
|
import { html, isServer, LitElement } from 'lit';
|
|
8
9
|
import { property, queryAssignedElements, state } from 'lit/decorators.js';
|
|
9
|
-
|
|
10
|
+
import { polyfillElementInternalsAria, setupHostAria } from '../../internal/aria/aria.js';
|
|
11
|
+
import { Tab } from './tab.js';
|
|
10
12
|
const NAVIGATION_KEYS = new Map([
|
|
11
13
|
['default', new Set(['Home', 'End'])],
|
|
12
14
|
['horizontal', new Set(['ArrowLeft', 'ArrowRight'])],
|
|
13
|
-
['vertical', new Set(['ArrowUp', 'ArrowDown'])]
|
|
14
15
|
]);
|
|
15
16
|
/**
|
|
16
17
|
* @fires change Fired when the selected tab changes. The target's selected or
|
|
@@ -37,6 +38,9 @@ const NAVIGATION_KEYS = new Map([
|
|
|
37
38
|
*
|
|
38
39
|
*/
|
|
39
40
|
export class Tabs extends LitElement {
|
|
41
|
+
get items() {
|
|
42
|
+
return this.maybeTabItems.filter(isTab);
|
|
43
|
+
}
|
|
40
44
|
/**
|
|
41
45
|
* The item currently selected.
|
|
42
46
|
*/
|
|
@@ -57,14 +61,6 @@ export class Tabs extends LitElement {
|
|
|
57
61
|
}
|
|
58
62
|
constructor() {
|
|
59
63
|
super();
|
|
60
|
-
/**
|
|
61
|
-
* Styling variant to display, 'primary' (default) or 'secondary'.
|
|
62
|
-
*/
|
|
63
|
-
this.variant = 'primary';
|
|
64
|
-
/**
|
|
65
|
-
* Whether or not the item is `disabled`.
|
|
66
|
-
*/
|
|
67
|
-
this.disabled = false;
|
|
68
64
|
/**
|
|
69
65
|
* Index of the selected item.
|
|
70
66
|
*/
|
|
@@ -78,15 +74,14 @@ export class Tabs extends LitElement {
|
|
|
78
74
|
// this tracks if items have changed, which triggers rendering so they can
|
|
79
75
|
// be kept in sync
|
|
80
76
|
this.itemsDirty = false;
|
|
81
|
-
this.
|
|
77
|
+
this.internals = polyfillElementInternalsAria(this, this /* needed for closure */.attachInternals());
|
|
82
78
|
// focus item on keydown and optionally select it
|
|
83
79
|
this.handleKeydown = async (event) => {
|
|
84
80
|
const { key } = event;
|
|
85
81
|
const shouldHandleKey = NAVIGATION_KEYS.get('default').has(key) ||
|
|
86
82
|
NAVIGATION_KEYS.get('horizontal').has(key);
|
|
87
83
|
// await to after user may cancel event.
|
|
88
|
-
if (!shouldHandleKey || (await this.wasEventPrevented(event, true))
|
|
89
|
-
this.disabled) {
|
|
84
|
+
if (!shouldHandleKey || (await this.wasEventPrevented(event, true))) {
|
|
90
85
|
return;
|
|
91
86
|
}
|
|
92
87
|
let indexToFocus = -1;
|
|
@@ -105,8 +100,7 @@ export class Tabs extends LitElement {
|
|
|
105
100
|
indexToFocus =
|
|
106
101
|
indexToFocus < 0 ? itemCount - 1 : indexToFocus % itemCount;
|
|
107
102
|
}
|
|
108
|
-
const itemToFocus = this.
|
|
109
|
-
indexToFocus = this.items.indexOf(itemToFocus);
|
|
103
|
+
const itemToFocus = this.items[indexToFocus];
|
|
110
104
|
if (itemToFocus !== null && itemToFocus !== focused) {
|
|
111
105
|
this.updateFocusableItem(itemToFocus);
|
|
112
106
|
itemToFocus.focus();
|
|
@@ -129,29 +123,12 @@ export class Tabs extends LitElement {
|
|
|
129
123
|
}
|
|
130
124
|
};
|
|
131
125
|
if (!isServer) {
|
|
126
|
+
this.internals.role = 'tablist';
|
|
132
127
|
this.addEventListener('keydown', this.handleKeydown);
|
|
133
128
|
this.addEventListener('keyup', this.handleKeyup);
|
|
134
129
|
this.addEventListener('focusout', this.handleFocusout);
|
|
135
130
|
}
|
|
136
131
|
}
|
|
137
|
-
connectedCallback() {
|
|
138
|
-
super.connectedCallback();
|
|
139
|
-
this.setAttribute('role', 'tablist');
|
|
140
|
-
}
|
|
141
|
-
findFocusableItem(i = -1, prev = false, tries = 0) {
|
|
142
|
-
const itemCount = this.items.length - 1;
|
|
143
|
-
while (this.items[i]?.disabled && tries <= itemCount) {
|
|
144
|
-
tries++;
|
|
145
|
-
i = (i + (prev ? -1 : 1));
|
|
146
|
-
if (i > itemCount) {
|
|
147
|
-
return this.findFocusableItem(0, false, tries);
|
|
148
|
-
}
|
|
149
|
-
else if (i < 0) {
|
|
150
|
-
return this.findFocusableItem(itemCount, true, tries);
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
return this.items[i] ?? null;
|
|
154
|
-
}
|
|
155
132
|
// Note, this is async to allow the event to bubble to user code, which
|
|
156
133
|
// may call `preventDefault`. If it does, avoid performing the tabs action
|
|
157
134
|
// which is selecting a new tab. Sometimes, the native event must be
|
|
@@ -200,19 +177,17 @@ export class Tabs extends LitElement {
|
|
|
200
177
|
}
|
|
201
178
|
}
|
|
202
179
|
async updated(changed) {
|
|
203
|
-
const
|
|
180
|
+
const itemsChanged = changed.has('itemsDirty');
|
|
204
181
|
// sync state with items.
|
|
205
|
-
if (
|
|
182
|
+
if (itemsChanged) {
|
|
206
183
|
this.items.forEach((item, i) => {
|
|
207
184
|
item.selected = this.selected === i;
|
|
208
|
-
item.variant = this.variant;
|
|
209
|
-
item.disabled = this.disabled;
|
|
210
185
|
});
|
|
211
186
|
}
|
|
212
|
-
if (
|
|
187
|
+
if (itemsChanged || changed.has('selected')) {
|
|
213
188
|
if (this.previousSelectedItem !== this.selectedItem) {
|
|
214
|
-
this.previousSelectedItem?.removeAttribute(
|
|
215
|
-
this.selectedItem?.setAttribute(
|
|
189
|
+
this.previousSelectedItem?.removeAttribute('selected');
|
|
190
|
+
this.selectedItem?.setAttribute('selected', '');
|
|
216
191
|
}
|
|
217
192
|
if (this.selectedItem !== this.focusedItem) {
|
|
218
193
|
this.updateFocusableItem(this.selectedItem);
|
|
@@ -222,12 +197,15 @@ export class Tabs extends LitElement {
|
|
|
222
197
|
}
|
|
223
198
|
updateFocusableItem(focusableItem) {
|
|
224
199
|
for (const item of this.items) {
|
|
225
|
-
item.
|
|
200
|
+
item.tabIndex = item === focusableItem ? 0 : -1;
|
|
226
201
|
}
|
|
227
202
|
}
|
|
228
203
|
render() {
|
|
229
204
|
return html `
|
|
230
|
-
<
|
|
205
|
+
<div class="tabs">
|
|
206
|
+
<slot @slotchange=${this.handleSlotChange} @click=${this.handleItemClick}></slot>
|
|
207
|
+
</div>
|
|
208
|
+
<md-divider part="divider"></md-divider>
|
|
231
209
|
`;
|
|
232
210
|
}
|
|
233
211
|
async handleItemClick(event) {
|
|
@@ -262,36 +240,22 @@ export class Tabs extends LitElement {
|
|
|
262
240
|
}
|
|
263
241
|
// wait for items to render.
|
|
264
242
|
await this.itemsUpdateComplete();
|
|
265
|
-
|
|
266
|
-
const
|
|
267
|
-
const
|
|
268
|
-
const
|
|
269
|
-
const scroll = isVertical ? this.scrollTop : this.scrollLeft;
|
|
270
|
-
const hostExtent = isVertical ? this.offsetHeight : this.offsetWidth;
|
|
243
|
+
const offset = item.offsetLeft;
|
|
244
|
+
const extent = item.offsetWidth;
|
|
245
|
+
const scroll = this.scrollLeft;
|
|
246
|
+
const hostExtent = this.offsetWidth;
|
|
271
247
|
const min = offset - this.scrollMargin;
|
|
272
248
|
const max = offset + extent - hostExtent + this.scrollMargin;
|
|
273
249
|
const to = Math.min(min, Math.max(max, scroll));
|
|
274
250
|
const behavior =
|
|
275
251
|
// type annotation because `instant` is valid but not included in type.
|
|
276
252
|
this.focusedItem !== undefined ? 'smooth' : 'instant';
|
|
277
|
-
this.scrollTo({
|
|
278
|
-
behavior,
|
|
279
|
-
[isVertical ? 'left' : 'top']: 0,
|
|
280
|
-
[isVertical ? 'top' : 'left']: to
|
|
281
|
-
});
|
|
253
|
+
this.scrollTo({ behavior, top: 0, left: to });
|
|
282
254
|
}
|
|
283
255
|
}
|
|
284
|
-
|
|
285
|
-
Tabs
|
|
286
|
-
|
|
287
|
-
delegatesFocus: true
|
|
288
|
-
};
|
|
289
|
-
__decorate([
|
|
290
|
-
property({ reflect: true })
|
|
291
|
-
], Tabs.prototype, "variant", void 0);
|
|
292
|
-
__decorate([
|
|
293
|
-
property({ type: Boolean })
|
|
294
|
-
], Tabs.prototype, "disabled", void 0);
|
|
256
|
+
(() => {
|
|
257
|
+
setupHostAria(Tabs, { focusable: false });
|
|
258
|
+
})();
|
|
295
259
|
__decorate([
|
|
296
260
|
property({ type: Number })
|
|
297
261
|
], Tabs.prototype, "selected", void 0);
|
|
@@ -299,9 +263,12 @@ __decorate([
|
|
|
299
263
|
property({ type: Boolean, attribute: 'select-on-focus' })
|
|
300
264
|
], Tabs.prototype, "selectOnFocus", void 0);
|
|
301
265
|
__decorate([
|
|
302
|
-
queryAssignedElements({
|
|
303
|
-
], Tabs.prototype, "
|
|
266
|
+
queryAssignedElements({ flatten: true })
|
|
267
|
+
], Tabs.prototype, "maybeTabItems", void 0);
|
|
304
268
|
__decorate([
|
|
305
269
|
state()
|
|
306
270
|
], Tabs.prototype, "itemsDirty", void 0);
|
|
271
|
+
function isTab(element) {
|
|
272
|
+
return element instanceof Tab;
|
|
273
|
+
}
|
|
307
274
|
//# sourceMappingURL=tabs.js.map
|