@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 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?.platform || navigator.platform);
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
- 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);
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
- const root = node.getRootNode?.() || node.ownerDocument;
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
- if (this.tabs[index]) attr(this.tabs[index], "aria-selected", "true");
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.getElementsByTagName("u-tab")];
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].selected = true;
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 queryWithoutNested("u-tab", this);
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
- if (this.tabs[index]) attr(this.tabs[index], "aria-selected", "true");
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", "aria-selected", ARIA_CONTROLS];
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
- if (panelId) attr(this, ARIA_CONTROLS, panelId);
149
- }
150
- attributeChangedCallback(name, prev) {
151
- if (!this.selected) return;
152
- const nextPanel = getPanel(this);
153
- const nextPanelId = useId(nextPanel);
154
- if (name === "aria-selected" && this.tabList)
155
- for (const tab of queryWithoutNested("u-tab", this.tabList)) {
156
- if (tab !== this && isSelected(tab)) {
157
- const panel = getPanel(tab);
158
- if (panel) panel.hidden = true;
159
- attr(tab, "aria-selected", "false");
160
- tab.tabIndex = -1;
161
- }
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);
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
- return this.closest("u-tablist");
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 isSelected(this);
199
+ return attr(this, ARIA_SELECTED) === "true";
179
200
  }
180
201
  set selected(value) {
181
- attr(this, "aria-selected", `${!!value}`);
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 ? [...queryWithoutNested("u-tab", tabList)].indexOf(this) : 0;
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
- const root = getRoot(this).querySelectorAll(css);
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
- `${tag}:not(:scope ${self.nodeName}:not(:scope) ${tag})`
222
- );
223
- var isSelected = (tab) => attr(tab, "aria-selected") === "true";
224
- var getSelectedIndex = (tabs) => [...tabs].findIndex(isSelected);
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: Event): void;
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(name: string, prev: string): void;
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: Event): void;
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(name: string, prev: string): void;
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?.platform || navigator.platform);
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
- 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);
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
- const root = node.getRootNode?.() || node.ownerDocument;
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
- if (this.tabs[index]) attr(this.tabs[index], "aria-selected", "true");
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.getElementsByTagName("u-tab")];
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].selected = true;
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 queryWithoutNested("u-tab", this);
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
- if (this.tabs[index]) attr(this.tabs[index], "aria-selected", "true");
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", "aria-selected", ARIA_CONTROLS];
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
- if (panelId) attr(this, ARIA_CONTROLS, panelId);
147
- }
148
- attributeChangedCallback(name, prev) {
149
- if (!this.selected) return;
150
- const nextPanel = getPanel(this);
151
- const nextPanelId = useId(nextPanel);
152
- if (name === "aria-selected" && this.tabList)
153
- for (const tab of queryWithoutNested("u-tab", this.tabList)) {
154
- if (tab !== this && isSelected(tab)) {
155
- const panel = getPanel(tab);
156
- if (panel) panel.hidden = true;
157
- attr(tab, "aria-selected", "false");
158
- tab.tabIndex = -1;
159
- }
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);
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
- return this.closest("u-tablist");
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 isSelected(this);
197
+ return attr(this, ARIA_SELECTED) === "true";
177
198
  }
178
199
  set selected(value) {
179
- attr(this, "aria-selected", `${!!value}`);
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 ? [...queryWithoutNested("u-tab", tabList)].indexOf(this) : 0;
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
- const root = getRoot(this).querySelectorAll(css);
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
- `${tag}:not(:scope ${self.nodeName}:not(:scope) ${tag})`
220
- );
221
- var isSelected = (tab) => attr(tab, "aria-selected") === "true";
222
- var getSelectedIndex = (tabs) => [...tabs].findIndex(isSelected);
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": "/Users/eirikbacker/Library/Mobile Documents/com~apple~CloudDocs/5-capra/u-elements/packages/u-tabs/u-tabs.ts",
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": "//Users/eirikbacker/Library/Mobile%20Documents/com~apple~CloudDocs/5-capra/u-elements/packages/utils"
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": "//Users/eirikbacker/Library/Mobile%20Documents/com~apple~CloudDocs/5-capra/u-elements/packages/utils"
97
+ "module": "/utils"
97
98
  },
98
99
  "tagName": "u-tablist",
99
100
  "customElement": true
100
101
  },
101
102
  {
102
103
  "kind": "class",
103
- "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)",
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": "//Users/eirikbacker/Library/Mobile%20Documents/com~apple~CloudDocs/5-capra/u-elements/packages/utils"
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": "//Users/eirikbacker/Library/Mobile%20Documents/com~apple~CloudDocs/5-capra/u-elements/packages/utils"
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": "/Users/eirikbacker/Library/Mobile Documents/com~apple~CloudDocs/5-capra/u-elements/packages/u-tabs/u-tabs.ts"
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": "/Users/eirikbacker/Library/Mobile Documents/com~apple~CloudDocs/5-capra/u-elements/packages/u-tabs/u-tabs.ts"
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": "/Users/eirikbacker/Library/Mobile Documents/com~apple~CloudDocs/5-capra/u-elements/packages/u-tabs/u-tabs.ts"
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": "/Users/eirikbacker/Library/Mobile Documents/com~apple~CloudDocs/5-capra/u-elements/packages/u-tabs/u-tabs.ts"
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": "/Users/eirikbacker/Library/Mobile Documents/com~apple~CloudDocs/5-capra/u-elements/packages/u-tabs/u-tabs.ts"
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": "/Users/eirikbacker/Library/Mobile Documents/com~apple~CloudDocs/5-capra/u-elements/packages/u-tabs/u-tabs.ts"
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": "/Users/eirikbacker/Library/Mobile Documents/com~apple~CloudDocs/5-capra/u-elements/packages/u-tabs/u-tabs.ts"
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": "/Users/eirikbacker/Library/Mobile Documents/com~apple~CloudDocs/5-capra/u-elements/packages/u-tabs/u-tabs.ts"
257
+ "module": "u-tabs.ts"
260
258
  }
261
259
  }
262
260
  ]
@@ -16,11 +16,8 @@
16
16
  },
17
17
  {
18
18
  "name": "u-tab",
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": [
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.7",
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
  }