@primitiv-ui/react 0.1.0 → 0.1.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.
Files changed (207) hide show
  1. package/LICENSE +21 -0
  2. package/package.json +2 -1
  3. package/src/AccessibleIcon/AccessibleIcon.tsx +6 -2
  4. package/src/AccessibleIcon/__tests__/AccessibleIcon.test.tsx +1 -1
  5. package/src/AccessibleIcon/types.ts +4 -0
  6. package/src/Accordion/Accordion.tsx +34 -12
  7. package/src/Accordion/AccordionContext.ts +1 -1
  8. package/src/Accordion/__tests__/Accordion.reading-direction.test.tsx +1 -1
  9. package/src/Accordion/hooks/useAccordionItem.ts +1 -1
  10. package/src/Accordion/hooks/useAccordionRoot.ts +1 -1
  11. package/src/Accordion/hooks/useAccordionTrigger.ts +2 -2
  12. package/src/Accordion/index.ts +2 -1
  13. package/src/Accordion/types.ts +55 -13
  14. package/src/Alert/Alert.tsx +9 -2
  15. package/src/Alert/__tests__/Alert.test.tsx +1 -1
  16. package/src/Alert/types.ts +1 -0
  17. package/src/Avatar/Avatar.tsx +20 -7
  18. package/src/Avatar/AvatarContext.ts +12 -6
  19. package/src/Breadcrumb/Breadcrumb.tsx +32 -10
  20. package/src/Button/Button.tsx +5 -2
  21. package/src/Button/types.ts +4 -0
  22. package/src/Carousel/Carousel.tsx +30 -14
  23. package/src/Carousel/CarouselContext.ts +7 -3
  24. package/src/Carousel/__tests__/Carousel.asChild.test.tsx +1 -1
  25. package/src/Carousel/__tests__/Carousel.auto-play.test.tsx +1 -1
  26. package/src/Carousel/__tests__/Carousel.basic-rendering.test.tsx +1 -1
  27. package/src/Carousel/__tests__/Carousel.controlled-state.test.tsx +1 -1
  28. package/src/Carousel/__tests__/Carousel.error-handling.test.tsx +1 -1
  29. package/src/Carousel/__tests__/Carousel.ids.test.tsx +1 -1
  30. package/src/Carousel/__tests__/Carousel.imperative-api.test.tsx +2 -2
  31. package/src/Carousel/__tests__/Carousel.indicators.test.tsx +1 -1
  32. package/src/Carousel/__tests__/Carousel.intersection-observer.test.tsx +2 -2
  33. package/src/Carousel/__tests__/Carousel.keyboard-navigation.test.tsx +1 -1
  34. package/src/Carousel/__tests__/Carousel.play-pause.test.tsx +1 -1
  35. package/src/Carousel/__tests__/Carousel.prev-next.test.tsx +1 -1
  36. package/src/Carousel/__tests__/Carousel.reduced-motion.test.tsx +1 -1
  37. package/src/Carousel/__tests__/Carousel.refresh-progress.test.tsx +2 -2
  38. package/src/Carousel/__tests__/Carousel.scroll-snap-change.test.tsx +1 -1
  39. package/src/Carousel/__tests__/Carousel.scroll-sync.test.tsx +1 -1
  40. package/src/Carousel/__tests__/Carousel.slides-per-move.test.tsx +1 -1
  41. package/src/Carousel/__tests__/Carousel.slides-per-page.test.tsx +1 -1
  42. package/src/Carousel/__tests__/Carousel.touch-interaction.test.tsx +1 -1
  43. package/src/Carousel/__tests__/Carousel.transition-modes.test.tsx +1 -1
  44. package/src/Carousel/__tests__/Carousel.translations.test.tsx +1 -1
  45. package/src/Carousel/__tests__/Carousel.uncontrolled-state.test.tsx +1 -1
  46. package/src/Carousel/types.ts +8 -0
  47. package/src/Checkbox/Checkbox.tsx +11 -6
  48. package/src/Checkbox/CheckboxContext.ts +1 -1
  49. package/src/Checkbox/hooks/useCheckboxRoot.ts +1 -1
  50. package/src/Checkbox/index.ts +1 -0
  51. package/src/Checkbox/types.ts +30 -3
  52. package/src/CheckboxCard/CheckboxCard.tsx +13 -11
  53. package/src/CheckboxCard/CheckboxCardContext.ts +19 -6
  54. package/src/CheckboxCard/hooks/useCheckboxCardRoot.ts +2 -2
  55. package/src/CheckboxCard/types.ts +21 -5
  56. package/src/Collapsible/Collapsible.tsx +37 -21
  57. package/src/Collapsible/CollapsibleContext.ts +1 -1
  58. package/src/Collapsible/hooks/useCollapsibleRoot.ts +1 -1
  59. package/src/Collapsible/hooks/useCollapsibleTrigger.ts +1 -1
  60. package/src/Collapsible/index.ts +1 -0
  61. package/src/Collapsible/types.ts +45 -12
  62. package/src/ContextMenu/ContextMenu.tsx +60 -34
  63. package/src/ContextMenu/ContextMenuContext.ts +2 -2
  64. package/src/ContextMenu/ContextMenuSubContext.ts +1 -1
  65. package/src/ContextMenu/__tests__/ContextMenu.reading-direction.test.tsx +1 -1
  66. package/src/ContextMenu/index.ts +2 -1
  67. package/src/ContextMenu/types.ts +160 -17
  68. package/src/DirectionProvider/DirectionProvider.tsx +7 -1
  69. package/src/DirectionProvider/__tests__/DirectionProvider.test.tsx +1 -1
  70. package/src/DirectionProvider/types.ts +1 -0
  71. package/src/Divider/Divider.tsx +4 -1
  72. package/src/Divider/__tests__/Divider.test.tsx +1 -1
  73. package/src/Divider/index.ts +2 -1
  74. package/src/Divider/types.ts +5 -0
  75. package/src/Dropdown/Dropdown.tsx +60 -34
  76. package/src/Dropdown/DropdownContext.ts +2 -2
  77. package/src/Dropdown/DropdownSubContext.ts +1 -1
  78. package/src/Dropdown/__tests__/Dropdown.reading-direction.test.tsx +1 -1
  79. package/src/Dropdown/hooks/useDropdownContent.ts +1 -1
  80. package/src/Dropdown/hooks/useDropdownItem.ts +1 -1
  81. package/src/Dropdown/hooks/useDropdownRoot.ts +2 -2
  82. package/src/Dropdown/hooks/useDropdownTrigger.ts +1 -1
  83. package/src/Dropdown/index.ts +2 -1
  84. package/src/Dropdown/types.ts +153 -25
  85. package/src/EmptyState/EmptyState.tsx +34 -20
  86. package/src/EmptyState/__tests__/EmptyState.Actions.test.tsx +1 -1
  87. package/src/EmptyState/__tests__/EmptyState.Description.test.tsx +1 -1
  88. package/src/EmptyState/__tests__/EmptyState.Media.test.tsx +1 -1
  89. package/src/EmptyState/__tests__/EmptyState.Root.test.tsx +1 -1
  90. package/src/EmptyState/__tests__/EmptyState.Title.test.tsx +1 -1
  91. package/src/EmptyState/types.ts +2 -1
  92. package/src/Field/Field.tsx +24 -10
  93. package/src/Field/FieldContext.ts +1 -1
  94. package/src/Field/types.ts +4 -0
  95. package/src/Fieldset/Fieldset.tsx +26 -10
  96. package/src/Fieldset/types.ts +2 -0
  97. package/src/Input/Input.tsx +6 -3
  98. package/src/Input/__tests__/Input.field-integration.test.tsx +1 -1
  99. package/src/Input/types.ts +4 -0
  100. package/src/InputGroup/InputGroup.tsx +15 -8
  101. package/src/InputGroup/types.ts +9 -0
  102. package/src/MillerColumns/MillerColumns.tsx +28 -8
  103. package/src/MillerColumns/MillerColumnsContext.ts +1 -1
  104. package/src/MillerColumns/hooks/useMillerColumnsItem.ts +2 -2
  105. package/src/MillerColumns/hooks/useMillerColumnsRoot.ts +0 -0
  106. package/src/MillerColumns/index.ts +1 -1
  107. package/src/MillerColumns/types.ts +67 -14
  108. package/src/MillerColumns/useMillerColumnsSelection.ts +1 -1
  109. package/src/Modal/Modal.tsx +25 -11
  110. package/src/Modal/ModalContext.ts +14 -7
  111. package/src/Modal/hooks/useModalRoot.ts +1 -1
  112. package/src/Modal/hooks/useModalTrigger.ts +2 -2
  113. package/src/Modal/types.ts +51 -2
  114. package/src/Portal/Portal.tsx +3 -1
  115. package/src/Portal/types.ts +4 -0
  116. package/src/Progress/Progress.tsx +12 -7
  117. package/src/Progress/ProgressContext.ts +18 -6
  118. package/src/RadioCard/RadioCard.tsx +17 -11
  119. package/src/RadioCard/RadioCardContext.ts +17 -5
  120. package/src/RadioCard/RadioCardItemContext.ts +18 -5
  121. package/src/RadioCard/__tests__/RadioCard.reading-direction.test.tsx +1 -1
  122. package/src/RadioCard/hooks/useRadioCardRoot.ts +1 -1
  123. package/src/RadioCard/types.ts +24 -3
  124. package/src/RadioGroup/RadioGroup.tsx +17 -11
  125. package/src/RadioGroup/RadioGroupContext.ts +1 -1
  126. package/src/RadioGroup/RadioGroupItemContext.ts +1 -1
  127. package/src/RadioGroup/__tests__/RadioGroup.reading-direction.test.tsx +1 -1
  128. package/src/RadioGroup/hooks/useRadioGroupRoot.ts +1 -1
  129. package/src/RadioGroup/index.ts +1 -0
  130. package/src/RadioGroup/types.ts +34 -3
  131. package/src/Select/Select.tsx +23 -8
  132. package/src/Select/__tests__/Select.field-integration.test.tsx +1 -1
  133. package/src/Select/index.ts +1 -1
  134. package/src/Select/types.ts +18 -3
  135. package/src/SkipNav/SkipNav.tsx +7 -2
  136. package/src/SkipNav/__tests__/SkipNav.ids.test.tsx +1 -1
  137. package/src/Slider/Slider.tsx +26 -11
  138. package/src/Slider/SliderContext.ts +13 -6
  139. package/src/Slider/__tests__/Slider.reading-direction.test.tsx +1 -1
  140. package/src/Slider/hooks/useSliderRoot.ts +1 -1
  141. package/src/Slider/types.ts +12 -3
  142. package/src/Status/Status.tsx +9 -2
  143. package/src/Status/__tests__/Status.test.tsx +1 -1
  144. package/src/Status/types.ts +4 -0
  145. package/src/Switch/Switch.tsx +16 -6
  146. package/src/Switch/SwitchContext.ts +13 -5
  147. package/src/Switch/hooks/useSwitchRoot.ts +1 -1
  148. package/src/Switch/types.ts +24 -3
  149. package/src/Table/Table.tsx +51 -25
  150. package/src/Table/__tests__/Table.Body.test.tsx +1 -1
  151. package/src/Table/__tests__/Table.Caption.test.tsx +1 -1
  152. package/src/Table/__tests__/Table.Cell.test.tsx +1 -1
  153. package/src/Table/__tests__/Table.Footer.test.tsx +1 -1
  154. package/src/Table/__tests__/Table.Head.test.tsx +1 -1
  155. package/src/Table/__tests__/Table.Header.test.tsx +1 -1
  156. package/src/Table/__tests__/Table.Root.test.tsx +1 -1
  157. package/src/Table/__tests__/Table.Row.test.tsx +1 -1
  158. package/src/Table/__tests__/Table.ScrollArea.test.tsx +1 -1
  159. package/src/Table/index.ts +2 -1
  160. package/src/Tabs/Tabs.tsx +30 -10
  161. package/src/Tabs/TabsContext.ts +15 -7
  162. package/src/Tabs/__tests__/Tabs.asChild.test.tsx +1 -1
  163. package/src/Tabs/__tests__/Tabs.basic-rendering.test.tsx +1 -1
  164. package/src/Tabs/__tests__/Tabs.change-event-callbacks.test.tsx +1 -1
  165. package/src/Tabs/__tests__/Tabs.controlled-state.test.tsx +1 -1
  166. package/src/Tabs/__tests__/Tabs.error-handling.test.tsx +1 -1
  167. package/src/Tabs/__tests__/Tabs.imperative-api.test.tsx +1 -1
  168. package/src/Tabs/__tests__/Tabs.keyboard-interaction.test.tsx +1 -1
  169. package/src/Tabs/__tests__/Tabs.lazy-mount.test.tsx +1 -1
  170. package/src/Tabs/__tests__/Tabs.mouse-interaction.test.tsx +1 -1
  171. package/src/Tabs/__tests__/Tabs.reading-direction.test.tsx +1 -1
  172. package/src/Tabs/__tests__/Tabs.uncontrolled-state.test.tsx +1 -1
  173. package/src/Tabs/hooks/useTabsContent.ts +1 -1
  174. package/src/Tabs/hooks/useTabsRoot.ts +1 -1
  175. package/src/Tabs/hooks/useTabsTrigger.ts +1 -1
  176. package/src/Tabs/types.ts +35 -1
  177. package/src/Tabs/utils.ts +1 -1
  178. package/src/Textarea/Textarea.tsx +6 -3
  179. package/src/Textarea/__tests__/Textarea.field-integration.test.tsx +1 -1
  180. package/src/Textarea/types.ts +4 -0
  181. package/src/Toggle/Toggle.tsx +11 -4
  182. package/src/Toggle/types.ts +7 -3
  183. package/src/ToggleGroup/ToggleGroup.tsx +23 -13
  184. package/src/ToggleGroup/ToggleGroupContext.ts +1 -1
  185. package/src/ToggleGroup/__tests__/ToggleGroup.reading-direction.test.tsx +1 -1
  186. package/src/ToggleGroup/hooks/useToggleGroupRoot.ts +1 -1
  187. package/src/ToggleGroup/types.ts +45 -5
  188. package/src/Tooltip/Tooltip.tsx +46 -15
  189. package/src/Tooltip/TooltipContext.ts +1 -1
  190. package/src/Tooltip/hooks/useTooltipContent.ts +1 -1
  191. package/src/Tooltip/hooks/useTooltipRoot.ts +1 -1
  192. package/src/Tooltip/hooks/useTooltipTrigger.ts +1 -1
  193. package/src/Tooltip/index.ts +1 -0
  194. package/src/Tooltip/types.ts +50 -2
  195. package/src/Tree/Tree.tsx +58 -12
  196. package/src/Tree/TreeContext.ts +1 -1
  197. package/src/Tree/__tests__/Tree.selection-path.test.tsx +2 -2
  198. package/src/Tree/hooks/useTreeItemKeyboard.ts +1 -1
  199. package/src/Tree/hooks/useTreeRoot.ts +1 -1
  200. package/src/Tree/index.ts +1 -1
  201. package/src/Tree/types.ts +39 -7
  202. package/src/VisuallyHidden/VisuallyHidden.tsx +4 -2
  203. package/src/VisuallyHidden/__tests__/VisuallyHidden.test.tsx +1 -1
  204. package/src/VisuallyHidden/types.ts +4 -0
  205. package/src/index.ts +39 -38
  206. package/src/types.ts +1 -0
  207. package/src/utils/createStrictContext.ts +9 -5
@@ -1,25 +1,43 @@
1
1
  import { ButtonHTMLAttributes, ComponentProps, ReactNode, Ref } from "react";
2
2
 
3
- type SwitchRootBaseProps = Omit<
3
+ /** Props common to both controlled and uncontrolled `Switch.Root` modes. */
4
+ export type SwitchRootBaseProps = Omit<
4
5
  ButtonHTMLAttributes<HTMLButtonElement>,
5
6
  "type" | "role" | "aria-checked"
6
7
  > & {
8
+ /** Render the child element instead of the default `<button>`. */
7
9
  asChild?: boolean;
10
+ /** Ref to the rendered `<button>` element. */
8
11
  ref?: Ref<HTMLButtonElement>;
9
12
  };
10
13
 
11
- type SwitchRootUncontrolledProps = SwitchRootBaseProps & {
14
+ /**
15
+ * Props for `Switch.Root` in uncontrolled mode — the component owns the checked
16
+ * state. Pass `defaultChecked` to set the initial value; `checked` is forbidden.
17
+ */
18
+ export type SwitchRootUncontrolledProps = SwitchRootBaseProps & {
19
+ /** Initial checked state when uncontrolled. */
12
20
  defaultChecked?: boolean;
21
+ /** Forbidden in uncontrolled mode. */
13
22
  checked?: never;
23
+ /** Called whenever the checked state changes. */
14
24
  onCheckedChange?: (checked: boolean) => void;
15
25
  };
16
26
 
17
- type SwitchRootControlledProps = SwitchRootBaseProps & {
27
+ /**
28
+ * Props for `Switch.Root` in controlled mode — the parent owns the checked
29
+ * value. Pass `checked` and `onCheckedChange` together.
30
+ */
31
+ export type SwitchRootControlledProps = SwitchRootBaseProps & {
32
+ /** Forbidden in controlled mode. */
18
33
  defaultChecked?: never;
34
+ /** The controlled checked state. */
19
35
  checked: boolean;
36
+ /** Called whenever the component requests a checked-state change. */
20
37
  onCheckedChange: (checked: boolean) => void;
21
38
  };
22
39
 
40
+ /** Props for `Switch.Root` — discriminated controlled/uncontrolled union. */
23
41
  export type SwitchRootProps =
24
42
  | SwitchRootUncontrolledProps
25
43
  | SwitchRootControlledProps;
@@ -31,7 +49,10 @@ export type SwitchRootProps =
31
49
  */
32
50
  export type SwitchProps = SwitchRootProps;
33
51
 
52
+ /** Props for `Switch.Thumb`, the sliding indicator inside the track. */
34
53
  export type SwitchThumbProps = ComponentProps<"span"> & {
54
+ /** Optional thumb content. */
35
55
  children?: ReactNode;
56
+ /** Render the child element instead of the default `<span>`. */
36
57
  asChild?: boolean;
37
58
  };
@@ -1,3 +1,5 @@
1
+ import type { ReactElement } from "react";
2
+
1
3
  import {
2
4
  TableBodyProps,
3
5
  TableCaptionProps,
@@ -40,11 +42,12 @@ import {
40
42
  * </Table.Root>
41
43
  * ```
42
44
  */
43
- function Table({ children, ...rest }: TableRootProps) {
45
+ export function TableRoot({ children, ...rest }: TableRootProps): ReactElement {
44
46
  return <table {...rest}>{children}</table>;
45
47
  }
46
48
 
47
- Table.displayName = "Table";
49
+ /** @internal */
50
+ TableRoot.displayName = "Table";
48
51
 
49
52
  /**
50
53
  * Groups header rows inside a `<thead>` element.
@@ -63,10 +66,11 @@ Table.displayName = "Table";
63
66
  * </Table.Head>
64
67
  * ```
65
68
  */
66
- function TableHead({ children, ...rest }: TableHeadProps) {
69
+ export function TableHead({ children, ...rest }: TableHeadProps): ReactElement {
67
70
  return <thead {...rest}>{children}</thead>;
68
71
  }
69
72
 
73
+ /** @internal */
70
74
  TableHead.displayName = "TableHead";
71
75
 
72
76
  /**
@@ -87,10 +91,11 @@ TableHead.displayName = "TableHead";
87
91
  * </Table.Body>
88
92
  * ```
89
93
  */
90
- function TableBody({ children, ...rest }: TableBodyProps) {
94
+ export function TableBody({ children, ...rest }: TableBodyProps): ReactElement {
91
95
  return <tbody {...rest}>{children}</tbody>;
92
96
  }
93
97
 
98
+ /** @internal */
94
99
  TableBody.displayName = "TableBody";
95
100
 
96
101
  /**
@@ -110,10 +115,14 @@ TableBody.displayName = "TableBody";
110
115
  * </Table.Footer>
111
116
  * ```
112
117
  */
113
- function TableFooter({ children, ...rest }: TableFooterProps) {
118
+ export function TableFooter({
119
+ children,
120
+ ...rest
121
+ }: TableFooterProps): ReactElement {
114
122
  return <tfoot {...rest}>{children}</tfoot>;
115
123
  }
116
124
 
125
+ /** @internal */
117
126
  TableFooter.displayName = "TableFooter";
118
127
 
119
128
  /**
@@ -132,10 +141,11 @@ TableFooter.displayName = "TableFooter";
132
141
  * </Table.Row>
133
142
  * ```
134
143
  */
135
- function TableRow({ children, ...rest }: TableRowProps) {
144
+ export function TableRow({ children, ...rest }: TableRowProps): ReactElement {
136
145
  return <tr {...rest}>{children}</tr>;
137
146
  }
138
147
 
148
+ /** @internal */
139
149
  TableRow.displayName = "TableRow";
140
150
 
141
151
  /**
@@ -166,10 +176,14 @@ TableRow.displayName = "TableRow";
166
176
  * <Table.Header scope="row">Alice</Table.Header>
167
177
  * ```
168
178
  */
169
- function TableHeader({ children, ...rest }: TableHeaderProps) {
179
+ export function TableHeader({
180
+ children,
181
+ ...rest
182
+ }: TableHeaderProps): ReactElement {
170
183
  return <th {...rest}>{children}</th>;
171
184
  }
172
185
 
186
+ /** @internal */
173
187
  TableHeader.displayName = "TableHeader";
174
188
 
175
189
  /**
@@ -188,10 +202,11 @@ TableHeader.displayName = "TableHeader";
188
202
  * <Table.Cell colSpan={2}>Full-width note</Table.Cell>
189
203
  * ```
190
204
  */
191
- function TableCell({ children, ...rest }: TableCellProps) {
205
+ export function TableCell({ children, ...rest }: TableCellProps): ReactElement {
192
206
  return <td {...rest}>{children}</td>;
193
207
  }
194
208
 
209
+ /** @internal */
195
210
  TableCell.displayName = "TableCell";
196
211
 
197
212
  /**
@@ -222,7 +237,11 @@ TableCell.displayName = "TableCell";
222
237
  * </Table.ScrollArea>
223
238
  * ```
224
239
  */
225
- function TableScrollArea({ children, style, ...rest }: TableScrollAreaProps) {
240
+ export function TableScrollArea({
241
+ children,
242
+ style,
243
+ ...rest
244
+ }: TableScrollAreaProps): ReactElement {
226
245
  return (
227
246
  <div
228
247
  style={{
@@ -238,6 +257,7 @@ function TableScrollArea({ children, style, ...rest }: TableScrollAreaProps) {
238
257
  );
239
258
  }
240
259
 
260
+ /** @internal */
241
261
  TableScrollArea.displayName = "TableScrollArea";
242
262
 
243
263
  /**
@@ -273,11 +293,11 @@ TableScrollArea.displayName = "TableScrollArea";
273
293
  * </Table.Root>
274
294
  * ```
275
295
  */
276
- function TableCaption({
296
+ export function TableCaption({
277
297
  children,
278
298
  captionSide = "bottom",
279
299
  ...rest
280
- }: TableCaptionProps) {
300
+ }: TableCaptionProps): ReactElement {
281
301
  return (
282
302
  <caption style={{ captionSide }} {...rest}>
283
303
  {children}
@@ -285,10 +305,15 @@ function TableCaption({
285
305
  );
286
306
  }
287
307
 
308
+ /** @internal */
288
309
  TableCaption.displayName = "TableCaption";
289
310
 
290
- type TableCompound = typeof Table & {
291
- Root: typeof Table;
311
+ /**
312
+ * The shape of the exported `Table` value — callable as `Table.Root` and
313
+ * carrying every sub-component as a static property.
314
+ */
315
+ export type TableCompound = typeof TableRoot & {
316
+ Root: typeof TableRoot;
292
317
  Head: typeof TableHead;
293
318
  Body: typeof TableBody;
294
319
  Footer: typeof TableFooter;
@@ -299,18 +324,6 @@ type TableCompound = typeof Table & {
299
324
  Caption: typeof TableCaption;
300
325
  };
301
326
 
302
- const TableCompound: TableCompound = Object.assign(Table, {
303
- Root: Table,
304
- Head: TableHead,
305
- Body: TableBody,
306
- Footer: TableFooter,
307
- Row: TableRow,
308
- Header: TableHeader,
309
- Cell: TableCell,
310
- ScrollArea: TableScrollArea,
311
- Caption: TableCaption,
312
- });
313
-
314
327
  /**
315
328
  * Headless, accessible **Table** — a compound component wrapping standard
316
329
  * HTML table elements with zero styles.
@@ -375,6 +388,19 @@ const TableCompound: TableCompound = Object.assign(Table, {
375
388
  * @see {@link TableCaption} for caption placement and why it beats `aria-label`.
376
389
  * @see {@link TableScrollArea} for the horizontal-scroll style caveat.
377
390
  */
391
+ const TableCompound: TableCompound = Object.assign(TableRoot, {
392
+ Root: TableRoot,
393
+ Head: TableHead,
394
+ Body: TableBody,
395
+ Footer: TableFooter,
396
+ Row: TableRow,
397
+ Header: TableHeader,
398
+ Cell: TableCell,
399
+ ScrollArea: TableScrollArea,
400
+ Caption: TableCaption,
401
+ });
402
+
403
+ /** @internal */
378
404
  TableCompound.displayName = "Table";
379
405
 
380
406
  export { TableCompound as Table };
@@ -1,4 +1,4 @@
1
- import { Table } from "..";
1
+ import { Table } from "../index.ts";
2
2
  import { render, screen } from "@testing-library/react";
3
3
 
4
4
  describe("Table.Body rendering", () => {
@@ -1,4 +1,4 @@
1
- import { Table } from "..";
1
+ import { Table } from "../index.ts";
2
2
  import { render, screen } from "@testing-library/react";
3
3
 
4
4
  describe("Table.Caption rendering", () => {
@@ -1,4 +1,4 @@
1
- import { Table } from "..";
1
+ import { Table } from "../index.ts";
2
2
  import { render, screen } from "@testing-library/react";
3
3
 
4
4
  describe("Table.Cell rendering", () => {
@@ -1,4 +1,4 @@
1
- import { Table } from "..";
1
+ import { Table } from "../index.ts";
2
2
  import { render, screen } from "@testing-library/react";
3
3
 
4
4
  describe("Table.Footer rendering", () => {
@@ -1,4 +1,4 @@
1
- import { Table } from "..";
1
+ import { Table } from "../index.ts";
2
2
  import { render, screen } from "@testing-library/react";
3
3
 
4
4
  describe("Table.Head rendering", () => {
@@ -1,4 +1,4 @@
1
- import { Table } from "..";
1
+ import { Table } from "../index.ts";
2
2
  import { render, screen } from "@testing-library/react";
3
3
 
4
4
  describe("Table.Header rendering", () => {
@@ -1,4 +1,4 @@
1
- import { Table } from "..";
1
+ import { Table } from "../index.ts";
2
2
  import { render, screen } from "@testing-library/react";
3
3
 
4
4
  describe("Table.Root rendering", () => {
@@ -1,4 +1,4 @@
1
- import { Table } from "..";
1
+ import { Table } from "../index.ts";
2
2
  import { render, screen } from "@testing-library/react";
3
3
 
4
4
  describe("Table.Row rendering", () => {
@@ -1,4 +1,4 @@
1
- import { Table } from "..";
1
+ import { Table } from "../index.ts";
2
2
  import { render, screen } from "@testing-library/react";
3
3
 
4
4
  describe("Table.ScrollArea rendering", () => {
@@ -1 +1,2 @@
1
- export * from './Table';
1
+ export * from "./Table";
2
+ export * from "./types";
package/src/Tabs/Tabs.tsx CHANGED
@@ -1,14 +1,20 @@
1
1
  import { forwardRef, Ref } from "react";
2
+ import type {
3
+ ForwardRefExoticComponent,
4
+ PropsWithoutRef,
5
+ ReactElement,
6
+ RefAttributes,
7
+ } from "react";
2
8
 
3
- import { useDirection } from "../DirectionProvider";
4
- import { Slot, composeRefs } from "../Slot";
9
+ import { useDirection } from "../DirectionProvider/index.ts";
10
+ import { Slot, composeRefs } from "../Slot/index.ts";
5
11
 
6
12
  import {
7
13
  useTabsRoot,
8
14
  useTabsContext,
9
15
  useTabsTrigger,
10
16
  useTabsContent,
11
- } from "./hooks";
17
+ } from "./hooks/index.ts";
12
18
  import { TabsProvider } from "./TabsContext";
13
19
  import type {
14
20
  TabsRootProps,
@@ -96,7 +102,9 @@ import type {
96
102
  * <button onClick={() => ref.current?.setActiveTab("two")}>Go to two</button>
97
103
  * ```
98
104
  */
99
- const TabsRoot = forwardRef<TabsImperativeApi, TabsRootProps>(function TabsRoot(
105
+ export const TabsRoot: ForwardRefExoticComponent<
106
+ PropsWithoutRef<TabsRootProps> & RefAttributes<TabsImperativeApi>
107
+ > = forwardRef<TabsImperativeApi, TabsRootProps>(function TabsRoot(
100
108
  {
101
109
  className = "",
102
110
  orientation = "horizontal",
@@ -166,7 +174,7 @@ export function TabsList({
166
174
  label,
167
175
  ariaLabelledBy,
168
176
  ...rest
169
- }: TabsListProps) {
177
+ }: TabsListProps): ReactElement {
170
178
  const { orientation } = useTabsContext();
171
179
 
172
180
  return (
@@ -188,6 +196,7 @@ export function TabsList({
188
196
  );
189
197
  }
190
198
 
199
+ /** @internal */
191
200
  TabsList.displayName = "TabsList";
192
201
 
193
202
  /**
@@ -259,7 +268,7 @@ export function TabsTrigger<T extends HTMLElement = HTMLButtonElement>({
259
268
  disabled = false,
260
269
  asChild = false,
261
270
  ...rest
262
- }: TabsTriggerProps<T>) {
271
+ }: TabsTriggerProps<T>): ReactElement {
263
272
  const {
264
273
  buttonRef,
265
274
  triggerId,
@@ -308,6 +317,7 @@ export function TabsTrigger<T extends HTMLElement = HTMLButtonElement>({
308
317
  );
309
318
  }
310
319
 
320
+ /** @internal */
311
321
  TabsTrigger.displayName = "TabsTrigger";
312
322
 
313
323
  /**
@@ -345,9 +355,16 @@ export function TabsContent({
345
355
  className = "",
346
356
  value,
347
357
  ...rest
348
- }: TabsContentProps) {
349
- const { panelId, triggerId, orientation, isActive, state, tabIndex, shouldRender } =
350
- useTabsContent({ value });
358
+ }: TabsContentProps): ReactElement {
359
+ const {
360
+ panelId,
361
+ triggerId,
362
+ orientation,
363
+ isActive,
364
+ state,
365
+ tabIndex,
366
+ shouldRender,
367
+ } = useTabsContent({ value });
351
368
 
352
369
  return (
353
370
  <div
@@ -366,9 +383,12 @@ export function TabsContent({
366
383
  );
367
384
  }
368
385
 
386
+ /** @internal */
369
387
  TabsContent.displayName = "TabsContent";
370
388
 
371
- type TabsCompound = typeof TabsRoot & {
389
+ /** Type of the {@link Tabs} compound: the callable `Tabs.Root` component
390
+ * augmented with its sub-components as static properties. */
391
+ export type TabsCompound = typeof TabsRoot & {
372
392
  Root: typeof TabsRoot;
373
393
  List: typeof TabsList;
374
394
  Trigger: typeof TabsTrigger;
@@ -1,13 +1,21 @@
1
- import { createStrictContext } from "../utils";
1
+ import type { Context, Provider } from "react";
2
+ import { createStrictContext } from "../utils/index.ts";
2
3
 
3
4
  import { TabsContextValue } from "./types";
4
5
 
5
- export const [TabsContext, useTabsContext] =
6
- createStrictContext<TabsContextValue>(
7
- "Component must be rendered as a child of Tabs.Root",
8
- "TabsContext",
9
- );
6
+ const tabsContextPair = createStrictContext<TabsContextValue>(
7
+ "Component must be rendered as a child of Tabs.Root",
8
+ "TabsContext",
9
+ );
10
10
 
11
- const TabsProvider = TabsContext.Provider;
11
+ /** Strict React context carrying the {@link TabsContextValue} from `Tabs.Root`
12
+ * to its descendants. `null` when read outside a `Tabs.Root`. */
13
+ export const TabsContext: Context<TabsContextValue | null> = tabsContextPair[0];
14
+ /** Reads the {@link TabsContextValue}; throws when used outside a `Tabs.Root`. */
15
+ export const useTabsContext: () => TabsContextValue = tabsContextPair[1];
16
+
17
+ /** Provider component for {@link TabsContext}, used by `Tabs.Root` to supply the
18
+ * {@link TabsContextValue} to its descendants. */
19
+ const TabsProvider: Provider<TabsContextValue | null> = TabsContext.Provider;
12
20
 
13
21
  export { TabsProvider };
@@ -2,7 +2,7 @@ import { render, screen } from "@testing-library/react";
2
2
  import userEvent from "@testing-library/user-event";
3
3
  import { createRef } from "react";
4
4
 
5
- import { Tabs } from "..";
5
+ import { Tabs } from "../index.ts";
6
6
 
7
7
  describe("Tabs.Trigger asChild", () => {
8
8
  it("renders the child element instead of a <button> when asChild is true", () => {
@@ -1,6 +1,6 @@
1
1
  import { render, screen } from "@testing-library/react";
2
2
 
3
- import { Tabs, TabsOrientation } from "..";
3
+ import { Tabs, TabsOrientation } from "../index.ts";
4
4
 
5
5
  describe("Tabs basic rendering tests", () => {
6
6
  describe("Tabs.Root", () => {
@@ -1,7 +1,7 @@
1
1
  import { render, screen } from '@testing-library/react';
2
2
  import userEvent from '@testing-library/user-event';
3
3
 
4
- import { Tabs } from '..';
4
+ import { Tabs } from '../index.ts';
5
5
 
6
6
  import { mouseChangeEventCases, keyboardChangeEventCases } from './Tabs.fixtures';
7
7
 
@@ -2,7 +2,7 @@ import { render, screen } from '@testing-library/react';
2
2
  import userEvent from '@testing-library/user-event';
3
3
  import { useState } from 'react';
4
4
 
5
- import { Tabs } from '..';
5
+ import { Tabs } from '../index.ts';
6
6
 
7
7
  describe('Tabs controlled state tests', () => {
8
8
  it('should respect the value prop for active tab', () => {
@@ -1,7 +1,7 @@
1
1
  import { render, screen } from '@testing-library/react';
2
2
  import { act, useState } from 'react';
3
3
 
4
- import { Tabs } from '..';
4
+ import { Tabs } from '../index.ts';
5
5
 
6
6
  import { errorCases } from './Tabs.fixtures';
7
7
 
@@ -1,7 +1,7 @@
1
1
  import { render, screen, waitFor } from "@testing-library/react";
2
2
  import { createRef } from "react";
3
3
 
4
- import { Tabs, TabsImperativeApi } from "..";
4
+ import { Tabs, TabsImperativeApi } from "../index.ts";
5
5
 
6
6
  describe("Tabs Imperative API", () => {
7
7
  it("should expose setActiveTab method via ref", () => {
@@ -1,7 +1,7 @@
1
1
  import { render, screen } from '@testing-library/react';
2
2
  import userEvent from '@testing-library/user-event';
3
3
 
4
- import { Tabs } from '..';
4
+ import { Tabs } from '../index.ts';
5
5
 
6
6
  import { arrowKeyCases } from './Tabs.fixtures';
7
7
 
@@ -1,7 +1,7 @@
1
1
  import { render, screen } from "@testing-library/react";
2
2
  import userEvent from "@testing-library/user-event";
3
3
 
4
- import { Tabs } from "..";
4
+ import { Tabs } from "../index.ts";
5
5
 
6
6
  function renderTabs(lazyMount: boolean) {
7
7
  return render(
@@ -1,7 +1,7 @@
1
1
  import { render, screen } from '@testing-library/react';
2
2
  import userEvent from '@testing-library/user-event';
3
3
 
4
- import { Tabs } from '..';
4
+ import { Tabs } from '../index.ts';
5
5
 
6
6
  describe('Tabs mouse interaction tests', () => {
7
7
  describe('tab and panel activation', () => {
@@ -1,7 +1,7 @@
1
1
  import { render, screen } from "@testing-library/react";
2
2
  import userEvent from "@testing-library/user-event";
3
3
 
4
- import { DirectionProvider } from "../../DirectionProvider";
4
+ import { DirectionProvider } from "../../DirectionProvider/index.ts";
5
5
  import { Tabs } from "../Tabs";
6
6
  import { TabsReadingDirection } from "../types";
7
7
 
@@ -1,7 +1,7 @@
1
1
  import { render, screen } from '@testing-library/react';
2
2
  import userEvent from '@testing-library/user-event';
3
3
 
4
- import { Tabs } from '..';
4
+ import { Tabs } from '../index.ts';
5
5
 
6
6
  describe('Tabs state tests', () => {
7
7
  describe('no defaultValue provided', () => {
@@ -3,7 +3,7 @@ import { useEffect, useState } from "react";
3
3
  import { TabsContentProps } from "../types";
4
4
  import { getTriggerAndPanelIds } from "../utils";
5
5
 
6
- import { useTabsContext } from ".";
6
+ import { useTabsContext } from "./index.ts";
7
7
 
8
8
  export function useTabsContent({ value }: Pick<TabsContentProps, "value">) {
9
9
  const { orientation, activeValue, tabsId, lazyMount } = useTabsContext();
@@ -7,7 +7,7 @@ import {
7
7
  Ref,
8
8
  } from "react";
9
9
 
10
- import { useCollection, useControllableState } from "../../hooks";
10
+ import { useCollection, useControllableState } from "../../hooks/index.ts";
11
11
 
12
12
  import type { TabsRootProps, TabsImperativeApi } from "../types";
13
13
 
@@ -5,7 +5,7 @@ import {
5
5
  MouseEvent,
6
6
  } from "react";
7
7
 
8
- import { useRovingTabindex } from "../../hooks";
8
+ import { useRovingTabindex } from "../../hooks/index.ts";
9
9
 
10
10
  import { TabsTriggerProps } from "../types";
11
11
  import { getTriggerAndPanelIds } from "../utils";