@u-elements/u-tabs 0.0.7 → 0.0.9
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/dist/u-tabs.cjs +71 -54
- package/dist/u-tabs.d.cts +2 -6
- package/dist/u-tabs.d.ts +2 -6
- package/dist/u-tabs.js +71 -54
- package/dist/u-tabs.manifest.json +15 -17
- package/dist/u-tabs.vscode.json +2 -5
- package/package.json +6 -3
package/dist/u-tabs.cjs
CHANGED
|
@@ -3,16 +3,18 @@
|
|
|
3
3
|
// ../utils.ts
|
|
4
4
|
var IS_BROWSER = typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.navigator !== "undefined";
|
|
5
5
|
var IS_ANDROID = IS_BROWSER && /android/i.test(navigator.userAgent);
|
|
6
|
+
var _a;
|
|
6
7
|
IS_BROWSER && // @ts-expect-error Typescript has not implemented userAgentData yet https://stackoverflow.com/a/71392474
|
|
7
|
-
/^Mac/i.test(navigator.userAgentData
|
|
8
|
+
/^Mac/i.test(((_a = navigator.userAgentData) == null ? void 0 : _a.platform) || navigator.platform);
|
|
8
9
|
var SAFE_LABELLEDBY = `${IS_ANDROID ? "data" : "aria"}-labelledby`;
|
|
9
10
|
var DISPLAY_BLOCK = ":host(:not([hidden])) { display: block }";
|
|
10
11
|
var UHTMLElement = typeof HTMLElement === "undefined" ? class {
|
|
11
12
|
} : HTMLElement;
|
|
12
13
|
function attr(el, name, value) {
|
|
13
|
-
|
|
14
|
-
if (value ===
|
|
15
|
-
|
|
14
|
+
var _a2;
|
|
15
|
+
if (value === void 0) return (_a2 = el.getAttribute(name)) != null ? _a2 : null;
|
|
16
|
+
if (value === null) el.removeAttribute(name);
|
|
17
|
+
else if (el.getAttribute(name) !== value) el.setAttribute(name, value);
|
|
16
18
|
return null;
|
|
17
19
|
}
|
|
18
20
|
var events = (action, element, rest) => {
|
|
@@ -28,6 +30,22 @@ var attachStyle = (element, css) => element.attachShadow({ mode: "open" }).appen
|
|
|
28
30
|
// Unnamed slot does automatically render all top element nodes
|
|
29
31
|
createElement("style", css)
|
|
30
32
|
);
|
|
33
|
+
var observers = /* @__PURE__ */ new WeakMap();
|
|
34
|
+
var mutationObserver = (element, options) => {
|
|
35
|
+
if (options === void 0) return observers.get(element);
|
|
36
|
+
try {
|
|
37
|
+
observers.get(element).disconnect();
|
|
38
|
+
observers.delete(element);
|
|
39
|
+
} catch (err) {
|
|
40
|
+
}
|
|
41
|
+
if (options) {
|
|
42
|
+
const observer = new MutationObserver(
|
|
43
|
+
(detail) => element.handleEvent({ type: "mutation", detail })
|
|
44
|
+
);
|
|
45
|
+
observer.observe(element, options);
|
|
46
|
+
observers.set(element, observer);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
31
49
|
var asButton = (event) => {
|
|
32
50
|
const isClick = "key" in event && (event.key === " " || event.key === "Enter");
|
|
33
51
|
if (isClick) event.preventDefault();
|
|
@@ -35,7 +53,8 @@ var asButton = (event) => {
|
|
|
35
53
|
return isClick;
|
|
36
54
|
};
|
|
37
55
|
var getRoot = (node) => {
|
|
38
|
-
|
|
56
|
+
var _a2;
|
|
57
|
+
const root = ((_a2 = node.getRootNode) == null ? void 0 : _a2.call(node)) || node.ownerDocument;
|
|
39
58
|
return root instanceof Document || root instanceof ShadowRoot ? root : document;
|
|
40
59
|
};
|
|
41
60
|
var id = 0;
|
|
@@ -55,6 +74,7 @@ var customElements = {
|
|
|
55
74
|
|
|
56
75
|
// u-tabs.ts
|
|
57
76
|
var ARIA_CONTROLS = "aria-controls";
|
|
77
|
+
var ARIA_SELECTED = "aria-selected";
|
|
58
78
|
var UHTMLTabsElement = class extends UHTMLElement {
|
|
59
79
|
constructor() {
|
|
60
80
|
super();
|
|
@@ -67,7 +87,7 @@ var UHTMLTabsElement = class extends UHTMLElement {
|
|
|
67
87
|
return getSelectedIndex(this.tabs);
|
|
68
88
|
}
|
|
69
89
|
set selectedIndex(index) {
|
|
70
|
-
|
|
90
|
+
setSelected(this.tabs[index]);
|
|
71
91
|
}
|
|
72
92
|
get tabs() {
|
|
73
93
|
return queryWithoutNested("u-tab", this);
|
|
@@ -84,17 +104,24 @@ var UHTMLTabListElement = class extends UHTMLElement {
|
|
|
84
104
|
connectedCallback() {
|
|
85
105
|
attr(this, "role", "tablist");
|
|
86
106
|
on(this, "click,keydown", this);
|
|
107
|
+
mutationObserver(this, { childList: true });
|
|
108
|
+
if (this.tabs.length) this.handleEvent();
|
|
87
109
|
}
|
|
88
110
|
disconnectedCallback() {
|
|
89
111
|
off(this, "click,keydown", this);
|
|
112
|
+
mutationObserver(this, false);
|
|
90
113
|
}
|
|
91
114
|
handleEvent(event) {
|
|
115
|
+
if (!event || event.type === "mutation") {
|
|
116
|
+
const tab = this.tabs[Math.max(this.selectedIndex, 0)];
|
|
117
|
+
return tab == null ? void 0 : tab.setAttribute(ARIA_SELECTED, "true");
|
|
118
|
+
}
|
|
92
119
|
const { key } = event;
|
|
93
|
-
const tabs = [...this.
|
|
120
|
+
const tabs = [...this.tabs];
|
|
94
121
|
const prev = tabs.findIndex((tab) => tab.contains(event.target));
|
|
95
122
|
let next = prev;
|
|
96
123
|
if (event.defaultPrevented || prev === -1) return;
|
|
97
|
-
if (event.type === "click") tabs[prev]
|
|
124
|
+
if (event.type === "click") setSelected(tabs[prev]);
|
|
98
125
|
if (event.type === "keydown" && !asButton(event)) {
|
|
99
126
|
if (key === "ArrowDown" || key === "ArrowRight")
|
|
100
127
|
next = (prev + 1) % tabs.length;
|
|
@@ -118,19 +145,20 @@ var UHTMLTabListElement = class extends UHTMLElement {
|
|
|
118
145
|
return this.closest("u-tabs");
|
|
119
146
|
}
|
|
120
147
|
get tabs() {
|
|
121
|
-
return
|
|
148
|
+
return this.querySelectorAll("u-tab");
|
|
122
149
|
}
|
|
123
150
|
get selectedIndex() {
|
|
124
151
|
return getSelectedIndex(this.tabs);
|
|
125
152
|
}
|
|
126
153
|
set selectedIndex(index) {
|
|
127
|
-
|
|
154
|
+
setSelected(this.tabs[index]);
|
|
128
155
|
}
|
|
129
156
|
};
|
|
157
|
+
var SKIP_ATTR_CHANGE = false;
|
|
130
158
|
var UHTMLTabElement = class extends UHTMLElement {
|
|
131
159
|
// Using ES2015 syntax for backwards compatibility
|
|
132
160
|
static get observedAttributes() {
|
|
133
|
-
return ["id",
|
|
161
|
+
return ["id", ARIA_SELECTED, ARIA_CONTROLS];
|
|
134
162
|
}
|
|
135
163
|
constructor() {
|
|
136
164
|
super();
|
|
@@ -140,50 +168,43 @@ var UHTMLTabElement = class extends UHTMLElement {
|
|
|
140
168
|
);
|
|
141
169
|
}
|
|
142
170
|
connectedCallback() {
|
|
143
|
-
const panelId = !attr(this, ARIA_CONTROLS) && useId(getPanel(this));
|
|
144
|
-
const selected = this.selected || ![...queryWithoutNested("u-tab", this.tabList || this)].some(isSelected);
|
|
145
|
-
attr(this, "aria-selected", `${selected}`);
|
|
146
171
|
attr(this, "role", "tab");
|
|
147
|
-
this.tabIndex = selected ? 0 : -1;
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
if (nextPanelId && attr(this, ARIA_CONTROLS) !== nextPanelId)
|
|
166
|
-
attr(this, ARIA_CONTROLS, nextPanelId);
|
|
167
|
-
this.tabIndex = 0;
|
|
168
|
-
if (nextPanel) attr(nextPanel, SAFE_LABELLEDBY, useId(this));
|
|
169
|
-
if (nextPanel) nextPanel.hidden = false;
|
|
172
|
+
this.tabIndex = this.selected ? 0 : -1;
|
|
173
|
+
}
|
|
174
|
+
attributeChangedCallback() {
|
|
175
|
+
if (!SKIP_ATTR_CHANGE && this.selected && this.tabList) {
|
|
176
|
+
SKIP_ATTR_CHANGE = true;
|
|
177
|
+
const tabs = [...this.tabList.querySelectorAll("u-tab")];
|
|
178
|
+
const panels = queryWithoutNested("u-tabpanel", this.tabsElement || this);
|
|
179
|
+
const nextPanel = getPanel(this, panels[tabs.indexOf(this)]);
|
|
180
|
+
if (nextPanel) attr(nextPanel, SAFE_LABELLEDBY, useId(this));
|
|
181
|
+
tabs.forEach((tab, index) => {
|
|
182
|
+
const panel = getPanel(tab, panels[index]);
|
|
183
|
+
tab.tabIndex = tab === this ? 0 : -1;
|
|
184
|
+
attr(tab, ARIA_SELECTED, `${tab === this}`);
|
|
185
|
+
if (panel) panel.hidden = panel !== nextPanel;
|
|
186
|
+
if (panel) attr(tab, ARIA_CONTROLS, panel.id);
|
|
187
|
+
});
|
|
188
|
+
SKIP_ATTR_CHANGE = false;
|
|
189
|
+
}
|
|
170
190
|
}
|
|
171
191
|
get tabsElement() {
|
|
172
192
|
return this.closest("u-tabs");
|
|
173
193
|
}
|
|
174
194
|
get tabList() {
|
|
175
|
-
|
|
195
|
+
const tablist = this.parentElement;
|
|
196
|
+
return (tablist == null ? void 0 : tablist.nodeName) === "U-TABLIST" ? tablist : null;
|
|
176
197
|
}
|
|
177
198
|
get selected() {
|
|
178
|
-
return
|
|
199
|
+
return attr(this, ARIA_SELECTED) === "true";
|
|
179
200
|
}
|
|
180
201
|
set selected(value) {
|
|
181
|
-
attr(this,
|
|
202
|
+
attr(this, ARIA_SELECTED, `${!!value}`);
|
|
182
203
|
}
|
|
183
204
|
/** Retrieves the ordinal position of an tab in a tablist. */
|
|
184
205
|
get index() {
|
|
185
206
|
const tabList = this.tabList;
|
|
186
|
-
return tabList ? [...
|
|
207
|
+
return tabList ? [...tabList.querySelectorAll("u-tab")].indexOf(this) : 0;
|
|
187
208
|
}
|
|
188
209
|
get panel() {
|
|
189
210
|
return getPanel(this);
|
|
@@ -213,24 +234,20 @@ var UHTMLTabPanelElement = class extends UHTMLElement {
|
|
|
213
234
|
}
|
|
214
235
|
get tabs() {
|
|
215
236
|
const css = `u-tab[${ARIA_CONTROLS}="${this.id}"]`;
|
|
216
|
-
|
|
217
|
-
return root.length ? root : document.querySelectorAll(css);
|
|
237
|
+
return getRoot(this).querySelectorAll(css);
|
|
218
238
|
}
|
|
219
239
|
};
|
|
220
|
-
var queryWithoutNested = (tag, self) => self.querySelectorAll(
|
|
221
|
-
|
|
222
|
-
);
|
|
223
|
-
|
|
224
|
-
|
|
240
|
+
var queryWithoutNested = (tag, self) => self.querySelectorAll(`${tag}:not(:scope u-tabpanel ${tag})`);
|
|
241
|
+
var getPanel = (tab, panel) => {
|
|
242
|
+
const id2 = attr(tab, ARIA_CONTROLS) || useId(panel);
|
|
243
|
+
const el = getRoot(tab).getElementById(id2);
|
|
244
|
+
return (el == null ? void 0 : el.nodeName) === "U-TABPANEL" ? el : null;
|
|
245
|
+
};
|
|
246
|
+
var getSelectedIndex = (tabs) => [...tabs].findIndex((tab) => attr(tab, ARIA_SELECTED) === "true");
|
|
247
|
+
var setSelected = (tab) => tab && attr(tab, "aria-selected", "true");
|
|
225
248
|
var isFocusable = (el) => el instanceof Element && !el.matches(':disabled,[tabindex^="-"]') && el.matches(
|
|
226
249
|
`[contenteditable],[controls],[href],[tabindex],input:not([type="hidden"]),select,textarea,button,summary,iframe`
|
|
227
250
|
);
|
|
228
|
-
var getPanel = (tab, id2) => {
|
|
229
|
-
const panelId = id2 || attr(tab, ARIA_CONTROLS);
|
|
230
|
-
const panelSelector = `u-tabpanel[id="${panelId}"]`;
|
|
231
|
-
const tabsElement = tab.closest("u-tabs");
|
|
232
|
-
return panelId && getRoot(tab).querySelector(panelSelector) || panelId && getRoot(tab).querySelector(panelSelector) || tabsElement && queryWithoutNested("u-tabpanel", tabsElement)[[...queryWithoutNested("u-tab", tabsElement)].indexOf(tab)] || null;
|
|
233
|
-
};
|
|
234
251
|
customElements.define("u-tabs", UHTMLTabsElement);
|
|
235
252
|
customElements.define("u-tablist", UHTMLTabListElement);
|
|
236
253
|
customElements.define("u-tab", UHTMLTabElement);
|
package/dist/u-tabs.d.cts
CHANGED
|
@@ -31,21 +31,17 @@ declare class UHTMLTabListElement extends UHTMLElement {
|
|
|
31
31
|
constructor();
|
|
32
32
|
connectedCallback(): void;
|
|
33
33
|
disconnectedCallback(): void;
|
|
34
|
-
handleEvent(event
|
|
34
|
+
handleEvent(event?: Event): void;
|
|
35
35
|
get tabsElement(): UHTMLTabsElement | null;
|
|
36
36
|
get tabs(): NodeListOf<UHTMLTabElement>;
|
|
37
37
|
get selectedIndex(): number;
|
|
38
38
|
set selectedIndex(index: number);
|
|
39
39
|
}
|
|
40
|
-
/**
|
|
41
|
-
* The `<u-tab>` HTML element is an interactive element inside a `<u-tablist>` that, when activated, displays its associated `<u-tabpanel>`.
|
|
42
|
-
* [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/tab_role)
|
|
43
|
-
*/
|
|
44
40
|
declare class UHTMLTabElement extends UHTMLElement {
|
|
45
41
|
static get observedAttributes(): string[];
|
|
46
42
|
constructor();
|
|
47
43
|
connectedCallback(): void;
|
|
48
|
-
attributeChangedCallback(
|
|
44
|
+
attributeChangedCallback(): void;
|
|
49
45
|
get tabsElement(): UHTMLTabsElement | null;
|
|
50
46
|
get tabList(): UHTMLTabListElement | null;
|
|
51
47
|
get selected(): boolean;
|
package/dist/u-tabs.d.ts
CHANGED
|
@@ -31,21 +31,17 @@ declare class UHTMLTabListElement extends UHTMLElement {
|
|
|
31
31
|
constructor();
|
|
32
32
|
connectedCallback(): void;
|
|
33
33
|
disconnectedCallback(): void;
|
|
34
|
-
handleEvent(event
|
|
34
|
+
handleEvent(event?: Event): void;
|
|
35
35
|
get tabsElement(): UHTMLTabsElement | null;
|
|
36
36
|
get tabs(): NodeListOf<UHTMLTabElement>;
|
|
37
37
|
get selectedIndex(): number;
|
|
38
38
|
set selectedIndex(index: number);
|
|
39
39
|
}
|
|
40
|
-
/**
|
|
41
|
-
* The `<u-tab>` HTML element is an interactive element inside a `<u-tablist>` that, when activated, displays its associated `<u-tabpanel>`.
|
|
42
|
-
* [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/tab_role)
|
|
43
|
-
*/
|
|
44
40
|
declare class UHTMLTabElement extends UHTMLElement {
|
|
45
41
|
static get observedAttributes(): string[];
|
|
46
42
|
constructor();
|
|
47
43
|
connectedCallback(): void;
|
|
48
|
-
attributeChangedCallback(
|
|
44
|
+
attributeChangedCallback(): void;
|
|
49
45
|
get tabsElement(): UHTMLTabsElement | null;
|
|
50
46
|
get tabList(): UHTMLTabListElement | null;
|
|
51
47
|
get selected(): boolean;
|
package/dist/u-tabs.js
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
// ../utils.ts
|
|
2
2
|
var IS_BROWSER = typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.navigator !== "undefined";
|
|
3
3
|
var IS_ANDROID = IS_BROWSER && /android/i.test(navigator.userAgent);
|
|
4
|
+
var _a;
|
|
4
5
|
IS_BROWSER && // @ts-expect-error Typescript has not implemented userAgentData yet https://stackoverflow.com/a/71392474
|
|
5
|
-
/^Mac/i.test(navigator.userAgentData
|
|
6
|
+
/^Mac/i.test(((_a = navigator.userAgentData) == null ? void 0 : _a.platform) || navigator.platform);
|
|
6
7
|
var SAFE_LABELLEDBY = `${IS_ANDROID ? "data" : "aria"}-labelledby`;
|
|
7
8
|
var DISPLAY_BLOCK = ":host(:not([hidden])) { display: block }";
|
|
8
9
|
var UHTMLElement = typeof HTMLElement === "undefined" ? class {
|
|
9
10
|
} : HTMLElement;
|
|
10
11
|
function attr(el, name, value) {
|
|
11
|
-
|
|
12
|
-
if (value ===
|
|
13
|
-
|
|
12
|
+
var _a2;
|
|
13
|
+
if (value === void 0) return (_a2 = el.getAttribute(name)) != null ? _a2 : null;
|
|
14
|
+
if (value === null) el.removeAttribute(name);
|
|
15
|
+
else if (el.getAttribute(name) !== value) el.setAttribute(name, value);
|
|
14
16
|
return null;
|
|
15
17
|
}
|
|
16
18
|
var events = (action, element, rest) => {
|
|
@@ -26,6 +28,22 @@ var attachStyle = (element, css) => element.attachShadow({ mode: "open" }).appen
|
|
|
26
28
|
// Unnamed slot does automatically render all top element nodes
|
|
27
29
|
createElement("style", css)
|
|
28
30
|
);
|
|
31
|
+
var observers = /* @__PURE__ */ new WeakMap();
|
|
32
|
+
var mutationObserver = (element, options) => {
|
|
33
|
+
if (options === void 0) return observers.get(element);
|
|
34
|
+
try {
|
|
35
|
+
observers.get(element).disconnect();
|
|
36
|
+
observers.delete(element);
|
|
37
|
+
} catch (err) {
|
|
38
|
+
}
|
|
39
|
+
if (options) {
|
|
40
|
+
const observer = new MutationObserver(
|
|
41
|
+
(detail) => element.handleEvent({ type: "mutation", detail })
|
|
42
|
+
);
|
|
43
|
+
observer.observe(element, options);
|
|
44
|
+
observers.set(element, observer);
|
|
45
|
+
}
|
|
46
|
+
};
|
|
29
47
|
var asButton = (event) => {
|
|
30
48
|
const isClick = "key" in event && (event.key === " " || event.key === "Enter");
|
|
31
49
|
if (isClick) event.preventDefault();
|
|
@@ -33,7 +51,8 @@ var asButton = (event) => {
|
|
|
33
51
|
return isClick;
|
|
34
52
|
};
|
|
35
53
|
var getRoot = (node) => {
|
|
36
|
-
|
|
54
|
+
var _a2;
|
|
55
|
+
const root = ((_a2 = node.getRootNode) == null ? void 0 : _a2.call(node)) || node.ownerDocument;
|
|
37
56
|
return root instanceof Document || root instanceof ShadowRoot ? root : document;
|
|
38
57
|
};
|
|
39
58
|
var id = 0;
|
|
@@ -53,6 +72,7 @@ var customElements = {
|
|
|
53
72
|
|
|
54
73
|
// u-tabs.ts
|
|
55
74
|
var ARIA_CONTROLS = "aria-controls";
|
|
75
|
+
var ARIA_SELECTED = "aria-selected";
|
|
56
76
|
var UHTMLTabsElement = class extends UHTMLElement {
|
|
57
77
|
constructor() {
|
|
58
78
|
super();
|
|
@@ -65,7 +85,7 @@ var UHTMLTabsElement = class extends UHTMLElement {
|
|
|
65
85
|
return getSelectedIndex(this.tabs);
|
|
66
86
|
}
|
|
67
87
|
set selectedIndex(index) {
|
|
68
|
-
|
|
88
|
+
setSelected(this.tabs[index]);
|
|
69
89
|
}
|
|
70
90
|
get tabs() {
|
|
71
91
|
return queryWithoutNested("u-tab", this);
|
|
@@ -82,17 +102,24 @@ var UHTMLTabListElement = class extends UHTMLElement {
|
|
|
82
102
|
connectedCallback() {
|
|
83
103
|
attr(this, "role", "tablist");
|
|
84
104
|
on(this, "click,keydown", this);
|
|
105
|
+
mutationObserver(this, { childList: true });
|
|
106
|
+
if (this.tabs.length) this.handleEvent();
|
|
85
107
|
}
|
|
86
108
|
disconnectedCallback() {
|
|
87
109
|
off(this, "click,keydown", this);
|
|
110
|
+
mutationObserver(this, false);
|
|
88
111
|
}
|
|
89
112
|
handleEvent(event) {
|
|
113
|
+
if (!event || event.type === "mutation") {
|
|
114
|
+
const tab = this.tabs[Math.max(this.selectedIndex, 0)];
|
|
115
|
+
return tab == null ? void 0 : tab.setAttribute(ARIA_SELECTED, "true");
|
|
116
|
+
}
|
|
90
117
|
const { key } = event;
|
|
91
|
-
const tabs = [...this.
|
|
118
|
+
const tabs = [...this.tabs];
|
|
92
119
|
const prev = tabs.findIndex((tab) => tab.contains(event.target));
|
|
93
120
|
let next = prev;
|
|
94
121
|
if (event.defaultPrevented || prev === -1) return;
|
|
95
|
-
if (event.type === "click") tabs[prev]
|
|
122
|
+
if (event.type === "click") setSelected(tabs[prev]);
|
|
96
123
|
if (event.type === "keydown" && !asButton(event)) {
|
|
97
124
|
if (key === "ArrowDown" || key === "ArrowRight")
|
|
98
125
|
next = (prev + 1) % tabs.length;
|
|
@@ -116,19 +143,20 @@ var UHTMLTabListElement = class extends UHTMLElement {
|
|
|
116
143
|
return this.closest("u-tabs");
|
|
117
144
|
}
|
|
118
145
|
get tabs() {
|
|
119
|
-
return
|
|
146
|
+
return this.querySelectorAll("u-tab");
|
|
120
147
|
}
|
|
121
148
|
get selectedIndex() {
|
|
122
149
|
return getSelectedIndex(this.tabs);
|
|
123
150
|
}
|
|
124
151
|
set selectedIndex(index) {
|
|
125
|
-
|
|
152
|
+
setSelected(this.tabs[index]);
|
|
126
153
|
}
|
|
127
154
|
};
|
|
155
|
+
var SKIP_ATTR_CHANGE = false;
|
|
128
156
|
var UHTMLTabElement = class extends UHTMLElement {
|
|
129
157
|
// Using ES2015 syntax for backwards compatibility
|
|
130
158
|
static get observedAttributes() {
|
|
131
|
-
return ["id",
|
|
159
|
+
return ["id", ARIA_SELECTED, ARIA_CONTROLS];
|
|
132
160
|
}
|
|
133
161
|
constructor() {
|
|
134
162
|
super();
|
|
@@ -138,50 +166,43 @@ var UHTMLTabElement = class extends UHTMLElement {
|
|
|
138
166
|
);
|
|
139
167
|
}
|
|
140
168
|
connectedCallback() {
|
|
141
|
-
const panelId = !attr(this, ARIA_CONTROLS) && useId(getPanel(this));
|
|
142
|
-
const selected = this.selected || ![...queryWithoutNested("u-tab", this.tabList || this)].some(isSelected);
|
|
143
|
-
attr(this, "aria-selected", `${selected}`);
|
|
144
169
|
attr(this, "role", "tab");
|
|
145
|
-
this.tabIndex = selected ? 0 : -1;
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
if (nextPanelId && attr(this, ARIA_CONTROLS) !== nextPanelId)
|
|
164
|
-
attr(this, ARIA_CONTROLS, nextPanelId);
|
|
165
|
-
this.tabIndex = 0;
|
|
166
|
-
if (nextPanel) attr(nextPanel, SAFE_LABELLEDBY, useId(this));
|
|
167
|
-
if (nextPanel) nextPanel.hidden = false;
|
|
170
|
+
this.tabIndex = this.selected ? 0 : -1;
|
|
171
|
+
}
|
|
172
|
+
attributeChangedCallback() {
|
|
173
|
+
if (!SKIP_ATTR_CHANGE && this.selected && this.tabList) {
|
|
174
|
+
SKIP_ATTR_CHANGE = true;
|
|
175
|
+
const tabs = [...this.tabList.querySelectorAll("u-tab")];
|
|
176
|
+
const panels = queryWithoutNested("u-tabpanel", this.tabsElement || this);
|
|
177
|
+
const nextPanel = getPanel(this, panels[tabs.indexOf(this)]);
|
|
178
|
+
if (nextPanel) attr(nextPanel, SAFE_LABELLEDBY, useId(this));
|
|
179
|
+
tabs.forEach((tab, index) => {
|
|
180
|
+
const panel = getPanel(tab, panels[index]);
|
|
181
|
+
tab.tabIndex = tab === this ? 0 : -1;
|
|
182
|
+
attr(tab, ARIA_SELECTED, `${tab === this}`);
|
|
183
|
+
if (panel) panel.hidden = panel !== nextPanel;
|
|
184
|
+
if (panel) attr(tab, ARIA_CONTROLS, panel.id);
|
|
185
|
+
});
|
|
186
|
+
SKIP_ATTR_CHANGE = false;
|
|
187
|
+
}
|
|
168
188
|
}
|
|
169
189
|
get tabsElement() {
|
|
170
190
|
return this.closest("u-tabs");
|
|
171
191
|
}
|
|
172
192
|
get tabList() {
|
|
173
|
-
|
|
193
|
+
const tablist = this.parentElement;
|
|
194
|
+
return (tablist == null ? void 0 : tablist.nodeName) === "U-TABLIST" ? tablist : null;
|
|
174
195
|
}
|
|
175
196
|
get selected() {
|
|
176
|
-
return
|
|
197
|
+
return attr(this, ARIA_SELECTED) === "true";
|
|
177
198
|
}
|
|
178
199
|
set selected(value) {
|
|
179
|
-
attr(this,
|
|
200
|
+
attr(this, ARIA_SELECTED, `${!!value}`);
|
|
180
201
|
}
|
|
181
202
|
/** Retrieves the ordinal position of an tab in a tablist. */
|
|
182
203
|
get index() {
|
|
183
204
|
const tabList = this.tabList;
|
|
184
|
-
return tabList ? [...
|
|
205
|
+
return tabList ? [...tabList.querySelectorAll("u-tab")].indexOf(this) : 0;
|
|
185
206
|
}
|
|
186
207
|
get panel() {
|
|
187
208
|
return getPanel(this);
|
|
@@ -211,24 +232,20 @@ var UHTMLTabPanelElement = class extends UHTMLElement {
|
|
|
211
232
|
}
|
|
212
233
|
get tabs() {
|
|
213
234
|
const css = `u-tab[${ARIA_CONTROLS}="${this.id}"]`;
|
|
214
|
-
|
|
215
|
-
return root.length ? root : document.querySelectorAll(css);
|
|
235
|
+
return getRoot(this).querySelectorAll(css);
|
|
216
236
|
}
|
|
217
237
|
};
|
|
218
|
-
var queryWithoutNested = (tag, self) => self.querySelectorAll(
|
|
219
|
-
|
|
220
|
-
);
|
|
221
|
-
|
|
222
|
-
|
|
238
|
+
var queryWithoutNested = (tag, self) => self.querySelectorAll(`${tag}:not(:scope u-tabpanel ${tag})`);
|
|
239
|
+
var getPanel = (tab, panel) => {
|
|
240
|
+
const id2 = attr(tab, ARIA_CONTROLS) || useId(panel);
|
|
241
|
+
const el = getRoot(tab).getElementById(id2);
|
|
242
|
+
return (el == null ? void 0 : el.nodeName) === "U-TABPANEL" ? el : null;
|
|
243
|
+
};
|
|
244
|
+
var getSelectedIndex = (tabs) => [...tabs].findIndex((tab) => attr(tab, ARIA_SELECTED) === "true");
|
|
245
|
+
var setSelected = (tab) => tab && attr(tab, "aria-selected", "true");
|
|
223
246
|
var isFocusable = (el) => el instanceof Element && !el.matches(':disabled,[tabindex^="-"]') && el.matches(
|
|
224
247
|
`[contenteditable],[controls],[href],[tabindex],input:not([type="hidden"]),select,textarea,button,summary,iframe`
|
|
225
248
|
);
|
|
226
|
-
var getPanel = (tab, id2) => {
|
|
227
|
-
const panelId = id2 || attr(tab, ARIA_CONTROLS);
|
|
228
|
-
const panelSelector = `u-tabpanel[id="${panelId}"]`;
|
|
229
|
-
const tabsElement = tab.closest("u-tabs");
|
|
230
|
-
return panelId && getRoot(tab).querySelector(panelSelector) || panelId && getRoot(tab).querySelector(panelSelector) || tabsElement && queryWithoutNested("u-tabpanel", tabsElement)[[...queryWithoutNested("u-tab", tabsElement)].indexOf(tab)] || null;
|
|
231
|
-
};
|
|
232
249
|
customElements.define("u-tabs", UHTMLTabsElement);
|
|
233
250
|
customElements.define("u-tablist", UHTMLTabListElement);
|
|
234
251
|
customElements.define("u-tab", UHTMLTabElement);
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"modules": [
|
|
5
5
|
{
|
|
6
6
|
"kind": "javascript-module",
|
|
7
|
-
"path": "
|
|
7
|
+
"path": "u-tabs.ts",
|
|
8
8
|
"declarations": [
|
|
9
9
|
{
|
|
10
10
|
"kind": "class",
|
|
@@ -45,7 +45,7 @@
|
|
|
45
45
|
],
|
|
46
46
|
"superclass": {
|
|
47
47
|
"name": "UHTMLElement",
|
|
48
|
-
"module": "
|
|
48
|
+
"module": "/utils"
|
|
49
49
|
},
|
|
50
50
|
"tagName": "u-tabs",
|
|
51
51
|
"customElement": true
|
|
@@ -61,6 +61,7 @@
|
|
|
61
61
|
"parameters": [
|
|
62
62
|
{
|
|
63
63
|
"name": "event",
|
|
64
|
+
"optional": true,
|
|
64
65
|
"type": {
|
|
65
66
|
"text": "Event"
|
|
66
67
|
}
|
|
@@ -93,14 +94,14 @@
|
|
|
93
94
|
],
|
|
94
95
|
"superclass": {
|
|
95
96
|
"name": "UHTMLElement",
|
|
96
|
-
"module": "
|
|
97
|
+
"module": "/utils"
|
|
97
98
|
},
|
|
98
99
|
"tagName": "u-tablist",
|
|
99
100
|
"customElement": true
|
|
100
101
|
},
|
|
101
102
|
{
|
|
102
103
|
"kind": "class",
|
|
103
|
-
"description": "
|
|
104
|
+
"description": "",
|
|
104
105
|
"name": "UHTMLTabElement",
|
|
105
106
|
"members": [
|
|
106
107
|
{
|
|
@@ -147,14 +148,11 @@
|
|
|
147
148
|
"attributes": [
|
|
148
149
|
{
|
|
149
150
|
"name": "id"
|
|
150
|
-
},
|
|
151
|
-
{
|
|
152
|
-
"name": "aria-selected"
|
|
153
151
|
}
|
|
154
152
|
],
|
|
155
153
|
"superclass": {
|
|
156
154
|
"name": "UHTMLElement",
|
|
157
|
-
"module": "
|
|
155
|
+
"module": "/utils"
|
|
158
156
|
},
|
|
159
157
|
"tagName": "u-tab",
|
|
160
158
|
"customElement": true
|
|
@@ -188,7 +186,7 @@
|
|
|
188
186
|
],
|
|
189
187
|
"superclass": {
|
|
190
188
|
"name": "UHTMLElement",
|
|
191
|
-
"module": "
|
|
189
|
+
"module": "/utils"
|
|
192
190
|
},
|
|
193
191
|
"tagName": "u-tabpanel",
|
|
194
192
|
"customElement": true
|
|
@@ -200,7 +198,7 @@
|
|
|
200
198
|
"name": "UHTMLTabsElement",
|
|
201
199
|
"declaration": {
|
|
202
200
|
"name": "UHTMLTabsElement",
|
|
203
|
-
"module": "
|
|
201
|
+
"module": "u-tabs.ts"
|
|
204
202
|
}
|
|
205
203
|
},
|
|
206
204
|
{
|
|
@@ -208,7 +206,7 @@
|
|
|
208
206
|
"name": "UHTMLTabListElement",
|
|
209
207
|
"declaration": {
|
|
210
208
|
"name": "UHTMLTabListElement",
|
|
211
|
-
"module": "
|
|
209
|
+
"module": "u-tabs.ts"
|
|
212
210
|
}
|
|
213
211
|
},
|
|
214
212
|
{
|
|
@@ -216,7 +214,7 @@
|
|
|
216
214
|
"name": "UHTMLTabElement",
|
|
217
215
|
"declaration": {
|
|
218
216
|
"name": "UHTMLTabElement",
|
|
219
|
-
"module": "
|
|
217
|
+
"module": "u-tabs.ts"
|
|
220
218
|
}
|
|
221
219
|
},
|
|
222
220
|
{
|
|
@@ -224,7 +222,7 @@
|
|
|
224
222
|
"name": "UHTMLTabPanelElement",
|
|
225
223
|
"declaration": {
|
|
226
224
|
"name": "UHTMLTabPanelElement",
|
|
227
|
-
"module": "
|
|
225
|
+
"module": "u-tabs.ts"
|
|
228
226
|
}
|
|
229
227
|
},
|
|
230
228
|
{
|
|
@@ -232,7 +230,7 @@
|
|
|
232
230
|
"name": "u-tabs",
|
|
233
231
|
"declaration": {
|
|
234
232
|
"name": "UHTMLTabsElement",
|
|
235
|
-
"module": "
|
|
233
|
+
"module": "u-tabs.ts"
|
|
236
234
|
}
|
|
237
235
|
},
|
|
238
236
|
{
|
|
@@ -240,7 +238,7 @@
|
|
|
240
238
|
"name": "u-tablist",
|
|
241
239
|
"declaration": {
|
|
242
240
|
"name": "UHTMLTabListElement",
|
|
243
|
-
"module": "
|
|
241
|
+
"module": "u-tabs.ts"
|
|
244
242
|
}
|
|
245
243
|
},
|
|
246
244
|
{
|
|
@@ -248,7 +246,7 @@
|
|
|
248
246
|
"name": "u-tab",
|
|
249
247
|
"declaration": {
|
|
250
248
|
"name": "UHTMLTabElement",
|
|
251
|
-
"module": "
|
|
249
|
+
"module": "u-tabs.ts"
|
|
252
250
|
}
|
|
253
251
|
},
|
|
254
252
|
{
|
|
@@ -256,7 +254,7 @@
|
|
|
256
254
|
"name": "u-tabpanel",
|
|
257
255
|
"declaration": {
|
|
258
256
|
"name": "UHTMLTabPanelElement",
|
|
259
|
-
"module": "
|
|
257
|
+
"module": "u-tabs.ts"
|
|
260
258
|
}
|
|
261
259
|
}
|
|
262
260
|
]
|
package/dist/u-tabs.vscode.json
CHANGED
|
@@ -16,11 +16,8 @@
|
|
|
16
16
|
},
|
|
17
17
|
{
|
|
18
18
|
"name": "u-tab",
|
|
19
|
-
"description": "
|
|
20
|
-
"attributes": [
|
|
21
|
-
{ "name": "id", "values": [] },
|
|
22
|
-
{ "name": "aria-selected", "values": [] }
|
|
23
|
-
],
|
|
19
|
+
"description": "\n---\n",
|
|
20
|
+
"attributes": [{ "name": "id", "values": [] }],
|
|
24
21
|
"references": []
|
|
25
22
|
},
|
|
26
23
|
{
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@u-elements/u-tabs",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.9",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"description": "HTML tags, just truly accessible",
|
|
6
6
|
"homepage": "https://u-elements.github.io/u-elements/",
|
|
@@ -14,12 +14,15 @@
|
|
|
14
14
|
],
|
|
15
15
|
"repository": {
|
|
16
16
|
"type": "git",
|
|
17
|
-
"url": "https://github.com/u-elements/u-elements.git"
|
|
17
|
+
"url": "git+https://github.com/u-elements/u-elements.git"
|
|
18
18
|
},
|
|
19
19
|
"bugs": {
|
|
20
20
|
"url": "https://github.com/u-elements/u-elements/issues"
|
|
21
21
|
},
|
|
22
22
|
"scripts": {
|
|
23
|
-
"build": "tsup --config ../../tsup.config.ts"
|
|
23
|
+
"build": "tsup --config ../../tsup.config.ts",
|
|
24
|
+
"publish:patch": "npm version patch && git push --tags origin main && npm publish",
|
|
25
|
+
"publish:minor": "npm version minor && git push --tags origin main && npm publish",
|
|
26
|
+
"publish:major": "npm version major && git push --tags origin main && npm publish"
|
|
24
27
|
}
|
|
25
28
|
}
|