@u-elements/u-tabs 0.0.5 → 0.0.7

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
@@ -3,20 +3,30 @@
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
+ IS_BROWSER && // @ts-expect-error Typescript has not implemented userAgentData yet https://stackoverflow.com/a/71392474
7
+ /^Mac/i.test(navigator.userAgentData?.platform || navigator.platform);
6
8
  var SAFE_LABELLEDBY = `${IS_ANDROID ? "data" : "aria"}-labelledby`;
7
9
  var DISPLAY_BLOCK = ":host(:not([hidden])) { display: block }";
8
10
  var UHTMLElement = typeof HTMLElement === "undefined" ? class {
9
11
  } : HTMLElement;
10
- var events = (action, element, rest) => rest[0].split(",").forEach((type) => {
11
- rest[0] = type;
12
- Element.prototype[`${action}EventListener`].apply(element, rest);
13
- });
12
+ function attr(el, name, value) {
13
+ if (value === void 0) return el?.getAttribute(name) ?? null;
14
+ if (value === null) el?.removeAttribute(name);
15
+ else if (el?.getAttribute(name) !== value) el?.setAttribute(name, value);
16
+ return null;
17
+ }
18
+ var events = (action, element, rest) => {
19
+ for (const type of rest[0].split(",")) {
20
+ rest[0] = type;
21
+ Element.prototype[`${action}EventListener`].apply(element, rest);
22
+ }
23
+ };
14
24
  var on = (element, ...rest) => events("add", element, rest);
15
25
  var off = (element, ...rest) => events("remove", element, rest);
16
- var attachStyle = (element, css) => element.attachShadow({ mode: "closed" }).append(
26
+ var attachStyle = (element, css) => element.attachShadow({ mode: "open" }).append(
17
27
  createElement("slot"),
18
28
  // Unnamed slot does automatically render all top element nodes
19
- createElement("style", { textContent: css })
29
+ createElement("style", css)
20
30
  );
21
31
  var asButton = (event) => {
22
32
  const isClick = "key" in event && (event.key === " " || event.key === "Enter");
@@ -24,10 +34,21 @@ var asButton = (event) => {
24
34
  if (isClick && event.target instanceof HTMLElement) event.target.click();
25
35
  return isClick;
26
36
  };
27
- var getRoot = (node) => node.getRootNode();
37
+ var getRoot = (node) => {
38
+ const root = node.getRootNode?.() || node.ownerDocument;
39
+ return root instanceof Document || root instanceof ShadowRoot ? root : document;
40
+ };
28
41
  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);
42
+ var useId = (el) => {
43
+ if (!el) return "";
44
+ if (!el.id) el.id = `:${el.nodeName.toLowerCase()}${(++id).toString(32)}`;
45
+ return el.id;
46
+ };
47
+ var createElement = (tagName, text, attrs) => {
48
+ const el = document.createElement(tagName);
49
+ if (text) el.textContent = text;
50
+ return el;
51
+ };
31
52
  var customElements = {
32
53
  define: (name, instance) => !IS_BROWSER || window.customElements.get(name) || window.customElements.define(name, instance)
33
54
  };
@@ -46,7 +67,7 @@ var UHTMLTabsElement = class extends UHTMLElement {
46
67
  return getSelectedIndex(this.tabs);
47
68
  }
48
69
  set selectedIndex(index) {
49
- if (this.tabs[index]) this.tabs[index].ariaSelected = "true";
70
+ if (this.tabs[index]) attr(this.tabs[index], "aria-selected", "true");
50
71
  }
51
72
  get tabs() {
52
73
  return queryWithoutNested("u-tab", this);
@@ -61,7 +82,7 @@ var UHTMLTabListElement = class extends UHTMLElement {
61
82
  attachStyle(this, DISPLAY_BLOCK);
62
83
  }
63
84
  connectedCallback() {
64
- this.role = "tablist";
85
+ attr(this, "role", "tablist");
65
86
  on(this, "click,keydown", this);
66
87
  }
67
88
  disconnectedCallback() {
@@ -103,44 +124,49 @@ var UHTMLTabListElement = class extends UHTMLElement {
103
124
  return getSelectedIndex(this.tabs);
104
125
  }
105
126
  set selectedIndex(index) {
106
- if (this.tabs[index]) this.tabs[index].ariaSelected = "true";
127
+ if (this.tabs[index]) attr(this.tabs[index], "aria-selected", "true");
107
128
  }
108
129
  };
109
130
  var UHTMLTabElement = class extends UHTMLElement {
131
+ // Using ES2015 syntax for backwards compatibility
132
+ static get observedAttributes() {
133
+ return ["id", "aria-selected", ARIA_CONTROLS];
134
+ }
110
135
  constructor() {
111
136
  super();
112
137
  attachStyle(
113
138
  this,
114
- `:host(:not([hidden])) { cursor: pointer; display: inline-block }`
139
+ ":host(:not([hidden])) { cursor: pointer; display: inline-block }"
115
140
  );
116
141
  }
117
142
  connectedCallback() {
143
+ const panelId = !attr(this, ARIA_CONTROLS) && useId(getPanel(this));
118
144
  const selected = this.selected || ![...queryWithoutNested("u-tab", this.tabList || this)].some(isSelected);
119
- this.role = "tab";
145
+ attr(this, "aria-selected", `${selected}`);
146
+ attr(this, "role", "tab");
120
147
  this.tabIndex = selected ? 0 : -1;
121
- this.ariaSelected = `${selected}`;
122
- if (!this.hasAttribute(ARIA_CONTROLS))
123
- this.setAttribute(ARIA_CONTROLS, useId(getPanel(this)));
148
+ if (panelId) attr(this, ARIA_CONTROLS, panelId);
124
149
  }
125
150
  attributeChangedCallback(name, prev) {
126
151
  if (!this.selected) return;
127
152
  const nextPanel = getPanel(this);
128
153
  const nextPanelId = useId(nextPanel);
129
154
  if (name === "aria-selected" && this.tabList)
130
- queryWithoutNested("u-tab", this.tabList).forEach((tab) => {
155
+ for (const tab of queryWithoutNested("u-tab", this.tabList)) {
131
156
  if (tab !== this && isSelected(tab)) {
132
- getPanel(tab)?.setAttribute("hidden", "");
133
- tab.ariaSelected = "false";
157
+ const panel = getPanel(tab);
158
+ if (panel) panel.hidden = true;
159
+ attr(tab, "aria-selected", "false");
134
160
  tab.tabIndex = -1;
135
161
  }
136
- });
137
- if (name === ARIA_CONTROLS && prev)
138
- getPanel(this, prev)?.setAttribute("hidden", "");
139
- if (this.getAttribute(ARIA_CONTROLS) !== nextPanelId)
140
- this.setAttribute(ARIA_CONTROLS, nextPanelId);
162
+ }
163
+ const prevPanel = name === ARIA_CONTROLS && prev && getPanel(this, prev);
164
+ if (prevPanel) prevPanel.hidden = true;
165
+ if (nextPanelId && attr(this, ARIA_CONTROLS) !== nextPanelId)
166
+ attr(this, ARIA_CONTROLS, nextPanelId);
141
167
  this.tabIndex = 0;
142
- nextPanel?.setAttribute(SAFE_LABELLEDBY, useId(this));
143
- nextPanel?.removeAttribute("hidden");
168
+ if (nextPanel) attr(nextPanel, SAFE_LABELLEDBY, useId(this));
169
+ if (nextPanel) nextPanel.hidden = false;
144
170
  }
145
171
  get tabsElement() {
146
172
  return this.closest("u-tabs");
@@ -152,7 +178,7 @@ var UHTMLTabElement = class extends UHTMLElement {
152
178
  return isSelected(this);
153
179
  }
154
180
  set selected(value) {
155
- this.ariaSelected = `${!!value}`;
181
+ attr(this, "aria-selected", `${!!value}`);
156
182
  }
157
183
  /** Retrieves the ordinal position of an tab in a tablist. */
158
184
  get index() {
@@ -163,15 +189,24 @@ var UHTMLTabElement = class extends UHTMLElement {
163
189
  return getPanel(this);
164
190
  }
165
191
  };
166
- UHTMLTabElement.observedAttributes = ["id", "aria-selected", ARIA_CONTROLS];
167
192
  var UHTMLTabPanelElement = class extends UHTMLElement {
193
+ // Using ES2015 syntax for backwards compatibility
194
+ static get observedAttributes() {
195
+ return ["hidden"];
196
+ }
168
197
  constructor() {
169
198
  super();
170
199
  attachStyle(this, DISPLAY_BLOCK);
171
200
  }
172
201
  connectedCallback() {
202
+ attr(this, "role", "tabpanel");
173
203
  this.hidden = getSelectedIndex(this.tabs) === -1;
174
- this.role = "tabpanel";
204
+ this.attributeChangedCallback();
205
+ }
206
+ attributeChangedCallback() {
207
+ if (this.hidden || isFocusable(this.firstChild))
208
+ attr(this, "tabindex", null);
209
+ else this.tabIndex = 0;
175
210
  }
176
211
  get tabsElement() {
177
212
  return this.closest("u-tabs");
@@ -182,16 +217,19 @@ var UHTMLTabPanelElement = class extends UHTMLElement {
182
217
  return root.length ? root : document.querySelectorAll(css);
183
218
  }
184
219
  };
185
- var queryWithoutNested = (tag, self) => {
186
- const css = `${tag}:not(:scope ${self.nodeName}:not(:scope) ${tag})`;
187
- return self.querySelectorAll(css);
188
- };
189
- var isSelected = (tab) => tab.ariaSelected === "true";
220
+ var queryWithoutNested = (tag, self) => self.querySelectorAll(
221
+ `${tag}:not(:scope ${self.nodeName}:not(:scope) ${tag})`
222
+ );
223
+ var isSelected = (tab) => attr(tab, "aria-selected") === "true";
190
224
  var getSelectedIndex = (tabs) => [...tabs].findIndex(isSelected);
191
- var getPanel = (self, id2) => {
192
- const css = `u-tabpanel[id="${id2 || self.getAttribute(ARIA_CONTROLS)}"]`;
193
- const tabsElement = self.closest("u-tabs");
194
- return getRoot(self).querySelector(css) || document.querySelector(css) || tabsElement && queryWithoutNested("u-tabpanel", tabsElement)[[...queryWithoutNested("u-tab", tabsElement)].indexOf(self)] || null;
225
+ var isFocusable = (el) => el instanceof Element && !el.matches(':disabled,[tabindex^="-"]') && el.matches(
226
+ `[contenteditable],[controls],[href],[tabindex],input:not([type="hidden"]),select,textarea,button,summary,iframe`
227
+ );
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;
195
233
  };
196
234
  customElements.define("u-tabs", UHTMLTabsElement);
197
235
  customElements.define("u-tablist", UHTMLTabListElement);
package/dist/u-tabs.d.cts CHANGED
@@ -5,10 +5,10 @@ declare const UHTMLElement: {
5
5
 
6
6
  declare global {
7
7
  interface HTMLElementTagNameMap {
8
- 'u-tabs': UHTMLTabsElement;
9
- 'u-tablist': UHTMLTabListElement;
10
- 'u-tab': UHTMLTabElement;
11
- 'u-tabpanel': UHTMLTabPanelElement;
8
+ "u-tabs": UHTMLTabsElement;
9
+ "u-tablist": UHTMLTabListElement;
10
+ "u-tab": UHTMLTabElement;
11
+ "u-tabpanel": UHTMLTabPanelElement;
12
12
  }
13
13
  }
14
14
  /**
@@ -42,7 +42,7 @@ declare class UHTMLTabListElement extends UHTMLElement {
42
42
  * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/tab_role)
43
43
  */
44
44
  declare class UHTMLTabElement extends UHTMLElement {
45
- static observedAttributes: string[];
45
+ static get observedAttributes(): string[];
46
46
  constructor();
47
47
  connectedCallback(): void;
48
48
  attributeChangedCallback(name: string, prev: string): void;
@@ -59,8 +59,10 @@ declare class UHTMLTabElement extends UHTMLElement {
59
59
  * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/tabpanel_role)
60
60
  */
61
61
  declare class UHTMLTabPanelElement extends UHTMLElement {
62
+ static get observedAttributes(): string[];
62
63
  constructor();
63
64
  connectedCallback(): void;
65
+ attributeChangedCallback(): void;
64
66
  get tabsElement(): UHTMLTabsElement | null;
65
67
  get tabs(): NodeListOf<UHTMLTabElement>;
66
68
  }
package/dist/u-tabs.d.ts CHANGED
@@ -5,10 +5,10 @@ declare const UHTMLElement: {
5
5
 
6
6
  declare global {
7
7
  interface HTMLElementTagNameMap {
8
- 'u-tabs': UHTMLTabsElement;
9
- 'u-tablist': UHTMLTabListElement;
10
- 'u-tab': UHTMLTabElement;
11
- 'u-tabpanel': UHTMLTabPanelElement;
8
+ "u-tabs": UHTMLTabsElement;
9
+ "u-tablist": UHTMLTabListElement;
10
+ "u-tab": UHTMLTabElement;
11
+ "u-tabpanel": UHTMLTabPanelElement;
12
12
  }
13
13
  }
14
14
  /**
@@ -42,7 +42,7 @@ declare class UHTMLTabListElement extends UHTMLElement {
42
42
  * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/tab_role)
43
43
  */
44
44
  declare class UHTMLTabElement extends UHTMLElement {
45
- static observedAttributes: string[];
45
+ static get observedAttributes(): string[];
46
46
  constructor();
47
47
  connectedCallback(): void;
48
48
  attributeChangedCallback(name: string, prev: string): void;
@@ -59,8 +59,10 @@ declare class UHTMLTabElement extends UHTMLElement {
59
59
  * [MDN Reference](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/tabpanel_role)
60
60
  */
61
61
  declare class UHTMLTabPanelElement extends UHTMLElement {
62
+ static get observedAttributes(): string[];
62
63
  constructor();
63
64
  connectedCallback(): void;
65
+ attributeChangedCallback(): void;
64
66
  get tabsElement(): UHTMLTabsElement | null;
65
67
  get tabs(): NodeListOf<UHTMLTabElement>;
66
68
  }
package/dist/u-tabs.js CHANGED
@@ -1,20 +1,30 @@
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
+ IS_BROWSER && // @ts-expect-error Typescript has not implemented userAgentData yet https://stackoverflow.com/a/71392474
5
+ /^Mac/i.test(navigator.userAgentData?.platform || navigator.platform);
4
6
  var SAFE_LABELLEDBY = `${IS_ANDROID ? "data" : "aria"}-labelledby`;
5
7
  var DISPLAY_BLOCK = ":host(:not([hidden])) { display: block }";
6
8
  var UHTMLElement = typeof HTMLElement === "undefined" ? class {
7
9
  } : HTMLElement;
8
- var events = (action, element, rest) => rest[0].split(",").forEach((type) => {
9
- rest[0] = type;
10
- Element.prototype[`${action}EventListener`].apply(element, rest);
11
- });
10
+ function attr(el, name, value) {
11
+ if (value === void 0) return el?.getAttribute(name) ?? null;
12
+ if (value === null) el?.removeAttribute(name);
13
+ else if (el?.getAttribute(name) !== value) el?.setAttribute(name, value);
14
+ return null;
15
+ }
16
+ var events = (action, element, rest) => {
17
+ for (const type of rest[0].split(",")) {
18
+ rest[0] = type;
19
+ Element.prototype[`${action}EventListener`].apply(element, rest);
20
+ }
21
+ };
12
22
  var on = (element, ...rest) => events("add", element, rest);
13
23
  var off = (element, ...rest) => events("remove", element, rest);
14
- var attachStyle = (element, css) => element.attachShadow({ mode: "closed" }).append(
24
+ var attachStyle = (element, css) => element.attachShadow({ mode: "open" }).append(
15
25
  createElement("slot"),
16
26
  // Unnamed slot does automatically render all top element nodes
17
- createElement("style", { textContent: css })
27
+ createElement("style", css)
18
28
  );
19
29
  var asButton = (event) => {
20
30
  const isClick = "key" in event && (event.key === " " || event.key === "Enter");
@@ -22,10 +32,21 @@ var asButton = (event) => {
22
32
  if (isClick && event.target instanceof HTMLElement) event.target.click();
23
33
  return isClick;
24
34
  };
25
- var getRoot = (node) => node.getRootNode();
35
+ var getRoot = (node) => {
36
+ const root = node.getRootNode?.() || node.ownerDocument;
37
+ return root instanceof Document || root instanceof ShadowRoot ? root : document;
38
+ };
26
39
  var id = 0;
27
- var useId = (el) => el ? el.id || (el.id = `:${el.nodeName.toLowerCase()}${(++id).toString(32)}`) : "";
28
- var createElement = (tagName, props) => Object.assign(document.createElement(tagName), props);
40
+ var useId = (el) => {
41
+ if (!el) return "";
42
+ if (!el.id) el.id = `:${el.nodeName.toLowerCase()}${(++id).toString(32)}`;
43
+ return el.id;
44
+ };
45
+ var createElement = (tagName, text, attrs) => {
46
+ const el = document.createElement(tagName);
47
+ if (text) el.textContent = text;
48
+ return el;
49
+ };
29
50
  var customElements = {
30
51
  define: (name, instance) => !IS_BROWSER || window.customElements.get(name) || window.customElements.define(name, instance)
31
52
  };
@@ -44,7 +65,7 @@ var UHTMLTabsElement = class extends UHTMLElement {
44
65
  return getSelectedIndex(this.tabs);
45
66
  }
46
67
  set selectedIndex(index) {
47
- if (this.tabs[index]) this.tabs[index].ariaSelected = "true";
68
+ if (this.tabs[index]) attr(this.tabs[index], "aria-selected", "true");
48
69
  }
49
70
  get tabs() {
50
71
  return queryWithoutNested("u-tab", this);
@@ -59,7 +80,7 @@ var UHTMLTabListElement = class extends UHTMLElement {
59
80
  attachStyle(this, DISPLAY_BLOCK);
60
81
  }
61
82
  connectedCallback() {
62
- this.role = "tablist";
83
+ attr(this, "role", "tablist");
63
84
  on(this, "click,keydown", this);
64
85
  }
65
86
  disconnectedCallback() {
@@ -101,44 +122,49 @@ var UHTMLTabListElement = class extends UHTMLElement {
101
122
  return getSelectedIndex(this.tabs);
102
123
  }
103
124
  set selectedIndex(index) {
104
- if (this.tabs[index]) this.tabs[index].ariaSelected = "true";
125
+ if (this.tabs[index]) attr(this.tabs[index], "aria-selected", "true");
105
126
  }
106
127
  };
107
128
  var UHTMLTabElement = class extends UHTMLElement {
129
+ // Using ES2015 syntax for backwards compatibility
130
+ static get observedAttributes() {
131
+ return ["id", "aria-selected", ARIA_CONTROLS];
132
+ }
108
133
  constructor() {
109
134
  super();
110
135
  attachStyle(
111
136
  this,
112
- `:host(:not([hidden])) { cursor: pointer; display: inline-block }`
137
+ ":host(:not([hidden])) { cursor: pointer; display: inline-block }"
113
138
  );
114
139
  }
115
140
  connectedCallback() {
141
+ const panelId = !attr(this, ARIA_CONTROLS) && useId(getPanel(this));
116
142
  const selected = this.selected || ![...queryWithoutNested("u-tab", this.tabList || this)].some(isSelected);
117
- this.role = "tab";
143
+ attr(this, "aria-selected", `${selected}`);
144
+ attr(this, "role", "tab");
118
145
  this.tabIndex = selected ? 0 : -1;
119
- this.ariaSelected = `${selected}`;
120
- if (!this.hasAttribute(ARIA_CONTROLS))
121
- this.setAttribute(ARIA_CONTROLS, useId(getPanel(this)));
146
+ if (panelId) attr(this, ARIA_CONTROLS, panelId);
122
147
  }
123
148
  attributeChangedCallback(name, prev) {
124
149
  if (!this.selected) return;
125
150
  const nextPanel = getPanel(this);
126
151
  const nextPanelId = useId(nextPanel);
127
152
  if (name === "aria-selected" && this.tabList)
128
- queryWithoutNested("u-tab", this.tabList).forEach((tab) => {
153
+ for (const tab of queryWithoutNested("u-tab", this.tabList)) {
129
154
  if (tab !== this && isSelected(tab)) {
130
- getPanel(tab)?.setAttribute("hidden", "");
131
- tab.ariaSelected = "false";
155
+ const panel = getPanel(tab);
156
+ if (panel) panel.hidden = true;
157
+ attr(tab, "aria-selected", "false");
132
158
  tab.tabIndex = -1;
133
159
  }
134
- });
135
- if (name === ARIA_CONTROLS && prev)
136
- getPanel(this, prev)?.setAttribute("hidden", "");
137
- if (this.getAttribute(ARIA_CONTROLS) !== nextPanelId)
138
- this.setAttribute(ARIA_CONTROLS, nextPanelId);
160
+ }
161
+ const prevPanel = name === ARIA_CONTROLS && prev && getPanel(this, prev);
162
+ if (prevPanel) prevPanel.hidden = true;
163
+ if (nextPanelId && attr(this, ARIA_CONTROLS) !== nextPanelId)
164
+ attr(this, ARIA_CONTROLS, nextPanelId);
139
165
  this.tabIndex = 0;
140
- nextPanel?.setAttribute(SAFE_LABELLEDBY, useId(this));
141
- nextPanel?.removeAttribute("hidden");
166
+ if (nextPanel) attr(nextPanel, SAFE_LABELLEDBY, useId(this));
167
+ if (nextPanel) nextPanel.hidden = false;
142
168
  }
143
169
  get tabsElement() {
144
170
  return this.closest("u-tabs");
@@ -150,7 +176,7 @@ var UHTMLTabElement = class extends UHTMLElement {
150
176
  return isSelected(this);
151
177
  }
152
178
  set selected(value) {
153
- this.ariaSelected = `${!!value}`;
179
+ attr(this, "aria-selected", `${!!value}`);
154
180
  }
155
181
  /** Retrieves the ordinal position of an tab in a tablist. */
156
182
  get index() {
@@ -161,15 +187,24 @@ var UHTMLTabElement = class extends UHTMLElement {
161
187
  return getPanel(this);
162
188
  }
163
189
  };
164
- UHTMLTabElement.observedAttributes = ["id", "aria-selected", ARIA_CONTROLS];
165
190
  var UHTMLTabPanelElement = class extends UHTMLElement {
191
+ // Using ES2015 syntax for backwards compatibility
192
+ static get observedAttributes() {
193
+ return ["hidden"];
194
+ }
166
195
  constructor() {
167
196
  super();
168
197
  attachStyle(this, DISPLAY_BLOCK);
169
198
  }
170
199
  connectedCallback() {
200
+ attr(this, "role", "tabpanel");
171
201
  this.hidden = getSelectedIndex(this.tabs) === -1;
172
- this.role = "tabpanel";
202
+ this.attributeChangedCallback();
203
+ }
204
+ attributeChangedCallback() {
205
+ if (this.hidden || isFocusable(this.firstChild))
206
+ attr(this, "tabindex", null);
207
+ else this.tabIndex = 0;
173
208
  }
174
209
  get tabsElement() {
175
210
  return this.closest("u-tabs");
@@ -180,16 +215,19 @@ var UHTMLTabPanelElement = class extends UHTMLElement {
180
215
  return root.length ? root : document.querySelectorAll(css);
181
216
  }
182
217
  };
183
- var queryWithoutNested = (tag, self) => {
184
- const css = `${tag}:not(:scope ${self.nodeName}:not(:scope) ${tag})`;
185
- return self.querySelectorAll(css);
186
- };
187
- var isSelected = (tab) => tab.ariaSelected === "true";
218
+ var queryWithoutNested = (tag, self) => self.querySelectorAll(
219
+ `${tag}:not(:scope ${self.nodeName}:not(:scope) ${tag})`
220
+ );
221
+ var isSelected = (tab) => attr(tab, "aria-selected") === "true";
188
222
  var getSelectedIndex = (tabs) => [...tabs].findIndex(isSelected);
189
- var getPanel = (self, id2) => {
190
- const css = `u-tabpanel[id="${id2 || self.getAttribute(ARIA_CONTROLS)}"]`;
191
- const tabsElement = self.closest("u-tabs");
192
- return getRoot(self).querySelector(css) || document.querySelector(css) || tabsElement && queryWithoutNested("u-tabpanel", tabsElement)[[...queryWithoutNested("u-tab", tabsElement)].indexOf(self)] || null;
223
+ var isFocusable = (el) => el instanceof Element && !el.matches(':disabled,[tabindex^="-"]') && el.matches(
224
+ `[contenteditable],[controls],[href],[tabindex],input:not([type="hidden"]),select,textarea,button,summary,iframe`
225
+ );
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;
193
231
  };
194
232
  customElements.define("u-tabs", UHTMLTabsElement);
195
233
  customElements.define("u-tablist", UHTMLTabListElement);
@@ -181,6 +181,11 @@
181
181
  "readonly": true
182
182
  }
183
183
  ],
184
+ "attributes": [
185
+ {
186
+ "name": "hidden"
187
+ }
188
+ ],
184
189
  "superclass": {
185
190
  "name": "UHTMLElement",
186
191
  "module": "//Users/eirikbacker/Library/Mobile%20Documents/com~apple~CloudDocs/5-capra/u-elements/packages/utils"
@@ -26,7 +26,7 @@
26
26
  {
27
27
  "name": "u-tabpanel",
28
28
  "description": "The `<u-tabpanel>` HTML element is a container for the resources of layered content associated with a `<u-tab>`.\n[MDN Reference](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/Roles/tabpanel_role)\n---\n",
29
- "attributes": [],
29
+ "attributes": [{ "name": "hidden", "values": [] }],
30
30
  "references": []
31
31
  }
32
32
  ]
package/package.json CHANGED
@@ -1,25 +1,25 @@
1
1
  {
2
- "name": "@u-elements/u-tabs",
3
- "version": "0.0.5",
4
- "license": "MIT",
5
- "description": "HTML tags, just truly accessible",
6
- "homepage": "https://u-elements.github.io/u-elements/",
7
- "type": "module",
8
- "main": "dist/u-tabs.cjs",
9
- "module": "dist/u-tabs.js",
10
- "types": "dist/u-tabs.d.ts",
11
- "customElements": "dist/u-tabs.manifest.json",
12
- "files": [
13
- "dist"
14
- ],
15
- "repository": {
16
- "type": "git",
17
- "url": "https://github.com/u-elements/u-elements.git"
18
- },
19
- "bugs": {
20
- "url": "https://github.com/u-elements/u-elements/issues"
21
- },
22
- "scripts": {
23
- "build": "tsup --config ../../tsup.config.ts"
24
- }
2
+ "name": "@u-elements/u-tabs",
3
+ "version": "0.0.7",
4
+ "license": "MIT",
5
+ "description": "HTML tags, just truly accessible",
6
+ "homepage": "https://u-elements.github.io/u-elements/",
7
+ "type": "module",
8
+ "main": "dist/u-tabs.cjs",
9
+ "module": "dist/u-tabs.js",
10
+ "types": "dist/u-tabs.d.ts",
11
+ "customElements": "dist/u-tabs.manifest.json",
12
+ "files": [
13
+ "dist"
14
+ ],
15
+ "repository": {
16
+ "type": "git",
17
+ "url": "https://github.com/u-elements/u-elements.git"
18
+ },
19
+ "bugs": {
20
+ "url": "https://github.com/u-elements/u-elements/issues"
21
+ },
22
+ "scripts": {
23
+ "build": "tsup --config ../../tsup.config.ts"
24
+ }
25
25
  }