@vaadin/tabsheet 24.3.2 → 24.4.0-dev.223e39f050
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/package.json +10 -9
- package/src/vaadin-tabsheet-mixin.d.ts +31 -0
- package/src/vaadin-tabsheet-mixin.js +186 -0
- package/src/vaadin-tabsheet.d.ts +2 -16
- package/src/vaadin-tabsheet.js +3 -183
- package/web-types.json +0 -65
- package/web-types.lit.json +0 -48
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vaadin/tabsheet",
|
|
3
|
-
"version": "24.
|
|
3
|
+
"version": "24.4.0-dev.223e39f050",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"access": "public"
|
|
6
6
|
},
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"repository": {
|
|
10
10
|
"type": "git",
|
|
11
11
|
"url": "https://github.com/vaadin/web-components.git",
|
|
12
|
-
"directory": "packages/
|
|
12
|
+
"directory": "packages/tabsheet"
|
|
13
13
|
},
|
|
14
14
|
"author": "Vaadin Ltd",
|
|
15
15
|
"homepage": "https://vaadin.com/components",
|
|
@@ -35,13 +35,14 @@
|
|
|
35
35
|
"polymer"
|
|
36
36
|
],
|
|
37
37
|
"dependencies": {
|
|
38
|
+
"@open-wc/dedupe-mixin": "^1.3.0",
|
|
38
39
|
"@polymer/polymer": "^3.0.0",
|
|
39
|
-
"@vaadin/component-base": "
|
|
40
|
-
"@vaadin/scroller": "
|
|
41
|
-
"@vaadin/tabs": "
|
|
42
|
-
"@vaadin/vaadin-lumo-styles": "
|
|
43
|
-
"@vaadin/vaadin-material-styles": "
|
|
44
|
-
"@vaadin/vaadin-themable-mixin": "
|
|
40
|
+
"@vaadin/component-base": "24.4.0-dev.223e39f050",
|
|
41
|
+
"@vaadin/scroller": "24.4.0-dev.223e39f050",
|
|
42
|
+
"@vaadin/tabs": "24.4.0-dev.223e39f050",
|
|
43
|
+
"@vaadin/vaadin-lumo-styles": "24.4.0-dev.223e39f050",
|
|
44
|
+
"@vaadin/vaadin-material-styles": "24.4.0-dev.223e39f050",
|
|
45
|
+
"@vaadin/vaadin-themable-mixin": "24.4.0-dev.223e39f050"
|
|
45
46
|
},
|
|
46
47
|
"devDependencies": {
|
|
47
48
|
"@esm-bundle/chai": "^4.3.4",
|
|
@@ -52,5 +53,5 @@
|
|
|
52
53
|
"web-types.json",
|
|
53
54
|
"web-types.lit.json"
|
|
54
55
|
],
|
|
55
|
-
"gitHead": "
|
|
56
|
+
"gitHead": "5e2e3bfc811c95aed9354235fab93fdbf43eb354"
|
|
56
57
|
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2019 - 2023 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
import type { Constructor } from '@open-wc/dedupe-mixin';
|
|
7
|
+
import type { DelegateStateMixinClass } from '@vaadin/component-base/src/delegate-state-mixin.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* A mixin providing common tab-sheet functionality.
|
|
11
|
+
*/
|
|
12
|
+
export declare function TabSheetMixin<
|
|
13
|
+
Tab extends HTMLElement,
|
|
14
|
+
T extends Constructor<HTMLElement> = Constructor<HTMLElement>,
|
|
15
|
+
>(base: T): Constructor<DelegateStateMixinClass> & Constructor<TabSheetMixinClass<Tab>> & T;
|
|
16
|
+
|
|
17
|
+
export declare class TabSheetMixinClass<Tab extends HTMLElement> {
|
|
18
|
+
/**
|
|
19
|
+
* The index of the selected tab.
|
|
20
|
+
*/
|
|
21
|
+
selected: number | null | undefined;
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* The list of `<vaadin-tab>`s from which a selection can be made.
|
|
25
|
+
* It is populated from the elements passed inside the slotted
|
|
26
|
+
* `<vaadin-tabs>`, and updated dynamically when adding or removing items.
|
|
27
|
+
*
|
|
28
|
+
* Note: unlike `<vaadin-combo-box>`, this property is read-only.
|
|
29
|
+
*/
|
|
30
|
+
readonly items: Tab[] | undefined;
|
|
31
|
+
}
|
|
@@ -0,0 +1,186 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright (c) 2022 - 2023 Vaadin Ltd.
|
|
4
|
+
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
|
+
*/
|
|
6
|
+
import { DelegateStateMixin } from '@vaadin/component-base/src/delegate-state-mixin.js';
|
|
7
|
+
import { OverflowController } from '@vaadin/component-base/src/overflow-controller.js';
|
|
8
|
+
import { SlotController } from '@vaadin/component-base/src/slot-controller.js';
|
|
9
|
+
import { SlotObserver } from '@vaadin/component-base/src/slot-observer.js';
|
|
10
|
+
import { generateUniqueId } from '@vaadin/component-base/src/unique-id-utils.js';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @private
|
|
14
|
+
* A controller which observes the <vaadin-tabs> slotted to the tabs slot.
|
|
15
|
+
*/
|
|
16
|
+
class TabsSlotController extends SlotController {
|
|
17
|
+
constructor(host) {
|
|
18
|
+
super(host, 'tabs');
|
|
19
|
+
this.__tabsItemsChangedListener = this.__tabsItemsChangedListener.bind(this);
|
|
20
|
+
this.__tabsSelectedChangedListener = this.__tabsSelectedChangedListener.bind(this);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/** @private */
|
|
24
|
+
__tabsItemsChangedListener() {
|
|
25
|
+
this.host._setItems(this.tabs.items);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/** @private */
|
|
29
|
+
__tabsSelectedChangedListener() {
|
|
30
|
+
this.host.selected = this.tabs.selected;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
initCustomNode(tabs) {
|
|
34
|
+
if (!(tabs instanceof customElements.get('vaadin-tabs'))) {
|
|
35
|
+
throw Error('The "tabs" slot of a <vaadin-tabsheet> must only contain a <vaadin-tabs> element!');
|
|
36
|
+
}
|
|
37
|
+
this.tabs = tabs;
|
|
38
|
+
tabs.addEventListener('items-changed', this.__tabsItemsChangedListener);
|
|
39
|
+
tabs.addEventListener('selected-changed', this.__tabsSelectedChangedListener);
|
|
40
|
+
this.host.__tabs = tabs;
|
|
41
|
+
this.host.stateTarget = tabs;
|
|
42
|
+
this.__tabsItemsChangedListener();
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
teardownNode(tabs) {
|
|
46
|
+
this.tabs = null;
|
|
47
|
+
tabs.removeEventListener('items-changed', this.__tabsItemsChangedListener);
|
|
48
|
+
tabs.removeEventListener('selected-changed', this.__tabsSelectedChangedListener);
|
|
49
|
+
this.host.__tabs = null;
|
|
50
|
+
this.host._setItems([]);
|
|
51
|
+
this.host.stateTarget = undefined;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* @polymerMixin
|
|
57
|
+
* @mixes DelegateStateMixin
|
|
58
|
+
*/
|
|
59
|
+
export const TabSheetMixin = (superClass) =>
|
|
60
|
+
class extends DelegateStateMixin(superClass) {
|
|
61
|
+
static get properties() {
|
|
62
|
+
return {
|
|
63
|
+
/**
|
|
64
|
+
* The list of `<vaadin-tab>`s from which a selection can be made.
|
|
65
|
+
* It is populated from the elements passed inside the slotted
|
|
66
|
+
* `<vaadin-tabs>`, and updated dynamically when adding or removing items.
|
|
67
|
+
*
|
|
68
|
+
* Note: unlike `<vaadin-combo-box>`, this property is read-only.
|
|
69
|
+
* @type {!Array<!Tab> | undefined}
|
|
70
|
+
*/
|
|
71
|
+
items: {
|
|
72
|
+
type: Array,
|
|
73
|
+
readOnly: true,
|
|
74
|
+
notify: true,
|
|
75
|
+
},
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* The index of the selected tab.
|
|
79
|
+
*/
|
|
80
|
+
selected: {
|
|
81
|
+
value: 0,
|
|
82
|
+
type: Number,
|
|
83
|
+
notify: true,
|
|
84
|
+
},
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* The slotted <vaadin-tabs> element.
|
|
88
|
+
*/
|
|
89
|
+
__tabs: {
|
|
90
|
+
type: Object,
|
|
91
|
+
},
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* The panel elements.
|
|
95
|
+
*/
|
|
96
|
+
__panels: {
|
|
97
|
+
type: Array,
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
static get observers() {
|
|
103
|
+
return ['__itemsOrPanelsChanged(items, __panels)', '__selectedTabItemChanged(selected, items, __panels)'];
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/** @override */
|
|
107
|
+
static get delegateProps() {
|
|
108
|
+
return ['selected'];
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/** @override */
|
|
112
|
+
static get delegateAttrs() {
|
|
113
|
+
return ['theme'];
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/** @protected */
|
|
117
|
+
ready() {
|
|
118
|
+
super.ready();
|
|
119
|
+
this.__overflowController = new OverflowController(this, this.shadowRoot.querySelector('[part="content"]'));
|
|
120
|
+
this.addController(this.__overflowController);
|
|
121
|
+
this._tabsSlotController = new TabsSlotController(this);
|
|
122
|
+
this.addController(this._tabsSlotController);
|
|
123
|
+
|
|
124
|
+
// Observe the panels slot for nodes. Set the assigned element nodes as the __panels array.
|
|
125
|
+
const panelSlot = this.shadowRoot.querySelector('#panel-slot');
|
|
126
|
+
this.__panelsObserver = new SlotObserver(panelSlot, () => {
|
|
127
|
+
this.__panels = Array.from(
|
|
128
|
+
panelSlot.assignedNodes({
|
|
129
|
+
flatten: true,
|
|
130
|
+
}),
|
|
131
|
+
).filter((node) => node.nodeType === Node.ELEMENT_NODE);
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* An observer which applies the necessary roles and ARIA attributes
|
|
137
|
+
* to associate the tab elements with the panels.
|
|
138
|
+
* @private
|
|
139
|
+
*/
|
|
140
|
+
__itemsOrPanelsChanged(items, panels) {
|
|
141
|
+
if (!items || !panels) {
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
items.forEach((tabItem) => {
|
|
145
|
+
const panel = panels.find((panel) => panel.getAttribute('tab') === tabItem.id);
|
|
146
|
+
if (panel) {
|
|
147
|
+
panel.role = 'tabpanel';
|
|
148
|
+
if (!panel.id) {
|
|
149
|
+
panel.id = `tabsheet-panel-${generateUniqueId()}`;
|
|
150
|
+
}
|
|
151
|
+
panel.setAttribute('aria-labelledby', tabItem.id);
|
|
152
|
+
tabItem.setAttribute('aria-controls', panel.id);
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* An observer which toggles the visibility of the panels based on the selected tab.
|
|
159
|
+
* @private
|
|
160
|
+
*/
|
|
161
|
+
__selectedTabItemChanged(selected, items, panels) {
|
|
162
|
+
if (!items || !panels || selected === undefined) {
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
const content = this.shadowRoot.querySelector('[part="content"]');
|
|
166
|
+
const selectedTab = items[selected];
|
|
167
|
+
const selectedTabId = selectedTab ? selectedTab.id : '';
|
|
168
|
+
const selectedPanel = panels.find((panel) => panel.getAttribute('tab') === selectedTabId);
|
|
169
|
+
|
|
170
|
+
// Mark loading state if a selected panel is not found.
|
|
171
|
+
this.toggleAttribute('loading', !selectedPanel);
|
|
172
|
+
const hasOneVisiblePanel = panels.filter((panel) => !panel.hidden).length === 1;
|
|
173
|
+
if (selectedPanel) {
|
|
174
|
+
// A selected panel is found, remove the loading state fallback height.
|
|
175
|
+
content.style.minHeight = '';
|
|
176
|
+
} else if (hasOneVisiblePanel) {
|
|
177
|
+
// Make sure the empty content has a fallback height in loading state..
|
|
178
|
+
content.style.minHeight = `${content.offsetHeight}px`;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Hide all panels and show only the selected panel.
|
|
182
|
+
panels.forEach((panel) => {
|
|
183
|
+
panel.hidden = panel !== selectedPanel;
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
};
|
package/src/vaadin-tabsheet.d.ts
CHANGED
|
@@ -4,10 +4,10 @@
|
|
|
4
4
|
* This program is available under Apache License Version 2.0, available at https://vaadin.com/license/
|
|
5
5
|
*/
|
|
6
6
|
import { ControllerMixin } from '@vaadin/component-base/src/controller-mixin.js';
|
|
7
|
-
import { DelegateStateMixin } from '@vaadin/component-base/src/delegate-state-mixin.js';
|
|
8
7
|
import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
|
|
9
8
|
import type { Tab } from '@vaadin/tabs/src/vaadin-tab.js';
|
|
10
9
|
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
10
|
+
import { TabSheetMixin } from './vaadin-tabsheet-mixin.js';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* Fired when the `items` property changes.
|
|
@@ -69,21 +69,7 @@ export interface TabSheetEventMap extends HTMLElementEventMap, TabSheetCustomEve
|
|
|
69
69
|
* @fires {CustomEvent} items-changed - Fired when the `items` property changes.
|
|
70
70
|
* @fires {CustomEvent} selected-changed - Fired when the `selected` property changes.
|
|
71
71
|
*/
|
|
72
|
-
declare class TabSheet extends ControllerMixin(
|
|
73
|
-
/**
|
|
74
|
-
* The index of the selected tab.
|
|
75
|
-
*/
|
|
76
|
-
selected: number | null | undefined;
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* The list of `<vaadin-tab>`s from which a selection can be made.
|
|
80
|
-
* It is populated from the elements passed inside the slotted
|
|
81
|
-
* `<vaadin-tabs>`, and updated dynamically when adding or removing items.
|
|
82
|
-
*
|
|
83
|
-
* Note: unlike `<vaadin-combo-box>`, this property is read-only.
|
|
84
|
-
*/
|
|
85
|
-
readonly items: Tab[] | undefined;
|
|
86
|
-
|
|
72
|
+
declare class TabSheet extends ThemableMixin(TabSheetMixin<Tab>(ControllerMixin(ElementMixin(HTMLElement)))) {
|
|
87
73
|
addEventListener<K extends keyof TabSheetEventMap>(
|
|
88
74
|
type: K,
|
|
89
75
|
listener: (this: TabSheet, ev: TabSheetEventMap[K]) => void,
|
package/src/vaadin-tabsheet.js
CHANGED
|
@@ -7,57 +7,9 @@ import './vaadin-tabsheet-scroller.js';
|
|
|
7
7
|
import { html, PolymerElement } from '@polymer/polymer/polymer-element.js';
|
|
8
8
|
import { ControllerMixin } from '@vaadin/component-base/src/controller-mixin.js';
|
|
9
9
|
import { defineCustomElement } from '@vaadin/component-base/src/define.js';
|
|
10
|
-
import { DelegateStateMixin } from '@vaadin/component-base/src/delegate-state-mixin.js';
|
|
11
10
|
import { ElementMixin } from '@vaadin/component-base/src/element-mixin.js';
|
|
12
|
-
import { OverflowController } from '@vaadin/component-base/src/overflow-controller.js';
|
|
13
|
-
import { SlotController } from '@vaadin/component-base/src/slot-controller.js';
|
|
14
|
-
import { SlotObserver } from '@vaadin/component-base/src/slot-observer.js';
|
|
15
|
-
import { generateUniqueId } from '@vaadin/component-base/src/unique-id-utils.js';
|
|
16
|
-
import { Tabs } from '@vaadin/tabs/src/vaadin-tabs.js';
|
|
17
11
|
import { ThemableMixin } from '@vaadin/vaadin-themable-mixin/vaadin-themable-mixin.js';
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* @private
|
|
21
|
-
* A controller which observes the <vaadin-tabs> slotted to the tabs slot.
|
|
22
|
-
*/
|
|
23
|
-
class TabsSlotController extends SlotController {
|
|
24
|
-
constructor(host) {
|
|
25
|
-
super(host, 'tabs');
|
|
26
|
-
this.__tabsItemsChangedListener = this.__tabsItemsChangedListener.bind(this);
|
|
27
|
-
this.__tabsSelectedChangedListener = this.__tabsSelectedChangedListener.bind(this);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/** @private */
|
|
31
|
-
__tabsItemsChangedListener() {
|
|
32
|
-
this.host._setItems(this.tabs.items);
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
/** @private */
|
|
36
|
-
__tabsSelectedChangedListener() {
|
|
37
|
-
this.host.selected = this.tabs.selected;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
initCustomNode(tabs) {
|
|
41
|
-
if (!(tabs instanceof Tabs)) {
|
|
42
|
-
throw Error('The "tabs" slot of a <vaadin-tabsheet> must only contain a <vaadin-tabs> element!');
|
|
43
|
-
}
|
|
44
|
-
this.tabs = tabs;
|
|
45
|
-
tabs.addEventListener('items-changed', this.__tabsItemsChangedListener);
|
|
46
|
-
tabs.addEventListener('selected-changed', this.__tabsSelectedChangedListener);
|
|
47
|
-
this.host.__tabs = tabs;
|
|
48
|
-
this.host.stateTarget = tabs;
|
|
49
|
-
this.__tabsItemsChangedListener();
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
teardownNode(tabs) {
|
|
53
|
-
this.tabs = null;
|
|
54
|
-
tabs.removeEventListener('items-changed', this.__tabsItemsChangedListener);
|
|
55
|
-
tabs.removeEventListener('selected-changed', this.__tabsSelectedChangedListener);
|
|
56
|
-
this.host.__tabs = null;
|
|
57
|
-
this.host._setItems([]);
|
|
58
|
-
this.host.stateTarget = undefined;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
12
|
+
import { TabSheetMixin } from './vaadin-tabsheet-mixin.js';
|
|
61
13
|
|
|
62
14
|
/**
|
|
63
15
|
* `<vaadin-tabsheet>` is a Web Component for organizing and grouping content
|
|
@@ -103,12 +55,12 @@ class TabsSlotController extends SlotController {
|
|
|
103
55
|
*
|
|
104
56
|
* @customElement
|
|
105
57
|
* @extends HTMLElement
|
|
58
|
+
* @mixes TabSheetMixin
|
|
106
59
|
* @mixes ElementMixin
|
|
107
60
|
* @mixes ThemableMixin
|
|
108
61
|
* @mixes ControllerMixin
|
|
109
|
-
* @mixes DelegateStateMixin
|
|
110
62
|
*/
|
|
111
|
-
class TabSheet extends
|
|
63
|
+
class TabSheet extends TabSheetMixin(ThemableMixin(ElementMixin(ControllerMixin(PolymerElement)))) {
|
|
112
64
|
static get template() {
|
|
113
65
|
return html`
|
|
114
66
|
<style>
|
|
@@ -156,138 +108,6 @@ class TabSheet extends ControllerMixin(DelegateStateMixin(ElementMixin(ThemableM
|
|
|
156
108
|
static get is() {
|
|
157
109
|
return 'vaadin-tabsheet';
|
|
158
110
|
}
|
|
159
|
-
|
|
160
|
-
static get properties() {
|
|
161
|
-
return {
|
|
162
|
-
/**
|
|
163
|
-
* The list of `<vaadin-tab>`s from which a selection can be made.
|
|
164
|
-
* It is populated from the elements passed inside the slotted
|
|
165
|
-
* `<vaadin-tabs>`, and updated dynamically when adding or removing items.
|
|
166
|
-
*
|
|
167
|
-
* Note: unlike `<vaadin-combo-box>`, this property is read-only.
|
|
168
|
-
* @type {!Array<!Tab> | undefined}
|
|
169
|
-
*/
|
|
170
|
-
items: {
|
|
171
|
-
type: Array,
|
|
172
|
-
readOnly: true,
|
|
173
|
-
notify: true,
|
|
174
|
-
},
|
|
175
|
-
|
|
176
|
-
/**
|
|
177
|
-
* The index of the selected tab.
|
|
178
|
-
*/
|
|
179
|
-
selected: {
|
|
180
|
-
value: 0,
|
|
181
|
-
type: Number,
|
|
182
|
-
notify: true,
|
|
183
|
-
},
|
|
184
|
-
|
|
185
|
-
/**
|
|
186
|
-
* The slotted <vaadin-tabs> element.
|
|
187
|
-
*/
|
|
188
|
-
__tabs: {
|
|
189
|
-
type: Object,
|
|
190
|
-
},
|
|
191
|
-
|
|
192
|
-
/**
|
|
193
|
-
* The panel elements.
|
|
194
|
-
*/
|
|
195
|
-
__panels: {
|
|
196
|
-
type: Array,
|
|
197
|
-
},
|
|
198
|
-
};
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
static get observers() {
|
|
202
|
-
return ['__itemsOrPanelsChanged(items, __panels)', '__selectedTabItemChanged(selected, items, __panels)'];
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
/** @override */
|
|
206
|
-
static get delegateProps() {
|
|
207
|
-
return ['selected'];
|
|
208
|
-
}
|
|
209
|
-
|
|
210
|
-
/** @override */
|
|
211
|
-
static get delegateAttrs() {
|
|
212
|
-
return ['theme'];
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
/** @protected */
|
|
216
|
-
ready() {
|
|
217
|
-
super.ready();
|
|
218
|
-
|
|
219
|
-
this.__overflowController = new OverflowController(this, this.shadowRoot.querySelector('[part="content"]'));
|
|
220
|
-
this.addController(this.__overflowController);
|
|
221
|
-
|
|
222
|
-
this._tabsSlotController = new TabsSlotController(this);
|
|
223
|
-
this.addController(this._tabsSlotController);
|
|
224
|
-
|
|
225
|
-
// Observe the panels slot for nodes. Set the assigned element nodes as the __panels array.
|
|
226
|
-
const panelSlot = this.shadowRoot.querySelector('#panel-slot');
|
|
227
|
-
this.__panelsObserver = new SlotObserver(panelSlot, () => {
|
|
228
|
-
this.__panels = Array.from(panelSlot.assignedNodes({ flatten: true })).filter(
|
|
229
|
-
(node) => node.nodeType === Node.ELEMENT_NODE,
|
|
230
|
-
);
|
|
231
|
-
});
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
/**
|
|
235
|
-
* An observer which applies the necessary roles and ARIA attributes
|
|
236
|
-
* to associate the tab elements with the panels.
|
|
237
|
-
* @private
|
|
238
|
-
*/
|
|
239
|
-
__itemsOrPanelsChanged(items, panels) {
|
|
240
|
-
if (!items || !panels) {
|
|
241
|
-
return;
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
items.forEach((tabItem) => {
|
|
245
|
-
const panel = panels.find((panel) => panel.getAttribute('tab') === tabItem.id);
|
|
246
|
-
if (panel) {
|
|
247
|
-
panel.role = 'tabpanel';
|
|
248
|
-
if (!panel.id) {
|
|
249
|
-
panel.id = `tabsheet-panel-${generateUniqueId()}`;
|
|
250
|
-
}
|
|
251
|
-
panel.setAttribute('aria-labelledby', tabItem.id);
|
|
252
|
-
|
|
253
|
-
tabItem.setAttribute('aria-controls', panel.id);
|
|
254
|
-
}
|
|
255
|
-
});
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
/**
|
|
259
|
-
* An observer which toggles the visibility of the panels based on the selected tab.
|
|
260
|
-
* @private
|
|
261
|
-
*/
|
|
262
|
-
__selectedTabItemChanged(selected, items, panels) {
|
|
263
|
-
if (!items || !panels || selected === undefined) {
|
|
264
|
-
return;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
const content = this.shadowRoot.querySelector('[part="content"]');
|
|
268
|
-
|
|
269
|
-
const selectedTab = items[selected];
|
|
270
|
-
const selectedTabId = selectedTab ? selectedTab.id : '';
|
|
271
|
-
const selectedPanel = panels.find((panel) => panel.getAttribute('tab') === selectedTabId);
|
|
272
|
-
|
|
273
|
-
// Mark loading state if a selected panel is not found.
|
|
274
|
-
this.toggleAttribute('loading', !selectedPanel);
|
|
275
|
-
|
|
276
|
-
const hasOneVisiblePanel = panels.filter((panel) => !panel.hidden).length === 1;
|
|
277
|
-
|
|
278
|
-
if (selectedPanel) {
|
|
279
|
-
// A selected panel is found, remove the loading state fallback height.
|
|
280
|
-
content.style.minHeight = '';
|
|
281
|
-
} else if (hasOneVisiblePanel) {
|
|
282
|
-
// Make sure the empty content has a fallback height in loading state..
|
|
283
|
-
content.style.minHeight = `${content.offsetHeight}px`;
|
|
284
|
-
}
|
|
285
|
-
|
|
286
|
-
// Hide all panels and show only the selected panel.
|
|
287
|
-
panels.forEach((panel) => {
|
|
288
|
-
panel.hidden = panel !== selectedPanel;
|
|
289
|
-
});
|
|
290
|
-
}
|
|
291
111
|
}
|
|
292
112
|
|
|
293
113
|
defineCustomElement(TabSheet);
|
package/web-types.json
DELETED
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://json.schemastore.org/web-types",
|
|
3
|
-
"name": "@vaadin/tabsheet",
|
|
4
|
-
"version": "24.3.2",
|
|
5
|
-
"description-markup": "markdown",
|
|
6
|
-
"contributions": {
|
|
7
|
-
"html": {
|
|
8
|
-
"elements": [
|
|
9
|
-
{
|
|
10
|
-
"name": "vaadin-tabsheet",
|
|
11
|
-
"description": "`<vaadin-tabsheet>` is a Web Component for organizing and grouping content\ninto scrollable panels. The panels can be switched between by using tabs.\n\n```\n <vaadin-tabsheet>\n <div slot=\"prefix\">Prefix</div>\n <div slot=\"suffix\">Suffix</div>\n\n <vaadin-tabs slot=\"tabs\">\n <vaadin-tab id=\"tab-1\">Tab 1</vaadin-tab>\n <vaadin-tab id=\"tab-2\">Tab 2</vaadin-tab>\n <vaadin-tab id=\"tab-3\">Tab 3</vaadin-tab>\n </vaadin-tabs>\n\n <div tab=\"tab-1\">Panel 1</div>\n <div tab=\"tab-2\">Panel 2</div>\n <div tab=\"tab-3\">Panel 3</div>\n </vaadin-tabsheet>\n```\n\n### Styling\n\nThe following shadow DOM parts are exposed for styling:\n\nPart name | Description\n--------- | ---------------\n`tabs-container` | The container for the slotted prefix, tabs and suffix\n`content` | The container for the slotted panels\n\nThe following state attributes are available for styling:\n\nAttribute | Description\n------------------|-------------\n`loading` | Set when a tab without associated content is selected\n`overflow` | Set to `top`, `bottom`, `start`, `end`, all of them, or none.\n\nSee [Styling Components](hhttps://vaadin.com/docs/latest/components/ds-resources/customization/styling-components) documentation.",
|
|
12
|
-
"attributes": [
|
|
13
|
-
{
|
|
14
|
-
"name": "selected",
|
|
15
|
-
"description": "The index of the selected tab.",
|
|
16
|
-
"value": {
|
|
17
|
-
"type": [
|
|
18
|
-
"number",
|
|
19
|
-
"null",
|
|
20
|
-
"undefined"
|
|
21
|
-
]
|
|
22
|
-
}
|
|
23
|
-
},
|
|
24
|
-
{
|
|
25
|
-
"name": "theme",
|
|
26
|
-
"description": "The theme variants to apply to the component.",
|
|
27
|
-
"value": {
|
|
28
|
-
"type": [
|
|
29
|
-
"string",
|
|
30
|
-
"null",
|
|
31
|
-
"undefined"
|
|
32
|
-
]
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
],
|
|
36
|
-
"js": {
|
|
37
|
-
"properties": [
|
|
38
|
-
{
|
|
39
|
-
"name": "selected",
|
|
40
|
-
"description": "The index of the selected tab.",
|
|
41
|
-
"value": {
|
|
42
|
-
"type": [
|
|
43
|
-
"number",
|
|
44
|
-
"null",
|
|
45
|
-
"undefined"
|
|
46
|
-
]
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
],
|
|
50
|
-
"events": [
|
|
51
|
-
{
|
|
52
|
-
"name": "items-changed",
|
|
53
|
-
"description": "Fired when the `items` property changes."
|
|
54
|
-
},
|
|
55
|
-
{
|
|
56
|
-
"name": "selected-changed",
|
|
57
|
-
"description": "Fired when the `selected` property changes."
|
|
58
|
-
}
|
|
59
|
-
]
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
]
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
package/web-types.lit.json
DELETED
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://json.schemastore.org/web-types",
|
|
3
|
-
"name": "@vaadin/tabsheet",
|
|
4
|
-
"version": "24.3.2",
|
|
5
|
-
"description-markup": "markdown",
|
|
6
|
-
"framework": "lit",
|
|
7
|
-
"framework-config": {
|
|
8
|
-
"enable-when": {
|
|
9
|
-
"node-packages": [
|
|
10
|
-
"lit"
|
|
11
|
-
]
|
|
12
|
-
}
|
|
13
|
-
},
|
|
14
|
-
"contributions": {
|
|
15
|
-
"html": {
|
|
16
|
-
"elements": [
|
|
17
|
-
{
|
|
18
|
-
"name": "vaadin-tabsheet",
|
|
19
|
-
"description": "`<vaadin-tabsheet>` is a Web Component for organizing and grouping content\ninto scrollable panels. The panels can be switched between by using tabs.\n\n```\n <vaadin-tabsheet>\n <div slot=\"prefix\">Prefix</div>\n <div slot=\"suffix\">Suffix</div>\n\n <vaadin-tabs slot=\"tabs\">\n <vaadin-tab id=\"tab-1\">Tab 1</vaadin-tab>\n <vaadin-tab id=\"tab-2\">Tab 2</vaadin-tab>\n <vaadin-tab id=\"tab-3\">Tab 3</vaadin-tab>\n </vaadin-tabs>\n\n <div tab=\"tab-1\">Panel 1</div>\n <div tab=\"tab-2\">Panel 2</div>\n <div tab=\"tab-3\">Panel 3</div>\n </vaadin-tabsheet>\n```\n\n### Styling\n\nThe following shadow DOM parts are exposed for styling:\n\nPart name | Description\n--------- | ---------------\n`tabs-container` | The container for the slotted prefix, tabs and suffix\n`content` | The container for the slotted panels\n\nThe following state attributes are available for styling:\n\nAttribute | Description\n------------------|-------------\n`loading` | Set when a tab without associated content is selected\n`overflow` | Set to `top`, `bottom`, `start`, `end`, all of them, or none.\n\nSee [Styling Components](hhttps://vaadin.com/docs/latest/components/ds-resources/customization/styling-components) documentation.",
|
|
20
|
-
"extension": true,
|
|
21
|
-
"attributes": [
|
|
22
|
-
{
|
|
23
|
-
"name": ".selected",
|
|
24
|
-
"description": "The index of the selected tab.",
|
|
25
|
-
"value": {
|
|
26
|
-
"kind": "expression"
|
|
27
|
-
}
|
|
28
|
-
},
|
|
29
|
-
{
|
|
30
|
-
"name": "@items-changed",
|
|
31
|
-
"description": "Fired when the `items` property changes.",
|
|
32
|
-
"value": {
|
|
33
|
-
"kind": "expression"
|
|
34
|
-
}
|
|
35
|
-
},
|
|
36
|
-
{
|
|
37
|
-
"name": "@selected-changed",
|
|
38
|
-
"description": "Fired when the `selected` property changes.",
|
|
39
|
-
"value": {
|
|
40
|
-
"kind": "expression"
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
]
|
|
44
|
-
}
|
|
45
|
-
]
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
}
|