@react-stately/table 3.12.3 → 3.13.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -0
- package/dist/Cell.main.js.map +1 -1
- package/dist/Cell.module.js.map +1 -1
- package/dist/Column.main.js +1 -1
- package/dist/Column.main.js.map +1 -1
- package/dist/Column.mjs +1 -1
- package/dist/Column.module.js +1 -1
- package/dist/Column.module.js.map +1 -1
- package/dist/Row.main.js.map +1 -1
- package/dist/Row.module.js.map +1 -1
- package/dist/TableBody.main.js.map +1 -1
- package/dist/TableBody.module.js.map +1 -1
- package/dist/TableCollection.main.js +33 -17
- package/dist/TableCollection.main.js.map +1 -1
- package/dist/TableCollection.mjs +33 -17
- package/dist/TableCollection.module.js +33 -17
- package/dist/TableCollection.module.js.map +1 -1
- package/dist/TableColumnLayout.main.js +2 -2
- package/dist/TableColumnLayout.main.js.map +1 -1
- package/dist/TableColumnLayout.mjs +2 -2
- package/dist/TableColumnLayout.module.js +2 -2
- package/dist/TableColumnLayout.module.js.map +1 -1
- package/dist/TableHeader.main.js.map +1 -1
- package/dist/TableHeader.module.js.map +1 -1
- package/dist/TableUtils.main.js +1 -1
- package/dist/TableUtils.main.js.map +1 -1
- package/dist/TableUtils.mjs +1 -1
- package/dist/TableUtils.module.js +1 -1
- package/dist/TableUtils.module.js.map +1 -1
- package/dist/types.d.ts +8 -8
- package/dist/types.d.ts.map +1 -1
- package/dist/useTableColumnResizeState.main.js.map +1 -1
- package/dist/useTableColumnResizeState.module.js.map +1 -1
- package/dist/useTableState.main.js +4 -3
- package/dist/useTableState.main.js.map +1 -1
- package/dist/useTableState.mjs +4 -3
- package/dist/useTableState.module.js +4 -3
- package/dist/useTableState.module.js.map +1 -1
- package/dist/useTreeGridState.main.js +5 -5
- package/dist/useTreeGridState.main.js.map +1 -1
- package/dist/useTreeGridState.mjs +5 -5
- package/dist/useTreeGridState.module.js +5 -5
- package/dist/useTreeGridState.module.js.map +1 -1
- package/package.json +13 -12
- package/src/Cell.ts +1 -1
- package/src/Column.ts +2 -2
- package/src/Row.ts +1 -1
- package/src/TableBody.ts +1 -1
- package/src/TableCollection.ts +23 -19
- package/src/TableColumnLayout.ts +2 -2
- package/src/TableHeader.ts +1 -1
- package/src/TableUtils.ts +17 -6
- package/src/useTableColumnResizeState.ts +1 -1
- package/src/useTableState.ts +3 -3
- package/src/useTreeGridState.ts +12 -11
|
@@ -95,7 +95,7 @@ function $ee65a0057fd99531$var$convertExpanded(expanded) {
|
|
|
95
95
|
}
|
|
96
96
|
function $ee65a0057fd99531$var$generateTreeGridCollection(nodes, opts) {
|
|
97
97
|
let { expandedKeys: expandedKeys = new Set() } = opts;
|
|
98
|
-
let body;
|
|
98
|
+
let body = null;
|
|
99
99
|
let flattenedRows = [];
|
|
100
100
|
let columnCount = 0;
|
|
101
101
|
let userColumnCount = 0;
|
|
@@ -157,7 +157,7 @@ function $ee65a0057fd99531$var$generateTreeGridCollection(nodes, opts) {
|
|
|
157
157
|
// via .childNodes returns the same object as the one found via keyMap look up
|
|
158
158
|
Object.assign(node, newProps);
|
|
159
159
|
keyMap.set(node.key, node);
|
|
160
|
-
let lastNode;
|
|
160
|
+
let lastNode = null;
|
|
161
161
|
let rowIndex = 0;
|
|
162
162
|
for (let child of node.childNodes)if (!(child.type === 'item' && expandedKeys !== 'all' && !expandedKeys.has(node.key))) {
|
|
163
163
|
if (child.parentKey == null) // if child is a cell/expanded row/column and the parent key isn't already established by the collection, match child node to parent row
|
|
@@ -173,15 +173,15 @@ function $ee65a0057fd99531$var$generateTreeGridCollection(nodes, opts) {
|
|
|
173
173
|
}
|
|
174
174
|
if (lastNode) lastNode.nextKey = null;
|
|
175
175
|
};
|
|
176
|
-
let last;
|
|
177
|
-
topLevelRows.
|
|
176
|
+
let last = null;
|
|
177
|
+
for (let [i, node] of topLevelRows.entries()){
|
|
178
178
|
visitNode(node, i);
|
|
179
179
|
if (last) {
|
|
180
180
|
last.nextKey = node.key;
|
|
181
181
|
node.prevKey = last.key;
|
|
182
182
|
} else node.prevKey = null;
|
|
183
183
|
last = node;
|
|
184
|
-
}
|
|
184
|
+
}
|
|
185
185
|
if (last) last.nextKey = null;
|
|
186
186
|
return {
|
|
187
187
|
keyMap: keyMap,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"mappings":"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","sources":["packages/@react-stately/table/src/useTreeGridState.ts"],"sourcesContent":["/*\n * Copyright 2023 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {CollectionBuilder} from '@react-stately/collections';\nimport {GridNode} from '@react-types/grid';\nimport {Key} from '@react-types/shared';\nimport {ReactElement, useMemo} from 'react';\nimport {TableCollection} from './TableCollection';\nimport {tableNestedRows} from '@react-stately/flags';\nimport {TableState, TableStateProps, useTableState} from './useTableState';\nimport {useControlledState} from '@react-stately/utils';\n\nexport interface TreeGridState<T> extends TableState<T> {\n /** A set of keys for items that are expanded. */\n expandedKeys: 'all' | Set<Key>,\n /** Toggles the expanded state for a row by its key. */\n toggleKey(key: Key): void,\n /** The key map containing nodes representing the collection's tree grid structure. */\n keyMap: Map<Key, GridNode<T>>,\n /** The number of leaf columns provided by the user. */\n userColumnCount: number\n}\n\nexport interface TreeGridStateProps<T> extends Omit<TableStateProps<T>, 'collection'> {\n /** The currently expanded keys in the collection (controlled). */\n UNSTABLE_expandedKeys?: 'all' | Iterable<Key>,\n /** The initial expanded keys in the collection (uncontrolled). */\n UNSTABLE_defaultExpandedKeys?: 'all' | Iterable<Key>,\n /** Handler that is called when items are expanded or collapsed. */\n UNSTABLE_onExpandedChange?: (keys: Set<Key>) => any\n}\n\n/**\n * Provides state management for a tree grid component. Handles building a collection\n * of columns and rows from props. In addition, it tracks and manages expanded rows, row selection, and sort order changes.\n */\nexport function UNSTABLE_useTreeGridState<T extends object>(props: TreeGridStateProps<T>): TreeGridState<T> {\n let {\n selectionMode = 'none',\n showSelectionCheckboxes,\n showDragButtons,\n UNSTABLE_expandedKeys: propExpandedKeys,\n UNSTABLE_defaultExpandedKeys: propDefaultExpandedKeys,\n UNSTABLE_onExpandedChange,\n children\n } = props;\n\n if (!tableNestedRows()) {\n throw new Error('Feature flag for table nested rows must be enabled to use useTreeGridState.');\n }\n\n let [expandedKeys, setExpandedKeys] = useControlledState(\n propExpandedKeys ? convertExpanded(propExpandedKeys) : undefined,\n propDefaultExpandedKeys ? convertExpanded(propDefaultExpandedKeys) : new Set(),\n UNSTABLE_onExpandedChange\n );\n\n let context = useMemo(() => ({\n showSelectionCheckboxes: showSelectionCheckboxes && selectionMode !== 'none',\n showDragButtons: showDragButtons,\n selectionMode,\n columns: []\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }), [children, showSelectionCheckboxes, selectionMode, showDragButtons]);\n\n let builder = useMemo(() => new CollectionBuilder<T>(), []);\n let nodes = useMemo(() => builder.build({children: children as ReactElement<any>[]}, context), [builder, children, context]);\n let treeGridCollection = useMemo(() => {\n return generateTreeGridCollection<T>(nodes, {showSelectionCheckboxes, showDragButtons, expandedKeys});\n }, [nodes, showSelectionCheckboxes, showDragButtons, expandedKeys]);\n\n let onToggle = (key: Key) => {\n setExpandedKeys(toggleKey(expandedKeys, key, treeGridCollection));\n };\n\n let collection = useMemo(() => {\n return new TableCollection(treeGridCollection.tableNodes, null, context);\n }, [context, treeGridCollection.tableNodes]);\n\n let tableState = useTableState({...props, collection});\n return {\n ...tableState,\n keyMap: treeGridCollection.keyMap,\n userColumnCount: treeGridCollection.userColumnCount,\n expandedKeys,\n toggleKey: onToggle\n };\n}\n\nfunction toggleKey<T>(currentExpandedKeys: 'all' | Set<Key>, key: Key, collection: TreeGridCollection<T>): Set<Key> {\n let updatedExpandedKeys: Set<Key>;\n if (currentExpandedKeys === 'all') {\n updatedExpandedKeys = new Set(collection.flattenedRows.filter(row => row.props.UNSTABLE_childItems || row.props.children.length > collection.userColumnCount).map(row => row.key));\n updatedExpandedKeys.delete(key);\n } else {\n updatedExpandedKeys = new Set(currentExpandedKeys);\n if (updatedExpandedKeys.has(key)) {\n updatedExpandedKeys.delete(key);\n } else {\n updatedExpandedKeys.add(key);\n }\n }\n\n return updatedExpandedKeys;\n}\n\nfunction convertExpanded(expanded: 'all' | Iterable<Key>): 'all' | Set<Key> {\n if (!expanded) {\n return new Set<Key>();\n }\n\n return expanded === 'all'\n ? 'all'\n : new Set(expanded);\n}\n\ninterface TreeGridCollectionOptions {\n showSelectionCheckboxes?: boolean,\n showDragButtons?: boolean,\n expandedKeys: 'all' | Set<Key>\n}\n\ninterface TreeGridCollection<T> {\n keyMap: Map<Key, GridNode<T>>,\n tableNodes: GridNode<T>[],\n flattenedRows: GridNode<T>[],\n userColumnCount: number\n}\nfunction generateTreeGridCollection<T>(nodes, opts: TreeGridCollectionOptions): TreeGridCollection<T> {\n let {\n expandedKeys = new Set()\n } = opts;\n\n let body: GridNode<T>;\n let flattenedRows = [];\n let columnCount = 0;\n let userColumnCount = 0;\n let originalColumns = [];\n let keyMap = new Map();\n\n if (opts?.showSelectionCheckboxes) {\n columnCount++;\n }\n\n if (opts?.showDragButtons) {\n columnCount++;\n }\n\n let topLevelRows = [];\n let visit = (node: GridNode<T>) => {\n switch (node.type) {\n case 'body':\n body = node;\n keyMap.set(body.key, body);\n break;\n case 'column':\n if (!node.hasChildNodes) {\n userColumnCount++;\n }\n break;\n case 'item':\n topLevelRows.push(node);\n return;\n }\n\n for (let child of node.childNodes) {\n visit(child);\n }\n };\n\n for (let node of nodes) {\n if (node.type === 'column') {\n originalColumns.push(node);\n }\n visit(node);\n }\n columnCount += userColumnCount;\n\n // Update each grid node in the treegrid table with values specific to a treegrid structure. Also store a set of flattened row nodes for TableCollection to consume\n let globalRowCount = 0;\n let visitNode = (node: GridNode<T>, i?: number) => {\n // Clone row node and its children so modifications to the node for treegrid specific values aren't applied on the nodes provided\n // to TableCollection. Index, level, and parent keys are all changed to reflect a flattened row structure rather than the treegrid structure\n // values automatically calculated via CollectionBuilder\n if (node.type === 'item') {\n let childNodes = [];\n for (let child of node.childNodes) {\n if (child.type === 'cell') {\n let cellClone = {...child};\n if (cellClone.index + 1 === columnCount) {\n cellClone.nextKey = null;\n }\n childNodes.push({...cellClone});\n }\n }\n let clone = {...node, childNodes: childNodes, parentKey: body.key, level: 1, index: globalRowCount++};\n flattenedRows.push(clone);\n }\n\n let newProps = {};\n\n // Assign indexOfType to cells and rows for aria-posinset\n if (node.type !== 'placeholder' && node.type !== 'column') {\n newProps['indexOfType'] = i;\n }\n\n // Use Object.assign instead of spread to preserve object reference for keyMap. Also ensures retrieving nodes\n // via .childNodes returns the same object as the one found via keyMap look up\n Object.assign(node, newProps);\n keyMap.set(node.key, node);\n\n let lastNode: GridNode<T>;\n let rowIndex = 0;\n for (let child of node.childNodes) {\n if (!(child.type === 'item' && expandedKeys !== 'all' && !expandedKeys.has(node.key))) {\n if (child.parentKey == null) {\n // if child is a cell/expanded row/column and the parent key isn't already established by the collection, match child node to parent row\n child.parentKey = node.key;\n }\n\n if (lastNode) {\n lastNode.nextKey = child.key;\n child.prevKey = lastNode.key;\n } else {\n child.prevKey = null;\n }\n\n if (child.type === 'item') {\n visitNode(child, rowIndex++);\n } else {\n // We enforce that the cells come before rows so can just reuse cell index\n visitNode(child, child.index);\n }\n\n lastNode = child;\n }\n }\n\n if (lastNode) {\n lastNode.nextKey = null;\n }\n };\n\n let last: GridNode<T>;\n topLevelRows.forEach((node: GridNode<T>, i) => {\n visitNode(node as GridNode<T>, i);\n\n if (last) {\n last.nextKey = node.key;\n node.prevKey = last.key;\n } else {\n node.prevKey = null;\n }\n\n last = node;\n });\n\n if (last) {\n last.nextKey = null;\n }\n\n return {\n keyMap,\n userColumnCount,\n flattenedRows,\n tableNodes: [...originalColumns, {...body, childNodes: flattenedRows}]\n };\n}\n"],"names":[],"version":3,"file":"useTreeGridState.module.js.map"}
|
|
1
|
+
{"mappings":"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","sources":["packages/@react-stately/table/src/useTreeGridState.ts"],"sourcesContent":["/*\n * Copyright 2023 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {CollectionBuilder} from '@react-stately/collections';\nimport {GridNode} from '@react-types/grid';\nimport {Key} from '@react-types/shared';\nimport {ReactElement, useMemo} from 'react';\nimport {TableCollection} from './TableCollection';\nimport {tableNestedRows} from '@react-stately/flags';\nimport {TableState, TableStateProps, useTableState} from './useTableState';\nimport {useControlledState} from '@react-stately/utils';\n\nexport interface TreeGridState<T> extends TableState<T> {\n /** A set of keys for items that are expanded. */\n expandedKeys: 'all' | Set<Key>,\n /** Toggles the expanded state for a row by its key. */\n toggleKey(key: Key): void,\n /** The key map containing nodes representing the collection's tree grid structure. */\n keyMap: Map<Key, GridNode<T>>,\n /** The number of leaf columns provided by the user. */\n userColumnCount: number\n}\n\nexport interface TreeGridStateProps<T> extends Omit<TableStateProps<T>, 'collection'> {\n /** The currently expanded keys in the collection (controlled). */\n UNSTABLE_expandedKeys?: 'all' | Iterable<Key>,\n /** The initial expanded keys in the collection (uncontrolled). */\n UNSTABLE_defaultExpandedKeys?: 'all' | Iterable<Key>,\n /** Handler that is called when items are expanded or collapsed. */\n UNSTABLE_onExpandedChange?: (keys: Set<Key>) => any\n}\n\n/**\n * Provides state management for a tree grid component. Handles building a collection\n * of columns and rows from props. In addition, it tracks and manages expanded rows, row selection, and sort order changes.\n */\nexport function UNSTABLE_useTreeGridState<T extends object>(props: TreeGridStateProps<T>): TreeGridState<T> {\n let {\n selectionMode = 'none',\n showSelectionCheckboxes,\n showDragButtons,\n UNSTABLE_expandedKeys: propExpandedKeys,\n UNSTABLE_defaultExpandedKeys: propDefaultExpandedKeys,\n UNSTABLE_onExpandedChange,\n children\n } = props;\n\n if (!tableNestedRows()) {\n throw new Error('Feature flag for table nested rows must be enabled to use useTreeGridState.');\n }\n\n let [expandedKeys, setExpandedKeys] = useControlledState(\n propExpandedKeys ? convertExpanded(propExpandedKeys) : undefined,\n propDefaultExpandedKeys ? convertExpanded(propDefaultExpandedKeys) : new Set(),\n UNSTABLE_onExpandedChange\n );\n\n let context = useMemo(() => ({\n showSelectionCheckboxes: showSelectionCheckboxes && selectionMode !== 'none',\n showDragButtons: showDragButtons,\n selectionMode,\n columns: []\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }), [children, showSelectionCheckboxes, selectionMode, showDragButtons]);\n\n let builder = useMemo(() => new CollectionBuilder<T>(), []);\n let nodes = useMemo(() => builder.build({children: children as ReactElement<any>[]}, context), [builder, children, context]);\n let treeGridCollection = useMemo(() => {\n return generateTreeGridCollection<T>(nodes, {showSelectionCheckboxes, showDragButtons, expandedKeys});\n }, [nodes, showSelectionCheckboxes, showDragButtons, expandedKeys]);\n\n let onToggle = (key: Key) => {\n setExpandedKeys(toggleKey(expandedKeys, key, treeGridCollection));\n };\n\n let collection = useMemo(() => {\n return new TableCollection(treeGridCollection.tableNodes, null, context);\n }, [context, treeGridCollection.tableNodes]);\n\n let tableState = useTableState({...props, collection});\n return {\n ...tableState,\n keyMap: treeGridCollection.keyMap,\n userColumnCount: treeGridCollection.userColumnCount,\n expandedKeys,\n toggleKey: onToggle\n };\n}\n\nfunction toggleKey<T>(currentExpandedKeys: 'all' | Set<Key>, key: Key, collection: TreeGridCollection<T>): Set<Key> {\n let updatedExpandedKeys: Set<Key>;\n if (currentExpandedKeys === 'all') {\n updatedExpandedKeys = new Set(collection.flattenedRows.filter(row => row.props.UNSTABLE_childItems || row.props.children.length > collection.userColumnCount).map(row => row.key));\n updatedExpandedKeys.delete(key);\n } else {\n updatedExpandedKeys = new Set(currentExpandedKeys);\n if (updatedExpandedKeys.has(key)) {\n updatedExpandedKeys.delete(key);\n } else {\n updatedExpandedKeys.add(key);\n }\n }\n\n return updatedExpandedKeys;\n}\n\nfunction convertExpanded(expanded: 'all' | Iterable<Key>): 'all' | Set<Key> {\n if (!expanded) {\n return new Set<Key>();\n }\n\n return expanded === 'all'\n ? 'all'\n : new Set(expanded);\n}\n\ninterface TreeGridCollectionOptions {\n showSelectionCheckboxes?: boolean,\n showDragButtons?: boolean,\n expandedKeys: 'all' | Set<Key>\n}\n\ninterface TreeGridCollection<T> {\n keyMap: Map<Key, GridNode<T>>,\n tableNodes: GridNode<T>[],\n flattenedRows: GridNode<T>[],\n userColumnCount: number\n}\nfunction generateTreeGridCollection<T>(nodes, opts: TreeGridCollectionOptions): TreeGridCollection<T> {\n let {\n expandedKeys = new Set()\n } = opts;\n\n let body: GridNode<T> | null = null;\n let flattenedRows: GridNode<T>[] = [];\n let columnCount = 0;\n let userColumnCount = 0;\n let originalColumns: GridNode<T>[] = [];\n let keyMap = new Map();\n\n if (opts?.showSelectionCheckboxes) {\n columnCount++;\n }\n\n if (opts?.showDragButtons) {\n columnCount++;\n }\n\n let topLevelRows: GridNode<T>[] = [];\n let visit = (node: GridNode<T>) => {\n switch (node.type) {\n case 'body':\n body = node;\n keyMap.set(body.key, body);\n break;\n case 'column':\n if (!node.hasChildNodes) {\n userColumnCount++;\n }\n break;\n case 'item':\n topLevelRows.push(node);\n return;\n }\n\n for (let child of node.childNodes) {\n visit(child);\n }\n };\n\n for (let node of nodes) {\n if (node.type === 'column') {\n originalColumns.push(node);\n }\n visit(node);\n }\n\n columnCount += userColumnCount;\n\n // Update each grid node in the treegrid table with values specific to a treegrid structure. Also store a set of flattened row nodes for TableCollection to consume\n let globalRowCount = 0;\n let visitNode = (node: GridNode<T>, i?: number) => {\n // Clone row node and its children so modifications to the node for treegrid specific values aren't applied on the nodes provided\n // to TableCollection. Index, level, and parent keys are all changed to reflect a flattened row structure rather than the treegrid structure\n // values automatically calculated via CollectionBuilder\n if (node.type === 'item') {\n let childNodes: GridNode<T>[] = [];\n for (let child of node.childNodes) {\n if (child.type === 'cell') {\n let cellClone = {...child};\n if (cellClone.index + 1 === columnCount) {\n cellClone.nextKey = null;\n }\n childNodes.push({...cellClone});\n }\n }\n let clone: GridNode<T> = {...node, childNodes: childNodes, parentKey: body!.key, level: 1, index: globalRowCount++};\n flattenedRows.push(clone);\n }\n\n let newProps = {};\n\n // Assign indexOfType to cells and rows for aria-posinset\n if (node.type !== 'placeholder' && node.type !== 'column') {\n newProps['indexOfType'] = i;\n }\n\n // Use Object.assign instead of spread to preserve object reference for keyMap. Also ensures retrieving nodes\n // via .childNodes returns the same object as the one found via keyMap look up\n Object.assign(node, newProps);\n keyMap.set(node.key, node);\n\n let lastNode: GridNode<T> | null = null;\n let rowIndex = 0;\n for (let child of node.childNodes) {\n if (!(child.type === 'item' && expandedKeys !== 'all' && !expandedKeys.has(node.key))) {\n if (child.parentKey == null) {\n // if child is a cell/expanded row/column and the parent key isn't already established by the collection, match child node to parent row\n child.parentKey = node.key;\n }\n\n if (lastNode) {\n lastNode.nextKey = child.key;\n child.prevKey = lastNode.key;\n } else {\n child.prevKey = null;\n }\n\n if (child.type === 'item') {\n visitNode(child, rowIndex++);\n } else {\n // We enforce that the cells come before rows so can just reuse cell index\n visitNode(child, child.index);\n }\n\n lastNode = child;\n }\n }\n\n if (lastNode) {\n lastNode.nextKey = null;\n }\n };\n\n let last: GridNode<T> | null = null;\n for (let [i, node] of topLevelRows.entries()) {\n visitNode(node as GridNode<T>, i);\n\n if (last) {\n last.nextKey = node.key;\n node.prevKey = last.key;\n } else {\n node.prevKey = null;\n }\n\n last = node;\n }\n\n if (last) {\n last.nextKey = null;\n }\n\n return {\n keyMap,\n userColumnCount,\n flattenedRows,\n tableNodes: [...originalColumns, {...body!, childNodes: flattenedRows}]\n };\n}\n"],"names":[],"version":3,"file":"useTreeGridState.module.js.map"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@react-stately/table",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.13.1",
|
|
4
4
|
"description": "Spectrum UI components in React",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"main": "dist/main.js",
|
|
@@ -22,20 +22,21 @@
|
|
|
22
22
|
"url": "https://github.com/adobe/react-spectrum"
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
|
-
"@react-stately/collections": "^3.
|
|
26
|
-
"@react-stately/flags": "^3.0.
|
|
27
|
-
"@react-stately/grid": "^3.
|
|
28
|
-
"@react-stately/selection": "^3.
|
|
29
|
-
"@react-stately/utils": "^3.10.
|
|
30
|
-
"@react-types/grid": "^3.2.
|
|
31
|
-
"@react-types/shared": "^3.
|
|
32
|
-
"@react-types/table": "^3.10.
|
|
25
|
+
"@react-stately/collections": "^3.12.1",
|
|
26
|
+
"@react-stately/flags": "^3.0.5",
|
|
27
|
+
"@react-stately/grid": "^3.10.1",
|
|
28
|
+
"@react-stately/selection": "^3.19.0",
|
|
29
|
+
"@react-stately/utils": "^3.10.5",
|
|
30
|
+
"@react-types/grid": "^3.2.11",
|
|
31
|
+
"@react-types/shared": "^3.27.0",
|
|
32
|
+
"@react-types/table": "^3.10.4",
|
|
33
33
|
"@swc/helpers": "^0.5.0"
|
|
34
34
|
},
|
|
35
35
|
"peerDependencies": {
|
|
36
|
-
"react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0"
|
|
36
|
+
"react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
|
|
37
37
|
},
|
|
38
38
|
"publishConfig": {
|
|
39
39
|
"access": "public"
|
|
40
|
-
}
|
|
41
|
-
|
|
40
|
+
},
|
|
41
|
+
"gitHead": "09e7f44bebdc9d89122926b2b439a0a38a2814ea"
|
|
42
|
+
}
|
package/src/Cell.ts
CHANGED
|
@@ -14,7 +14,7 @@ import {CellProps} from '@react-types/table';
|
|
|
14
14
|
import {JSX, ReactElement} from 'react';
|
|
15
15
|
import {PartialNode} from '@react-stately/collections';
|
|
16
16
|
|
|
17
|
-
function Cell(props: CellProps): ReactElement { // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
17
|
+
function Cell(props: CellProps): ReactElement | null { // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
18
18
|
return null;
|
|
19
19
|
}
|
|
20
20
|
|
package/src/Column.ts
CHANGED
|
@@ -16,7 +16,7 @@ import {GridNode} from '@react-types/grid';
|
|
|
16
16
|
import {PartialNode} from '@react-stately/collections';
|
|
17
17
|
import React, {JSX, ReactElement} from 'react';
|
|
18
18
|
|
|
19
|
-
function Column<T>(props: ColumnProps<T>): ReactElement { // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
19
|
+
function Column<T>(props: ColumnProps<T>): ReactElement | null { // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
20
20
|
return null;
|
|
21
21
|
}
|
|
22
22
|
|
|
@@ -28,7 +28,7 @@ Column.getCollectionNode = function* getCollectionNode<T>(props: ColumnProps<T>,
|
|
|
28
28
|
|
|
29
29
|
let fullNodes = yield {
|
|
30
30
|
type: 'column',
|
|
31
|
-
hasChildNodes: !!childColumns || (title && React.Children.count(children) > 0),
|
|
31
|
+
hasChildNodes: !!childColumns || (!!title && React.Children.count(children) > 0),
|
|
32
32
|
rendered,
|
|
33
33
|
textValue,
|
|
34
34
|
props,
|
package/src/Row.ts
CHANGED
|
@@ -15,7 +15,7 @@ import {PartialNode} from '@react-stately/collections';
|
|
|
15
15
|
import React, {JSX, ReactElement} from 'react';
|
|
16
16
|
import {RowProps} from '@react-types/table';
|
|
17
17
|
|
|
18
|
-
function Row<T>(props: RowProps<T>): ReactElement { // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
18
|
+
function Row<T>(props: RowProps<T>): ReactElement | null { // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
19
19
|
return null;
|
|
20
20
|
}
|
|
21
21
|
|
package/src/TableBody.ts
CHANGED
|
@@ -14,7 +14,7 @@ import {PartialNode} from '@react-stately/collections';
|
|
|
14
14
|
import React, {JSX, ReactElement} from 'react';
|
|
15
15
|
import {TableBodyProps} from '@react-types/table';
|
|
16
16
|
|
|
17
|
-
function TableBody<T>(props: TableBodyProps<T>): ReactElement { // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
17
|
+
function TableBody<T>(props: TableBodyProps<T>): ReactElement | null { // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
18
18
|
return null;
|
|
19
19
|
}
|
|
20
20
|
|
package/src/TableCollection.ts
CHANGED
|
@@ -40,7 +40,7 @@ export function buildHeaderRows<T>(keyMap: Map<Key, GridNode<T>>, columnNodes: G
|
|
|
40
40
|
let col = [column];
|
|
41
41
|
|
|
42
42
|
while (parentKey) {
|
|
43
|
-
let parent: GridNode<T> = keyMap.get(parentKey);
|
|
43
|
+
let parent: GridNode<T> | undefined = keyMap.get(parentKey);
|
|
44
44
|
if (!parent) {
|
|
45
45
|
break;
|
|
46
46
|
}
|
|
@@ -50,6 +50,7 @@ export function buildHeaderRows<T>(keyMap: Map<Key, GridNode<T>>, columnNodes: G
|
|
|
50
50
|
// than the previous column, than we need to shift the parent
|
|
51
51
|
// in the previous column so it's level with the current column.
|
|
52
52
|
if (seen.has(parent)) {
|
|
53
|
+
parent.colspan ??= 0;
|
|
53
54
|
parent.colspan++;
|
|
54
55
|
|
|
55
56
|
let {column, index} = seen.get(parent);
|
|
@@ -82,7 +83,7 @@ export function buildHeaderRows<T>(keyMap: Map<Key, GridNode<T>>, columnNodes: G
|
|
|
82
83
|
}
|
|
83
84
|
|
|
84
85
|
let maxLength = Math.max(...columns.map(c => c.length));
|
|
85
|
-
let headerRows = Array(maxLength).fill(0).map(() => []);
|
|
86
|
+
let headerRows: GridNode<T>[][] = Array(maxLength).fill(0).map(() => []);
|
|
86
87
|
|
|
87
88
|
// Convert columns into rows.
|
|
88
89
|
let colIndex = 0;
|
|
@@ -92,7 +93,7 @@ export function buildHeaderRows<T>(keyMap: Map<Key, GridNode<T>>, columnNodes: G
|
|
|
92
93
|
if (item) {
|
|
93
94
|
// Fill the space up until the current column with a placeholder
|
|
94
95
|
let row = headerRows[i];
|
|
95
|
-
let rowLength = row.reduce((p, c) => p + c.colspan, 0);
|
|
96
|
+
let rowLength = row.reduce((p, c) => p + (c.colspan ?? 1), 0);
|
|
96
97
|
if (rowLength < colIndex) {
|
|
97
98
|
let placeholder: GridNode<T> = {
|
|
98
99
|
type: 'placeholder',
|
|
@@ -104,7 +105,7 @@ export function buildHeaderRows<T>(keyMap: Map<Key, GridNode<T>>, columnNodes: G
|
|
|
104
105
|
level: i,
|
|
105
106
|
hasChildNodes: false,
|
|
106
107
|
childNodes: [],
|
|
107
|
-
textValue:
|
|
108
|
+
textValue: ''
|
|
108
109
|
};
|
|
109
110
|
|
|
110
111
|
// eslint-disable-next-line max-depth
|
|
@@ -135,7 +136,7 @@ export function buildHeaderRows<T>(keyMap: Map<Key, GridNode<T>>, columnNodes: G
|
|
|
135
136
|
// Add placeholders at the end of each row that is shorter than the maximum
|
|
136
137
|
let i = 0;
|
|
137
138
|
for (let row of headerRows) {
|
|
138
|
-
let rowLength = row.reduce((p, c) => p + c.colspan, 0);
|
|
139
|
+
let rowLength = row.reduce((p, c) => p + (c.colspan ?? 1), 0);
|
|
139
140
|
if (rowLength < columnNodes.length) {
|
|
140
141
|
let placeholder: GridNode<T> = {
|
|
141
142
|
type: 'placeholder',
|
|
@@ -147,7 +148,7 @@ export function buildHeaderRows<T>(keyMap: Map<Key, GridNode<T>>, columnNodes: G
|
|
|
147
148
|
level: i,
|
|
148
149
|
hasChildNodes: false,
|
|
149
150
|
childNodes: [],
|
|
150
|
-
textValue:
|
|
151
|
+
textValue: '',
|
|
151
152
|
prevKey: row[row.length - 1].key
|
|
152
153
|
};
|
|
153
154
|
|
|
@@ -167,7 +168,7 @@ export function buildHeaderRows<T>(keyMap: Map<Key, GridNode<T>>, columnNodes: G
|
|
|
167
168
|
level: 0,
|
|
168
169
|
hasChildNodes: true,
|
|
169
170
|
childNodes,
|
|
170
|
-
textValue:
|
|
171
|
+
textValue: ''
|
|
171
172
|
};
|
|
172
173
|
|
|
173
174
|
return row;
|
|
@@ -181,9 +182,9 @@ export class TableCollection<T> extends GridCollection<T> implements ITableColle
|
|
|
181
182
|
body: GridNode<T>;
|
|
182
183
|
_size: number = 0;
|
|
183
184
|
|
|
184
|
-
constructor(nodes: Iterable<GridNode<T>>, prev?: ITableCollection<T
|
|
185
|
+
constructor(nodes: Iterable<GridNode<T>>, prev?: ITableCollection<T> | null, opts?: GridCollectionOptions) {
|
|
185
186
|
let rowHeaderColumnKeys: Set<Key> = new Set();
|
|
186
|
-
let body: GridNode<T
|
|
187
|
+
let body: GridNode<T> | null = null;
|
|
187
188
|
let columns: GridNode<T>[] = [];
|
|
188
189
|
// Add cell for selection checkboxes if needed.
|
|
189
190
|
if (opts?.showSelectionCheckboxes) {
|
|
@@ -225,7 +226,7 @@ export class TableCollection<T> extends GridCollection<T> implements ITableColle
|
|
|
225
226
|
columns.unshift(rowHeaderColumn);
|
|
226
227
|
}
|
|
227
228
|
|
|
228
|
-
let rows = [];
|
|
229
|
+
let rows: GridNode<T>[] = [];
|
|
229
230
|
let columnKeyMap = new Map();
|
|
230
231
|
let visit = (node: GridNode<T>) => {
|
|
231
232
|
switch (node.type) {
|
|
@@ -268,13 +269,16 @@ export class TableCollection<T> extends GridCollection<T> implements ITableColle
|
|
|
268
269
|
});
|
|
269
270
|
this.columns = columns;
|
|
270
271
|
this.rowHeaderColumnKeys = rowHeaderColumnKeys;
|
|
271
|
-
this.body = body
|
|
272
|
+
this.body = body!;
|
|
272
273
|
this.headerRows = headerRows;
|
|
273
|
-
this._size = [...body
|
|
274
|
+
this._size = [...body!.childNodes].length;
|
|
274
275
|
|
|
275
276
|
// Default row header column to the first one.
|
|
276
277
|
if (this.rowHeaderColumnKeys.size === 0) {
|
|
277
|
-
this.
|
|
278
|
+
let col = this.columns.find(column => !column.props?.isDragButtonCell && !column.props?.isSelectionCell);
|
|
279
|
+
if (col) {
|
|
280
|
+
this.rowHeaderColumnKeys.add(col.key);
|
|
281
|
+
}
|
|
278
282
|
}
|
|
279
283
|
}
|
|
280
284
|
|
|
@@ -292,24 +296,24 @@ export class TableCollection<T> extends GridCollection<T> implements ITableColle
|
|
|
292
296
|
|
|
293
297
|
getKeyBefore(key: Key) {
|
|
294
298
|
let node = this.keyMap.get(key);
|
|
295
|
-
return node
|
|
299
|
+
return node?.prevKey ?? null;
|
|
296
300
|
}
|
|
297
301
|
|
|
298
302
|
getKeyAfter(key: Key) {
|
|
299
303
|
let node = this.keyMap.get(key);
|
|
300
|
-
return node
|
|
304
|
+
return node?.nextKey ?? null;
|
|
301
305
|
}
|
|
302
306
|
|
|
303
307
|
getFirstKey() {
|
|
304
|
-
return getFirstItem(this.body.childNodes)?.key;
|
|
308
|
+
return getFirstItem(this.body.childNodes)?.key ?? null;
|
|
305
309
|
}
|
|
306
310
|
|
|
307
311
|
getLastKey() {
|
|
308
|
-
return getLastItem(this.body.childNodes)?.key;
|
|
312
|
+
return getLastItem(this.body.childNodes)?.key ?? null;
|
|
309
313
|
}
|
|
310
314
|
|
|
311
315
|
getItem(key: Key) {
|
|
312
|
-
return this.keyMap.get(key);
|
|
316
|
+
return this.keyMap.get(key) ?? null;
|
|
313
317
|
}
|
|
314
318
|
|
|
315
319
|
at(idx: number) {
|
|
@@ -339,7 +343,7 @@ export class TableCollection<T> extends GridCollection<T> implements ITableColle
|
|
|
339
343
|
// Otherwise combine the text of each of the row header columns.
|
|
340
344
|
let rowHeaderColumnKeys = this.rowHeaderColumnKeys;
|
|
341
345
|
if (rowHeaderColumnKeys) {
|
|
342
|
-
let text = [];
|
|
346
|
+
let text: string[] = [];
|
|
343
347
|
for (let cell of row.childNodes) {
|
|
344
348
|
let column = this.columns[cell.index];
|
|
345
349
|
if (rowHeaderColumnKeys.has(column.key) && cell.textValue) {
|
package/src/TableColumnLayout.ts
CHANGED
|
@@ -54,7 +54,7 @@ export class TableColumnLayout<T> {
|
|
|
54
54
|
if (uncontrolledColumns.has(col.key)) {
|
|
55
55
|
return [col.key, uncontrolledWidths.get(col.key)];
|
|
56
56
|
} else {
|
|
57
|
-
return [col.key, controlledColumns.get(col.key)
|
|
57
|
+
return [col.key, controlledColumns.get(col.key)!.props.width];
|
|
58
58
|
}
|
|
59
59
|
}));
|
|
60
60
|
}
|
|
@@ -91,7 +91,7 @@ export class TableColumnLayout<T> {
|
|
|
91
91
|
freeze = false;
|
|
92
92
|
} else if (freeze) {
|
|
93
93
|
// freeze columns to the left to their previous pixel value
|
|
94
|
-
newWidths.set(column.key, prevColumnWidths.get(column.key));
|
|
94
|
+
newWidths.set(column.key, prevColumnWidths.get(column.key) ?? 0);
|
|
95
95
|
} else {
|
|
96
96
|
newWidths.set(column.key, column.props.width ?? uncontrolledWidths.get(column.key));
|
|
97
97
|
}
|
package/src/TableHeader.ts
CHANGED
|
@@ -15,7 +15,7 @@ import {PartialNode} from '@react-stately/collections';
|
|
|
15
15
|
import React, {JSX, ReactElement} from 'react';
|
|
16
16
|
import {TableHeaderProps} from '@react-types/table';
|
|
17
17
|
|
|
18
|
-
function TableHeader<T>(props: TableHeaderProps<T>): ReactElement { // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
18
|
+
function TableHeader<T>(props: TableHeaderProps<T>): ReactElement | null { // eslint-disable-line @typescript-eslint/no-unused-vars
|
|
19
19
|
return null;
|
|
20
20
|
}
|
|
21
21
|
|
package/src/TableUtils.ts
CHANGED
|
@@ -44,7 +44,7 @@ export function parseStaticWidth(width: number | string, tableWidth: number): nu
|
|
|
44
44
|
}
|
|
45
45
|
|
|
46
46
|
|
|
47
|
-
export function getMaxWidth(maxWidth: number | string, tableWidth: number): number {
|
|
47
|
+
export function getMaxWidth(maxWidth: number | string | null | undefined, tableWidth: number): number {
|
|
48
48
|
return maxWidth != null
|
|
49
49
|
? parseStaticWidth(maxWidth, tableWidth)
|
|
50
50
|
: Number.MAX_SAFE_INTEGER;
|
|
@@ -63,7 +63,18 @@ export interface IColumn {
|
|
|
63
63
|
maxWidth?: number | string,
|
|
64
64
|
width?: number | string,
|
|
65
65
|
defaultWidth?: number | string,
|
|
66
|
-
key
|
|
66
|
+
key: Key
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
interface FlexItem {
|
|
70
|
+
frozen: boolean,
|
|
71
|
+
baseSize: number,
|
|
72
|
+
hypotheticalMainSize: number,
|
|
73
|
+
min: number,
|
|
74
|
+
max: number,
|
|
75
|
+
flex: number,
|
|
76
|
+
targetMainSize: number,
|
|
77
|
+
violation: number
|
|
67
78
|
}
|
|
68
79
|
|
|
69
80
|
/**
|
|
@@ -93,12 +104,12 @@ export interface IColumn {
|
|
|
93
104
|
*/
|
|
94
105
|
export function calculateColumnSizes(availableWidth: number, columns: IColumn[], changedColumns: Map<Key, ColumnSize>, getDefaultWidth, getDefaultMinWidth) {
|
|
95
106
|
let hasNonFrozenItems = false;
|
|
96
|
-
let flexItems = columns.map((column, index) => {
|
|
107
|
+
let flexItems: FlexItem[] = columns.map((column, index) => {
|
|
97
108
|
let width = changedColumns.get(column.key) != null ? changedColumns.get(column.key) : column.width ?? column.defaultWidth ?? getDefaultWidth?.(index) ?? '1fr';
|
|
98
109
|
let frozen = false;
|
|
99
110
|
let baseSize = 0;
|
|
100
111
|
let flex = 0;
|
|
101
|
-
let targetMainSize =
|
|
112
|
+
let targetMainSize = 0;
|
|
102
113
|
if (isStatic(width)) {
|
|
103
114
|
baseSize = parseStaticWidth(width, availableWidth);
|
|
104
115
|
frozen = true;
|
|
@@ -232,7 +243,7 @@ export function calculateColumnSizes(availableWidth: number, columns: IColumn[],
|
|
|
232
243
|
return cascadeRounding(flexItems);
|
|
233
244
|
}
|
|
234
245
|
|
|
235
|
-
function cascadeRounding(flexItems): number[] {
|
|
246
|
+
function cascadeRounding(flexItems: FlexItem[]): number[] {
|
|
236
247
|
/*
|
|
237
248
|
Given an array of floats that sum to an integer, this rounds the floats
|
|
238
249
|
and returns an array of integers with the same sum.
|
|
@@ -240,7 +251,7 @@ function cascadeRounding(flexItems): number[] {
|
|
|
240
251
|
|
|
241
252
|
let fpTotal = 0;
|
|
242
253
|
let intTotal = 0;
|
|
243
|
-
let roundedArray = [];
|
|
254
|
+
let roundedArray: number[] = [];
|
|
244
255
|
flexItems.forEach(function (item) {
|
|
245
256
|
let float = item.targetMainSize;
|
|
246
257
|
let integer = Math.round(float + fpTotal) - intTotal;
|
|
@@ -108,7 +108,7 @@ export function useTableColumnResizeState<T>(props: TableColumnResizeStateProps<
|
|
|
108
108
|
|
|
109
109
|
let updateResizedColumns = useCallback((key: Key, width: number): Map<Key, ColumnSize> => {
|
|
110
110
|
let newSizes = columnLayout.resizeColumnWidth(state.collection, uncontrolledWidths, key, width);
|
|
111
|
-
let map = new Map(Array.from(uncontrolledColumns).map(([key]) => [key, newSizes.get(key)]));
|
|
111
|
+
let map = new Map(Array.from(uncontrolledColumns).map(([key]) => [key, newSizes.get(key)!]));
|
|
112
112
|
map.set(key, width);
|
|
113
113
|
setUncontrolledWidths(map);
|
|
114
114
|
return newSizes;
|
package/src/useTableState.ts
CHANGED
|
@@ -24,7 +24,7 @@ export interface TableState<T> extends GridState<T, ITableCollection<T>> {
|
|
|
24
24
|
/** Whether the row selection checkboxes should be displayed. */
|
|
25
25
|
showSelectionCheckboxes: boolean,
|
|
26
26
|
/** The current sorted column and direction. */
|
|
27
|
-
sortDescriptor: SortDescriptor,
|
|
27
|
+
sortDescriptor: SortDescriptor | null,
|
|
28
28
|
/** Calls the provided onSortChange handler with the provided column key and sort direction. */
|
|
29
29
|
sort(columnKey: Key, direction?: 'ascending' | 'descending'): void,
|
|
30
30
|
/** Whether keyboard navigation is disabled, such as when the arrow keys should be handled by a component within a cell. */
|
|
@@ -94,11 +94,11 @@ export function useTableState<T extends object>(props: TableStateProps<T>): Tabl
|
|
|
94
94
|
disabledKeys,
|
|
95
95
|
selectionManager,
|
|
96
96
|
showSelectionCheckboxes: props.showSelectionCheckboxes || false,
|
|
97
|
-
sortDescriptor: props.sortDescriptor,
|
|
97
|
+
sortDescriptor: props.sortDescriptor ?? null,
|
|
98
98
|
isKeyboardNavigationDisabled: collection.size === 0 || isKeyboardNavigationDisabled,
|
|
99
99
|
setKeyboardNavigationDisabled,
|
|
100
100
|
sort(columnKey: Key, direction?: 'ascending' | 'descending') {
|
|
101
|
-
props.onSortChange({
|
|
101
|
+
props.onSortChange?.({
|
|
102
102
|
column: columnKey,
|
|
103
103
|
direction: direction ?? (props.sortDescriptor?.column === columnKey
|
|
104
104
|
? OPPOSITE_SORT_DIRECTION[props.sortDescriptor.direction]
|
package/src/useTreeGridState.ts
CHANGED
|
@@ -140,11 +140,11 @@ function generateTreeGridCollection<T>(nodes, opts: TreeGridCollectionOptions):
|
|
|
140
140
|
expandedKeys = new Set()
|
|
141
141
|
} = opts;
|
|
142
142
|
|
|
143
|
-
let body: GridNode<T
|
|
144
|
-
let flattenedRows = [];
|
|
143
|
+
let body: GridNode<T> | null = null;
|
|
144
|
+
let flattenedRows: GridNode<T>[] = [];
|
|
145
145
|
let columnCount = 0;
|
|
146
146
|
let userColumnCount = 0;
|
|
147
|
-
let originalColumns = [];
|
|
147
|
+
let originalColumns: GridNode<T>[] = [];
|
|
148
148
|
let keyMap = new Map();
|
|
149
149
|
|
|
150
150
|
if (opts?.showSelectionCheckboxes) {
|
|
@@ -155,7 +155,7 @@ function generateTreeGridCollection<T>(nodes, opts: TreeGridCollectionOptions):
|
|
|
155
155
|
columnCount++;
|
|
156
156
|
}
|
|
157
157
|
|
|
158
|
-
let topLevelRows = [];
|
|
158
|
+
let topLevelRows: GridNode<T>[] = [];
|
|
159
159
|
let visit = (node: GridNode<T>) => {
|
|
160
160
|
switch (node.type) {
|
|
161
161
|
case 'body':
|
|
@@ -183,6 +183,7 @@ function generateTreeGridCollection<T>(nodes, opts: TreeGridCollectionOptions):
|
|
|
183
183
|
}
|
|
184
184
|
visit(node);
|
|
185
185
|
}
|
|
186
|
+
|
|
186
187
|
columnCount += userColumnCount;
|
|
187
188
|
|
|
188
189
|
// Update each grid node in the treegrid table with values specific to a treegrid structure. Also store a set of flattened row nodes for TableCollection to consume
|
|
@@ -192,7 +193,7 @@ function generateTreeGridCollection<T>(nodes, opts: TreeGridCollectionOptions):
|
|
|
192
193
|
// to TableCollection. Index, level, and parent keys are all changed to reflect a flattened row structure rather than the treegrid structure
|
|
193
194
|
// values automatically calculated via CollectionBuilder
|
|
194
195
|
if (node.type === 'item') {
|
|
195
|
-
let childNodes = [];
|
|
196
|
+
let childNodes: GridNode<T>[] = [];
|
|
196
197
|
for (let child of node.childNodes) {
|
|
197
198
|
if (child.type === 'cell') {
|
|
198
199
|
let cellClone = {...child};
|
|
@@ -202,7 +203,7 @@ function generateTreeGridCollection<T>(nodes, opts: TreeGridCollectionOptions):
|
|
|
202
203
|
childNodes.push({...cellClone});
|
|
203
204
|
}
|
|
204
205
|
}
|
|
205
|
-
let clone = {...node, childNodes: childNodes, parentKey: body
|
|
206
|
+
let clone: GridNode<T> = {...node, childNodes: childNodes, parentKey: body!.key, level: 1, index: globalRowCount++};
|
|
206
207
|
flattenedRows.push(clone);
|
|
207
208
|
}
|
|
208
209
|
|
|
@@ -218,7 +219,7 @@ function generateTreeGridCollection<T>(nodes, opts: TreeGridCollectionOptions):
|
|
|
218
219
|
Object.assign(node, newProps);
|
|
219
220
|
keyMap.set(node.key, node);
|
|
220
221
|
|
|
221
|
-
let lastNode: GridNode<T
|
|
222
|
+
let lastNode: GridNode<T> | null = null;
|
|
222
223
|
let rowIndex = 0;
|
|
223
224
|
for (let child of node.childNodes) {
|
|
224
225
|
if (!(child.type === 'item' && expandedKeys !== 'all' && !expandedKeys.has(node.key))) {
|
|
@@ -250,8 +251,8 @@ function generateTreeGridCollection<T>(nodes, opts: TreeGridCollectionOptions):
|
|
|
250
251
|
}
|
|
251
252
|
};
|
|
252
253
|
|
|
253
|
-
let last: GridNode<T
|
|
254
|
-
|
|
254
|
+
let last: GridNode<T> | null = null;
|
|
255
|
+
for (let [i, node] of topLevelRows.entries()) {
|
|
255
256
|
visitNode(node as GridNode<T>, i);
|
|
256
257
|
|
|
257
258
|
if (last) {
|
|
@@ -262,7 +263,7 @@ function generateTreeGridCollection<T>(nodes, opts: TreeGridCollectionOptions):
|
|
|
262
263
|
}
|
|
263
264
|
|
|
264
265
|
last = node;
|
|
265
|
-
}
|
|
266
|
+
}
|
|
266
267
|
|
|
267
268
|
if (last) {
|
|
268
269
|
last.nextKey = null;
|
|
@@ -272,6 +273,6 @@ function generateTreeGridCollection<T>(nodes, opts: TreeGridCollectionOptions):
|
|
|
272
273
|
keyMap,
|
|
273
274
|
userColumnCount,
|
|
274
275
|
flattenedRows,
|
|
275
|
-
tableNodes: [...originalColumns, {...body
|
|
276
|
+
tableNodes: [...originalColumns, {...body!, childNodes: flattenedRows}]
|
|
276
277
|
};
|
|
277
278
|
}
|