@u-elements/u-tabs 0.0.1 → 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 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(window.navigator.userAgent);
6
- var ARIA_CONTROLS = "aria-controls";
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 bind = (element, rest, action) => rest[0].split(",").forEach((type) => {
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) => bind(element, rest, "add");
17
- var off = (element, ...rest) => bind(element, rest, "remove");
14
+ var on = (element, ...rest) => events("add", element, rest);
15
+ var off = (element, ...rest) => events("remove", element, rest);
18
16
  var attachStyle = (element, css) => element.attachShadow({ mode: "closed" }).append(
19
17
  createElement("slot"),
20
18
  // Unnamed slot does automatically render all top element nodes
21
19
  createElement("style", { textContent: css })
22
20
  );
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
- }
35
21
  var asButton = (event) => {
36
22
  const isClick = "key" in event && (event.key === " " || event.key === "Enter");
37
23
  if (isClick)
@@ -42,13 +28,14 @@ var asButton = (event) => {
42
28
  };
43
29
  var getRoot = (node) => node.getRootNode();
44
30
  var id = 0;
45
- var useId = (el) => el ? el.id || (el.id = `:${el.nodeName.toLowerCase()}${(++id).toString(32)}`) : void 0;
31
+ var useId = (el) => el ? el.id || (el.id = `:${el.nodeName.toLowerCase()}${(++id).toString(32)}`) : "";
46
32
  var createElement = (tagName, props) => Object.assign(document.createElement(tagName), props);
47
33
  var customElements = {
48
34
  define: (name, instance) => !IS_BROWSER || window.customElements.get(name) || window.customElements.define(name, instance)
49
35
  };
50
36
 
51
37
  // u-tabs.ts
38
+ var ARIA_CONTROLS = "aria-controls";
52
39
  var UHTMLTabsElement = class extends UHTMLElement {
53
40
  constructor() {
54
41
  super();
@@ -58,10 +45,10 @@ var UHTMLTabsElement = class extends UHTMLElement {
58
45
  return queryWithoutNested("u-tablist", this)[0] || null;
59
46
  }
60
47
  get selectedIndex() {
61
- return [...this.tabs].findIndex((tab) => attr(tab, ARIA_SELECTED) === "true");
48
+ return [...this.tabs].findIndex((tab) => tab.ariaSelected === "true");
62
49
  }
63
50
  set selectedIndex(index) {
64
- attr(this.tabs[index], ARIA_SELECTED, true);
51
+ this.tabs[index].ariaSelected = "true";
65
52
  }
66
53
  get tabs() {
67
54
  return queryWithoutNested("u-tab", this);
@@ -76,7 +63,7 @@ var UHTMLTabListElement = class extends UHTMLElement {
76
63
  attachStyle(this, DISPLAY_BLOCK);
77
64
  }
78
65
  connectedCallback() {
79
- attr(this, "role", "tablist");
66
+ this.role = "tablist";
80
67
  on(this, "click,keydown", this);
81
68
  }
82
69
  disconnectedCallback() {
@@ -109,41 +96,42 @@ var UHTMLTabListElement = class extends UHTMLElement {
109
96
  return this.closest("u-tabs");
110
97
  }
111
98
  };
112
- var skipAttrChange = false;
99
+ var SKIP_ATTR_CHANGE = false;
113
100
  var UHTMLTabElement = class extends UHTMLElement {
114
- static get observedAttributes() {
115
- return ["id", ARIA_SELECTED, ARIA_CONTROLS];
116
- }
117
101
  constructor() {
118
102
  super();
119
- attachStyle(this, `:host(:not([hidden])) { cursor: pointer; display: inline-block }`);
103
+ attachStyle(
104
+ this,
105
+ `:host(:not([hidden])) { cursor: pointer; display: inline-block }`
106
+ );
120
107
  }
121
108
  connectedCallback() {
122
109
  this.selected = !!this.selected;
123
110
  }
124
111
  attributeChangedCallback(_name, prev, next) {
125
- if (!skipAttrChange && prev !== next && (skipAttrChange = true)) {
112
+ if (!SKIP_ATTR_CHANGE && prev !== next && (SKIP_ATTR_CHANGE = true)) {
126
113
  const { tabs = [], panels = [], selectedIndex } = this.tabsElement || {};
127
114
  const selected = this.selected ? this : tabs[selectedIndex || 0] || this;
128
115
  let selectedPanel;
129
- panels.forEach((panel) => attr(panel, { [ARIA_LABELLEDBY]: null, hidden: "" }));
116
+ panels.forEach((panel) => {
117
+ panel.removeAttribute(SAFE_LABELLEDBY);
118
+ panel.hidden = true;
119
+ });
130
120
  tabs.forEach((tab, index) => {
131
- const tabindex = selected === tab ? 0 : -1;
132
121
  const panel = getPanel(tab) || panels[index] || null;
133
- if (!tabindex && panel)
122
+ if (selected === tab && panel)
134
123
  selectedPanel = panel;
135
- attr(tab, {
136
- [ARIA_SELECTED]: !tabindex,
137
- [ARIA_CONTROLS]: useId(panel),
138
- role: "tab",
139
- tabindex
140
- });
141
- attr(panel, {
142
- [ARIA_LABELLEDBY]: useId(selectedPanel === panel ? selected : tab),
143
- hidden: selectedPanel === panel ? null : ""
144
- });
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
+ );
145
133
  });
146
- skipAttrChange = false;
134
+ SKIP_ATTR_CHANGE = false;
147
135
  }
148
136
  }
149
137
  get tabsElement() {
@@ -153,10 +141,10 @@ var UHTMLTabElement = class extends UHTMLElement {
153
141
  return this.closest("u-tablist");
154
142
  }
155
143
  get selected() {
156
- return attr(this, ARIA_SELECTED) === "true";
144
+ return this.ariaSelected === "true";
157
145
  }
158
146
  set selected(value) {
159
- attr(this, ARIA_SELECTED, !!value);
147
+ this.ariaSelected = `${value}`;
160
148
  }
161
149
  /** Retrieves the ordinal position of an tab in a tablist. */
162
150
  get index() {
@@ -166,22 +154,20 @@ var UHTMLTabElement = class extends UHTMLElement {
166
154
  return getPanel(this);
167
155
  }
168
156
  };
157
+ UHTMLTabElement.observedAttributes = ["id", "aria-selected", ARIA_CONTROLS];
169
158
  var UHTMLTabPanelElement = class extends UHTMLElement {
170
- static get observedAttributes() {
171
- return ["id"];
172
- }
173
159
  constructor() {
174
160
  super();
175
161
  attachStyle(this, DISPLAY_BLOCK);
176
162
  }
177
163
  connectedCallback() {
178
- attr(this, "role", "tabpanel");
164
+ this.role = "tabpanel";
179
165
  this.hidden = Array.from(this.tabs).every((tab) => !tab.selected);
180
166
  }
181
167
  attributeChangedCallback(_name, prev, next) {
182
- if (!skipAttrChange && prev !== next) {
183
- Array.from(getTabs(this, prev), (tab) => attr(tab, ARIA_CONTROLS, next));
184
- }
168
+ if (SKIP_ATTR_CHANGE || prev === next)
169
+ return;
170
+ getTabs(this, prev).forEach((tab) => tab.setAttribute(ARIA_CONTROLS, next));
185
171
  }
186
172
  get tabsElement() {
187
173
  return this.closest("u-tabs");
@@ -190,12 +176,13 @@ var UHTMLTabPanelElement = class extends UHTMLElement {
190
176
  return getTabs(this, this.id);
191
177
  }
192
178
  };
179
+ UHTMLTabPanelElement.observedAttributes = ["id"];
193
180
  var queryWithoutNested = (tag, self) => {
194
181
  const selector = `${tag}:not(:scope ${self.nodeName}:not(:scope) ${tag})`;
195
182
  return self.querySelectorAll(selector);
196
183
  };
197
184
  var getPanel = (self) => {
198
- const css = `u-tabpanel[id="${attr(self, ARIA_CONTROLS)}"]`;
185
+ const css = `u-tabpanel[id="${self.getAttribute(ARIA_CONTROLS)}"]`;
199
186
  return getRoot(self).querySelector(css) || document.querySelector(css);
200
187
  };
201
188
  var getTabs = (self, id2) => {
package/dist/u-tabs.d.cts CHANGED
@@ -39,7 +39,7 @@ declare class UHTMLTabListElement extends UHTMLElement {
39
39
  * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/tab_role)
40
40
  */
41
41
  declare class UHTMLTabElement extends UHTMLElement {
42
- static get observedAttributes(): string[];
42
+ static observedAttributes: string[];
43
43
  constructor();
44
44
  connectedCallback(): void;
45
45
  attributeChangedCallback(_name: string, prev: string, next: string): void;
@@ -56,7 +56,7 @@ declare class UHTMLTabElement extends UHTMLElement {
56
56
  * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/tabpanel_role)
57
57
  */
58
58
  declare class UHTMLTabPanelElement extends UHTMLElement {
59
- static get observedAttributes(): string[];
59
+ static observedAttributes: string[];
60
60
  constructor();
61
61
  connectedCallback(): void;
62
62
  attributeChangedCallback(_name: string, prev: string, next: string): void;
@@ -65,15 +65,15 @@ declare class UHTMLTabPanelElement extends UHTMLElement {
65
65
  }
66
66
 
67
67
  export { UHTMLTabElement, UHTMLTabListElement, UHTMLTabPanelElement, UHTMLTabsElement };
68
-
69
68
  import type * as VueJSX from '@vue/runtime-dom'
70
69
  import type { JSX as QwikJSX } from '@builder.io/qwik/jsx-runtime'
71
70
  import type { JSX as ReactJSX } from 'react'
72
71
  import type { JSX as SolidJSX } from 'solid-js'
73
72
  import type { SvelteHTMLElements } from 'svelte/elements'
73
+
74
74
  export type VueTabs = VueJSX.IntrinsicElementAttributes['div']
75
75
  export type QwikTabs = QwikJSX.IntrinsicElements['div']
76
- export type ReactTabs = ReactJSX.IntrinsicElements['div']
76
+ export type ReactTabs = ReactJSX.IntrinsicElements['div'] & { class?: string }
77
77
  export type SolidJSTabs = SolidJSX.HTMLElementTags['div']
78
78
  export type SvelteTabs = SvelteHTMLElements['div']
79
79
 
@@ -83,10 +83,9 @@ declare module '@builder.io/qwik/jsx-runtime' { export namespace JSX { export in
83
83
  declare global { namespace React.JSX { interface IntrinsicElements { 'u-tabs': ReactTabs } } }
84
84
  declare module 'solid-js' { namespace JSX { interface IntrinsicElements { 'u-tabs': SolidJSTabs } } }
85
85
  declare module 'svelte/elements' { interface SvelteHTMLElements { 'u-tabs': SvelteTabs } }
86
-
87
86
  export type VueTablist = VueJSX.IntrinsicElementAttributes['div']
88
87
  export type QwikTablist = QwikJSX.IntrinsicElements['div']
89
- export type ReactTablist = ReactJSX.IntrinsicElements['div']
88
+ export type ReactTablist = ReactJSX.IntrinsicElements['div'] & { class?: string }
90
89
  export type SolidJSTablist = SolidJSX.HTMLElementTags['div']
91
90
  export type SvelteTablist = SvelteHTMLElements['div']
92
91
 
@@ -96,10 +95,9 @@ declare module '@builder.io/qwik/jsx-runtime' { export namespace JSX { export in
96
95
  declare global { namespace React.JSX { interface IntrinsicElements { 'u-tablist': ReactTablist } } }
97
96
  declare module 'solid-js' { namespace JSX { interface IntrinsicElements { 'u-tablist': SolidJSTablist } } }
98
97
  declare module 'svelte/elements' { interface SvelteHTMLElements { 'u-tablist': SvelteTablist } }
99
-
100
98
  export type VueTab = VueJSX.IntrinsicElementAttributes['div']
101
99
  export type QwikTab = QwikJSX.IntrinsicElements['div']
102
- export type ReactTab = ReactJSX.IntrinsicElements['div']
100
+ export type ReactTab = ReactJSX.IntrinsicElements['div'] & { class?: string }
103
101
  export type SolidJSTab = SolidJSX.HTMLElementTags['div']
104
102
  export type SvelteTab = SvelteHTMLElements['div']
105
103
 
@@ -109,10 +107,9 @@ declare module '@builder.io/qwik/jsx-runtime' { export namespace JSX { export in
109
107
  declare global { namespace React.JSX { interface IntrinsicElements { 'u-tab': ReactTab } } }
110
108
  declare module 'solid-js' { namespace JSX { interface IntrinsicElements { 'u-tab': SolidJSTab } } }
111
109
  declare module 'svelte/elements' { interface SvelteHTMLElements { 'u-tab': SvelteTab } }
112
-
113
110
  export type VueTabpanel = VueJSX.IntrinsicElementAttributes['div']
114
111
  export type QwikTabpanel = QwikJSX.IntrinsicElements['div']
115
- export type ReactTabpanel = ReactJSX.IntrinsicElements['div']
112
+ export type ReactTabpanel = ReactJSX.IntrinsicElements['div'] & { class?: string }
116
113
  export type SolidJSTabpanel = SolidJSX.HTMLElementTags['div']
117
114
  export type SvelteTabpanel = SvelteHTMLElements['div']
118
115
 
package/dist/u-tabs.d.ts CHANGED
@@ -39,7 +39,7 @@ declare class UHTMLTabListElement extends UHTMLElement {
39
39
  * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/tab_role)
40
40
  */
41
41
  declare class UHTMLTabElement extends UHTMLElement {
42
- static get observedAttributes(): string[];
42
+ static observedAttributes: string[];
43
43
  constructor();
44
44
  connectedCallback(): void;
45
45
  attributeChangedCallback(_name: string, prev: string, next: string): void;
@@ -56,7 +56,7 @@ declare class UHTMLTabElement extends UHTMLElement {
56
56
  * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/tabpanel_role)
57
57
  */
58
58
  declare class UHTMLTabPanelElement extends UHTMLElement {
59
- static get observedAttributes(): string[];
59
+ static observedAttributes: string[];
60
60
  constructor();
61
61
  connectedCallback(): void;
62
62
  attributeChangedCallback(_name: string, prev: string, next: string): void;
@@ -65,15 +65,15 @@ declare class UHTMLTabPanelElement extends UHTMLElement {
65
65
  }
66
66
 
67
67
  export { UHTMLTabElement, UHTMLTabListElement, UHTMLTabPanelElement, UHTMLTabsElement };
68
-
69
68
  import type * as VueJSX from '@vue/runtime-dom'
70
69
  import type { JSX as QwikJSX } from '@builder.io/qwik/jsx-runtime'
71
70
  import type { JSX as ReactJSX } from 'react'
72
71
  import type { JSX as SolidJSX } from 'solid-js'
73
72
  import type { SvelteHTMLElements } from 'svelte/elements'
73
+
74
74
  export type VueTabs = VueJSX.IntrinsicElementAttributes['div']
75
75
  export type QwikTabs = QwikJSX.IntrinsicElements['div']
76
- export type ReactTabs = ReactJSX.IntrinsicElements['div']
76
+ export type ReactTabs = ReactJSX.IntrinsicElements['div'] & { class?: string }
77
77
  export type SolidJSTabs = SolidJSX.HTMLElementTags['div']
78
78
  export type SvelteTabs = SvelteHTMLElements['div']
79
79
 
@@ -83,10 +83,9 @@ declare module '@builder.io/qwik/jsx-runtime' { export namespace JSX { export in
83
83
  declare global { namespace React.JSX { interface IntrinsicElements { 'u-tabs': ReactTabs } } }
84
84
  declare module 'solid-js' { namespace JSX { interface IntrinsicElements { 'u-tabs': SolidJSTabs } } }
85
85
  declare module 'svelte/elements' { interface SvelteHTMLElements { 'u-tabs': SvelteTabs } }
86
-
87
86
  export type VueTablist = VueJSX.IntrinsicElementAttributes['div']
88
87
  export type QwikTablist = QwikJSX.IntrinsicElements['div']
89
- export type ReactTablist = ReactJSX.IntrinsicElements['div']
88
+ export type ReactTablist = ReactJSX.IntrinsicElements['div'] & { class?: string }
90
89
  export type SolidJSTablist = SolidJSX.HTMLElementTags['div']
91
90
  export type SvelteTablist = SvelteHTMLElements['div']
92
91
 
@@ -96,10 +95,9 @@ declare module '@builder.io/qwik/jsx-runtime' { export namespace JSX { export in
96
95
  declare global { namespace React.JSX { interface IntrinsicElements { 'u-tablist': ReactTablist } } }
97
96
  declare module 'solid-js' { namespace JSX { interface IntrinsicElements { 'u-tablist': SolidJSTablist } } }
98
97
  declare module 'svelte/elements' { interface SvelteHTMLElements { 'u-tablist': SvelteTablist } }
99
-
100
98
  export type VueTab = VueJSX.IntrinsicElementAttributes['div']
101
99
  export type QwikTab = QwikJSX.IntrinsicElements['div']
102
- export type ReactTab = ReactJSX.IntrinsicElements['div']
100
+ export type ReactTab = ReactJSX.IntrinsicElements['div'] & { class?: string }
103
101
  export type SolidJSTab = SolidJSX.HTMLElementTags['div']
104
102
  export type SvelteTab = SvelteHTMLElements['div']
105
103
 
@@ -109,10 +107,9 @@ declare module '@builder.io/qwik/jsx-runtime' { export namespace JSX { export in
109
107
  declare global { namespace React.JSX { interface IntrinsicElements { 'u-tab': ReactTab } } }
110
108
  declare module 'solid-js' { namespace JSX { interface IntrinsicElements { 'u-tab': SolidJSTab } } }
111
109
  declare module 'svelte/elements' { interface SvelteHTMLElements { 'u-tab': SvelteTab } }
112
-
113
110
  export type VueTabpanel = VueJSX.IntrinsicElementAttributes['div']
114
111
  export type QwikTabpanel = QwikJSX.IntrinsicElements['div']
115
- export type ReactTabpanel = ReactJSX.IntrinsicElements['div']
112
+ export type ReactTabpanel = ReactJSX.IntrinsicElements['div'] & { class?: string }
116
113
  export type SolidJSTabpanel = SolidJSX.HTMLElementTags['div']
117
114
  export type SvelteTabpanel = SvelteHTMLElements['div']
118
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(window.navigator.userAgent);
4
- var ARIA_CONTROLS = "aria-controls";
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 bind = (element, rest, action) => rest[0].split(",").forEach((type) => {
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) => bind(element, rest, "add");
15
- var off = (element, ...rest) => bind(element, rest, "remove");
12
+ var on = (element, ...rest) => events("add", element, rest);
13
+ var off = (element, ...rest) => events("remove", element, rest);
16
14
  var attachStyle = (element, css) => element.attachShadow({ mode: "closed" }).append(
17
15
  createElement("slot"),
18
16
  // Unnamed slot does automatically render all top element nodes
19
17
  createElement("style", { textContent: css })
20
18
  );
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
- }
33
19
  var asButton = (event) => {
34
20
  const isClick = "key" in event && (event.key === " " || event.key === "Enter");
35
21
  if (isClick)
@@ -40,13 +26,14 @@ var asButton = (event) => {
40
26
  };
41
27
  var getRoot = (node) => node.getRootNode();
42
28
  var id = 0;
43
- var useId = (el) => el ? el.id || (el.id = `:${el.nodeName.toLowerCase()}${(++id).toString(32)}`) : void 0;
29
+ var useId = (el) => el ? el.id || (el.id = `:${el.nodeName.toLowerCase()}${(++id).toString(32)}`) : "";
44
30
  var createElement = (tagName, props) => Object.assign(document.createElement(tagName), props);
45
31
  var customElements = {
46
32
  define: (name, instance) => !IS_BROWSER || window.customElements.get(name) || window.customElements.define(name, instance)
47
33
  };
48
34
 
49
35
  // u-tabs.ts
36
+ var ARIA_CONTROLS = "aria-controls";
50
37
  var UHTMLTabsElement = class extends UHTMLElement {
51
38
  constructor() {
52
39
  super();
@@ -56,10 +43,10 @@ var UHTMLTabsElement = class extends UHTMLElement {
56
43
  return queryWithoutNested("u-tablist", this)[0] || null;
57
44
  }
58
45
  get selectedIndex() {
59
- return [...this.tabs].findIndex((tab) => attr(tab, ARIA_SELECTED) === "true");
46
+ return [...this.tabs].findIndex((tab) => tab.ariaSelected === "true");
60
47
  }
61
48
  set selectedIndex(index) {
62
- attr(this.tabs[index], ARIA_SELECTED, true);
49
+ this.tabs[index].ariaSelected = "true";
63
50
  }
64
51
  get tabs() {
65
52
  return queryWithoutNested("u-tab", this);
@@ -74,7 +61,7 @@ var UHTMLTabListElement = class extends UHTMLElement {
74
61
  attachStyle(this, DISPLAY_BLOCK);
75
62
  }
76
63
  connectedCallback() {
77
- attr(this, "role", "tablist");
64
+ this.role = "tablist";
78
65
  on(this, "click,keydown", this);
79
66
  }
80
67
  disconnectedCallback() {
@@ -107,41 +94,42 @@ var UHTMLTabListElement = class extends UHTMLElement {
107
94
  return this.closest("u-tabs");
108
95
  }
109
96
  };
110
- var skipAttrChange = false;
97
+ var SKIP_ATTR_CHANGE = false;
111
98
  var UHTMLTabElement = class extends UHTMLElement {
112
- static get observedAttributes() {
113
- return ["id", ARIA_SELECTED, ARIA_CONTROLS];
114
- }
115
99
  constructor() {
116
100
  super();
117
- attachStyle(this, `:host(:not([hidden])) { cursor: pointer; display: inline-block }`);
101
+ attachStyle(
102
+ this,
103
+ `:host(:not([hidden])) { cursor: pointer; display: inline-block }`
104
+ );
118
105
  }
119
106
  connectedCallback() {
120
107
  this.selected = !!this.selected;
121
108
  }
122
109
  attributeChangedCallback(_name, prev, next) {
123
- if (!skipAttrChange && prev !== next && (skipAttrChange = true)) {
110
+ if (!SKIP_ATTR_CHANGE && prev !== next && (SKIP_ATTR_CHANGE = true)) {
124
111
  const { tabs = [], panels = [], selectedIndex } = this.tabsElement || {};
125
112
  const selected = this.selected ? this : tabs[selectedIndex || 0] || this;
126
113
  let selectedPanel;
127
- panels.forEach((panel) => attr(panel, { [ARIA_LABELLEDBY]: null, hidden: "" }));
114
+ panels.forEach((panel) => {
115
+ panel.removeAttribute(SAFE_LABELLEDBY);
116
+ panel.hidden = true;
117
+ });
128
118
  tabs.forEach((tab, index) => {
129
- const tabindex = selected === tab ? 0 : -1;
130
119
  const panel = getPanel(tab) || panels[index] || null;
131
- if (!tabindex && panel)
120
+ if (selected === tab && panel)
132
121
  selectedPanel = panel;
133
- attr(tab, {
134
- [ARIA_SELECTED]: !tabindex,
135
- [ARIA_CONTROLS]: useId(panel),
136
- role: "tab",
137
- tabindex
138
- });
139
- attr(panel, {
140
- [ARIA_LABELLEDBY]: useId(selectedPanel === panel ? selected : tab),
141
- hidden: selectedPanel === panel ? null : ""
142
- });
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
+ );
143
131
  });
144
- skipAttrChange = false;
132
+ SKIP_ATTR_CHANGE = false;
145
133
  }
146
134
  }
147
135
  get tabsElement() {
@@ -151,10 +139,10 @@ var UHTMLTabElement = class extends UHTMLElement {
151
139
  return this.closest("u-tablist");
152
140
  }
153
141
  get selected() {
154
- return attr(this, ARIA_SELECTED) === "true";
142
+ return this.ariaSelected === "true";
155
143
  }
156
144
  set selected(value) {
157
- attr(this, ARIA_SELECTED, !!value);
145
+ this.ariaSelected = `${value}`;
158
146
  }
159
147
  /** Retrieves the ordinal position of an tab in a tablist. */
160
148
  get index() {
@@ -164,22 +152,20 @@ var UHTMLTabElement = class extends UHTMLElement {
164
152
  return getPanel(this);
165
153
  }
166
154
  };
155
+ UHTMLTabElement.observedAttributes = ["id", "aria-selected", ARIA_CONTROLS];
167
156
  var UHTMLTabPanelElement = class extends UHTMLElement {
168
- static get observedAttributes() {
169
- return ["id"];
170
- }
171
157
  constructor() {
172
158
  super();
173
159
  attachStyle(this, DISPLAY_BLOCK);
174
160
  }
175
161
  connectedCallback() {
176
- attr(this, "role", "tabpanel");
162
+ this.role = "tabpanel";
177
163
  this.hidden = Array.from(this.tabs).every((tab) => !tab.selected);
178
164
  }
179
165
  attributeChangedCallback(_name, prev, next) {
180
- if (!skipAttrChange && prev !== next) {
181
- Array.from(getTabs(this, prev), (tab) => attr(tab, ARIA_CONTROLS, next));
182
- }
166
+ if (SKIP_ATTR_CHANGE || prev === next)
167
+ return;
168
+ getTabs(this, prev).forEach((tab) => tab.setAttribute(ARIA_CONTROLS, next));
183
169
  }
184
170
  get tabsElement() {
185
171
  return this.closest("u-tabs");
@@ -188,12 +174,13 @@ var UHTMLTabPanelElement = class extends UHTMLElement {
188
174
  return getTabs(this, this.id);
189
175
  }
190
176
  };
177
+ UHTMLTabPanelElement.observedAttributes = ["id"];
191
178
  var queryWithoutNested = (tag, self) => {
192
179
  const selector = `${tag}:not(:scope ${self.nodeName}:not(:scope) ${tag})`;
193
180
  return self.querySelectorAll(selector);
194
181
  };
195
182
  var getPanel = (self) => {
196
- const css = `u-tabpanel[id="${attr(self, ARIA_CONTROLS)}"]`;
183
+ const css = `u-tabpanel[id="${self.getAttribute(ARIA_CONTROLS)}"]`;
197
184
  return getRoot(self).querySelector(css) || document.querySelector(css);
198
185
  };
199
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
  ]
@@ -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": [{ "name": "id", "values": [] }],
20
+ "attributes": [
21
+ { "name": "id", "values": [] },
22
+ { "name": "aria-selected", "values": [] }
23
+ ],
21
24
  "references": []
22
25
  },
23
26
  {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@u-elements/u-tabs",
3
- "version": "0.0.1",
3
+ "version": "0.0.2",
4
4
  "license": "MIT",
5
5
  "description": "HTML tags, just truly accessible",
6
6
  "homepage": "https://u-elements.github.io/u-elements/",