@itwin/itwinui-react 5.0.0-alpha.11 → 5.0.0-alpha.12

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 (53) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +13 -2
  3. package/dist/DEV/bricks/Checkbox.js +7 -14
  4. package/dist/DEV/bricks/Description.js +7 -14
  5. package/dist/DEV/bricks/DropdownMenu.js +57 -19
  6. package/dist/DEV/bricks/Field.internal.js +47 -0
  7. package/dist/DEV/bricks/Field.js +116 -85
  8. package/dist/DEV/bricks/Icon.js +32 -0
  9. package/dist/DEV/bricks/Label.js +4 -10
  10. package/dist/DEV/bricks/Radio.js +7 -14
  11. package/dist/DEV/bricks/Select.js +9 -15
  12. package/dist/DEV/bricks/Switch.js +8 -15
  13. package/dist/DEV/bricks/Table.js +71 -37
  14. package/dist/DEV/bricks/Tabs.js +4 -29
  15. package/dist/DEV/bricks/TextBox.js +23 -37
  16. package/dist/DEV/bricks/TreeItem.js +87 -8
  17. package/dist/DEV/bricks/index.js +3 -1
  18. package/dist/DEV/bricks/styles.css.js +1 -1
  19. package/dist/DEV/foundations/styles.css.js +1 -1
  20. package/dist/bricks/Checkbox.d.ts +13 -5
  21. package/dist/bricks/Checkbox.js +7 -14
  22. package/dist/bricks/Description.d.ts +2 -6
  23. package/dist/bricks/Description.js +7 -14
  24. package/dist/bricks/DropdownMenu.d.ts +9 -9
  25. package/dist/bricks/DropdownMenu.js +56 -18
  26. package/dist/bricks/Field.d.ts +63 -27
  27. package/dist/bricks/Field.internal.d.ts +33 -0
  28. package/dist/bricks/Field.internal.js +47 -0
  29. package/dist/bricks/Field.js +111 -84
  30. package/dist/bricks/Icon.d.ts +3 -0
  31. package/dist/bricks/Icon.js +31 -0
  32. package/dist/bricks/Label.d.ts +5 -12
  33. package/dist/bricks/Label.js +4 -10
  34. package/dist/bricks/Radio.d.ts +14 -5
  35. package/dist/bricks/Radio.js +7 -14
  36. package/dist/bricks/Select.d.ts +29 -12
  37. package/dist/bricks/Select.js +9 -15
  38. package/dist/bricks/Switch.d.ts +12 -5
  39. package/dist/bricks/Switch.js +8 -15
  40. package/dist/bricks/Table.d.ts +94 -37
  41. package/dist/bricks/Table.js +69 -36
  42. package/dist/bricks/Tabs.d.ts +3 -4
  43. package/dist/bricks/Tabs.js +4 -29
  44. package/dist/bricks/TextBox.d.ts +42 -19
  45. package/dist/bricks/TextBox.js +23 -37
  46. package/dist/bricks/TreeItem.d.ts +46 -8
  47. package/dist/bricks/TreeItem.js +76 -8
  48. package/dist/bricks/index.d.ts +2 -1
  49. package/dist/bricks/index.js +3 -1
  50. package/dist/bricks/styles.css.js +1 -1
  51. package/dist/bricks/~hooks.d.ts +1 -1
  52. package/dist/foundations/styles.css.js +1 -1
  53. package/package.json +1 -1
@@ -7,13 +7,22 @@ interface RadioProps extends InputBaseProps, RadioOwnProps {
7
7
  /**
8
8
  * A styled radio input element, typically used for selecting a single option from a list.
9
9
  *
10
- * Works well with the `Field` and `Label` components.
10
+ * Use with the `Field` components to automatically handle ID associations for
11
+ * labels and descriptions:
12
+ * ```tsx
13
+ * <Field.Root>
14
+ * <Field.Label>Choose one</Field.Label>
15
+ * <Field.Control render={<Radio />} />
16
+ * </Field.Root>
17
+ * ```
11
18
  *
19
+ * Without the `Field` components you will need to manually associate labels,
20
+ * descriptions, etc.:
12
21
  * ```tsx
13
- * <Field>
14
- * <Label>Choose one</Label>
15
- * <Radio />
16
- * </Field>
22
+ * <Radio id="editor-vim" name="editor" value="vim" />
23
+ * <Label htmlFor="editor-vim">Vim</Label>
24
+ * <Radio id="editor-emacs" name="editor" value="emacs" />
25
+ * <Label htmlFor="editor-emacs">Emacs</Label>
17
26
  * ```
18
27
  *
19
28
  * Underneath, it's an HTML radio input, i.e. `<input type="radio">`, so it supports the same props,
@@ -3,24 +3,17 @@ import cx from "classnames";
3
3
  import {
4
4
  Radio as AkRadio
5
5
  } from "@ariakit/react/radio";
6
- import { FieldControl } from "./Field.js";
7
6
  import { forwardRef } from "./~utils.js";
7
+ import { useFieldControlType } from "./Field.internal.js";
8
8
  const Radio = forwardRef((props, forwardedRef) => {
9
- const { id, ...rest } = props;
9
+ useFieldControlType("checkable");
10
10
  return /* @__PURE__ */ jsx(
11
- FieldControl,
11
+ AkRadio,
12
12
  {
13
- type: "checkable",
14
- id,
15
- render: /* @__PURE__ */ jsx(
16
- AkRadio,
17
- {
18
- accessibleWhenDisabled: true,
19
- ...rest,
20
- className: cx("\u{1F95D}-checkbox", "\u{1F95D}-radio", props.className),
21
- ref: forwardedRef
22
- }
23
- )
13
+ accessibleWhenDisabled: true,
14
+ ...props,
15
+ className: cx("\u{1F95D}-checkbox", "\u{1F95D}-radio", props.className),
16
+ ref: forwardedRef
24
17
  }
25
18
  );
26
19
  });
@@ -3,20 +3,37 @@ import { type FocusableProps } from "./~utils.js";
3
3
  /**
4
4
  * Compound component for a select element, which allows the user to select a value from a list of options.
5
5
  *
6
- * Works well with the `Field` and `Label` components.
6
+ * Use with the `Field` components to automatically handle ID associations for
7
+ * labels and descriptions:
8
+ * ```tsx
9
+ * <Field.Root>
10
+ * <Field.Label>Fruit</Field.Label>
11
+ * <Field.Control
12
+ * render={(controlProps) => (
13
+ * <Select.Root>
14
+ * <Select.HtmlSelect name="fruit" {...controlProps}>
15
+ * <option value="kiwi">Kiwi</option>
16
+ * <option value="mango">Mango</option>
17
+ * <option value="papaya">Papaya</option>
18
+ * </Select.HtmlSelect>
19
+ * </Select.Root>
20
+ * )}
21
+ * />
22
+ * </Field.Root>
23
+ * ```
7
24
  *
8
- * Example usage:
25
+ * Without the `Field` components you will need to manually associate labels,
26
+ * descriptions, etc.:
9
27
  * ```tsx
10
- * <Field>
11
- * <Label>Select an option</Label>
12
- * <Select.Root>
13
- * <Select.HtmlSelect>
14
- * <option value="1">Option 1</option>
15
- * <option value="2">Option 2</option>
16
- * <option value="3">Option 3</option>
17
- * </Select.HtmlSelect>
18
- * </Select.Root>
19
- * </Field>
28
+ * <Label htmlFor="fruit">Fruit</Label>
29
+ * <Description id="fruit-description">Something to include in a fruit salad.</Description>
30
+ * <Select.Root>
31
+ * <Select.HtmlSelect id="fruit" aria-labelledby="fruit-description">
32
+ * <option value="kiwi">Kiwi</option>
33
+ * <option value="mango">Mango</option>
34
+ * <option value="papaya">Papaya</option>
35
+ * </Select.HtmlSelect>
36
+ * </Select.Root>
20
37
  * ```
21
38
  */
22
39
  declare const SelectRoot: React.ForwardRefExoticComponent<Pick<import("@ariakit/react/role").RoleProps, "render"> & Omit<Omit<React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement>, "ref">, "render"> & React.RefAttributes<HTMLElement | HTMLDivElement>>;
@@ -7,11 +7,12 @@ import {
7
7
  isBrowser
8
8
  } from "./~utils.js";
9
9
  import { DisclosureArrow } from "./Icon.js";
10
- import { FieldControl } from "./Field.js";
10
+ import { useFieldControlType } from "./Field.internal.js";
11
11
  const supportsHas = isBrowser && CSS?.supports?.("selector(:has(+ *))");
12
12
  const HtmlSelectContext = React.createContext(() => {
13
13
  });
14
14
  const SelectRoot = forwardRef((props, forwardedRef) => {
15
+ useFieldControlType("textlike");
15
16
  const [isHtmlSelect, setIsHtmlSelect] = React.useState(false);
16
17
  return /* @__PURE__ */ jsx(HtmlSelectContext.Provider, { value: setIsHtmlSelect, children: /* @__PURE__ */ jsx(
17
18
  Role.div,
@@ -25,7 +26,7 @@ const SelectRoot = forwardRef((props, forwardedRef) => {
25
26
  });
26
27
  const HtmlSelect = forwardRef(
27
28
  (props, forwardedRef) => {
28
- const { id, variant = "solid", ...rest } = props;
29
+ const { variant = "solid", ...rest } = props;
29
30
  const setIsHtmlSelect = React.useContext(HtmlSelectContext);
30
31
  React.useEffect(
31
32
  function updateContext() {
@@ -35,20 +36,13 @@ const HtmlSelect = forwardRef(
35
36
  );
36
37
  return /* @__PURE__ */ jsxs(Fragment, { children: [
37
38
  /* @__PURE__ */ jsx(
38
- FieldControl,
39
+ Role.select,
39
40
  {
40
- type: "textlike",
41
- id,
42
- render: /* @__PURE__ */ jsx(
43
- Role.select,
44
- {
45
- ...rest,
46
- className: cx("\u{1F95D}-button", "\u{1F95D}-select", props.className),
47
- "data-kiwi-tone": "neutral",
48
- "data-kiwi-variant": variant,
49
- ref: forwardedRef
50
- }
51
- )
41
+ ...rest,
42
+ className: cx("\u{1F95D}-button", "\u{1F95D}-select", props.className),
43
+ "data-kiwi-tone": "neutral",
44
+ "data-kiwi-variant": variant,
45
+ ref: forwardedRef
52
46
  }
53
47
  ),
54
48
  /* @__PURE__ */ jsx(DisclosureArrow, { className: "\u{1F95D}-select-arrow" })
@@ -11,13 +11,20 @@ interface SwitchProps extends InputBaseProps, CheckboxOwnProps {
11
11
  /**
12
12
  * A toggle switch element, typically used for enabling or disabling a feature.
13
13
  *
14
- * Works well with the `Field` and `Label` components.
14
+ * Use with the `Field` components to automatically handle ID associations for
15
+ * labels and descriptions:
16
+ * ```tsx
17
+ * <Field.Root>
18
+ * <Field.Label>Enable feature</Field.Label>
19
+ * <Field.Control render={<Switch />} />
20
+ * </Field.Root>
21
+ * ```
15
22
  *
23
+ * Without the `Field` components you will need to manually associate labels,
24
+ * descriptions, etc.:
16
25
  * ```tsx
17
- * <Field>
18
- * <Label>Enable feature</Label>
19
- * <Switch />
20
- * </Field>
26
+ * <Switch id="dark-mode" />
27
+ * <Label htmlFor="dark-mode">Dark mode</Label>
21
28
  * ```
22
29
  *
23
30
  * Underneath, it's an HTML checkbox, i.e. `<input type="checkbox">`, so it supports the same props,
@@ -3,26 +3,19 @@ import cx from "classnames";
3
3
  import {
4
4
  Checkbox as AkCheckbox
5
5
  } from "@ariakit/react/checkbox";
6
- import { FieldControl } from "./Field.js";
7
6
  import { forwardRef } from "./~utils.js";
7
+ import { useFieldControlType } from "./Field.internal.js";
8
8
  const Switch = forwardRef(
9
9
  (props, forwardedRef) => {
10
- const { id, ...rest } = props;
10
+ useFieldControlType("checkable");
11
11
  return /* @__PURE__ */ jsx(
12
- FieldControl,
12
+ AkCheckbox,
13
13
  {
14
- type: "checkable",
15
- id,
16
- render: /* @__PURE__ */ jsx(
17
- AkCheckbox,
18
- {
19
- accessibleWhenDisabled: true,
20
- ...rest,
21
- className: cx("\u{1F95D}-switch", props.className),
22
- role: "switch",
23
- ref: forwardedRef
24
- }
25
- )
14
+ accessibleWhenDisabled: true,
15
+ ...props,
16
+ className: cx("\u{1F95D}-switch", props.className),
17
+ role: "switch",
18
+ ref: forwardedRef
26
19
  }
27
20
  );
28
21
  }
@@ -1,44 +1,89 @@
1
1
  import * as React from "react";
2
2
  import { type BaseProps } from "./~utils.js";
3
- interface TableProps extends BaseProps {
3
+ interface HtmlTableProps extends BaseProps {
4
4
  }
5
5
  /**
6
6
  * A table is a grid of rows and columns that displays data in a structured format.
7
7
  *
8
- * `Table.Root` is the root component for a table.
9
- * `Table.Header`, `Table.Body`, and `Table.Cell` can be nested inside a `Table.Root` to create a table structure.
8
+ * `Table.HtmlTable` uses native HTML table elements for the table root *and its descendants*.
9
+ *
10
+ * E.g. `<table>`, `<thead>`, `<tbody>`, `<tr>`, `<th>`, and `<td>`.
11
+ *
12
+ * Related: `Table.CustomTable`
10
13
  *
11
14
  * Example:
12
15
  * ```tsx
13
- * <Table.Root>
14
- * <Table.Caption>Table Caption</Table.Caption>
15
- * <Table.Header>
16
- * <Table.Row>
17
- * <Table.Cell>Header 1</Table.Cell>
18
- * <Table.Cell>Header 2</Table.Cell>
19
- * </Table.Row>
20
- * </Table.Header>
21
- *
22
- * <Table.Body>
23
- * <Table.Row>
24
- * <Table.Cell>Cell 1.1</Table.Cell>
25
- * <Table.Cell>Cell 1.2</Table.Cell>
26
- * </Table.Row>
27
- * <Table.Row>
28
- * <Table.Cell>Cell 2.1</Table.Cell>
29
- * <Table.Cell>Cell 2.2</Table.Cell>
30
- * </Table.Row>
31
- * </Table.Body>
32
- * </Table.Root>
16
+ * <Table.HtmlTable> // <table>
17
+ * <Table.Caption>Table Caption</Table.Caption> // <caption>
18
+ *
19
+ * <Table.Header> // <thead>
20
+ * <Table.Row> // <tr>
21
+ * <Table.Cell>Header 1</Table.Cell> // <th>
22
+ * <Table.Cell>Header 2</Table.Cell> // <th>
23
+ * </Table.Row>
24
+ * </Table.Header>
25
+ *
26
+ * <Table.Body> // <tbody>
27
+ * <Table.Row> // <tr>
28
+ * <Table.Cell>Cell 1.1</Table.Cell> // <td>
29
+ * <Table.Cell>Cell 1.2</Table.Cell> // <td>
30
+ * </Table.Row>
31
+ * <Table.Row> // <tr>
32
+ * <Table.Cell>Cell 2.1</Table.Cell> // <td>
33
+ * <Table.Cell>Cell 2.2</Table.Cell> // <td>
34
+ * </Table.Row>
35
+ * </Table.Body>
36
+ * </Table.HtmlTable>
37
+ * ```
38
+ */
39
+ declare const HtmlTable: React.ForwardRefExoticComponent<HtmlTableProps & React.RefAttributes<HTMLElement | HTMLTableElement>>;
40
+ interface CustomTableProps extends BaseProps {
41
+ }
42
+ /**
43
+ * A table is a grid of rows and columns that displays data in a structured format.
44
+ *
45
+ * `Table.CustomTable` implements the [WAI-ARIA table pattern](https://www.w3.org/WAI/ARIA/apg/patterns/table/) using
46
+ * divs + appropriate roles for the table root *and its descendants*.
47
+ *
48
+ * E.g. `<div role="table">`, `<div role="row">`, `<div role="columnheader">`, and `<div role="cell">`.
49
+ *
50
+ * Related: `Table.HtmlTable`
51
+ *
52
+ * Example:
53
+ * ```tsx
54
+ * <Table.CustomTable> // <div role="table">
55
+ * <Table.Caption>Table Caption</Table.Caption> // <div role="caption">
56
+ *
57
+ * <Table.Header> // <div role="rowgroup">
58
+ * <Table.Row> // <div role="row">
59
+ * <Table.Cell>Header 1</Table.Cell> // <div role="columnheader">
60
+ * <Table.Cell>Header 2</Table.Cell> // <div role="columnheader">
61
+ * </Table.Row>
62
+ * </Table.Header>
63
+ *
64
+ * <Table.Body>
65
+ * <Table.Row> // <div role="row">
66
+ * <Table.Cell>Cell 1.1</Table.Cell> // <div role="cell">
67
+ * <Table.Cell>Cell 1.2</Table.Cell> // <div role="cell">
68
+ * </Table.Row>
69
+ * <Table.Row> // <div role="row">
70
+ * <Table.Cell>Cell 2.1</Table.Cell> // <div role="cell">
71
+ * <Table.Cell>Cell 2.2</Table.Cell> // <div role="cell">
72
+ * </Table.Row>
73
+ * </Table.Body>
74
+ * </Table.CustomTable>
33
75
  * ```
34
76
  */
35
- declare const Table: React.ForwardRefExoticComponent<TableProps & React.RefAttributes<HTMLElement | HTMLDivElement>>;
36
- interface TableHeaderProps extends BaseProps {
77
+ declare const CustomTable: React.ForwardRefExoticComponent<CustomTableProps & React.RefAttributes<HTMLElement | HTMLDivElement>>;
78
+ interface TableHeaderProps extends BaseProps<"div"> {
37
79
  }
38
80
  /**
39
81
  * `Table.Header` is a column component of cells that labels the columns of a table.
40
82
  * `Table.Row` and `Table.Cell` can be nested inside a `Table.Header` to create a header row.
41
83
  *
84
+ * If within a `Table.HtmlTable`: it will render a `<thead>` element.
85
+ * If within a `Table.CustomTable`: it will render a `<div role="rowgroup">` element.
86
+ *
42
87
  * Example:
43
88
  * ```tsx
44
89
  * <Table.Header>
@@ -50,13 +95,14 @@ interface TableHeaderProps extends BaseProps {
50
95
  * ```
51
96
  */
52
97
  declare const TableHeader: React.ForwardRefExoticComponent<TableHeaderProps & React.RefAttributes<HTMLElement | HTMLDivElement>>;
53
- interface TableBodyProps extends BaseProps {
98
+ interface TableBodyProps extends BaseProps<"div"> {
54
99
  }
55
100
  /**
56
101
  * `Table.Body` is a component that contains the rows of table data.
57
102
  * Multiple `Table.Row`s and `Table.Cell`s can be nested inside a `Table.Body` to create a table body.
58
103
  *
59
- * This component intentionally does not set `role=rowgroup` because it is not properly supported.
104
+ * If within a `Table.HtmlTable`: it will render a `<tbody>` element.
105
+ * If within a `Table.CustomTable`: it will render a `<div>` element.
60
106
  *
61
107
  * Example:
62
108
  * ```tsx
@@ -73,11 +119,14 @@ interface TableBodyProps extends BaseProps {
73
119
  * ```
74
120
  */
75
121
  declare const TableBody: React.ForwardRefExoticComponent<TableBodyProps & React.RefAttributes<HTMLElement | HTMLDivElement>>;
76
- interface TableRowProps extends BaseProps {
122
+ interface TableRowProps extends BaseProps<"div"> {
77
123
  }
78
124
  /**
79
125
  * `Table.Row` is a component that contains the cells of a table row.
80
126
  *
127
+ * If within a `Table.HtmlTable`: it will render a `<tr>` element.
128
+ * If within a `Table.CustomTable`: it will render a `<div role="row">` element.
129
+ *
81
130
  * Example:
82
131
  * ```tsx
83
132
  * <Table.Row>
@@ -87,29 +136,37 @@ interface TableRowProps extends BaseProps {
87
136
  * ```
88
137
  */
89
138
  declare const TableRow: React.ForwardRefExoticComponent<TableRowProps & React.RefAttributes<HTMLElement | HTMLDivElement>>;
90
- interface TableCaptionProps extends BaseProps<"caption"> {
139
+ interface TableCaptionProps extends BaseProps<"div"> {
91
140
  }
92
141
  /**
93
142
  * `Table.Caption` is a component that contains the caption of a table.
94
143
  *
144
+ * If within a `Table.HtmlTable`: it will render a `<caption>` element.
145
+ * If within a `Table.CustomTable`: it will render a `<div role="caption">` element.
146
+ *
95
147
  * Example:
96
148
  * ```tsx
97
- * <Table.Root>
98
- * <Table.Caption>Table Caption</Table.Caption>
99
- *
100
- * </Table.Root>
149
+ * <Table.CustomTable> // Or <Table.HtmlTable>
150
+ * <Table.Caption>Table Caption</Table.Caption>
151
+ *
152
+ * </Table.CustomTable> // Or </Table.HtmlTable>
101
153
  * ```
102
154
  */
103
- declare const TableCaption: React.ForwardRefExoticComponent<TableCaptionProps & React.RefAttributes<HTMLElement>>;
104
- interface TableCellProps extends BaseProps<"span"> {
155
+ declare const TableCaption: React.ForwardRefExoticComponent<TableCaptionProps & React.RefAttributes<HTMLElement | HTMLDivElement>>;
156
+ interface TableCellProps extends BaseProps<"div"> {
105
157
  }
106
158
  /**
107
159
  * `Table.Cell` is a component that contains the data of a table cell.
108
160
  *
161
+ * - If within a `Table.HtmlTable`: it will render a `<th>` element if also within a `Table.Header`, or a `<td>` element
162
+ * if also within a `Table.Body`.
163
+ * - If within a `Table.CustomTable`: it will render a `<div role="columnheader">` element if also within a
164
+ * `Table.Header`, or a `<div role="cell">` element if also within a `Table.Body`.
165
+ *
109
166
  * Example:
110
167
  * ```tsx
111
168
  * <Table.Cell>Cell 1.1</Table.Cell>
112
169
  * ```
113
170
  */
114
- declare const TableCell: React.ForwardRefExoticComponent<TableCellProps & React.RefAttributes<HTMLElement | HTMLSpanElement>>;
115
- export { Table as Root, TableHeader as Header, TableBody as Body, TableRow as Row, TableCaption as Caption, TableCell as Cell, };
171
+ declare const TableCell: React.ForwardRefExoticComponent<TableCellProps & React.RefAttributes<HTMLElement | HTMLDivElement>>;
172
+ export { HtmlTable, CustomTable, TableHeader as Header, TableBody as Body, TableRow as Row, TableCaption as Caption, TableCell as Cell, };
@@ -3,98 +3,130 @@ import { Role } from "@ariakit/react/role";
3
3
  import * as React from "react";
4
4
  import cx from "classnames";
5
5
  import { forwardRef } from "./~utils.js";
6
- import { useMergedRefs } from "./~hooks.js";
7
- const TableContext = React.createContext({
8
- setCaptionId: () => {
9
- }
10
- });
11
- const Table = forwardRef((props, forwardedRef) => {
12
- const [captionId, setCaptionId] = React.useState();
13
- const tableContext = React.useMemo(() => ({ setCaptionId }), []);
14
- return /* @__PURE__ */ jsx(TableContext.Provider, { value: tableContext, children: /* @__PURE__ */ jsx(
6
+ import { useMergedRefs, useSafeContext } from "./~hooks.js";
7
+ const TableContext = React.createContext(void 0);
8
+ const TableHeaderContext = React.createContext(false);
9
+ const HtmlTable = forwardRef((props, forwardedRef) => {
10
+ const tableContextValue = React.useMemo(
11
+ () => ({ mode: "html" }),
12
+ []
13
+ );
14
+ return /* @__PURE__ */ jsx(TableContext.Provider, { value: tableContextValue, children: /* @__PURE__ */ jsx(
15
15
  Role,
16
16
  {
17
+ render: /* @__PURE__ */ jsx("table", {}),
17
18
  ...props,
18
- className: cx("\u{1F95D}-table", props.className),
19
19
  ref: forwardedRef,
20
- role: "table",
21
- "aria-labelledby": captionId,
22
- children: props.children
20
+ className: cx("\u{1F95D}-table", props.className)
23
21
  }
24
22
  ) });
25
23
  });
26
- const TableHeaderContext = React.createContext(false);
24
+ const CustomTable = forwardRef(
25
+ (props, forwardedRef) => {
26
+ const [captionId, setCaptionId] = React.useState();
27
+ const tableContextValue = React.useMemo(
28
+ () => ({ captionId, setCaptionId, mode: "aria" }),
29
+ [captionId]
30
+ );
31
+ return /* @__PURE__ */ jsx(TableContext.Provider, { value: tableContextValue, children: /* @__PURE__ */ jsx(
32
+ Role.div,
33
+ {
34
+ role: "table",
35
+ "aria-labelledby": captionId,
36
+ ...props,
37
+ ref: forwardedRef,
38
+ className: cx("\u{1F95D}-table", props.className)
39
+ }
40
+ ) });
41
+ }
42
+ );
27
43
  const TableHeader = forwardRef(
28
44
  (props, forwardedRef) => {
45
+ const { mode } = useSafeContext(TableContext);
46
+ const render = mode === "html" ? /* @__PURE__ */ jsx("thead", {}) : void 0;
47
+ const role = mode === "aria" ? "rowgroup" : void 0;
29
48
  return /* @__PURE__ */ jsx(TableHeaderContext.Provider, { value: true, children: /* @__PURE__ */ jsx(
30
49
  Role.div,
31
50
  {
51
+ render,
52
+ role,
32
53
  ...props,
33
- className: cx("\u{1F95D}-table-header", props.className),
34
54
  ref: forwardedRef,
35
- role: "rowgroup",
36
- children: props.children
55
+ className: cx("\u{1F95D}-table-header", props.className)
37
56
  }
38
57
  ) });
39
58
  }
40
59
  );
41
60
  const TableBody = forwardRef((props, forwardedRef) => {
61
+ const { mode } = useSafeContext(TableContext);
62
+ const render = mode === "html" ? /* @__PURE__ */ jsx("tbody", {}) : void 0;
42
63
  return /* @__PURE__ */ jsx(
43
64
  Role.div,
44
65
  {
66
+ render,
67
+ role: void 0,
45
68
  ...props,
46
- className: cx("\u{1F95D}-table-body", props.className),
47
69
  ref: forwardedRef,
48
- children: props.children
70
+ className: cx("\u{1F95D}-table-body", props.className)
49
71
  }
50
72
  );
51
73
  });
52
74
  const TableRow = forwardRef((props, forwardedRef) => {
53
- const { children, ...rest } = props;
75
+ const { mode } = useSafeContext(TableContext);
76
+ const render = mode === "html" ? /* @__PURE__ */ jsx("tr", {}) : void 0;
77
+ const role = mode === "aria" ? "row" : void 0;
54
78
  return /* @__PURE__ */ jsx(
55
79
  Role.div,
56
80
  {
57
- ...rest,
58
- className: cx("\u{1F95D}-table-row", props.className),
81
+ render,
82
+ role,
83
+ ...props,
59
84
  ref: forwardedRef,
60
- role: "row",
61
- children
85
+ className: cx("\u{1F95D}-table-row", props.className)
62
86
  }
63
87
  );
64
88
  });
65
89
  const TableCaption = forwardRef(
66
90
  (props, forwardedRef) => {
67
91
  const fallbackId = React.useId();
68
- const { id = fallbackId, children, ...rest } = props;
69
- const { setCaptionId } = React.useContext(TableContext);
92
+ const { id = fallbackId, ...rest } = props;
93
+ const { mode, setCaptionId } = useSafeContext(TableContext);
94
+ const render = mode === "html" ? /* @__PURE__ */ jsx("caption", {}) : void 0;
70
95
  const captionIdRef = React.useCallback(
71
96
  (element) => {
72
- setCaptionId(element ? id : void 0);
97
+ setCaptionId?.(element ? id : void 0);
73
98
  },
74
99
  [id, setCaptionId]
75
100
  );
76
101
  return /* @__PURE__ */ jsx(
77
- Role,
102
+ Role.div,
78
103
  {
104
+ render,
79
105
  ...rest,
80
106
  id,
81
- className: cx("\u{1F95D}-table-caption", props.className),
82
107
  ref: useMergedRefs(forwardedRef, captionIdRef),
83
- children
108
+ className: cx("\u{1F95D}-table-caption", props.className)
84
109
  }
85
110
  );
86
111
  }
87
112
  );
88
113
  const TableCell = forwardRef((props, forwardedRef) => {
89
- const isWithinTableHeader = React.useContext(TableHeaderContext);
114
+ const isWithinTableHeader = useSafeContext(TableHeaderContext);
115
+ const { mode } = useSafeContext(TableContext);
116
+ const { render, role } = React.useMemo(() => {
117
+ if (mode === "aria") {
118
+ return { role: isWithinTableHeader ? "columnheader" : "cell" };
119
+ }
120
+ return { render: isWithinTableHeader ? /* @__PURE__ */ jsx("th", {}) : /* @__PURE__ */ jsx("td", {}) };
121
+ }, [isWithinTableHeader, mode]);
90
122
  return /* @__PURE__ */ jsx(
91
- Role.span,
123
+ Role.div,
92
124
  {
125
+ render,
126
+ role,
93
127
  ...props,
94
- className: cx("\u{1F95D}-table-cell", props.className),
95
128
  ref: forwardedRef,
96
- role: isWithinTableHeader ? "columnheader" : "cell",
97
- children: props.children
129
+ className: cx("\u{1F95D}-table-cell", props.className)
98
130
  }
99
131
  );
100
132
  });
@@ -102,7 +134,8 @@ export {
102
134
  TableBody as Body,
103
135
  TableCaption as Caption,
104
136
  TableCell as Cell,
137
+ CustomTable,
105
138
  TableHeader as Header,
106
- Table as Root,
139
+ HtmlTable,
107
140
  TableRow as Row
108
141
  };
@@ -1,4 +1,3 @@
1
- import * as React from "react";
2
1
  import * as AkTab from "@ariakit/react/tab";
3
2
  import { type FocusableProps, type BaseProps } from "./~utils.js";
4
3
  interface TabsProps extends Pick<AkTab.TabProviderProps, "defaultSelectedId" | "selectedId" | "setSelectedId" | "selectOnMove" | "children"> {
@@ -52,7 +51,7 @@ interface TabListProps extends BaseProps {
52
51
  * </Tabs.TabList>
53
52
  * ```
54
53
  */
55
- declare const TabList: React.ForwardRefExoticComponent<TabListProps & React.RefAttributes<HTMLElement | HTMLDivElement>>;
54
+ declare const TabList: import("react").ForwardRefExoticComponent<TabListProps & import("react").RefAttributes<HTMLElement | HTMLDivElement>>;
56
55
  interface TabProps extends FocusableProps<"button">, Pick<AkTab.TabProps, "id"> {
57
56
  }
58
57
  /**
@@ -66,7 +65,7 @@ interface TabProps extends FocusableProps<"button">, Pick<AkTab.TabProps, "id">
66
65
  * <Tabs.Tab id="tab-1">Tab 1</Tabs.Tab>
67
66
  * ```
68
67
  */
69
- declare const Tab: React.ForwardRefExoticComponent<TabProps & React.RefAttributes<HTMLElement | HTMLButtonElement>>;
68
+ declare const Tab: import("react").ForwardRefExoticComponent<TabProps & import("react").RefAttributes<HTMLElement | HTMLButtonElement>>;
70
69
  interface TabPanelProps extends FocusableProps<"div">, Pick<AkTab.TabPanelProps, "tabId" | "unmountOnHide" | "focusable"> {
71
70
  }
72
71
  /**
@@ -78,5 +77,5 @@ interface TabPanelProps extends FocusableProps<"div">, Pick<AkTab.TabPanelProps,
78
77
  * <Tabs.TabPanel tabId="tab-1">Tab 1 content</Tabs.TabPanel>
79
78
  * ```
80
79
  */
81
- declare const TabPanel: React.ForwardRefExoticComponent<TabPanelProps & React.RefAttributes<HTMLElement | HTMLDivElement>>;
80
+ declare const TabPanel: import("react").ForwardRefExoticComponent<TabPanelProps & import("react").RefAttributes<HTMLElement | HTMLDivElement>>;
82
81
  export { Tabs as Root, TabList, Tab, TabPanel };