@itwin/itwinui-react 1.40.0 → 1.42.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +34 -0
- package/cjs/core/ComboBox/ComboBox.js +22 -18
- package/cjs/core/ErrorPage/ErrorPage.d.ts +3 -1
- package/cjs/core/ErrorPage/ErrorPage.js +31 -1
- package/cjs/core/Modal/Modal.d.ts +1 -0
- package/cjs/core/Modal/Modal.js +11 -8
- package/cjs/core/Table/Table.d.ts +23 -0
- package/cjs/core/Table/Table.js +15 -9
- package/cjs/core/Table/TableRowMemoized.d.ts +4 -0
- package/cjs/core/Table/TableRowMemoized.js +15 -3
- package/cjs/core/Table/cells/EditableCell.js +7 -2
- package/cjs/core/Table/hooks/index.d.ts +1 -0
- package/cjs/core/Table/hooks/index.js +3 -1
- package/cjs/core/Table/hooks/useScrollToRow.d.ts +11 -0
- package/cjs/core/Table/hooks/useScrollToRow.js +49 -0
- package/cjs/core/Tree/Tree.d.ts +9 -0
- package/cjs/core/Tree/Tree.js +67 -19
- package/cjs/core/Tree/TreeContext.d.ts +4 -0
- package/cjs/core/Tree/TreeNode.js +8 -9
- package/cjs/core/Typography/Small/Small.js +1 -1
- package/cjs/core/utils/components/VirtualScroll.js +2 -2
- package/cjs/core/utils/hooks/index.d.ts +1 -0
- package/cjs/core/utils/hooks/index.js +1 -0
- package/cjs/core/utils/hooks/useLatestRef.d.ts +9 -0
- package/cjs/core/utils/hooks/useLatestRef.js +26 -0
- package/esm/core/ComboBox/ComboBox.js +23 -19
- package/esm/core/ErrorPage/ErrorPage.d.ts +3 -1
- package/esm/core/ErrorPage/ErrorPage.js +31 -1
- package/esm/core/Modal/Modal.d.ts +1 -0
- package/esm/core/Modal/Modal.js +11 -8
- package/esm/core/Table/Table.d.ts +23 -0
- package/esm/core/Table/Table.js +17 -11
- package/esm/core/Table/TableRowMemoized.d.ts +4 -0
- package/esm/core/Table/TableRowMemoized.js +15 -3
- package/esm/core/Table/cells/EditableCell.js +7 -2
- package/esm/core/Table/hooks/index.d.ts +1 -0
- package/esm/core/Table/hooks/index.js +1 -0
- package/esm/core/Table/hooks/useScrollToRow.d.ts +11 -0
- package/esm/core/Table/hooks/useScrollToRow.js +42 -0
- package/esm/core/Tree/Tree.d.ts +9 -0
- package/esm/core/Tree/Tree.js +68 -20
- package/esm/core/Tree/TreeContext.d.ts +4 -0
- package/esm/core/Tree/TreeNode.js +8 -9
- package/esm/core/Typography/Small/Small.js +1 -1
- package/esm/core/utils/components/VirtualScroll.js +2 -2
- package/esm/core/utils/hooks/index.d.ts +1 -0
- package/esm/core/utils/hooks/index.js +1 -0
- package/esm/core/utils/hooks/useLatestRef.d.ts +9 -0
- package/esm/core/utils/hooks/useLatestRef.js +19 -0
- package/package.json +4 -4
|
@@ -24,14 +24,25 @@ import { TableCell } from './TableCell';
|
|
|
24
24
|
* When adding new features check whether it changes state that affects row. If it does then add equality check to `React.memo`.
|
|
25
25
|
*/
|
|
26
26
|
export var TableRow = function (props) {
|
|
27
|
-
var row = props.row, rowProps = props.rowProps, isLast = props.isLast, onRowInViewport = props.onRowInViewport, onBottomReached = props.onBottomReached, intersectionMargin = props.intersectionMargin, onClick = props.onClick, subComponent = props.subComponent, isDisabled = props.isDisabled, tableHasSubRows = props.tableHasSubRows, tableInstance = props.tableInstance, expanderCell = props.expanderCell;
|
|
27
|
+
var row = props.row, rowProps = props.rowProps, isLast = props.isLast, onRowInViewport = props.onRowInViewport, onBottomReached = props.onBottomReached, intersectionMargin = props.intersectionMargin, onClick = props.onClick, subComponent = props.subComponent, isDisabled = props.isDisabled, tableHasSubRows = props.tableHasSubRows, tableInstance = props.tableInstance, expanderCell = props.expanderCell, bodyRef = props.bodyRef, tableRowRef = props.tableRowRef;
|
|
28
28
|
var onIntersect = React.useCallback(function () {
|
|
29
29
|
var _a, _b;
|
|
30
30
|
(_a = onRowInViewport.current) === null || _a === void 0 ? void 0 : _a.call(onRowInViewport, row.original);
|
|
31
31
|
isLast && ((_b = onBottomReached.current) === null || _b === void 0 ? void 0 : _b.call(onBottomReached));
|
|
32
32
|
}, [isLast, onBottomReached, onRowInViewport, row.original]);
|
|
33
|
-
var
|
|
33
|
+
var intersectionRoot = React.useMemo(function () {
|
|
34
|
+
var _a, _b;
|
|
35
|
+
var isTableBodyScrollable = ((_a = bodyRef === null || bodyRef === void 0 ? void 0 : bodyRef.scrollHeight) !== null && _a !== void 0 ? _a : 0) > ((_b = bodyRef === null || bodyRef === void 0 ? void 0 : bodyRef.offsetHeight) !== null && _b !== void 0 ? _b : 0);
|
|
36
|
+
// If table body is scrollable, make it the intersection root
|
|
37
|
+
if (isTableBodyScrollable) {
|
|
38
|
+
return bodyRef;
|
|
39
|
+
}
|
|
40
|
+
// Otherwise, make the viewport the intersection root
|
|
41
|
+
return undefined;
|
|
42
|
+
}, [bodyRef]);
|
|
43
|
+
var intersectionRef = useIntersection(onIntersect, {
|
|
34
44
|
rootMargin: "".concat(intersectionMargin, "px"),
|
|
45
|
+
root: intersectionRoot,
|
|
35
46
|
});
|
|
36
47
|
var userRowProps = rowProps === null || rowProps === void 0 ? void 0 : rowProps(row);
|
|
37
48
|
var mergedProps = __assign(__assign(__assign({}, row.getRowProps({ style: { flex: "0 0 auto", minWidth: '100%' } })), userRowProps), {
|
|
@@ -41,7 +52,7 @@ export var TableRow = function (props) {
|
|
|
41
52
|
'iui-disabled': isDisabled,
|
|
42
53
|
}, userRowProps === null || userRowProps === void 0 ? void 0 : userRowProps.className),
|
|
43
54
|
});
|
|
44
|
-
var refs = useMergedRefs(
|
|
55
|
+
var refs = useMergedRefs(intersectionRef, mergedProps.ref, tableRowRef);
|
|
45
56
|
return (React.createElement(React.Fragment, null,
|
|
46
57
|
React.createElement("div", __assign({}, mergedProps, { ref: refs, onClick: function (event) {
|
|
47
58
|
var _a;
|
|
@@ -90,6 +101,7 @@ export var TableRowMemoized = React.memo(TableRow, function (prevProp, nextProp)
|
|
|
90
101
|
prevProp.rowProps === nextProp.rowProps &&
|
|
91
102
|
prevProp.expanderCell === nextProp.expanderCell &&
|
|
92
103
|
prevProp.tableHasSubRows === nextProp.tableHasSubRows &&
|
|
104
|
+
prevProp.bodyRef === nextProp.bodyRef &&
|
|
93
105
|
prevProp.state.columnOrder === nextProp.state.columnOrder &&
|
|
94
106
|
!nextProp.state.columnResizing.isResizingColumn &&
|
|
95
107
|
prevProp.state.isTableResizing === nextProp.state.isTableResizing &&
|
|
@@ -25,6 +25,7 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
25
25
|
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
26
26
|
*--------------------------------------------------------------------------------------------*/
|
|
27
27
|
import React from 'react';
|
|
28
|
+
import { getRandomValue } from '../../utils';
|
|
28
29
|
/**
|
|
29
30
|
* Editable cell.
|
|
30
31
|
* It should be passed to `cellRenderer`.
|
|
@@ -47,8 +48,9 @@ export var EditableCell = function (props) {
|
|
|
47
48
|
React.useEffect(function () {
|
|
48
49
|
setValue(sanitizeString(cellProps.value));
|
|
49
50
|
}, [cellProps.value]);
|
|
50
|
-
var _b = React.useState(
|
|
51
|
-
|
|
51
|
+
var _b = React.useState(getRandomValue(10)), key = _b[0], setKey = _b[1];
|
|
52
|
+
var _c = React.useState(false), isDirty = _c[0], setIsDirty = _c[1];
|
|
53
|
+
return (React.createElement("div", __assign({}, cellElementProps, { contentEditable: true, suppressContentEditableWarning: true, key: key }, rest, { onInput: function (e) {
|
|
52
54
|
var _a;
|
|
53
55
|
setValue(sanitizeString(e.target.innerText));
|
|
54
56
|
setIsDirty(true);
|
|
@@ -59,6 +61,9 @@ export var EditableCell = function (props) {
|
|
|
59
61
|
onCellEdit(cellProps.column.id, value, cellProps.row.original);
|
|
60
62
|
}
|
|
61
63
|
(_a = props.onBlur) === null || _a === void 0 ? void 0 : _a.call(props, e);
|
|
64
|
+
// Prevents error when text is cleared.
|
|
65
|
+
// New key makes React to reattach with the DOM so it won't complain about deleted text node.
|
|
66
|
+
setKey(getRandomValue(10));
|
|
62
67
|
}, onKeyDown: function (e) {
|
|
63
68
|
var _a;
|
|
64
69
|
// Prevents from adding HTML elements (div, br) inside a cell on Enter press
|
|
@@ -4,4 +4,5 @@ export { useSubRowFiltering } from './useSubRowFiltering';
|
|
|
4
4
|
export { useSubRowSelection } from './useSubRowSelection';
|
|
5
5
|
export { useResizeColumns } from './useResizeColumns';
|
|
6
6
|
export { useColumnDragAndDrop } from './useColumnDragAndDrop';
|
|
7
|
+
export { useScrollToRow } from './useScrollToRow';
|
|
7
8
|
export { useStickyColumns } from './useStickyColumns';
|
|
@@ -8,4 +8,5 @@ export { useSubRowFiltering } from './useSubRowFiltering';
|
|
|
8
8
|
export { useSubRowSelection } from './useSubRowSelection';
|
|
9
9
|
export { useResizeColumns } from './useResizeColumns';
|
|
10
10
|
export { useColumnDragAndDrop } from './useColumnDragAndDrop';
|
|
11
|
+
export { useScrollToRow } from './useScrollToRow';
|
|
11
12
|
export { useStickyColumns } from './useStickyColumns';
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Row } from 'react-table';
|
|
2
|
+
import { TableProps } from '../Table';
|
|
3
|
+
declare type ScrollToRow<T extends Record<string, unknown>> = {
|
|
4
|
+
scrollToIndex: number | undefined;
|
|
5
|
+
tableRowRef: (row: Row<T>) => (element: HTMLDivElement) => void;
|
|
6
|
+
};
|
|
7
|
+
declare type ScrollToRowProps<T extends Record<string, unknown>> = TableProps<T> & {
|
|
8
|
+
page: Row<T>[];
|
|
9
|
+
};
|
|
10
|
+
export declare function useScrollToRow<T extends Record<string, unknown>>({ data, enableVirtualization, page, paginatorRenderer, scrollToRow, onBottomReached, }: ScrollToRowProps<T>): ScrollToRow<T>;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/*---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
3
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
import React from 'react';
|
|
6
|
+
export function useScrollToRow(_a) {
|
|
7
|
+
var data = _a.data, enableVirtualization = _a.enableVirtualization, page = _a.page, paginatorRenderer = _a.paginatorRenderer, scrollToRow = _a.scrollToRow, onBottomReached = _a.onBottomReached;
|
|
8
|
+
var rowRefs = React.useRef({});
|
|
9
|
+
// Refs prevents from having `page` and `data` as dependencies
|
|
10
|
+
// therefore we avoid unnecessary scroll to row.
|
|
11
|
+
var pageRef = React.useRef(page);
|
|
12
|
+
pageRef.current = page;
|
|
13
|
+
var dataRef = React.useRef(data);
|
|
14
|
+
dataRef.current = data;
|
|
15
|
+
// For virtualized tables, all we need to do is pass the index of the item
|
|
16
|
+
// to the VirtualScroll component
|
|
17
|
+
var scrollToIndex = React.useMemo(function () {
|
|
18
|
+
if (!scrollToRow || paginatorRenderer || onBottomReached) {
|
|
19
|
+
return undefined;
|
|
20
|
+
}
|
|
21
|
+
var index = scrollToRow(pageRef.current, dataRef.current);
|
|
22
|
+
return index < 0 ? undefined : index;
|
|
23
|
+
}, [onBottomReached, paginatorRenderer, scrollToRow]);
|
|
24
|
+
// For non-virtualized tables, we need to add a ref to each row
|
|
25
|
+
// and scroll to the element
|
|
26
|
+
React.useEffect(function () {
|
|
27
|
+
var _a;
|
|
28
|
+
if (enableVirtualization ||
|
|
29
|
+
scrollToIndex === undefined ||
|
|
30
|
+
scrollToIndex === null ||
|
|
31
|
+
scrollToIndex < 0) {
|
|
32
|
+
return;
|
|
33
|
+
}
|
|
34
|
+
(_a = rowRefs.current[pageRef.current[scrollToIndex].id]) === null || _a === void 0 ? void 0 : _a.scrollIntoView();
|
|
35
|
+
}, [enableVirtualization, scrollToIndex]);
|
|
36
|
+
var tableRowRef = React.useCallback(function (row) {
|
|
37
|
+
return function (element) {
|
|
38
|
+
rowRefs.current[row.id] = element;
|
|
39
|
+
};
|
|
40
|
+
}, []);
|
|
41
|
+
return { scrollToIndex: scrollToIndex, tableRowRef: tableRowRef };
|
|
42
|
+
}
|
package/esm/core/Tree/Tree.d.ts
CHANGED
|
@@ -68,6 +68,15 @@ export declare type TreeProps<T> = {
|
|
|
68
68
|
* }, [expandedNodes]);
|
|
69
69
|
*/
|
|
70
70
|
getNode: (node: T) => NodeData<T>;
|
|
71
|
+
/**
|
|
72
|
+
* Virtualization is used to have a better performance with a lot of nodes.
|
|
73
|
+
*
|
|
74
|
+
* When enabled, Tree DOM structure will change - it will have a wrapper div
|
|
75
|
+
* to which `className` and `style` will be applied.
|
|
76
|
+
* @default false
|
|
77
|
+
* @beta
|
|
78
|
+
*/
|
|
79
|
+
enableVirtualization?: boolean;
|
|
71
80
|
} & Omit<CommonProps, 'title'>;
|
|
72
81
|
/**
|
|
73
82
|
* Tree component used to display a hierarchical structure of `TreeNodes`.
|
package/esm/core/Tree/Tree.js
CHANGED
|
@@ -25,7 +25,7 @@ var __rest = (this && this.__rest) || function (s, e) {
|
|
|
25
25
|
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
26
26
|
*--------------------------------------------------------------------------------------------*/
|
|
27
27
|
import React from 'react';
|
|
28
|
-
import { useTheme, getFocusableElements } from '../utils';
|
|
28
|
+
import { useTheme, getFocusableElements, useVirtualization, mergeRefs, } from '../utils';
|
|
29
29
|
import '@itwin/itwinui-css/css/tree.css';
|
|
30
30
|
import cx from 'classnames';
|
|
31
31
|
import { TreeContext } from './TreeContext';
|
|
@@ -80,7 +80,7 @@ import { TreeContext } from './TreeContext';
|
|
|
80
80
|
/>
|
|
81
81
|
*/
|
|
82
82
|
export var Tree = function (props) {
|
|
83
|
-
var data = props.data, className = props.className, nodeRenderer = props.nodeRenderer, getNode = props.getNode, rest = __rest(props, ["data", "className", "nodeRenderer", "getNode"]);
|
|
83
|
+
var data = props.data, className = props.className, nodeRenderer = props.nodeRenderer, getNode = props.getNode, _a = props.enableVirtualization, enableVirtualization = _a === void 0 ? false : _a, style = props.style, rest = __rest(props, ["data", "className", "nodeRenderer", "getNode", "enableVirtualization", "style"]);
|
|
84
84
|
useTheme();
|
|
85
85
|
var treeRef = React.useRef(null);
|
|
86
86
|
var focusedIndex = React.useRef(0);
|
|
@@ -118,7 +118,7 @@ export var Tree = function (props) {
|
|
|
118
118
|
break;
|
|
119
119
|
}
|
|
120
120
|
};
|
|
121
|
-
var
|
|
121
|
+
var _b = React.useMemo(function () {
|
|
122
122
|
var flatList = [];
|
|
123
123
|
var firstLevelNodes = [];
|
|
124
124
|
var flattenNodes = function (nodes, depth, parentNode) {
|
|
@@ -147,24 +147,72 @@ export var Tree = function (props) {
|
|
|
147
147
|
};
|
|
148
148
|
flattenNodes(data);
|
|
149
149
|
return [flatList, firstLevelNodes];
|
|
150
|
-
}, [data, getNode]), flatNodesList =
|
|
151
|
-
|
|
152
|
-
var _a;
|
|
153
|
-
var items = getFocusableNodes();
|
|
154
|
-
if (items.length > 0) {
|
|
155
|
-
(_a = items[focusedIndex.current]) === null || _a === void 0 ? void 0 : _a.focus();
|
|
156
|
-
}
|
|
157
|
-
} }, rest), flatNodesList.map(function (flatNode) {
|
|
150
|
+
}, [data, getNode]), flatNodesList = _b[0], firstLevelNodesList = _b[1];
|
|
151
|
+
var itemRenderer = React.useCallback(function (index) {
|
|
158
152
|
var _a, _b, _c, _d;
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
153
|
+
var node = flatNodesList[index];
|
|
154
|
+
return (React.createElement(TreeContext.Provider, { key: node.nodeProps.nodeId, value: {
|
|
155
|
+
nodeDepth: node.depth,
|
|
156
|
+
subNodeIds: node.subNodeIds,
|
|
157
|
+
groupSize: node.depth === 0
|
|
163
158
|
? firstLevelNodesList.length
|
|
164
|
-
: (_c = (_b = (_a =
|
|
165
|
-
indexInGroup:
|
|
166
|
-
parentNodeId: (_d =
|
|
167
|
-
|
|
168
|
-
|
|
159
|
+
: (_c = (_b = (_a = node.parentNode) === null || _a === void 0 ? void 0 : _a.subNodeIds) === null || _b === void 0 ? void 0 : _b.length) !== null && _c !== void 0 ? _c : 0,
|
|
160
|
+
indexInGroup: node.indexInGroup,
|
|
161
|
+
parentNodeId: (_d = node.parentNode) === null || _d === void 0 ? void 0 : _d.nodeProps.nodeId,
|
|
162
|
+
scrollToParent: node.parentNode
|
|
163
|
+
? function () {
|
|
164
|
+
var _a;
|
|
165
|
+
var parentNodeId = (_a = node.parentNode) === null || _a === void 0 ? void 0 : _a.nodeProps.nodeId;
|
|
166
|
+
var parentNodeIndex = flatNodesList.findIndex(function (n) { return n.nodeProps.nodeId === parentNodeId; });
|
|
167
|
+
setScrollToIndex(parentNodeIndex);
|
|
168
|
+
}
|
|
169
|
+
: undefined,
|
|
170
|
+
} }, nodeRenderer(node.nodeProps)));
|
|
171
|
+
}, [firstLevelNodesList.length, flatNodesList, nodeRenderer]);
|
|
172
|
+
var _c = React.useState(), scrollToIndex = _c[0], setScrollToIndex = _c[1];
|
|
173
|
+
var flatNodesListRef = React.useRef(flatNodesList);
|
|
174
|
+
React.useEffect(function () {
|
|
175
|
+
flatNodesListRef.current = flatNodesList;
|
|
176
|
+
}, [flatNodesList]);
|
|
177
|
+
React.useEffect(function () {
|
|
178
|
+
setTimeout(function () {
|
|
179
|
+
var _a;
|
|
180
|
+
if (scrollToIndex !== undefined) {
|
|
181
|
+
var nodeId = flatNodesListRef.current[scrollToIndex].nodeProps.nodeId;
|
|
182
|
+
var nodeElement = (_a = treeRef.current) === null || _a === void 0 ? void 0 : _a.ownerDocument.querySelector("#".concat(nodeId));
|
|
183
|
+
nodeElement === null || nodeElement === void 0 ? void 0 : nodeElement.focus();
|
|
184
|
+
// Need to reset that if navigating with mouse and keyboard,
|
|
185
|
+
// e.g. pressing arrow left to go to parent node and then with mouse
|
|
186
|
+
// clicking some other child node and then pressing arrow left
|
|
187
|
+
setScrollToIndex(undefined);
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
}, [scrollToIndex]);
|
|
191
|
+
var handleFocus = function (event) {
|
|
192
|
+
var _a, _b;
|
|
193
|
+
if ((_a = treeRef.current) === null || _a === void 0 ? void 0 : _a.contains(event.relatedTarget)) {
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
var items = getFocusableNodes();
|
|
197
|
+
if (items.length > 0) {
|
|
198
|
+
(_b = items[focusedIndex.current]) === null || _b === void 0 ? void 0 : _b.focus();
|
|
199
|
+
}
|
|
200
|
+
};
|
|
201
|
+
return (React.createElement(React.Fragment, null, enableVirtualization ? (React.createElement(VirtualizedTree, __assign({ flatNodesList: flatNodesList, itemRenderer: itemRenderer, scrollToIndex: scrollToIndex, onFocus: handleFocus, onKeyDown: handleKeyDown, ref: treeRef, className: className, style: style }, rest))) : (React.createElement(TreeElement, __assign({ onKeyDown: handleKeyDown, onFocus: handleFocus, className: className, style: style, ref: treeRef }, rest), flatNodesList.map(function (_, i) { return itemRenderer(i); })))));
|
|
169
202
|
};
|
|
203
|
+
var TreeElement = React.forwardRef(function (_a, ref) {
|
|
204
|
+
var children = _a.children, className = _a.className, rest = __rest(_a, ["children", "className"]);
|
|
205
|
+
return (React.createElement("ul", __assign({ className: cx('iui-tree', className), role: 'tree', ref: ref, tabIndex: 0 }, rest), children));
|
|
206
|
+
});
|
|
207
|
+
// Having virtualized tree separately prevents from running all virtualization logic
|
|
208
|
+
var VirtualizedTree = React.forwardRef(function (_a, ref) {
|
|
209
|
+
var flatNodesList = _a.flatNodesList, itemRenderer = _a.itemRenderer, scrollToIndex = _a.scrollToIndex, className = _a.className, style = _a.style, rest = __rest(_a, ["flatNodesList", "itemRenderer", "scrollToIndex", "className", "style"]);
|
|
210
|
+
var _b = useVirtualization({
|
|
211
|
+
itemsLength: flatNodesList.length,
|
|
212
|
+
itemRenderer: itemRenderer,
|
|
213
|
+
scrollToIndex: scrollToIndex,
|
|
214
|
+
}), outerProps = _b.outerProps, innerProps = _b.innerProps, visibleChildren = _b.visibleChildren;
|
|
215
|
+
return (React.createElement("div", __assign({}, __assign(__assign({}, outerProps), { className: cx(className, outerProps.className), style: __assign(__assign({}, style), outerProps.style) })),
|
|
216
|
+
React.createElement(TreeElement, __assign({}, innerProps, rest, { ref: mergeRefs(ref, innerProps.ref) }), visibleChildren)));
|
|
217
|
+
});
|
|
170
218
|
export default Tree;
|
|
@@ -20,6 +20,10 @@ export declare type TreeContextProps = {
|
|
|
20
20
|
* Node index in the list of nodes under the same parent node or in the root. Used for an accessibility attribute.
|
|
21
21
|
*/
|
|
22
22
|
indexInGroup: number;
|
|
23
|
+
/**
|
|
24
|
+
* Function that scrolls to the node's parent node.
|
|
25
|
+
*/
|
|
26
|
+
scrollToParent?: () => void;
|
|
23
27
|
};
|
|
24
28
|
export declare const TreeContext: React.Context<TreeContextProps | undefined>;
|
|
25
29
|
export declare const useTreeContext: () => TreeContextProps;
|
|
@@ -52,7 +52,7 @@ import { useTreeContext } from './TreeContext';
|
|
|
52
52
|
export var TreeNode = function (props) {
|
|
53
53
|
var nodeId = props.nodeId, label = props.label, sublabel = props.sublabel, children = props.children, className = props.className, icon = props.icon, _a = props.hasSubNodes, hasSubNodes = _a === void 0 ? false : _a, _b = props.isDisabled, isDisabled = _b === void 0 ? false : _b, _c = props.isExpanded, isExpanded = _c === void 0 ? false : _c, _d = props.isSelected, isSelected = _d === void 0 ? false : _d, onSelected = props.onSelected, onExpanded = props.onExpanded, checkbox = props.checkbox, expander = props.expander, rest = __rest(props, ["nodeId", "label", "sublabel", "children", "className", "icon", "hasSubNodes", "isDisabled", "isExpanded", "isSelected", "onSelected", "onExpanded", "checkbox", "expander"]);
|
|
54
54
|
useTheme();
|
|
55
|
-
var _e = useTreeContext(), nodeDepth = _e.nodeDepth, _f = _e.subNodeIds, subNodeIds = _f === void 0 ? [] : _f, parentNodeId = _e.parentNodeId, groupSize = _e.groupSize, indexInGroup = _e.indexInGroup;
|
|
55
|
+
var _e = useTreeContext(), nodeDepth = _e.nodeDepth, _f = _e.subNodeIds, subNodeIds = _f === void 0 ? [] : _f, parentNodeId = _e.parentNodeId, scrollToParent = _e.scrollToParent, groupSize = _e.groupSize, indexInGroup = _e.indexInGroup;
|
|
56
56
|
var _g = React.useState(false), isFocused = _g[0], setIsFocused = _g[1];
|
|
57
57
|
var nodeRef = React.useRef(null);
|
|
58
58
|
var styleDepth = React.useMemo(function () {
|
|
@@ -62,7 +62,7 @@ export var TreeNode = function (props) {
|
|
|
62
62
|
: { marginLeft: nodeDepth ? nodeDepth * 28 : 0 };
|
|
63
63
|
}, [nodeDepth]);
|
|
64
64
|
var onKeyDown = function (event) {
|
|
65
|
-
var _a, _b, _c, _d, _e, _f
|
|
65
|
+
var _a, _b, _c, _d, _e, _f;
|
|
66
66
|
var isNodeFocused = nodeRef.current === ((_a = nodeRef.current) === null || _a === void 0 ? void 0 : _a.ownerDocument.activeElement);
|
|
67
67
|
switch (event.key) {
|
|
68
68
|
case 'ArrowLeft': {
|
|
@@ -73,20 +73,19 @@ export var TreeNode = function (props) {
|
|
|
73
73
|
break;
|
|
74
74
|
}
|
|
75
75
|
if (parentNodeId) {
|
|
76
|
-
|
|
77
|
-
parentNode === null || parentNode === void 0 ? void 0 : parentNode.focus();
|
|
76
|
+
scrollToParent === null || scrollToParent === void 0 ? void 0 : scrollToParent();
|
|
78
77
|
break;
|
|
79
78
|
}
|
|
80
79
|
// If it is top level node (doesn't have parent node), then do nothing.
|
|
81
80
|
break;
|
|
82
81
|
}
|
|
83
82
|
var focusableElements = getFocusableElements(nodeRef.current);
|
|
84
|
-
var currentIndex = focusableElements.indexOf((
|
|
83
|
+
var currentIndex = focusableElements.indexOf((_b = nodeRef.current) === null || _b === void 0 ? void 0 : _b.ownerDocument.activeElement);
|
|
85
84
|
if (currentIndex === 0) {
|
|
86
|
-
(
|
|
85
|
+
(_c = nodeRef.current) === null || _c === void 0 ? void 0 : _c.focus();
|
|
87
86
|
}
|
|
88
87
|
else {
|
|
89
|
-
(
|
|
88
|
+
(_d = focusableElements[currentIndex - 1]) === null || _d === void 0 ? void 0 : _d.focus();
|
|
90
89
|
}
|
|
91
90
|
break;
|
|
92
91
|
}
|
|
@@ -98,10 +97,10 @@ export var TreeNode = function (props) {
|
|
|
98
97
|
onExpanded(nodeId, true);
|
|
99
98
|
break;
|
|
100
99
|
}
|
|
101
|
-
(
|
|
100
|
+
(_e = focusableElements[0]) === null || _e === void 0 ? void 0 : _e.focus();
|
|
102
101
|
break;
|
|
103
102
|
}
|
|
104
|
-
var currentIndex = focusableElements.indexOf((
|
|
103
|
+
var currentIndex = focusableElements.indexOf((_f = nodeRef.current) === null || _f === void 0 ? void 0 : _f.ownerDocument.activeElement);
|
|
105
104
|
if (currentIndex < focusableElements.length - 1) {
|
|
106
105
|
focusableElements[currentIndex + 1].focus();
|
|
107
106
|
break;
|
|
@@ -37,6 +37,6 @@ import '@itwin/itwinui-css/css/text.css';
|
|
|
37
37
|
export var Small = React.forwardRef(function (props, ref) {
|
|
38
38
|
var className = props.className, _a = props.isMuted, isMuted = _a === void 0 ? false : _a, rest = __rest(props, ["className", "isMuted"]);
|
|
39
39
|
useTheme();
|
|
40
|
-
return (React.createElement("
|
|
40
|
+
return (React.createElement("small", __assign({ ref: ref, className: cx('iui-text-small', { 'iui-text-muted': isMuted }, className) }, rest)));
|
|
41
41
|
});
|
|
42
42
|
export default Small;
|
|
@@ -285,11 +285,11 @@ export var useVirtualization = function (props) {
|
|
|
285
285
|
updateVirtualScroll();
|
|
286
286
|
}, [scrollContainerHeight, updateVirtualScroll]);
|
|
287
287
|
return {
|
|
288
|
-
outerProps: __assign({ style: __assign({
|
|
288
|
+
outerProps: __assign({ style: __assign({ minHeight: itemsLength > 1
|
|
289
289
|
? Math.max(itemsLength - 2, 0) * childHeight.current.middle +
|
|
290
290
|
childHeight.current.first +
|
|
291
291
|
childHeight.current.last
|
|
292
|
-
: childHeight.current.middle,
|
|
292
|
+
: childHeight.current.middle, minWidth: '100%' }, style) }, rest),
|
|
293
293
|
innerProps: {
|
|
294
294
|
style: { willChange: 'transform' },
|
|
295
295
|
ref: mergeRefs(parentRef), // convert object ref to callback ref for better types
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
/**
|
|
3
|
+
* Hook that keeps track of the latest value in a ref.
|
|
4
|
+
* @private
|
|
5
|
+
* @example
|
|
6
|
+
* const { value } = props;
|
|
7
|
+
* const valueRef = useLatestRef(value);
|
|
8
|
+
*/
|
|
9
|
+
export declare const useLatestRef: <T>(value: T) => React.MutableRefObject<T>;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/*---------------------------------------------------------------------------------------------
|
|
2
|
+
* Copyright (c) Bentley Systems, Incorporated. All rights reserved.
|
|
3
|
+
* See LICENSE.md in the project root for license terms and full copyright notice.
|
|
4
|
+
*--------------------------------------------------------------------------------------------*/
|
|
5
|
+
import React from 'react';
|
|
6
|
+
/**
|
|
7
|
+
* Hook that keeps track of the latest value in a ref.
|
|
8
|
+
* @private
|
|
9
|
+
* @example
|
|
10
|
+
* const { value } = props;
|
|
11
|
+
* const valueRef = useLatestRef(value);
|
|
12
|
+
*/
|
|
13
|
+
export var useLatestRef = function (value) {
|
|
14
|
+
var valueRef = React.useRef(value);
|
|
15
|
+
React.useEffect(function () {
|
|
16
|
+
valueRef.current = value;
|
|
17
|
+
}, [value]);
|
|
18
|
+
return valueRef;
|
|
19
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@itwin/itwinui-react",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.42.0",
|
|
4
4
|
"author": "Bentley Systems",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"main": "cjs/index.js",
|
|
@@ -35,15 +35,15 @@
|
|
|
35
35
|
"clean:coverage": "rimraf coverage",
|
|
36
36
|
"test": "jest",
|
|
37
37
|
"test:watch": "jest --watch",
|
|
38
|
-
"createComponent": "node scripts/createComponent.js",
|
|
39
38
|
"format": "prettier --config .prettierrc **/*.{tsx,ts,js} --ignore-path .gitignore --write",
|
|
40
39
|
"lint": "eslint \"**/*.{js,ts,tsx}\" --max-warnings=0",
|
|
41
40
|
"lint:fix": "yarn lint --fix && node ../configs/copyrightLinter.js --fix \"*/**/*.{js,ts,tsx}\"",
|
|
42
41
|
"copy-files": "cpy \"../../{README,LICENSE}.md\" .",
|
|
43
|
-
"dev": "yarn build:watch"
|
|
42
|
+
"dev": "yarn build:watch",
|
|
43
|
+
"createComponent": "node ../../scripts/createComponent.js"
|
|
44
44
|
},
|
|
45
45
|
"dependencies": {
|
|
46
|
-
"@itwin/itwinui-css": "^0.
|
|
46
|
+
"@itwin/itwinui-css": "^0.61.0",
|
|
47
47
|
"@itwin/itwinui-icons-react": "^1.10.1",
|
|
48
48
|
"@itwin/itwinui-illustrations-react": "^1.3.1",
|
|
49
49
|
"@tippyjs/react": "^4.2.5",
|