@octanejs/aria 0.0.4 → 0.0.6

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 (210) hide show
  1. package/package.json +7 -5
  2. package/src/autocomplete/useAutocomplete.ts +656 -0
  3. package/src/collections/BaseCollection.ts +374 -0
  4. package/src/collections/CollectionBuilder.ts +343 -0
  5. package/src/collections/Document.ts +451 -0
  6. package/src/collections/Hidden.ts +84 -0
  7. package/src/collections/useCachedChildren.ts +103 -0
  8. package/src/components/Autocomplete.ts +124 -0
  9. package/src/components/Breadcrumbs.ts +170 -0
  10. package/src/components/Button.ts +209 -0
  11. package/src/components/Checkbox.ts +593 -0
  12. package/src/components/Collection.ts +301 -0
  13. package/src/components/ComboBox.ts +477 -0
  14. package/src/components/Dialog.ts +195 -0
  15. package/src/components/Disclosure.ts +322 -0
  16. package/src/components/DragAndDrop.ts +177 -0
  17. package/src/components/FieldError.ts +79 -0
  18. package/src/components/Form.ts +65 -0
  19. package/src/components/GridList.ts +1099 -0
  20. package/src/components/Group.ts +146 -0
  21. package/src/components/Header.ts +32 -0
  22. package/src/components/Heading.ts +45 -0
  23. package/src/components/Input.ts +139 -0
  24. package/src/components/Keyboard.ts +23 -0
  25. package/src/components/Label.ts +30 -0
  26. package/src/components/Link.ts +137 -0
  27. package/src/components/ListBox.ts +886 -0
  28. package/src/components/Menu.ts +685 -0
  29. package/src/components/Meter.ts +100 -0
  30. package/src/components/Modal.ts +352 -0
  31. package/src/components/NumberField.ts +221 -0
  32. package/src/components/OverlayArrow.ts +117 -0
  33. package/src/components/Popover.ts +385 -0
  34. package/src/components/ProgressBar.ts +112 -0
  35. package/src/components/RadioGroup.ts +542 -0
  36. package/src/components/SearchField.ts +208 -0
  37. package/src/components/Select.ts +505 -0
  38. package/src/components/SelectionIndicator.ts +52 -0
  39. package/src/components/Separator.ts +97 -0
  40. package/src/components/SharedElementTransition.ts +209 -0
  41. package/src/components/Slider.ts +472 -0
  42. package/src/components/Switch.ts +449 -0
  43. package/src/components/Table.ts +2618 -0
  44. package/src/components/Tabs.ts +675 -0
  45. package/src/components/TagGroup.ts +443 -0
  46. package/src/components/Text.ts +27 -0
  47. package/src/components/TextArea.ts +92 -0
  48. package/src/components/TextField.ts +200 -0
  49. package/src/components/ToggleButton.ts +147 -0
  50. package/src/components/ToggleButtonGroup.ts +106 -0
  51. package/src/components/Toolbar.ts +74 -0
  52. package/src/components/Tooltip.ts +249 -0
  53. package/src/components/Tree.ts +1450 -0
  54. package/src/components/TreeDropTargetDelegate.ts +363 -0
  55. package/src/components/index.ts +359 -0
  56. package/src/components/useDragAndDrop.ts +164 -0
  57. package/src/components/utils.ts +521 -0
  58. package/src/grid/GridKeyboardDelegate.ts +514 -0
  59. package/src/grid/useGrid.ts +263 -0
  60. package/src/grid/useGridCell.ts +346 -0
  61. package/src/grid/useGridRow.ts +108 -0
  62. package/src/grid/useGridRowGroup.ts +29 -0
  63. package/src/grid/utils.ts +24 -0
  64. package/src/index.ts +38 -0
  65. package/src/intl/autocomplete/ar-AE.json +3 -0
  66. package/src/intl/autocomplete/bg-BG.json +3 -0
  67. package/src/intl/autocomplete/cs-CZ.json +3 -0
  68. package/src/intl/autocomplete/da-DK.json +3 -0
  69. package/src/intl/autocomplete/de-DE.json +3 -0
  70. package/src/intl/autocomplete/el-GR.json +3 -0
  71. package/src/intl/autocomplete/en-US.json +3 -0
  72. package/src/intl/autocomplete/es-ES.json +3 -0
  73. package/src/intl/autocomplete/et-EE.json +3 -0
  74. package/src/intl/autocomplete/fi-FI.json +3 -0
  75. package/src/intl/autocomplete/fr-FR.json +3 -0
  76. package/src/intl/autocomplete/he-IL.json +3 -0
  77. package/src/intl/autocomplete/hr-HR.json +3 -0
  78. package/src/intl/autocomplete/hu-HU.json +3 -0
  79. package/src/intl/autocomplete/index.ts +82 -0
  80. package/src/intl/autocomplete/it-IT.json +3 -0
  81. package/src/intl/autocomplete/ja-JP.json +3 -0
  82. package/src/intl/autocomplete/ko-KR.json +3 -0
  83. package/src/intl/autocomplete/lt-LT.json +3 -0
  84. package/src/intl/autocomplete/lv-LV.json +3 -0
  85. package/src/intl/autocomplete/nb-NO.json +3 -0
  86. package/src/intl/autocomplete/nl-NL.json +3 -0
  87. package/src/intl/autocomplete/pl-PL.json +3 -0
  88. package/src/intl/autocomplete/pt-BR.json +3 -0
  89. package/src/intl/autocomplete/pt-PT.json +3 -0
  90. package/src/intl/autocomplete/ro-RO.json +3 -0
  91. package/src/intl/autocomplete/ru-RU.json +3 -0
  92. package/src/intl/autocomplete/sk-SK.json +3 -0
  93. package/src/intl/autocomplete/sl-SI.json +3 -0
  94. package/src/intl/autocomplete/sr-SP.json +3 -0
  95. package/src/intl/autocomplete/sv-SE.json +3 -0
  96. package/src/intl/autocomplete/tr-TR.json +3 -0
  97. package/src/intl/autocomplete/uk-UA.json +3 -0
  98. package/src/intl/autocomplete/zh-CN.json +3 -0
  99. package/src/intl/autocomplete/zh-TW.json +3 -0
  100. package/src/intl/breadcrumbs/index.ts +9 -2
  101. package/src/intl/combobox/index.ts +9 -2
  102. package/src/intl/compileMessages.ts +356 -0
  103. package/src/intl/grid/index.ts +9 -2
  104. package/src/intl/gridlist/index.ts +9 -2
  105. package/src/intl/menu/index.ts +9 -2
  106. package/src/intl/numberfield/index.ts +9 -2
  107. package/src/intl/overlays/index.ts +9 -2
  108. package/src/intl/searchfield/index.ts +9 -2
  109. package/src/intl/spinbutton/index.ts +9 -2
  110. package/src/intl/table/ar-AE.json +13 -0
  111. package/src/intl/table/bg-BG.json +13 -0
  112. package/src/intl/table/cs-CZ.json +13 -0
  113. package/src/intl/table/da-DK.json +13 -0
  114. package/src/intl/table/de-DE.json +13 -0
  115. package/src/intl/table/el-GR.json +13 -0
  116. package/src/intl/table/en-US.json +13 -0
  117. package/src/intl/table/es-ES.json +13 -0
  118. package/src/intl/table/et-EE.json +13 -0
  119. package/src/intl/table/fi-FI.json +13 -0
  120. package/src/intl/table/fr-FR.json +13 -0
  121. package/src/intl/table/he-IL.json +13 -0
  122. package/src/intl/table/hr-HR.json +13 -0
  123. package/src/intl/table/hu-HU.json +13 -0
  124. package/src/intl/table/index.ts +82 -0
  125. package/src/intl/table/it-IT.json +13 -0
  126. package/src/intl/table/ja-JP.json +13 -0
  127. package/src/intl/table/ko-KR.json +13 -0
  128. package/src/intl/table/lt-LT.json +13 -0
  129. package/src/intl/table/lv-LV.json +13 -0
  130. package/src/intl/table/nb-NO.json +13 -0
  131. package/src/intl/table/nl-NL.json +13 -0
  132. package/src/intl/table/pl-PL.json +13 -0
  133. package/src/intl/table/pt-BR.json +13 -0
  134. package/src/intl/table/pt-PT.json +13 -0
  135. package/src/intl/table/ro-RO.json +13 -0
  136. package/src/intl/table/ru-RU.json +13 -0
  137. package/src/intl/table/sk-SK.json +13 -0
  138. package/src/intl/table/sl-SI.json +13 -0
  139. package/src/intl/table/sr-SP.json +13 -0
  140. package/src/intl/table/sv-SE.json +13 -0
  141. package/src/intl/table/tr-TR.json +13 -0
  142. package/src/intl/table/uk-UA.json +13 -0
  143. package/src/intl/table/zh-CN.json +13 -0
  144. package/src/intl/table/zh-TW.json +13 -0
  145. package/src/intl/tag/index.ts +9 -2
  146. package/src/intl/tree/ar-AE.json +4 -0
  147. package/src/intl/tree/bg-BG.json +4 -0
  148. package/src/intl/tree/cs-CZ.json +4 -0
  149. package/src/intl/tree/da-DK.json +4 -0
  150. package/src/intl/tree/de-DE.json +4 -0
  151. package/src/intl/tree/el-GR.json +4 -0
  152. package/src/intl/tree/en-US.json +4 -0
  153. package/src/intl/tree/es-ES.json +4 -0
  154. package/src/intl/tree/et-EE.json +4 -0
  155. package/src/intl/tree/fi-FI.json +4 -0
  156. package/src/intl/tree/fr-FR.json +4 -0
  157. package/src/intl/tree/he-IL.json +4 -0
  158. package/src/intl/tree/hr-HR.json +4 -0
  159. package/src/intl/tree/hu-HU.json +4 -0
  160. package/src/intl/tree/index.ts +82 -0
  161. package/src/intl/tree/it-IT.json +4 -0
  162. package/src/intl/tree/ja-JP.json +4 -0
  163. package/src/intl/tree/ko-KR.json +4 -0
  164. package/src/intl/tree/lt-LT.json +4 -0
  165. package/src/intl/tree/lv-LV.json +4 -0
  166. package/src/intl/tree/nb-NO.json +4 -0
  167. package/src/intl/tree/nl-NL.json +4 -0
  168. package/src/intl/tree/pl-PL.json +4 -0
  169. package/src/intl/tree/pt-BR.json +4 -0
  170. package/src/intl/tree/pt-PT.json +4 -0
  171. package/src/intl/tree/ro-RO.json +4 -0
  172. package/src/intl/tree/ru-RU.json +4 -0
  173. package/src/intl/tree/sk-SK.json +4 -0
  174. package/src/intl/tree/sl-SI.json +4 -0
  175. package/src/intl/tree/sr-SP.json +4 -0
  176. package/src/intl/tree/sv-SE.json +4 -0
  177. package/src/intl/tree/tr-TR.json +4 -0
  178. package/src/intl/tree/uk-UA.json +4 -0
  179. package/src/intl/tree/zh-CN.json +4 -0
  180. package/src/intl/tree/zh-TW.json +4 -0
  181. package/src/stately/autocomplete/useAutocompleteState.ts +85 -0
  182. package/src/stately/grid/GridCollection.ts +200 -0
  183. package/src/stately/grid/useGridState.ts +160 -0
  184. package/src/stately/index.ts +43 -0
  185. package/src/stately/table/Cell.ts +49 -0
  186. package/src/stately/table/Column.ts +121 -0
  187. package/src/stately/table/Row.ts +145 -0
  188. package/src/stately/table/TableBody.ts +66 -0
  189. package/src/stately/table/TableCollection.ts +390 -0
  190. package/src/stately/table/TableColumnLayout.ts +148 -0
  191. package/src/stately/table/TableHeader.ts +65 -0
  192. package/src/stately/table/TableUtils.ts +269 -0
  193. package/src/stately/table/useTableColumnResizeState.ts +202 -0
  194. package/src/stately/table/useTableState.ts +235 -0
  195. package/src/stately/table/useTreeGridState.ts +248 -0
  196. package/src/table/TableKeyboardDelegate.ts +205 -0
  197. package/src/table/useTable.ts +175 -0
  198. package/src/table/useTableCell.ts +81 -0
  199. package/src/table/useTableColumnHeader.ts +155 -0
  200. package/src/table/useTableColumnResize.ts +374 -0
  201. package/src/table/useTableHeaderRow.ts +57 -0
  202. package/src/table/useTableRow.ts +198 -0
  203. package/src/table/useTableRowGroup.ts +13 -0
  204. package/src/table/useTableSelectionCheckbox.ts +105 -0
  205. package/src/table/utils.ts +42 -0
  206. package/src/tree/useTree.ts +76 -0
  207. package/src/tree/useTreeItem.ts +109 -0
  208. package/src/utils/animation.ts +149 -0
  209. package/src/utils/useLoadMoreSentinel.ts +78 -0
  210. package/src/utils/useViewportSize.ts +123 -0
@@ -116,3 +116,46 @@ export type { NumberFieldState, NumberFieldStateOptions } from './numberfield/us
116
116
  // slider
117
117
  export { useSliderState } from './slider/useSliderState';
118
118
  export type { SliderState, SliderStateOptions } from './slider/useSliderState';
119
+
120
+ // grid — mirrors the @react-stately/grid shim surface.
121
+ export { useGridState } from './grid/useGridState';
122
+ export { GridCollection } from './grid/GridCollection';
123
+ export type { GridStateOptions, GridState } from './grid/useGridState';
124
+ export type { IGridCollection, GridNode, GridRow } from './grid/GridCollection';
125
+
126
+ // table — mirrors the @react-stately/table shim surface (Section is already
127
+ // exported from the collections section above).
128
+ export { useTableState, UNSTABLE_useFilteredTableState } from './table/useTableState';
129
+ export { useTableColumnResizeState } from './table/useTableColumnResizeState';
130
+ export { UNSTABLE_useTreeGridState } from './table/useTreeGridState';
131
+ export { TableHeader } from './table/TableHeader';
132
+ export { TableBody } from './table/TableBody';
133
+ export { Column } from './table/Column';
134
+ export { Row } from './table/Row';
135
+ export { Cell } from './table/Cell';
136
+ export { TableCollection, buildHeaderRows } from './table/TableCollection';
137
+ export { TableColumnLayout } from './table/TableColumnLayout';
138
+ export type {
139
+ TableProps,
140
+ TableState,
141
+ TableStateProps,
142
+ CollectionBuilderContext,
143
+ } from './table/useTableState';
144
+ export type {
145
+ TableColumnResizeState,
146
+ TableColumnResizeStateProps,
147
+ } from './table/useTableColumnResizeState';
148
+ export type { TreeGridState, TreeGridStateProps } from './table/useTreeGridState';
149
+ export type {
150
+ ColumnProps,
151
+ ColumnSize,
152
+ ColumnDynamicSize,
153
+ ColumnStaticSize,
154
+ ColumnElement,
155
+ ColumnRenderer,
156
+ } from './table/Column';
157
+ export type { TableHeaderProps } from './table/TableHeader';
158
+ export type { TableBodyProps } from './table/TableBody';
159
+ export type { RowProps, RowElement } from './table/Row';
160
+ export type { CellProps, CellElement, CellRenderer } from './table/Cell';
161
+ export type { ITableCollection } from './table/TableCollection';
@@ -0,0 +1,49 @@
1
+ // Ported from react-stately (source: .react-spectrum/packages/react-stately/src/table/Cell.ts).
2
+ // octane adaptations: React element types → `any` (octane element descriptors). `<Cell>` is
3
+ // a collection DESCRIPTOR component — it renders nothing; CollectionBuilder walks it via
4
+ // the static `getCollectionNode` generator.
5
+ import type { Key } from '@react-types/shared';
6
+ import type { PartialNode } from '../collections/types';
7
+
8
+ export interface CellProps {
9
+ /** The contents of the cell. */
10
+ children: any;
11
+ /** A string representation of the cell's contents, used for features like typeahead. */
12
+ textValue?: string;
13
+ /** Indicates how many columns the data cell spans. */
14
+ colSpan?: number;
15
+ }
16
+
17
+ export type CellElement = any;
18
+ export type CellRenderer = (columnKey: Key) => CellElement;
19
+
20
+ function Cell(props: CellProps): any {
21
+ return null;
22
+ }
23
+
24
+ Cell.getCollectionNode = function* getCollectionNode<T>(
25
+ props: CellProps,
26
+ ): Generator<PartialNode<T>> {
27
+ let { children } = props;
28
+
29
+ let textValue =
30
+ props.textValue ||
31
+ (typeof children === 'string' ? children : '') ||
32
+ (props as any)['aria-label'] ||
33
+ '';
34
+ yield {
35
+ type: 'cell',
36
+ props: props,
37
+ rendered: children,
38
+ textValue,
39
+ 'aria-label': (props as any)['aria-label'],
40
+ hasChildNodes: false,
41
+ };
42
+ };
43
+
44
+ /**
45
+ * A Cell represents the value of a single Column within a Table Row.
46
+ */
47
+ // We don't want getCollectionNode to show up in the type definition
48
+ let _Cell = Cell as unknown as (props: CellProps) => any;
49
+ export { _Cell as Cell };
@@ -0,0 +1,121 @@
1
+ // Ported from react-stately (source: .react-spectrum/packages/react-stately/src/table/Column.ts).
2
+ // octane adaptations: React.Children → octane Children (descriptor arrays); React element
3
+ // types → `any` descriptors. Renders nothing; walked via static `getCollectionNode`.
4
+ import { Children } from 'octane';
5
+
6
+ import type { CollectionBuilderContext } from './useTableState';
7
+ import type { GridNode } from '../grid/GridCollection';
8
+ import type { PartialNode } from '../collections/types';
9
+
10
+ /** Widths that result in a constant pixel value for the same Table width. */
11
+ export type ColumnStaticSize = number | `${number}` | `${number}%`; // match regex: /^(\d+)(?=%$)/
12
+ /**
13
+ * Widths that change size in relation to the remaining space and in ratio to other dynamic columns.
14
+ * All numbers must be integers and greater than 0.
15
+ * FR units take up remaining, if any, space in the table.
16
+ */
17
+ export type ColumnDynamicSize = `${number}fr`; // match regex: /^(\d+)(?=fr$)/
18
+ /** All possible sizes a column can be assigned. */
19
+ export type ColumnSize = ColumnStaticSize | ColumnDynamicSize;
20
+
21
+ export type ColumnElement<T> = any;
22
+ export type ColumnRenderer<T> = (item: T) => ColumnElement<T>;
23
+ export interface ColumnProps<T> {
24
+ /** Rendered contents of the column if `children` contains child columns. */
25
+ title?: any;
26
+ /** Static child columns or content to render as the column header. */
27
+ children: any;
28
+ /** A list of child columns used when dynamically rendering nested child columns. */
29
+ childColumns?: T[];
30
+ /** The width of the column. */
31
+ width?: ColumnSize | null;
32
+ /** The minimum width of the column. */
33
+ minWidth?: ColumnStaticSize | null;
34
+ /** The maximum width of the column. */
35
+ maxWidth?: ColumnStaticSize | null;
36
+ /** The default width of the column. */
37
+ defaultWidth?: ColumnSize | null;
38
+ /** Whether the column allows resizing. */
39
+ allowsResizing?: boolean;
40
+ /** Whether the column allows sorting. */
41
+ allowsSorting?: boolean;
42
+ /**
43
+ * Whether a column is a [row header](https://www.w3.org/TR/wai-aria-1.1/#rowheader) and should be
44
+ * announced by assistive technology during row navigation.
45
+ */
46
+ isRowHeader?: boolean;
47
+ /** A string representation of the column's contents, used for accessibility announcements. */
48
+ textValue?: string;
49
+ }
50
+
51
+ function Column<T>(props: ColumnProps<T>): any {
52
+ return null;
53
+ }
54
+
55
+ Column.getCollectionNode = function* getCollectionNode<T>(
56
+ props: ColumnProps<T>,
57
+ context: CollectionBuilderContext<T>,
58
+ ): Generator<PartialNode<T>, void, GridNode<T>[]> {
59
+ let { title, children, childColumns } = props;
60
+
61
+ let rendered = title || children;
62
+ let textValue =
63
+ props.textValue ||
64
+ (typeof rendered === 'string' ? rendered : '') ||
65
+ (props as any)['aria-label'];
66
+
67
+ let fullNodes = yield {
68
+ type: 'column',
69
+ hasChildNodes: !!childColumns || (!!title && Children.count(children) > 0),
70
+ rendered,
71
+ textValue,
72
+ props,
73
+ *childNodes() {
74
+ if (childColumns) {
75
+ for (let child of childColumns) {
76
+ yield {
77
+ type: 'column',
78
+ value: child,
79
+ };
80
+ }
81
+ } else if (title) {
82
+ let childColumns: PartialNode<T>[] = [];
83
+ Children.forEach(children, (child: any) => {
84
+ childColumns.push({
85
+ type: 'column',
86
+ element: child,
87
+ });
88
+ });
89
+
90
+ yield* childColumns;
91
+ }
92
+ },
93
+ shouldInvalidate(newContext: CollectionBuilderContext<T>) {
94
+ // This is a bit of a hack, but it works.
95
+ // If this method is called, then there's a cached version of this node available.
96
+ // But, we need to keep the list of columns in the new context up to date.
97
+ updateContext(newContext);
98
+ return false;
99
+ },
100
+ };
101
+
102
+ let updateContext = (context: CollectionBuilderContext<T>) => {
103
+ // register leaf columns on the context so that <Row> can access them
104
+ for (let node of fullNodes) {
105
+ if (!node.hasChildNodes) {
106
+ context.columns.push(node);
107
+ }
108
+ }
109
+ };
110
+
111
+ updateContext(context);
112
+ };
113
+
114
+ /**
115
+ * A Column represents a field of each item within a Table. Columns may also contain nested
116
+ * Column elements to represent column groups. Nested columns can be statically defined as
117
+ * children, or dynamically generated using a function based on the `childColumns` prop.
118
+ */
119
+ // We don't want getCollectionNode to show up in the type definition
120
+ let _Column = Column as unknown as <T>(props: ColumnProps<T>) => any;
121
+ export { _Column as Column };
@@ -0,0 +1,145 @@
1
+ // Ported from react-stately (source: .react-spectrum/packages/react-stately/src/table/Row.ts).
2
+ // octane adaptations: React.Children → octane Children (descriptor arrays); React element
3
+ // types → `any` descriptors. Renders nothing; walked via static `getCollectionNode`.
4
+ // The `node.type === Row` check compares against the INTERNAL function identity, which is
5
+ // what descriptor `.type` carries for `<Row>` used at a value position.
6
+ import type { LinkDOMProps } from '@react-types/shared';
7
+ import { Children } from 'octane';
8
+
9
+ import type { CellElement, CellRenderer } from './Cell';
10
+ import type { CollectionBuilderContext } from './useTableState';
11
+ import type { PartialNode } from '../collections/types';
12
+
13
+ export type RowElement<T> = any;
14
+ export interface RowProps<T> extends LinkDOMProps {
15
+ /**
16
+ * A list of child item objects used when dynamically rendering row children. Requires the feature
17
+ * flag to be enabled along with UNSTABLE_allowsExpandableRows, see
18
+ * https://react-spectrum.adobe.com/react-spectrum/TableView.html#expandable-rows.
19
+ *
20
+ * @private
21
+ * @version alpha
22
+ */
23
+ UNSTABLE_childItems?: Iterable<T>;
24
+ // TODO: update when async loading is supported for expandable rows
25
+ // /** Whether this row has children, even if not loaded yet. */
26
+ // hasChildItems?: boolean,
27
+ /** Rendered contents of the row or row child items. */
28
+ children: CellElement | CellElement[] | CellRenderer;
29
+ /** A string representation of the row's contents, used for features like typeahead. */
30
+ textValue?: string; // ???
31
+ }
32
+
33
+ function Row<T>(props: RowProps<T>): any {
34
+ return null;
35
+ }
36
+
37
+ Row.getCollectionNode = function* getCollectionNode<T>(
38
+ props: RowProps<T>,
39
+ context: CollectionBuilderContext<T>,
40
+ ): Generator<PartialNode<T>> {
41
+ let { children, textValue, UNSTABLE_childItems } = props;
42
+
43
+ yield {
44
+ type: 'item',
45
+ props: props,
46
+ textValue,
47
+ 'aria-label': (props as any)['aria-label'],
48
+ hasChildNodes: true,
49
+ *childNodes() {
50
+ // Process cells first
51
+ if (context.showDragButtons) {
52
+ yield {
53
+ type: 'cell',
54
+ key: 'header-drag', // this is combined with the row key by CollectionBuilder
55
+ props: {
56
+ isDragButtonCell: true,
57
+ },
58
+ };
59
+ }
60
+
61
+ if (context.showSelectionCheckboxes && context.selectionMode !== 'none') {
62
+ yield {
63
+ type: 'cell',
64
+ key: 'header', // this is combined with the row key by CollectionBuilder
65
+ props: {
66
+ isSelectionCell: true,
67
+ },
68
+ };
69
+ }
70
+
71
+ if (typeof children === 'function') {
72
+ for (let column of context.columns) {
73
+ yield {
74
+ type: 'cell',
75
+ element: children(column.key),
76
+ key: column.key, // this is combined with the row key by CollectionBuilder
77
+ };
78
+ }
79
+
80
+ if (UNSTABLE_childItems) {
81
+ for (let child of UNSTABLE_childItems) {
82
+ // Note: in order to reuse the render function of TableBody for our child rows, we just need to yield a type and a value here. CollectionBuilder will then look up
83
+ // the parent renderer and use that to build the full node of this child row, using the value provided here to generate the cells
84
+ yield {
85
+ type: 'item',
86
+ value: child,
87
+ };
88
+ }
89
+ }
90
+ } else {
91
+ let cells: PartialNode<T>[] = [];
92
+ let childRows: PartialNode<T>[] = [];
93
+ let columnCount = 0;
94
+ Children.forEach(children, (node: any) => {
95
+ if (node.type === Row) {
96
+ if (cells.length < context.columns.length) {
97
+ throw new Error(
98
+ "All of a Row's child Cells must be positioned before any child Rows.",
99
+ );
100
+ }
101
+
102
+ childRows.push({
103
+ type: 'item',
104
+ element: node,
105
+ });
106
+ } else {
107
+ cells.push({
108
+ type: 'cell',
109
+ element: node,
110
+ });
111
+ columnCount += node.props.colSpan ?? 1;
112
+ }
113
+ });
114
+
115
+ if (columnCount !== context.columns.length) {
116
+ throw new Error(
117
+ `Cell count must match column count. Found ${columnCount} cells and ${context.columns.length} columns.`,
118
+ );
119
+ }
120
+
121
+ yield* cells;
122
+ yield* childRows;
123
+ }
124
+ },
125
+ shouldInvalidate(newContext: CollectionBuilderContext<T>) {
126
+ // Invalidate all rows if the columns changed.
127
+ return (
128
+ newContext.columns.length !== context.columns.length ||
129
+ newContext.columns.some((c, i) => c.key !== context.columns[i].key) ||
130
+ newContext.showSelectionCheckboxes !== context.showSelectionCheckboxes ||
131
+ newContext.showDragButtons !== context.showDragButtons ||
132
+ newContext.selectionMode !== context.selectionMode
133
+ );
134
+ },
135
+ };
136
+ };
137
+
138
+ /**
139
+ * A Row represents a single item in a Table and contains Cell elements for each column.
140
+ * Cells can be statically defined as children, or generated dynamically using a function
141
+ * based on the columns defined in the TableHeader.
142
+ */
143
+ // We don't want getCollectionNode to show up in the type definition
144
+ let _Row = Row as unknown as <T>(props: RowProps<T>) => any;
145
+ export { _Row as Row };
@@ -0,0 +1,66 @@
1
+ // Ported from react-stately (source: .react-spectrum/packages/react-stately/src/table/TableBody.ts).
2
+ // octane adaptations: React.Children → octane Children (descriptor arrays); React element
3
+ // types → `any` descriptors. Renders nothing; walked via static `getCollectionNode`.
4
+ import type { AsyncLoadable, LoadingState } from '@react-types/shared';
5
+ import { Children } from 'octane';
6
+
7
+ import type { PartialNode } from '../collections/types';
8
+ import type { RowElement } from './Row';
9
+
10
+ export interface TableBodyProps<T> extends Omit<AsyncLoadable, 'isLoading'> {
11
+ /** The contents of the table body. Supports static items or a function for dynamic rendering. */
12
+ children: RowElement<T> | RowElement<T>[] | ((item: T) => RowElement<T>);
13
+ /** A list of row objects in the table body used when dynamically rendering rows. */
14
+ items?: Iterable<T>;
15
+ /** The current loading state of the table. */
16
+ loadingState?: LoadingState;
17
+ }
18
+
19
+ function TableBody<T>(props: TableBodyProps<T>): any {
20
+ return null;
21
+ }
22
+
23
+ TableBody.getCollectionNode = function* getCollectionNode<T>(
24
+ props: TableBodyProps<T>,
25
+ ): Generator<PartialNode<T>> {
26
+ let { children, items } = props;
27
+ yield {
28
+ type: 'body',
29
+ hasChildNodes: true,
30
+ props,
31
+ *childNodes() {
32
+ if (typeof children === 'function') {
33
+ if (!items) {
34
+ throw new Error('props.children was a function but props.items is missing');
35
+ }
36
+
37
+ for (let item of items) {
38
+ yield {
39
+ type: 'item',
40
+ value: item,
41
+ renderer: children,
42
+ };
43
+ }
44
+ } else {
45
+ let items: PartialNode<T>[] = [];
46
+ Children.forEach(children, (item: any) => {
47
+ items.push({
48
+ type: 'item',
49
+ element: item,
50
+ });
51
+ });
52
+
53
+ yield* items;
54
+ }
55
+ },
56
+ };
57
+ };
58
+
59
+ /**
60
+ * A TableBody is a container for the Row elements of a Table. Rows can be statically defined as
61
+ * children, or generated dynamically using a function based on the data passed to the `items`
62
+ * prop.
63
+ */
64
+ // We don't want getCollectionNode to show up in the type definition
65
+ let _TableBody = TableBody as unknown as <T>(props: TableBodyProps<T>) => any;
66
+ export { _TableBody as TableBody };