@u-elements/u-tabs 0.0.0 → 0.0.2
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 +59 -61
- package/dist/u-tabs.d.cts +11 -11
- package/dist/u-tabs.d.ts +11 -11
- package/dist/u-tabs.js +59 -61
- package/dist/u-tabs.manifest.json +16 -13
- package/dist/u-tabs.vscode.json +4 -1
- package/package.json +1 -1
package/dist/u-tabs.cjs
CHANGED
|
@@ -2,36 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
// ../utils.ts
|
|
4
4
|
var IS_BROWSER = typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.navigator !== "undefined";
|
|
5
|
-
var IS_ANDROID = IS_BROWSER && /android/i.test(
|
|
6
|
-
var
|
|
7
|
-
var ARIA_LABELLEDBY = IS_ANDROID ? "data-labelledby" : "aria-labelledby";
|
|
8
|
-
var ARIA_SELECTED = "aria-selected";
|
|
5
|
+
var IS_ANDROID = IS_BROWSER && /android/i.test(navigator.userAgent);
|
|
6
|
+
var SAFE_LABELLEDBY = `${IS_ANDROID ? "data" : "aria"}-labelledby`;
|
|
9
7
|
var DISPLAY_BLOCK = ":host(:not([hidden])) { display: block }";
|
|
10
8
|
var UHTMLElement = typeof HTMLElement === "undefined" ? class {
|
|
11
9
|
} : HTMLElement;
|
|
12
|
-
var
|
|
10
|
+
var events = (action, element, rest) => rest[0].split(",").forEach((type) => {
|
|
13
11
|
rest[0] = type;
|
|
14
12
|
Element.prototype[`${action}EventListener`].apply(element, rest);
|
|
15
13
|
});
|
|
16
|
-
var on = (element, ...rest) =>
|
|
17
|
-
var off = (element, ...rest) =>
|
|
18
|
-
var
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
function attr(element, name, value) {
|
|
24
|
-
if (element instanceof Element) {
|
|
25
|
-
if (typeof name === "object")
|
|
26
|
-
Object.entries(name).map(([name2, value2]) => attr(element, name2, value2));
|
|
27
|
-
else if (value === void 0)
|
|
28
|
-
return element.getAttribute(name);
|
|
29
|
-
else if (value === null)
|
|
30
|
-
element.removeAttribute(name);
|
|
31
|
-
else if (element.getAttribute(name) !== `${value}`)
|
|
32
|
-
element.setAttribute(name, `${value}`);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
14
|
+
var on = (element, ...rest) => events("add", element, rest);
|
|
15
|
+
var off = (element, ...rest) => events("remove", element, rest);
|
|
16
|
+
var attachStyle = (element, css) => element.attachShadow({ mode: "closed" }).append(
|
|
17
|
+
createElement("slot"),
|
|
18
|
+
// Unnamed slot does automatically render all top element nodes
|
|
19
|
+
createElement("style", { textContent: css })
|
|
20
|
+
);
|
|
35
21
|
var asButton = (event) => {
|
|
36
22
|
const isClick = "key" in event && (event.key === " " || event.key === "Enter");
|
|
37
23
|
if (isClick)
|
|
@@ -41,25 +27,28 @@ var asButton = (event) => {
|
|
|
41
27
|
return isClick;
|
|
42
28
|
};
|
|
43
29
|
var getRoot = (node) => node.getRootNode();
|
|
44
|
-
var id =
|
|
45
|
-
var useId = (el) => el ? el.id || (el.id = `:${el.nodeName.toLowerCase()}${(++id).toString(32)}`) :
|
|
30
|
+
var id = 0;
|
|
31
|
+
var useId = (el) => el ? el.id || (el.id = `:${el.nodeName.toLowerCase()}${(++id).toString(32)}`) : "";
|
|
32
|
+
var createElement = (tagName, props) => Object.assign(document.createElement(tagName), props);
|
|
46
33
|
var customElements = {
|
|
47
34
|
define: (name, instance) => !IS_BROWSER || window.customElements.get(name) || window.customElements.define(name, instance)
|
|
48
35
|
};
|
|
49
36
|
|
|
50
37
|
// u-tabs.ts
|
|
38
|
+
var ARIA_CONTROLS = "aria-controls";
|
|
51
39
|
var UHTMLTabsElement = class extends UHTMLElement {
|
|
52
|
-
|
|
53
|
-
|
|
40
|
+
constructor() {
|
|
41
|
+
super();
|
|
42
|
+
attachStyle(this, DISPLAY_BLOCK);
|
|
54
43
|
}
|
|
55
44
|
get tabList() {
|
|
56
45
|
return queryWithoutNested("u-tablist", this)[0] || null;
|
|
57
46
|
}
|
|
58
47
|
get selectedIndex() {
|
|
59
|
-
return [...this.tabs].findIndex((tab) =>
|
|
48
|
+
return [...this.tabs].findIndex((tab) => tab.ariaSelected === "true");
|
|
60
49
|
}
|
|
61
50
|
set selectedIndex(index) {
|
|
62
|
-
|
|
51
|
+
this.tabs[index].ariaSelected = "true";
|
|
63
52
|
}
|
|
64
53
|
get tabs() {
|
|
65
54
|
return queryWithoutNested("u-tab", this);
|
|
@@ -69,9 +58,12 @@ var UHTMLTabsElement = class extends UHTMLElement {
|
|
|
69
58
|
}
|
|
70
59
|
};
|
|
71
60
|
var UHTMLTabListElement = class extends UHTMLElement {
|
|
61
|
+
constructor() {
|
|
62
|
+
super();
|
|
63
|
+
attachStyle(this, DISPLAY_BLOCK);
|
|
64
|
+
}
|
|
72
65
|
connectedCallback() {
|
|
73
|
-
|
|
74
|
-
attr(this, "role", "tablist");
|
|
66
|
+
this.role = "tablist";
|
|
75
67
|
on(this, "click,keydown", this);
|
|
76
68
|
}
|
|
77
69
|
disconnectedCallback() {
|
|
@@ -104,38 +96,42 @@ var UHTMLTabListElement = class extends UHTMLElement {
|
|
|
104
96
|
return this.closest("u-tabs");
|
|
105
97
|
}
|
|
106
98
|
};
|
|
107
|
-
var
|
|
99
|
+
var SKIP_ATTR_CHANGE = false;
|
|
108
100
|
var UHTMLTabElement = class extends UHTMLElement {
|
|
109
|
-
|
|
110
|
-
|
|
101
|
+
constructor() {
|
|
102
|
+
super();
|
|
103
|
+
attachStyle(
|
|
104
|
+
this,
|
|
105
|
+
`:host(:not([hidden])) { cursor: pointer; display: inline-block }`
|
|
106
|
+
);
|
|
111
107
|
}
|
|
112
108
|
connectedCallback() {
|
|
113
|
-
style(this, `${DISPLAY_BLOCK}:host { cursor: pointer }`);
|
|
114
109
|
this.selected = !!this.selected;
|
|
115
110
|
}
|
|
116
111
|
attributeChangedCallback(_name, prev, next) {
|
|
117
|
-
if (!
|
|
112
|
+
if (!SKIP_ATTR_CHANGE && prev !== next && (SKIP_ATTR_CHANGE = true)) {
|
|
118
113
|
const { tabs = [], panels = [], selectedIndex } = this.tabsElement || {};
|
|
119
114
|
const selected = this.selected ? this : tabs[selectedIndex || 0] || this;
|
|
120
115
|
let selectedPanel;
|
|
121
|
-
panels.forEach((panel) =>
|
|
116
|
+
panels.forEach((panel) => {
|
|
117
|
+
panel.removeAttribute(SAFE_LABELLEDBY);
|
|
118
|
+
panel.hidden = true;
|
|
119
|
+
});
|
|
122
120
|
tabs.forEach((tab, index) => {
|
|
123
|
-
const tabindex = selected === tab ? 0 : -1;
|
|
124
121
|
const panel = getPanel(tab) || panels[index] || null;
|
|
125
|
-
if (
|
|
122
|
+
if (selected === tab && panel)
|
|
126
123
|
selectedPanel = panel;
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
});
|
|
124
|
+
tab.role = "tab";
|
|
125
|
+
tab.tabIndex = selected === tab ? 0 : -1;
|
|
126
|
+
tab.ariaSelected = `${selected === tab}`;
|
|
127
|
+
tab.setAttribute(ARIA_CONTROLS, useId(panel));
|
|
128
|
+
panel?.toggleAttribute("hidden", selectedPanel !== panel);
|
|
129
|
+
panel?.setAttribute(
|
|
130
|
+
SAFE_LABELLEDBY,
|
|
131
|
+
useId(selectedPanel === panel ? selected : tab)
|
|
132
|
+
);
|
|
137
133
|
});
|
|
138
|
-
|
|
134
|
+
SKIP_ATTR_CHANGE = false;
|
|
139
135
|
}
|
|
140
136
|
}
|
|
141
137
|
get tabsElement() {
|
|
@@ -145,10 +141,10 @@ var UHTMLTabElement = class extends UHTMLElement {
|
|
|
145
141
|
return this.closest("u-tablist");
|
|
146
142
|
}
|
|
147
143
|
get selected() {
|
|
148
|
-
return
|
|
144
|
+
return this.ariaSelected === "true";
|
|
149
145
|
}
|
|
150
146
|
set selected(value) {
|
|
151
|
-
|
|
147
|
+
this.ariaSelected = `${value}`;
|
|
152
148
|
}
|
|
153
149
|
/** Retrieves the ordinal position of an tab in a tablist. */
|
|
154
150
|
get index() {
|
|
@@ -158,19 +154,20 @@ var UHTMLTabElement = class extends UHTMLElement {
|
|
|
158
154
|
return getPanel(this);
|
|
159
155
|
}
|
|
160
156
|
};
|
|
157
|
+
UHTMLTabElement.observedAttributes = ["id", "aria-selected", ARIA_CONTROLS];
|
|
161
158
|
var UHTMLTabPanelElement = class extends UHTMLElement {
|
|
162
|
-
|
|
163
|
-
|
|
159
|
+
constructor() {
|
|
160
|
+
super();
|
|
161
|
+
attachStyle(this, DISPLAY_BLOCK);
|
|
164
162
|
}
|
|
165
163
|
connectedCallback() {
|
|
166
|
-
|
|
167
|
-
attr(this, "role", "tabpanel");
|
|
164
|
+
this.role = "tabpanel";
|
|
168
165
|
this.hidden = Array.from(this.tabs).every((tab) => !tab.selected);
|
|
169
166
|
}
|
|
170
167
|
attributeChangedCallback(_name, prev, next) {
|
|
171
|
-
if (
|
|
172
|
-
|
|
173
|
-
|
|
168
|
+
if (SKIP_ATTR_CHANGE || prev === next)
|
|
169
|
+
return;
|
|
170
|
+
getTabs(this, prev).forEach((tab) => tab.setAttribute(ARIA_CONTROLS, next));
|
|
174
171
|
}
|
|
175
172
|
get tabsElement() {
|
|
176
173
|
return this.closest("u-tabs");
|
|
@@ -179,12 +176,13 @@ var UHTMLTabPanelElement = class extends UHTMLElement {
|
|
|
179
176
|
return getTabs(this, this.id);
|
|
180
177
|
}
|
|
181
178
|
};
|
|
179
|
+
UHTMLTabPanelElement.observedAttributes = ["id"];
|
|
182
180
|
var queryWithoutNested = (tag, self) => {
|
|
183
181
|
const selector = `${tag}:not(:scope ${self.nodeName}:not(:scope) ${tag})`;
|
|
184
182
|
return self.querySelectorAll(selector);
|
|
185
183
|
};
|
|
186
184
|
var getPanel = (self) => {
|
|
187
|
-
const css = `u-tabpanel[id="${
|
|
185
|
+
const css = `u-tabpanel[id="${self.getAttribute(ARIA_CONTROLS)}"]`;
|
|
188
186
|
return getRoot(self).querySelector(css) || document.querySelector(css);
|
|
189
187
|
};
|
|
190
188
|
var getTabs = (self, id2) => {
|
package/dist/u-tabs.d.cts
CHANGED
|
@@ -16,7 +16,7 @@ declare global {
|
|
|
16
16
|
* No MDN reference available.
|
|
17
17
|
*/
|
|
18
18
|
declare class UHTMLTabsElement extends UHTMLElement {
|
|
19
|
-
|
|
19
|
+
constructor();
|
|
20
20
|
get tabList(): UHTMLTabListElement | null;
|
|
21
21
|
get selectedIndex(): number;
|
|
22
22
|
set selectedIndex(index: number);
|
|
@@ -28,6 +28,7 @@ declare class UHTMLTabsElement extends UHTMLElement {
|
|
|
28
28
|
* [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/tablist_role)
|
|
29
29
|
*/
|
|
30
30
|
declare class UHTMLTabListElement extends UHTMLElement {
|
|
31
|
+
constructor();
|
|
31
32
|
connectedCallback(): void;
|
|
32
33
|
disconnectedCallback(): void;
|
|
33
34
|
handleEvent(event: Event): void;
|
|
@@ -38,7 +39,8 @@ declare class UHTMLTabListElement extends UHTMLElement {
|
|
|
38
39
|
* [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/tab_role)
|
|
39
40
|
*/
|
|
40
41
|
declare class UHTMLTabElement extends UHTMLElement {
|
|
41
|
-
static
|
|
42
|
+
static observedAttributes: string[];
|
|
43
|
+
constructor();
|
|
42
44
|
connectedCallback(): void;
|
|
43
45
|
attributeChangedCallback(_name: string, prev: string, next: string): void;
|
|
44
46
|
get tabsElement(): UHTMLTabsElement | null;
|
|
@@ -54,7 +56,8 @@ declare class UHTMLTabElement extends UHTMLElement {
|
|
|
54
56
|
* [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/tabpanel_role)
|
|
55
57
|
*/
|
|
56
58
|
declare class UHTMLTabPanelElement extends UHTMLElement {
|
|
57
|
-
static
|
|
59
|
+
static observedAttributes: string[];
|
|
60
|
+
constructor();
|
|
58
61
|
connectedCallback(): void;
|
|
59
62
|
attributeChangedCallback(_name: string, prev: string, next: string): void;
|
|
60
63
|
get tabsElement(): UHTMLTabsElement | null;
|
|
@@ -62,15 +65,15 @@ declare class UHTMLTabPanelElement extends UHTMLElement {
|
|
|
62
65
|
}
|
|
63
66
|
|
|
64
67
|
export { UHTMLTabElement, UHTMLTabListElement, UHTMLTabPanelElement, UHTMLTabsElement };
|
|
65
|
-
|
|
66
68
|
import type * as VueJSX from '@vue/runtime-dom'
|
|
67
69
|
import type { JSX as QwikJSX } from '@builder.io/qwik/jsx-runtime'
|
|
68
70
|
import type { JSX as ReactJSX } from 'react'
|
|
69
71
|
import type { JSX as SolidJSX } from 'solid-js'
|
|
70
72
|
import type { SvelteHTMLElements } from 'svelte/elements'
|
|
73
|
+
|
|
71
74
|
export type VueTabs = VueJSX.IntrinsicElementAttributes['div']
|
|
72
75
|
export type QwikTabs = QwikJSX.IntrinsicElements['div']
|
|
73
|
-
export type ReactTabs = ReactJSX.IntrinsicElements['div']
|
|
76
|
+
export type ReactTabs = ReactJSX.IntrinsicElements['div'] & { class?: string }
|
|
74
77
|
export type SolidJSTabs = SolidJSX.HTMLElementTags['div']
|
|
75
78
|
export type SvelteTabs = SvelteHTMLElements['div']
|
|
76
79
|
|
|
@@ -80,10 +83,9 @@ declare module '@builder.io/qwik/jsx-runtime' { export namespace JSX { export in
|
|
|
80
83
|
declare global { namespace React.JSX { interface IntrinsicElements { 'u-tabs': ReactTabs } } }
|
|
81
84
|
declare module 'solid-js' { namespace JSX { interface IntrinsicElements { 'u-tabs': SolidJSTabs } } }
|
|
82
85
|
declare module 'svelte/elements' { interface SvelteHTMLElements { 'u-tabs': SvelteTabs } }
|
|
83
|
-
|
|
84
86
|
export type VueTablist = VueJSX.IntrinsicElementAttributes['div']
|
|
85
87
|
export type QwikTablist = QwikJSX.IntrinsicElements['div']
|
|
86
|
-
export type ReactTablist = ReactJSX.IntrinsicElements['div']
|
|
88
|
+
export type ReactTablist = ReactJSX.IntrinsicElements['div'] & { class?: string }
|
|
87
89
|
export type SolidJSTablist = SolidJSX.HTMLElementTags['div']
|
|
88
90
|
export type SvelteTablist = SvelteHTMLElements['div']
|
|
89
91
|
|
|
@@ -93,10 +95,9 @@ declare module '@builder.io/qwik/jsx-runtime' { export namespace JSX { export in
|
|
|
93
95
|
declare global { namespace React.JSX { interface IntrinsicElements { 'u-tablist': ReactTablist } } }
|
|
94
96
|
declare module 'solid-js' { namespace JSX { interface IntrinsicElements { 'u-tablist': SolidJSTablist } } }
|
|
95
97
|
declare module 'svelte/elements' { interface SvelteHTMLElements { 'u-tablist': SvelteTablist } }
|
|
96
|
-
|
|
97
98
|
export type VueTab = VueJSX.IntrinsicElementAttributes['div']
|
|
98
99
|
export type QwikTab = QwikJSX.IntrinsicElements['div']
|
|
99
|
-
export type ReactTab = ReactJSX.IntrinsicElements['div']
|
|
100
|
+
export type ReactTab = ReactJSX.IntrinsicElements['div'] & { class?: string }
|
|
100
101
|
export type SolidJSTab = SolidJSX.HTMLElementTags['div']
|
|
101
102
|
export type SvelteTab = SvelteHTMLElements['div']
|
|
102
103
|
|
|
@@ -106,10 +107,9 @@ declare module '@builder.io/qwik/jsx-runtime' { export namespace JSX { export in
|
|
|
106
107
|
declare global { namespace React.JSX { interface IntrinsicElements { 'u-tab': ReactTab } } }
|
|
107
108
|
declare module 'solid-js' { namespace JSX { interface IntrinsicElements { 'u-tab': SolidJSTab } } }
|
|
108
109
|
declare module 'svelte/elements' { interface SvelteHTMLElements { 'u-tab': SvelteTab } }
|
|
109
|
-
|
|
110
110
|
export type VueTabpanel = VueJSX.IntrinsicElementAttributes['div']
|
|
111
111
|
export type QwikTabpanel = QwikJSX.IntrinsicElements['div']
|
|
112
|
-
export type ReactTabpanel = ReactJSX.IntrinsicElements['div']
|
|
112
|
+
export type ReactTabpanel = ReactJSX.IntrinsicElements['div'] & { class?: string }
|
|
113
113
|
export type SolidJSTabpanel = SolidJSX.HTMLElementTags['div']
|
|
114
114
|
export type SvelteTabpanel = SvelteHTMLElements['div']
|
|
115
115
|
|
package/dist/u-tabs.d.ts
CHANGED
|
@@ -16,7 +16,7 @@ declare global {
|
|
|
16
16
|
* No MDN reference available.
|
|
17
17
|
*/
|
|
18
18
|
declare class UHTMLTabsElement extends UHTMLElement {
|
|
19
|
-
|
|
19
|
+
constructor();
|
|
20
20
|
get tabList(): UHTMLTabListElement | null;
|
|
21
21
|
get selectedIndex(): number;
|
|
22
22
|
set selectedIndex(index: number);
|
|
@@ -28,6 +28,7 @@ declare class UHTMLTabsElement extends UHTMLElement {
|
|
|
28
28
|
* [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/tablist_role)
|
|
29
29
|
*/
|
|
30
30
|
declare class UHTMLTabListElement extends UHTMLElement {
|
|
31
|
+
constructor();
|
|
31
32
|
connectedCallback(): void;
|
|
32
33
|
disconnectedCallback(): void;
|
|
33
34
|
handleEvent(event: Event): void;
|
|
@@ -38,7 +39,8 @@ declare class UHTMLTabListElement extends UHTMLElement {
|
|
|
38
39
|
* [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/tab_role)
|
|
39
40
|
*/
|
|
40
41
|
declare class UHTMLTabElement extends UHTMLElement {
|
|
41
|
-
static
|
|
42
|
+
static observedAttributes: string[];
|
|
43
|
+
constructor();
|
|
42
44
|
connectedCallback(): void;
|
|
43
45
|
attributeChangedCallback(_name: string, prev: string, next: string): void;
|
|
44
46
|
get tabsElement(): UHTMLTabsElement | null;
|
|
@@ -54,7 +56,8 @@ declare class UHTMLTabElement extends UHTMLElement {
|
|
|
54
56
|
* [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/tabpanel_role)
|
|
55
57
|
*/
|
|
56
58
|
declare class UHTMLTabPanelElement extends UHTMLElement {
|
|
57
|
-
static
|
|
59
|
+
static observedAttributes: string[];
|
|
60
|
+
constructor();
|
|
58
61
|
connectedCallback(): void;
|
|
59
62
|
attributeChangedCallback(_name: string, prev: string, next: string): void;
|
|
60
63
|
get tabsElement(): UHTMLTabsElement | null;
|
|
@@ -62,15 +65,15 @@ declare class UHTMLTabPanelElement extends UHTMLElement {
|
|
|
62
65
|
}
|
|
63
66
|
|
|
64
67
|
export { UHTMLTabElement, UHTMLTabListElement, UHTMLTabPanelElement, UHTMLTabsElement };
|
|
65
|
-
|
|
66
68
|
import type * as VueJSX from '@vue/runtime-dom'
|
|
67
69
|
import type { JSX as QwikJSX } from '@builder.io/qwik/jsx-runtime'
|
|
68
70
|
import type { JSX as ReactJSX } from 'react'
|
|
69
71
|
import type { JSX as SolidJSX } from 'solid-js'
|
|
70
72
|
import type { SvelteHTMLElements } from 'svelte/elements'
|
|
73
|
+
|
|
71
74
|
export type VueTabs = VueJSX.IntrinsicElementAttributes['div']
|
|
72
75
|
export type QwikTabs = QwikJSX.IntrinsicElements['div']
|
|
73
|
-
export type ReactTabs = ReactJSX.IntrinsicElements['div']
|
|
76
|
+
export type ReactTabs = ReactJSX.IntrinsicElements['div'] & { class?: string }
|
|
74
77
|
export type SolidJSTabs = SolidJSX.HTMLElementTags['div']
|
|
75
78
|
export type SvelteTabs = SvelteHTMLElements['div']
|
|
76
79
|
|
|
@@ -80,10 +83,9 @@ declare module '@builder.io/qwik/jsx-runtime' { export namespace JSX { export in
|
|
|
80
83
|
declare global { namespace React.JSX { interface IntrinsicElements { 'u-tabs': ReactTabs } } }
|
|
81
84
|
declare module 'solid-js' { namespace JSX { interface IntrinsicElements { 'u-tabs': SolidJSTabs } } }
|
|
82
85
|
declare module 'svelte/elements' { interface SvelteHTMLElements { 'u-tabs': SvelteTabs } }
|
|
83
|
-
|
|
84
86
|
export type VueTablist = VueJSX.IntrinsicElementAttributes['div']
|
|
85
87
|
export type QwikTablist = QwikJSX.IntrinsicElements['div']
|
|
86
|
-
export type ReactTablist = ReactJSX.IntrinsicElements['div']
|
|
88
|
+
export type ReactTablist = ReactJSX.IntrinsicElements['div'] & { class?: string }
|
|
87
89
|
export type SolidJSTablist = SolidJSX.HTMLElementTags['div']
|
|
88
90
|
export type SvelteTablist = SvelteHTMLElements['div']
|
|
89
91
|
|
|
@@ -93,10 +95,9 @@ declare module '@builder.io/qwik/jsx-runtime' { export namespace JSX { export in
|
|
|
93
95
|
declare global { namespace React.JSX { interface IntrinsicElements { 'u-tablist': ReactTablist } } }
|
|
94
96
|
declare module 'solid-js' { namespace JSX { interface IntrinsicElements { 'u-tablist': SolidJSTablist } } }
|
|
95
97
|
declare module 'svelte/elements' { interface SvelteHTMLElements { 'u-tablist': SvelteTablist } }
|
|
96
|
-
|
|
97
98
|
export type VueTab = VueJSX.IntrinsicElementAttributes['div']
|
|
98
99
|
export type QwikTab = QwikJSX.IntrinsicElements['div']
|
|
99
|
-
export type ReactTab = ReactJSX.IntrinsicElements['div']
|
|
100
|
+
export type ReactTab = ReactJSX.IntrinsicElements['div'] & { class?: string }
|
|
100
101
|
export type SolidJSTab = SolidJSX.HTMLElementTags['div']
|
|
101
102
|
export type SvelteTab = SvelteHTMLElements['div']
|
|
102
103
|
|
|
@@ -106,10 +107,9 @@ declare module '@builder.io/qwik/jsx-runtime' { export namespace JSX { export in
|
|
|
106
107
|
declare global { namespace React.JSX { interface IntrinsicElements { 'u-tab': ReactTab } } }
|
|
107
108
|
declare module 'solid-js' { namespace JSX { interface IntrinsicElements { 'u-tab': SolidJSTab } } }
|
|
108
109
|
declare module 'svelte/elements' { interface SvelteHTMLElements { 'u-tab': SvelteTab } }
|
|
109
|
-
|
|
110
110
|
export type VueTabpanel = VueJSX.IntrinsicElementAttributes['div']
|
|
111
111
|
export type QwikTabpanel = QwikJSX.IntrinsicElements['div']
|
|
112
|
-
export type ReactTabpanel = ReactJSX.IntrinsicElements['div']
|
|
112
|
+
export type ReactTabpanel = ReactJSX.IntrinsicElements['div'] & { class?: string }
|
|
113
113
|
export type SolidJSTabpanel = SolidJSX.HTMLElementTags['div']
|
|
114
114
|
export type SvelteTabpanel = SvelteHTMLElements['div']
|
|
115
115
|
|
package/dist/u-tabs.js
CHANGED
|
@@ -1,35 +1,21 @@
|
|
|
1
1
|
// ../utils.ts
|
|
2
2
|
var IS_BROWSER = typeof window !== "undefined" && typeof window.document !== "undefined" && typeof window.navigator !== "undefined";
|
|
3
|
-
var IS_ANDROID = IS_BROWSER && /android/i.test(
|
|
4
|
-
var
|
|
5
|
-
var ARIA_LABELLEDBY = IS_ANDROID ? "data-labelledby" : "aria-labelledby";
|
|
6
|
-
var ARIA_SELECTED = "aria-selected";
|
|
3
|
+
var IS_ANDROID = IS_BROWSER && /android/i.test(navigator.userAgent);
|
|
4
|
+
var SAFE_LABELLEDBY = `${IS_ANDROID ? "data" : "aria"}-labelledby`;
|
|
7
5
|
var DISPLAY_BLOCK = ":host(:not([hidden])) { display: block }";
|
|
8
6
|
var UHTMLElement = typeof HTMLElement === "undefined" ? class {
|
|
9
7
|
} : HTMLElement;
|
|
10
|
-
var
|
|
8
|
+
var events = (action, element, rest) => rest[0].split(",").forEach((type) => {
|
|
11
9
|
rest[0] = type;
|
|
12
10
|
Element.prototype[`${action}EventListener`].apply(element, rest);
|
|
13
11
|
});
|
|
14
|
-
var on = (element, ...rest) =>
|
|
15
|
-
var off = (element, ...rest) =>
|
|
16
|
-
var
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
function attr(element, name, value) {
|
|
22
|
-
if (element instanceof Element) {
|
|
23
|
-
if (typeof name === "object")
|
|
24
|
-
Object.entries(name).map(([name2, value2]) => attr(element, name2, value2));
|
|
25
|
-
else if (value === void 0)
|
|
26
|
-
return element.getAttribute(name);
|
|
27
|
-
else if (value === null)
|
|
28
|
-
element.removeAttribute(name);
|
|
29
|
-
else if (element.getAttribute(name) !== `${value}`)
|
|
30
|
-
element.setAttribute(name, `${value}`);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
12
|
+
var on = (element, ...rest) => events("add", element, rest);
|
|
13
|
+
var off = (element, ...rest) => events("remove", element, rest);
|
|
14
|
+
var attachStyle = (element, css) => element.attachShadow({ mode: "closed" }).append(
|
|
15
|
+
createElement("slot"),
|
|
16
|
+
// Unnamed slot does automatically render all top element nodes
|
|
17
|
+
createElement("style", { textContent: css })
|
|
18
|
+
);
|
|
33
19
|
var asButton = (event) => {
|
|
34
20
|
const isClick = "key" in event && (event.key === " " || event.key === "Enter");
|
|
35
21
|
if (isClick)
|
|
@@ -39,25 +25,28 @@ var asButton = (event) => {
|
|
|
39
25
|
return isClick;
|
|
40
26
|
};
|
|
41
27
|
var getRoot = (node) => node.getRootNode();
|
|
42
|
-
var id =
|
|
43
|
-
var useId = (el) => el ? el.id || (el.id = `:${el.nodeName.toLowerCase()}${(++id).toString(32)}`) :
|
|
28
|
+
var id = 0;
|
|
29
|
+
var useId = (el) => el ? el.id || (el.id = `:${el.nodeName.toLowerCase()}${(++id).toString(32)}`) : "";
|
|
30
|
+
var createElement = (tagName, props) => Object.assign(document.createElement(tagName), props);
|
|
44
31
|
var customElements = {
|
|
45
32
|
define: (name, instance) => !IS_BROWSER || window.customElements.get(name) || window.customElements.define(name, instance)
|
|
46
33
|
};
|
|
47
34
|
|
|
48
35
|
// u-tabs.ts
|
|
36
|
+
var ARIA_CONTROLS = "aria-controls";
|
|
49
37
|
var UHTMLTabsElement = class extends UHTMLElement {
|
|
50
|
-
|
|
51
|
-
|
|
38
|
+
constructor() {
|
|
39
|
+
super();
|
|
40
|
+
attachStyle(this, DISPLAY_BLOCK);
|
|
52
41
|
}
|
|
53
42
|
get tabList() {
|
|
54
43
|
return queryWithoutNested("u-tablist", this)[0] || null;
|
|
55
44
|
}
|
|
56
45
|
get selectedIndex() {
|
|
57
|
-
return [...this.tabs].findIndex((tab) =>
|
|
46
|
+
return [...this.tabs].findIndex((tab) => tab.ariaSelected === "true");
|
|
58
47
|
}
|
|
59
48
|
set selectedIndex(index) {
|
|
60
|
-
|
|
49
|
+
this.tabs[index].ariaSelected = "true";
|
|
61
50
|
}
|
|
62
51
|
get tabs() {
|
|
63
52
|
return queryWithoutNested("u-tab", this);
|
|
@@ -67,9 +56,12 @@ var UHTMLTabsElement = class extends UHTMLElement {
|
|
|
67
56
|
}
|
|
68
57
|
};
|
|
69
58
|
var UHTMLTabListElement = class extends UHTMLElement {
|
|
59
|
+
constructor() {
|
|
60
|
+
super();
|
|
61
|
+
attachStyle(this, DISPLAY_BLOCK);
|
|
62
|
+
}
|
|
70
63
|
connectedCallback() {
|
|
71
|
-
|
|
72
|
-
attr(this, "role", "tablist");
|
|
64
|
+
this.role = "tablist";
|
|
73
65
|
on(this, "click,keydown", this);
|
|
74
66
|
}
|
|
75
67
|
disconnectedCallback() {
|
|
@@ -102,38 +94,42 @@ var UHTMLTabListElement = class extends UHTMLElement {
|
|
|
102
94
|
return this.closest("u-tabs");
|
|
103
95
|
}
|
|
104
96
|
};
|
|
105
|
-
var
|
|
97
|
+
var SKIP_ATTR_CHANGE = false;
|
|
106
98
|
var UHTMLTabElement = class extends UHTMLElement {
|
|
107
|
-
|
|
108
|
-
|
|
99
|
+
constructor() {
|
|
100
|
+
super();
|
|
101
|
+
attachStyle(
|
|
102
|
+
this,
|
|
103
|
+
`:host(:not([hidden])) { cursor: pointer; display: inline-block }`
|
|
104
|
+
);
|
|
109
105
|
}
|
|
110
106
|
connectedCallback() {
|
|
111
|
-
style(this, `${DISPLAY_BLOCK}:host { cursor: pointer }`);
|
|
112
107
|
this.selected = !!this.selected;
|
|
113
108
|
}
|
|
114
109
|
attributeChangedCallback(_name, prev, next) {
|
|
115
|
-
if (!
|
|
110
|
+
if (!SKIP_ATTR_CHANGE && prev !== next && (SKIP_ATTR_CHANGE = true)) {
|
|
116
111
|
const { tabs = [], panels = [], selectedIndex } = this.tabsElement || {};
|
|
117
112
|
const selected = this.selected ? this : tabs[selectedIndex || 0] || this;
|
|
118
113
|
let selectedPanel;
|
|
119
|
-
panels.forEach((panel) =>
|
|
114
|
+
panels.forEach((panel) => {
|
|
115
|
+
panel.removeAttribute(SAFE_LABELLEDBY);
|
|
116
|
+
panel.hidden = true;
|
|
117
|
+
});
|
|
120
118
|
tabs.forEach((tab, index) => {
|
|
121
|
-
const tabindex = selected === tab ? 0 : -1;
|
|
122
119
|
const panel = getPanel(tab) || panels[index] || null;
|
|
123
|
-
if (
|
|
120
|
+
if (selected === tab && panel)
|
|
124
121
|
selectedPanel = panel;
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
});
|
|
122
|
+
tab.role = "tab";
|
|
123
|
+
tab.tabIndex = selected === tab ? 0 : -1;
|
|
124
|
+
tab.ariaSelected = `${selected === tab}`;
|
|
125
|
+
tab.setAttribute(ARIA_CONTROLS, useId(panel));
|
|
126
|
+
panel?.toggleAttribute("hidden", selectedPanel !== panel);
|
|
127
|
+
panel?.setAttribute(
|
|
128
|
+
SAFE_LABELLEDBY,
|
|
129
|
+
useId(selectedPanel === panel ? selected : tab)
|
|
130
|
+
);
|
|
135
131
|
});
|
|
136
|
-
|
|
132
|
+
SKIP_ATTR_CHANGE = false;
|
|
137
133
|
}
|
|
138
134
|
}
|
|
139
135
|
get tabsElement() {
|
|
@@ -143,10 +139,10 @@ var UHTMLTabElement = class extends UHTMLElement {
|
|
|
143
139
|
return this.closest("u-tablist");
|
|
144
140
|
}
|
|
145
141
|
get selected() {
|
|
146
|
-
return
|
|
142
|
+
return this.ariaSelected === "true";
|
|
147
143
|
}
|
|
148
144
|
set selected(value) {
|
|
149
|
-
|
|
145
|
+
this.ariaSelected = `${value}`;
|
|
150
146
|
}
|
|
151
147
|
/** Retrieves the ordinal position of an tab in a tablist. */
|
|
152
148
|
get index() {
|
|
@@ -156,19 +152,20 @@ var UHTMLTabElement = class extends UHTMLElement {
|
|
|
156
152
|
return getPanel(this);
|
|
157
153
|
}
|
|
158
154
|
};
|
|
155
|
+
UHTMLTabElement.observedAttributes = ["id", "aria-selected", ARIA_CONTROLS];
|
|
159
156
|
var UHTMLTabPanelElement = class extends UHTMLElement {
|
|
160
|
-
|
|
161
|
-
|
|
157
|
+
constructor() {
|
|
158
|
+
super();
|
|
159
|
+
attachStyle(this, DISPLAY_BLOCK);
|
|
162
160
|
}
|
|
163
161
|
connectedCallback() {
|
|
164
|
-
|
|
165
|
-
attr(this, "role", "tabpanel");
|
|
162
|
+
this.role = "tabpanel";
|
|
166
163
|
this.hidden = Array.from(this.tabs).every((tab) => !tab.selected);
|
|
167
164
|
}
|
|
168
165
|
attributeChangedCallback(_name, prev, next) {
|
|
169
|
-
if (
|
|
170
|
-
|
|
171
|
-
|
|
166
|
+
if (SKIP_ATTR_CHANGE || prev === next)
|
|
167
|
+
return;
|
|
168
|
+
getTabs(this, prev).forEach((tab) => tab.setAttribute(ARIA_CONTROLS, next));
|
|
172
169
|
}
|
|
173
170
|
get tabsElement() {
|
|
174
171
|
return this.closest("u-tabs");
|
|
@@ -177,12 +174,13 @@ var UHTMLTabPanelElement = class extends UHTMLElement {
|
|
|
177
174
|
return getTabs(this, this.id);
|
|
178
175
|
}
|
|
179
176
|
};
|
|
177
|
+
UHTMLTabPanelElement.observedAttributes = ["id"];
|
|
180
178
|
var queryWithoutNested = (tag, self) => {
|
|
181
179
|
const selector = `${tag}:not(:scope ${self.nodeName}:not(:scope) ${tag})`;
|
|
182
180
|
return self.querySelectorAll(selector);
|
|
183
181
|
};
|
|
184
182
|
var getPanel = (self) => {
|
|
185
|
-
const css = `u-tabpanel[id="${
|
|
183
|
+
const css = `u-tabpanel[id="${self.getAttribute(ARIA_CONTROLS)}"]`;
|
|
186
184
|
return getRoot(self).querySelector(css) || document.querySelector(css);
|
|
187
185
|
};
|
|
188
186
|
var getTabs = (self, id2) => {
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"modules": [
|
|
5
5
|
{
|
|
6
6
|
"kind": "javascript-module",
|
|
7
|
-
"path": "u-tabs.ts",
|
|
7
|
+
"path": "/Users/eirikbacker/Library/Mobile Documents/com~apple~CloudDocs/5-capra/u-elements/packages/u-tabs/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": "/utils"
|
|
48
|
+
"module": "//Users/eirikbacker/Library/Mobile%20Documents/com~apple~CloudDocs/5-capra/u-elements/packages/utils"
|
|
49
49
|
},
|
|
50
50
|
"tagName": "u-tabs",
|
|
51
51
|
"customElement": true
|
|
@@ -78,7 +78,7 @@
|
|
|
78
78
|
],
|
|
79
79
|
"superclass": {
|
|
80
80
|
"name": "UHTMLElement",
|
|
81
|
-
"module": "/utils"
|
|
81
|
+
"module": "//Users/eirikbacker/Library/Mobile%20Documents/com~apple~CloudDocs/5-capra/u-elements/packages/utils"
|
|
82
82
|
},
|
|
83
83
|
"tagName": "u-tablist",
|
|
84
84
|
"customElement": true
|
|
@@ -132,11 +132,14 @@
|
|
|
132
132
|
"attributes": [
|
|
133
133
|
{
|
|
134
134
|
"name": "id"
|
|
135
|
+
},
|
|
136
|
+
{
|
|
137
|
+
"name": "aria-selected"
|
|
135
138
|
}
|
|
136
139
|
],
|
|
137
140
|
"superclass": {
|
|
138
141
|
"name": "UHTMLElement",
|
|
139
|
-
"module": "/utils"
|
|
142
|
+
"module": "//Users/eirikbacker/Library/Mobile%20Documents/com~apple~CloudDocs/5-capra/u-elements/packages/utils"
|
|
140
143
|
},
|
|
141
144
|
"tagName": "u-tab",
|
|
142
145
|
"customElement": true
|
|
@@ -170,7 +173,7 @@
|
|
|
170
173
|
],
|
|
171
174
|
"superclass": {
|
|
172
175
|
"name": "UHTMLElement",
|
|
173
|
-
"module": "/utils"
|
|
176
|
+
"module": "//Users/eirikbacker/Library/Mobile%20Documents/com~apple~CloudDocs/5-capra/u-elements/packages/utils"
|
|
174
177
|
},
|
|
175
178
|
"tagName": "u-tabpanel",
|
|
176
179
|
"customElement": true
|
|
@@ -182,7 +185,7 @@
|
|
|
182
185
|
"name": "UHTMLTabsElement",
|
|
183
186
|
"declaration": {
|
|
184
187
|
"name": "UHTMLTabsElement",
|
|
185
|
-
"module": "u-tabs.ts"
|
|
188
|
+
"module": "/Users/eirikbacker/Library/Mobile Documents/com~apple~CloudDocs/5-capra/u-elements/packages/u-tabs/u-tabs.ts"
|
|
186
189
|
}
|
|
187
190
|
},
|
|
188
191
|
{
|
|
@@ -190,7 +193,7 @@
|
|
|
190
193
|
"name": "UHTMLTabListElement",
|
|
191
194
|
"declaration": {
|
|
192
195
|
"name": "UHTMLTabListElement",
|
|
193
|
-
"module": "u-tabs.ts"
|
|
196
|
+
"module": "/Users/eirikbacker/Library/Mobile Documents/com~apple~CloudDocs/5-capra/u-elements/packages/u-tabs/u-tabs.ts"
|
|
194
197
|
}
|
|
195
198
|
},
|
|
196
199
|
{
|
|
@@ -198,7 +201,7 @@
|
|
|
198
201
|
"name": "UHTMLTabElement",
|
|
199
202
|
"declaration": {
|
|
200
203
|
"name": "UHTMLTabElement",
|
|
201
|
-
"module": "u-tabs.ts"
|
|
204
|
+
"module": "/Users/eirikbacker/Library/Mobile Documents/com~apple~CloudDocs/5-capra/u-elements/packages/u-tabs/u-tabs.ts"
|
|
202
205
|
}
|
|
203
206
|
},
|
|
204
207
|
{
|
|
@@ -206,7 +209,7 @@
|
|
|
206
209
|
"name": "UHTMLTabPanelElement",
|
|
207
210
|
"declaration": {
|
|
208
211
|
"name": "UHTMLTabPanelElement",
|
|
209
|
-
"module": "u-tabs.ts"
|
|
212
|
+
"module": "/Users/eirikbacker/Library/Mobile Documents/com~apple~CloudDocs/5-capra/u-elements/packages/u-tabs/u-tabs.ts"
|
|
210
213
|
}
|
|
211
214
|
},
|
|
212
215
|
{
|
|
@@ -214,7 +217,7 @@
|
|
|
214
217
|
"name": "u-tabs",
|
|
215
218
|
"declaration": {
|
|
216
219
|
"name": "UHTMLTabsElement",
|
|
217
|
-
"module": "u-tabs.ts"
|
|
220
|
+
"module": "/Users/eirikbacker/Library/Mobile Documents/com~apple~CloudDocs/5-capra/u-elements/packages/u-tabs/u-tabs.ts"
|
|
218
221
|
}
|
|
219
222
|
},
|
|
220
223
|
{
|
|
@@ -222,7 +225,7 @@
|
|
|
222
225
|
"name": "u-tablist",
|
|
223
226
|
"declaration": {
|
|
224
227
|
"name": "UHTMLTabListElement",
|
|
225
|
-
"module": "u-tabs.ts"
|
|
228
|
+
"module": "/Users/eirikbacker/Library/Mobile Documents/com~apple~CloudDocs/5-capra/u-elements/packages/u-tabs/u-tabs.ts"
|
|
226
229
|
}
|
|
227
230
|
},
|
|
228
231
|
{
|
|
@@ -230,7 +233,7 @@
|
|
|
230
233
|
"name": "u-tab",
|
|
231
234
|
"declaration": {
|
|
232
235
|
"name": "UHTMLTabElement",
|
|
233
|
-
"module": "u-tabs.ts"
|
|
236
|
+
"module": "/Users/eirikbacker/Library/Mobile Documents/com~apple~CloudDocs/5-capra/u-elements/packages/u-tabs/u-tabs.ts"
|
|
234
237
|
}
|
|
235
238
|
},
|
|
236
239
|
{
|
|
@@ -238,7 +241,7 @@
|
|
|
238
241
|
"name": "u-tabpanel",
|
|
239
242
|
"declaration": {
|
|
240
243
|
"name": "UHTMLTabPanelElement",
|
|
241
|
-
"module": "u-tabs.ts"
|
|
244
|
+
"module": "/Users/eirikbacker/Library/Mobile Documents/com~apple~CloudDocs/5-capra/u-elements/packages/u-tabs/u-tabs.ts"
|
|
242
245
|
}
|
|
243
246
|
}
|
|
244
247
|
]
|
package/dist/u-tabs.vscode.json
CHANGED
|
@@ -17,7 +17,10 @@
|
|
|
17
17
|
{
|
|
18
18
|
"name": "u-tab",
|
|
19
19
|
"description": "The `<u-tab>` HTML element is an interactive element inside a `<u-tablist>` that, when activated, displays its associated `<u-tabpanel>`.\n[MDN Reference](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/tab_role)\n---\n",
|
|
20
|
-
"attributes": [
|
|
20
|
+
"attributes": [
|
|
21
|
+
{ "name": "id", "values": [] },
|
|
22
|
+
{ "name": "aria-selected", "values": [] }
|
|
23
|
+
],
|
|
21
24
|
"references": []
|
|
22
25
|
},
|
|
23
26
|
{
|