@arun-dev/headless 4.6.0 → 4.7.0

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.
@@ -0,0 +1,255 @@
1
+ import {
2
+ byDocumentOrder,
3
+ rovingIndex
4
+ } from "../chunk-2S4XG4VD.js";
5
+ import {
6
+ anchorNameFor,
7
+ anchoredDataAttributes,
8
+ anchoredPopupStyle
9
+ } from "../chunk-HCOCPQXS.js";
10
+ import {
11
+ useControlled
12
+ } from "../chunk-UEIB3I3T.js";
13
+ import {
14
+ __export,
15
+ useRender
16
+ } from "../chunk-OQTWWZ4B.js";
17
+
18
+ // src/menu/index.parts.ts
19
+ var index_parts_exports = {};
20
+ __export(index_parts_exports, {
21
+ Item: () => MenuItem,
22
+ Popup: () => MenuPopup,
23
+ Root: () => MenuRoot,
24
+ Trigger: () => MenuTrigger
25
+ });
26
+
27
+ // src/menu/MenuRoot.tsx
28
+ import { useCallback, useId, useMemo, useRef, useState } from "react";
29
+
30
+ // src/menu/MenuRootContext.ts
31
+ import { createContext, useContext } from "react";
32
+ var MenuRootContext = createContext(null);
33
+ function useMenuRootContext(part) {
34
+ const context = useContext(MenuRootContext);
35
+ if (context === null) {
36
+ throw new Error(`<Menu.${part}> must be rendered inside <Menu.Root>.`);
37
+ }
38
+ return context;
39
+ }
40
+
41
+ // src/menu/MenuRoot.tsx
42
+ import { jsx } from "react/jsx-runtime";
43
+ function MenuRoot({
44
+ open: openProp,
45
+ defaultOpen,
46
+ onOpenChange,
47
+ focusableWhenDisabled = false,
48
+ children
49
+ }) {
50
+ const [open, setOpenState] = useControlled({
51
+ controlled: openProp,
52
+ default: defaultOpen ?? false,
53
+ name: "Menu.Root",
54
+ state: "open"
55
+ });
56
+ const setOpen = useCallback(
57
+ (next) => {
58
+ if (next === open) return;
59
+ setOpenState(next);
60
+ onOpenChange?.(next);
61
+ },
62
+ [open, setOpenState, onOpenChange]
63
+ );
64
+ const [items, setItems] = useState([]);
65
+ const register = useCallback((entry) => {
66
+ setItems((current) => [...current, entry].sort(byDocumentOrder));
67
+ return () => setItems((current) => current.filter((i) => i !== entry));
68
+ }, []);
69
+ const navigableItems = useMemo(
70
+ () => focusableWhenDisabled ? items : items.filter((i) => !i.disabled),
71
+ [items, focusableWhenDisabled]
72
+ );
73
+ const id = useId();
74
+ const triggerRef = useRef(null);
75
+ const focusOnOpenRef = useRef("first");
76
+ const context = useMemo(
77
+ () => ({
78
+ open,
79
+ setOpen,
80
+ navigableItems,
81
+ focusableWhenDisabled,
82
+ register,
83
+ focusOnOpenRef,
84
+ triggerId: `${id}-trigger`,
85
+ popupId: `${id}-popup`,
86
+ anchorName: anchorNameFor(id),
87
+ triggerRef
88
+ }),
89
+ [open, setOpen, navigableItems, focusableWhenDisabled, register, id]
90
+ );
91
+ return /* @__PURE__ */ jsx(MenuRootContext.Provider, { value: context, children });
92
+ }
93
+
94
+ // src/menu/menuDataAttributes.ts
95
+ function menuDataAttributes({ open }) {
96
+ return {
97
+ "data-open": open ? "" : void 0,
98
+ "data-closed": open ? void 0 : ""
99
+ };
100
+ }
101
+ function menuItemDataAttributes(disabled) {
102
+ return { "data-disabled": disabled ? "" : void 0 };
103
+ }
104
+
105
+ // src/menu/MenuTrigger.tsx
106
+ function MenuTrigger({ className, children, render, ...rest }) {
107
+ const { open, setOpen, focusOnOpenRef, triggerId, popupId, anchorName, triggerRef } = useMenuRootContext("Trigger");
108
+ return useRender({
109
+ render,
110
+ defaultTagName: "button",
111
+ props: {
112
+ type: "button",
113
+ id: triggerId,
114
+ "aria-haspopup": "menu",
115
+ "aria-expanded": open,
116
+ "aria-controls": popupId,
117
+ ...menuDataAttributes({ open }),
118
+ style: { anchorName },
119
+ className,
120
+ children,
121
+ ref: triggerRef,
122
+ onClick() {
123
+ focusOnOpenRef.current = "first";
124
+ setOpen(!open);
125
+ },
126
+ onKeyDown(event) {
127
+ if (event.key !== "ArrowDown" && event.key !== "ArrowUp") return;
128
+ event.preventDefault();
129
+ focusOnOpenRef.current = event.key === "ArrowUp" ? "last" : "first";
130
+ setOpen(true);
131
+ }
132
+ },
133
+ consumerProps: rest
134
+ });
135
+ }
136
+
137
+ // src/menu/MenuPopup.tsx
138
+ import { useEffect, useReducer, useRef as useRef2 } from "react";
139
+ function MenuPopup({
140
+ side = "bottom",
141
+ align = "start",
142
+ className,
143
+ children,
144
+ render,
145
+ ...rest
146
+ }) {
147
+ const {
148
+ open,
149
+ setOpen,
150
+ navigableItems,
151
+ focusOnOpenRef,
152
+ triggerId,
153
+ popupId,
154
+ anchorName,
155
+ triggerRef
156
+ } = useMenuRootContext("Popup");
157
+ const elementRef = useRef2(null);
158
+ const focusPendingRef = useRef2(false);
159
+ const [, resync] = useReducer((n) => n + 1, 0);
160
+ useEffect(() => {
161
+ const popup = elementRef.current;
162
+ if (!popup || typeof popup.showPopover !== "function") return;
163
+ const shown = popup.matches(":popover-open");
164
+ if (open && !shown) {
165
+ popup.showPopover({ source: triggerRef.current ?? void 0 });
166
+ if (!popup.matches(":popover-open")) setOpen(false);
167
+ else focusPendingRef.current = true;
168
+ } else if (!open && shown) {
169
+ focusPendingRef.current = false;
170
+ popup.hidePopover();
171
+ }
172
+ if (focusPendingRef.current && navigableItems.length > 0) {
173
+ focusPendingRef.current = false;
174
+ const target = focusOnOpenRef.current === "last" ? navigableItems.at(-1) : navigableItems[0];
175
+ target?.ref.current?.focus();
176
+ }
177
+ });
178
+ return useRender({
179
+ render,
180
+ defaultTagName: "div",
181
+ props: {
182
+ id: popupId,
183
+ popover: "auto",
184
+ role: "menu",
185
+ "aria-labelledby": triggerId,
186
+ ...anchoredDataAttributes(side, align),
187
+ ...menuDataAttributes({ open }),
188
+ style: anchoredPopupStyle(anchorName, side, align),
189
+ className,
190
+ children,
191
+ ref: elementRef,
192
+ onKeyDown(event) {
193
+ if (event.key === "Tab") {
194
+ setOpen(false);
195
+ return;
196
+ }
197
+ const current = navigableItems.findIndex((i) => i.ref.current === event.target);
198
+ if (current < 0 && event.target !== event.currentTarget) return;
199
+ const next = rovingIndex(event.key, {
200
+ count: navigableItems.length,
201
+ current,
202
+ orientation: "vertical",
203
+ rtl: false
204
+ });
205
+ if (next === null) return;
206
+ event.preventDefault();
207
+ navigableItems[next]?.ref.current?.focus();
208
+ },
209
+ onToggle(event) {
210
+ if (event.target !== event.currentTarget) return;
211
+ if (event.nativeEvent.newState !== "closed") return;
212
+ setOpen(false);
213
+ resync();
214
+ }
215
+ },
216
+ consumerProps: rest
217
+ });
218
+ }
219
+
220
+ // src/menu/MenuItem.tsx
221
+ import { useLayoutEffect, useRef as useRef3 } from "react";
222
+ function MenuItem({
223
+ disabled = false,
224
+ onClick,
225
+ className,
226
+ children,
227
+ render,
228
+ ...rest
229
+ }) {
230
+ const { setOpen, focusableWhenDisabled, register } = useMenuRootContext("Item");
231
+ const elementRef = useRef3(null);
232
+ useLayoutEffect(() => register({ disabled, ref: elementRef }), [register, disabled]);
233
+ return useRender({
234
+ render,
235
+ defaultTagName: "button",
236
+ props: {
237
+ type: "button",
238
+ role: "menuitem",
239
+ tabIndex: -1,
240
+ disabled: disabled && !focusableWhenDisabled || void 0,
241
+ "aria-disabled": disabled && focusableWhenDisabled || void 0,
242
+ ...menuItemDataAttributes(disabled),
243
+ className,
244
+ children,
245
+ ref: elementRef,
246
+ onClick() {
247
+ if (!disabled) setOpen(false);
248
+ }
249
+ },
250
+ consumerProps: disabled ? rest : { ...rest, onClick }
251
+ });
252
+ }
253
+ export {
254
+ index_parts_exports as Menu
255
+ };
@@ -36,6 +36,35 @@ __export(index_parts_exports, {
36
36
  // src/tabs/TabsRoot.tsx
37
37
  var import_react4 = require("react");
38
38
 
39
+ // src/core/rovingFocus.ts
40
+ function byDocumentOrder(a, b) {
41
+ const x = a.ref.current;
42
+ const y = b.ref.current;
43
+ if (!x || !y) return 0;
44
+ return x.compareDocumentPosition(y) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1;
45
+ }
46
+ function rovingIndex(key, {
47
+ count,
48
+ current,
49
+ orientation,
50
+ rtl
51
+ }) {
52
+ if (count === 0) return null;
53
+ const [prevKey, nextKey] = orientation === "vertical" ? ["ArrowUp", "ArrowDown"] : rtl ? ["ArrowRight", "ArrowLeft"] : ["ArrowLeft", "ArrowRight"];
54
+ switch (key) {
55
+ case nextKey:
56
+ return current < 0 ? 0 : (current + 1) % count;
57
+ case prevKey:
58
+ return current < 0 ? count - 1 : (current - 1 + count) % count;
59
+ case "Home":
60
+ return 0;
61
+ case "End":
62
+ return count - 1;
63
+ default:
64
+ return null;
65
+ }
66
+ }
67
+
39
68
  // src/core/useControlled.ts
40
69
  var import_react = require("react");
41
70
  function useControlled({
@@ -186,18 +215,13 @@ var import_jsx_runtime = require("react/jsx-runtime");
186
215
  function idPart(value) {
187
216
  return value.replace(/\s+/g, "_");
188
217
  }
189
- function documentOrder(a, b) {
190
- const x = a.ref.current;
191
- const y = b.ref.current;
192
- if (!x || !y) return 0;
193
- return x.compareDocumentPosition(y) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1;
194
- }
195
218
  function TabsRoot({
196
219
  value: valueProp,
197
220
  defaultValue,
198
221
  onValueChange,
199
222
  orientation = "horizontal",
200
223
  activationMode = "automatic",
224
+ focusableWhenDisabled: focusableWhenDisabledProp = false,
201
225
  className,
202
226
  children,
203
227
  render,
@@ -220,12 +244,16 @@ function TabsRoot({
220
244
  const [tabs, setTabs] = (0, import_react4.useState)([]);
221
245
  const register = (0, import_react4.useCallback)((entry) => {
222
246
  setTabs(
223
- (current) => [...current.filter((t) => t.value !== entry.value), entry].sort(documentOrder)
247
+ (current) => [...current.filter((t) => t.value !== entry.value), entry].sort(byDocumentOrder)
224
248
  );
225
249
  return () => setTabs((current) => current.filter((t) => t !== entry));
226
250
  }, []);
227
- const enabledTabs = (0, import_react4.useMemo)(() => tabs.filter((t) => !t.disabled), [tabs]);
228
- const tabStopValue = tabs.length === 0 ? value : (enabledTabs.find((t) => t.value === value) ?? enabledTabs[0])?.value;
251
+ const focusableWhenDisabled = focusableWhenDisabledProp && activationMode === "manual";
252
+ const navigableTabs = (0, import_react4.useMemo)(
253
+ () => focusableWhenDisabled ? tabs : tabs.filter((t) => !t.disabled),
254
+ [tabs, focusableWhenDisabled]
255
+ );
256
+ const tabStopValue = tabs.length === 0 ? value : (navigableTabs.find((t) => t.value === value) ?? navigableTabs[0])?.value;
229
257
  const baseId = (0, import_react4.useId)();
230
258
  const context = (0, import_react4.useMemo)(
231
259
  () => ({
@@ -233,13 +261,24 @@ function TabsRoot({
233
261
  setValue,
234
262
  orientation,
235
263
  activationMode,
236
- enabledTabs,
264
+ navigableTabs,
265
+ focusableWhenDisabled,
237
266
  tabStopValue,
238
267
  register,
239
268
  tabId: (v) => `${baseId}-tab-${idPart(v)}`,
240
269
  panelId: (v) => `${baseId}-panel-${idPart(v)}`
241
270
  }),
242
- [value, setValue, orientation, activationMode, enabledTabs, tabStopValue, register, baseId]
271
+ [
272
+ value,
273
+ setValue,
274
+ orientation,
275
+ activationMode,
276
+ navigableTabs,
277
+ focusableWhenDisabled,
278
+ tabStopValue,
279
+ register,
280
+ baseId
281
+ ]
243
282
  );
244
283
  const element = useRender({
245
284
  render,
@@ -252,33 +291,8 @@ function TabsRoot({
252
291
 
253
292
  // src/tabs/TabsList.tsx
254
293
  var import_react5 = require("react");
255
-
256
- // src/core/rovingFocus.ts
257
- function rovingIndex(key, {
258
- count,
259
- current,
260
- orientation,
261
- rtl
262
- }) {
263
- if (count === 0) return null;
264
- const [prevKey, nextKey] = orientation === "vertical" ? ["ArrowUp", "ArrowDown"] : rtl ? ["ArrowRight", "ArrowLeft"] : ["ArrowLeft", "ArrowRight"];
265
- switch (key) {
266
- case nextKey:
267
- return current < 0 ? 0 : (current + 1) % count;
268
- case prevKey:
269
- return current < 0 ? count - 1 : (current - 1 + count) % count;
270
- case "Home":
271
- return 0;
272
- case "End":
273
- return count - 1;
274
- default:
275
- return null;
276
- }
277
- }
278
-
279
- // src/tabs/TabsList.tsx
280
294
  function TabsList({ className, children, render, ...rest }) {
281
- const { orientation, enabledTabs } = useTabsRootContext("List");
295
+ const { orientation, navigableTabs } = useTabsRootContext("List");
282
296
  const elementRef = (0, import_react5.useRef)(null);
283
297
  return useRender({
284
298
  render,
@@ -292,19 +306,19 @@ function TabsList({ className, children, render, ...rest }) {
292
306
  children,
293
307
  ref: elementRef,
294
308
  onKeyDown(event) {
295
- const current = enabledTabs.findIndex((t) => t.ref.current === event.target);
309
+ const current = navigableTabs.findIndex((t) => t.ref.current === event.target);
296
310
  if (current < 0) return;
297
311
  const list = elementRef.current;
298
312
  const rtl = list ? getComputedStyle(list).direction === "rtl" : false;
299
313
  const next = rovingIndex(event.key, {
300
- count: enabledTabs.length,
314
+ count: navigableTabs.length,
301
315
  current,
302
316
  orientation,
303
317
  rtl
304
318
  });
305
319
  if (next === null) return;
306
320
  event.preventDefault();
307
- enabledTabs[next]?.ref.current?.focus();
321
+ navigableTabs[next]?.ref.current?.focus();
308
322
  }
309
323
  },
310
324
  consumerProps: rest
@@ -316,6 +330,7 @@ var import_react6 = require("react");
316
330
  function TabsTab({
317
331
  value,
318
332
  disabled = false,
333
+ onClick,
319
334
  className,
320
335
  children,
321
336
  render,
@@ -325,6 +340,7 @@ function TabsTab({
325
340
  value: selectedValue,
326
341
  setValue,
327
342
  activationMode,
343
+ focusableWhenDisabled,
328
344
  tabStopValue,
329
345
  register,
330
346
  tabId,
@@ -346,8 +362,10 @@ function TabsTab({
346
362
  "aria-selected": selected,
347
363
  "aria-controls": panelId(value),
348
364
  tabIndex: value === tabStopValue ? 0 : -1,
349
- // The platform keeps a disabled button out of focus and activation.
350
- disabled: disabled || void 0,
365
+ // The platform keeps a disabled button out of focus and activation. Focusable when
366
+ // disabled, it is aria-disabled instead, and activation is blocked here.
367
+ disabled: disabled && !focusableWhenDisabled || void 0,
368
+ "aria-disabled": disabled && focusableWhenDisabled || void 0,
351
369
  ...selectedDataAttributes(selected, disabled),
352
370
  className,
353
371
  children,
@@ -359,7 +377,8 @@ function TabsTab({
359
377
  if (activationMode === "automatic" && !disabled) setValue(value);
360
378
  }
361
379
  },
362
- consumerProps: rest
380
+ // A native `disabled` would block your onClick; aria-disabled does not, so it is left off.
381
+ consumerProps: disabled ? rest : { ...rest, onClick }
363
382
  });
364
383
  }
365
384
 
@@ -36,6 +36,13 @@ type TabsRootOwnProps = {
36
36
  * click. Manual suits panels that are slow to show.
37
37
  */
38
38
  activationMode?: TabsActivationMode;
39
+ /**
40
+ * Keeps disabled tabs in the arrow-key sequence, so a screen reader announces them as
41
+ * unavailable. They still cannot be selected. Only with `activationMode="manual"`: under
42
+ * `"automatic"` moving focus to a tab selects it, so disabled tabs are always skipped and
43
+ * this has no effect.
44
+ */
45
+ focusableWhenDisabled?: boolean;
39
46
  /** Element to render instead of the default `<div>`. Props and ref are merged onto it. */
40
47
  render?: ReactElement;
41
48
  /** Ref to the rendered element. Merged with any ref on the `render` element. */
@@ -52,7 +59,7 @@ type TabsRootProps = TabsRootOwnProps & Omit<ComponentPropsWithRef<'div'>, keyof
52
59
  * Each Tab registers its own `value` and `disabled` from its props; the Root never reads
53
60
  * them back from the DOM (decision 10). Elements are kept only to move focus to.
54
61
  */
55
- declare function TabsRoot({ value: valueProp, defaultValue, onValueChange, orientation, activationMode, className, children, render, ...rest }: TabsRootProps): react.JSX.Element;
62
+ declare function TabsRoot({ value: valueProp, defaultValue, onValueChange, orientation, activationMode, focusableWhenDisabled: focusableWhenDisabledProp, className, children, render, ...rest }: TabsRootProps): react.JSX.Element;
56
63
 
57
64
  type TabsListOwnProps = {
58
65
  /** Element to render instead of the default `<div>`. Props and ref are merged onto it. */
@@ -63,7 +70,8 @@ type TabsListOwnProps = {
63
70
  type TabsListProps = TabsListOwnProps & Omit<ComponentPropsWithRef<'div'>, keyof TabsListOwnProps>;
64
71
  /**
65
72
  * The tablist. Holds the keyboard: arrows along the orientation, wrapping at the ends,
66
- * Home and End — moving focus among the enabled tabs only. Whether focusing a tab also
73
+ * Home and End — moving focus among the enabled tabs, and the disabled ones too with
74
+ * `focusableWhenDisabled`. Whether focusing a tab also
67
75
  * selects it is the Tab's to decide, by `activationMode`.
68
76
  *
69
77
  * Name it with `aria-label` or `aria-labelledby` when the page has more than one.
@@ -73,7 +81,10 @@ declare function TabsList({ className, children, render, ...rest }: TabsListProp
73
81
  type TabsTabOwnProps = {
74
82
  /** Identifies this tab, and the Panel with the same `value`. */
75
83
  value: string;
76
- /** Skipped by the arrow keys and cannot be selected. */
84
+ /**
85
+ * Cannot be selected. Skipped by the arrow keys, unless the Root sets
86
+ * `focusableWhenDisabled` with `activationMode="manual"`.
87
+ */
77
88
  disabled?: boolean;
78
89
  /** Element to render instead of the default `<button>`. Props and ref are merged onto it. */
79
90
  render?: ReactElement;
@@ -89,7 +100,7 @@ type TabsTabProps = TabsTabOwnProps & Omit<ComponentPropsWithRef<'button'>, keyo
89
100
  * With `activationMode="automatic"` (the default) focus selects: the arrow keys change the
90
101
  * panel as they move. With `"manual"` they only move focus.
91
102
  */
92
- declare function TabsTab({ value, disabled, className, children, render, ...rest }: TabsTabProps): ReactElement<unknown, string | react.JSXElementConstructor<any>>;
103
+ declare function TabsTab({ value, disabled, onClick, className, children, render, ...rest }: TabsTabProps): ReactElement<unknown, string | react.JSXElementConstructor<any>>;
93
104
 
94
105
  type TabsPanelOwnProps = {
95
106
  /** The `value` of the Tab this panel belongs to. */
@@ -36,6 +36,13 @@ type TabsRootOwnProps = {
36
36
  * click. Manual suits panels that are slow to show.
37
37
  */
38
38
  activationMode?: TabsActivationMode;
39
+ /**
40
+ * Keeps disabled tabs in the arrow-key sequence, so a screen reader announces them as
41
+ * unavailable. They still cannot be selected. Only with `activationMode="manual"`: under
42
+ * `"automatic"` moving focus to a tab selects it, so disabled tabs are always skipped and
43
+ * this has no effect.
44
+ */
45
+ focusableWhenDisabled?: boolean;
39
46
  /** Element to render instead of the default `<div>`. Props and ref are merged onto it. */
40
47
  render?: ReactElement;
41
48
  /** Ref to the rendered element. Merged with any ref on the `render` element. */
@@ -52,7 +59,7 @@ type TabsRootProps = TabsRootOwnProps & Omit<ComponentPropsWithRef<'div'>, keyof
52
59
  * Each Tab registers its own `value` and `disabled` from its props; the Root never reads
53
60
  * them back from the DOM (decision 10). Elements are kept only to move focus to.
54
61
  */
55
- declare function TabsRoot({ value: valueProp, defaultValue, onValueChange, orientation, activationMode, className, children, render, ...rest }: TabsRootProps): react.JSX.Element;
62
+ declare function TabsRoot({ value: valueProp, defaultValue, onValueChange, orientation, activationMode, focusableWhenDisabled: focusableWhenDisabledProp, className, children, render, ...rest }: TabsRootProps): react.JSX.Element;
56
63
 
57
64
  type TabsListOwnProps = {
58
65
  /** Element to render instead of the default `<div>`. Props and ref are merged onto it. */
@@ -63,7 +70,8 @@ type TabsListOwnProps = {
63
70
  type TabsListProps = TabsListOwnProps & Omit<ComponentPropsWithRef<'div'>, keyof TabsListOwnProps>;
64
71
  /**
65
72
  * The tablist. Holds the keyboard: arrows along the orientation, wrapping at the ends,
66
- * Home and End — moving focus among the enabled tabs only. Whether focusing a tab also
73
+ * Home and End — moving focus among the enabled tabs, and the disabled ones too with
74
+ * `focusableWhenDisabled`. Whether focusing a tab also
67
75
  * selects it is the Tab's to decide, by `activationMode`.
68
76
  *
69
77
  * Name it with `aria-label` or `aria-labelledby` when the page has more than one.
@@ -73,7 +81,10 @@ declare function TabsList({ className, children, render, ...rest }: TabsListProp
73
81
  type TabsTabOwnProps = {
74
82
  /** Identifies this tab, and the Panel with the same `value`. */
75
83
  value: string;
76
- /** Skipped by the arrow keys and cannot be selected. */
84
+ /**
85
+ * Cannot be selected. Skipped by the arrow keys, unless the Root sets
86
+ * `focusableWhenDisabled` with `activationMode="manual"`.
87
+ */
77
88
  disabled?: boolean;
78
89
  /** Element to render instead of the default `<button>`. Props and ref are merged onto it. */
79
90
  render?: ReactElement;
@@ -89,7 +100,7 @@ type TabsTabProps = TabsTabOwnProps & Omit<ComponentPropsWithRef<'button'>, keyo
89
100
  * With `activationMode="automatic"` (the default) focus selects: the arrow keys change the
90
101
  * panel as they move. With `"manual"` they only move focus.
91
102
  */
92
- declare function TabsTab({ value, disabled, className, children, render, ...rest }: TabsTabProps): ReactElement<unknown, string | react.JSXElementConstructor<any>>;
103
+ declare function TabsTab({ value, disabled, onClick, className, children, render, ...rest }: TabsTabProps): ReactElement<unknown, string | react.JSXElementConstructor<any>>;
93
104
 
94
105
  type TabsPanelOwnProps = {
95
106
  /** The `value` of the Tab this panel belongs to. */