@itwin/itwinui-react 1.40.1 → 1.43.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.
Files changed (148) hide show
  1. package/CHANGELOG.md +42 -0
  2. package/cjs/core/Backdrop/Backdrop.d.ts +10 -0
  3. package/cjs/core/Backdrop/Backdrop.js +41 -0
  4. package/cjs/core/Backdrop/index.d.ts +2 -0
  5. package/cjs/core/Backdrop/index.js +9 -0
  6. package/cjs/core/Breadcrumbs/Breadcrumbs.js +18 -18
  7. package/cjs/core/ButtonGroup/ButtonGroup.js +11 -4
  8. package/cjs/core/ComboBox/ComboBox.js +22 -18
  9. package/cjs/core/Dialog/Dialog.d.ts +41 -0
  10. package/cjs/core/Dialog/Dialog.js +59 -0
  11. package/cjs/core/Dialog/DialogBackdrop.d.ts +12 -0
  12. package/cjs/core/Dialog/DialogBackdrop.js +61 -0
  13. package/cjs/core/Dialog/DialogButtonBar.d.ts +18 -0
  14. package/cjs/core/Dialog/DialogButtonBar.js +50 -0
  15. package/cjs/core/Dialog/DialogContent.d.ts +17 -0
  16. package/cjs/core/Dialog/DialogContent.js +49 -0
  17. package/cjs/core/Dialog/DialogContext.d.ts +39 -0
  18. package/cjs/core/Dialog/DialogContext.js +16 -0
  19. package/cjs/core/Dialog/DialogMain.d.ts +36 -0
  20. package/cjs/core/Dialog/DialogMain.js +120 -0
  21. package/cjs/core/Dialog/DialogTitleBar.d.ts +34 -0
  22. package/cjs/core/Dialog/DialogTitleBar.js +69 -0
  23. package/cjs/core/Dialog/DialogTitleBarTitle.d.ts +15 -0
  24. package/cjs/core/Dialog/DialogTitleBarTitle.js +47 -0
  25. package/cjs/core/Dialog/index.d.ts +8 -0
  26. package/cjs/core/Dialog/index.js +10 -0
  27. package/cjs/core/ErrorPage/ErrorPage.d.ts +3 -1
  28. package/cjs/core/ErrorPage/ErrorPage.js +31 -1
  29. package/cjs/core/Footer/Footer.d.ts +16 -2
  30. package/cjs/core/Footer/Footer.js +57 -45
  31. package/cjs/core/Footer/FooterItem.d.ts +8 -0
  32. package/cjs/core/Footer/FooterItem.js +46 -0
  33. package/cjs/core/Footer/FooterList.d.ts +8 -0
  34. package/cjs/core/Footer/FooterList.js +46 -0
  35. package/cjs/core/Footer/FooterSeparator.d.ts +8 -0
  36. package/cjs/core/Footer/FooterSeparator.js +46 -0
  37. package/cjs/core/Footer/index.d.ts +1 -1
  38. package/cjs/core/Footer/index.js +2 -1
  39. package/cjs/core/Modal/Modal.d.ts +4 -13
  40. package/cjs/core/Modal/Modal.js +9 -71
  41. package/cjs/core/Modal/ModalButtonBar.d.ts +1 -2
  42. package/cjs/core/Modal/ModalButtonBar.js +2 -39
  43. package/cjs/core/Modal/ModalContent.d.ts +1 -2
  44. package/cjs/core/Modal/ModalContent.js +2 -39
  45. package/cjs/core/Slider/Slider.d.ts +10 -0
  46. package/cjs/core/Slider/Slider.js +20 -14
  47. package/cjs/core/Slider/Thumb.d.ts +2 -1
  48. package/cjs/core/Slider/Thumb.js +5 -3
  49. package/cjs/core/Slider/Track.d.ts +2 -1
  50. package/cjs/core/Slider/Track.js +23 -4
  51. package/cjs/core/Table/Table.d.ts +24 -0
  52. package/cjs/core/Table/Table.js +21 -10
  53. package/cjs/core/Table/TableRowMemoized.d.ts +4 -0
  54. package/cjs/core/Table/TableRowMemoized.js +15 -3
  55. package/cjs/core/Table/cells/EditableCell.js +7 -2
  56. package/cjs/core/Table/columns/actionColumn.d.ts +8 -3
  57. package/cjs/core/Table/columns/actionColumn.js +33 -2
  58. package/cjs/core/Table/hooks/index.d.ts +1 -0
  59. package/cjs/core/Table/hooks/index.js +3 -1
  60. package/cjs/core/Table/hooks/useScrollToRow.d.ts +11 -0
  61. package/cjs/core/Table/hooks/useScrollToRow.js +49 -0
  62. package/cjs/core/Tree/Tree.d.ts +9 -0
  63. package/cjs/core/Tree/Tree.js +67 -19
  64. package/cjs/core/Tree/TreeContext.d.ts +4 -0
  65. package/cjs/core/Tree/TreeNode.js +8 -9
  66. package/cjs/core/Typography/Small/Small.js +1 -1
  67. package/cjs/core/index.d.ts +3 -1
  68. package/cjs/core/index.js +6 -3
  69. package/cjs/core/utils/components/FocusTrap.js +1 -1
  70. package/cjs/core/utils/components/MiddleTextTruncation.js +1 -1
  71. package/cjs/core/utils/hooks/index.d.ts +1 -0
  72. package/cjs/core/utils/hooks/index.js +1 -0
  73. package/cjs/core/utils/hooks/useLatestRef.d.ts +9 -0
  74. package/cjs/core/utils/hooks/useLatestRef.js +26 -0
  75. package/esm/core/Backdrop/Backdrop.d.ts +10 -0
  76. package/esm/core/Backdrop/Backdrop.js +35 -0
  77. package/esm/core/Backdrop/index.d.ts +2 -0
  78. package/esm/core/Backdrop/index.js +5 -0
  79. package/esm/core/Breadcrumbs/Breadcrumbs.js +18 -18
  80. package/esm/core/ButtonGroup/ButtonGroup.js +11 -4
  81. package/esm/core/ComboBox/ComboBox.js +23 -19
  82. package/esm/core/Dialog/Dialog.d.ts +41 -0
  83. package/esm/core/Dialog/Dialog.js +53 -0
  84. package/esm/core/Dialog/DialogBackdrop.d.ts +12 -0
  85. package/esm/core/Dialog/DialogBackdrop.js +55 -0
  86. package/esm/core/Dialog/DialogButtonBar.d.ts +18 -0
  87. package/esm/core/Dialog/DialogButtonBar.js +44 -0
  88. package/esm/core/Dialog/DialogContent.d.ts +17 -0
  89. package/esm/core/Dialog/DialogContent.js +43 -0
  90. package/esm/core/Dialog/DialogContext.d.ts +39 -0
  91. package/esm/core/Dialog/DialogContext.js +9 -0
  92. package/esm/core/Dialog/DialogMain.d.ts +36 -0
  93. package/esm/core/Dialog/DialogMain.js +114 -0
  94. package/esm/core/Dialog/DialogTitleBar.d.ts +34 -0
  95. package/esm/core/Dialog/DialogTitleBar.js +63 -0
  96. package/esm/core/Dialog/DialogTitleBarTitle.d.ts +15 -0
  97. package/esm/core/Dialog/DialogTitleBarTitle.js +41 -0
  98. package/esm/core/Dialog/index.d.ts +8 -0
  99. package/esm/core/Dialog/index.js +6 -0
  100. package/esm/core/ErrorPage/ErrorPage.d.ts +3 -1
  101. package/esm/core/ErrorPage/ErrorPage.js +31 -1
  102. package/esm/core/Footer/Footer.d.ts +16 -2
  103. package/esm/core/Footer/Footer.js +56 -43
  104. package/esm/core/Footer/FooterItem.d.ts +8 -0
  105. package/esm/core/Footer/FooterItem.js +39 -0
  106. package/esm/core/Footer/FooterList.d.ts +8 -0
  107. package/esm/core/Footer/FooterList.js +39 -0
  108. package/esm/core/Footer/FooterSeparator.d.ts +8 -0
  109. package/esm/core/Footer/FooterSeparator.js +39 -0
  110. package/esm/core/Footer/index.d.ts +1 -1
  111. package/esm/core/Footer/index.js +1 -1
  112. package/esm/core/Modal/Modal.d.ts +4 -13
  113. package/esm/core/Modal/Modal.js +10 -72
  114. package/esm/core/Modal/ModalButtonBar.d.ts +1 -2
  115. package/esm/core/Modal/ModalButtonBar.js +2 -35
  116. package/esm/core/Modal/ModalContent.d.ts +1 -2
  117. package/esm/core/Modal/ModalContent.js +2 -35
  118. package/esm/core/Slider/Slider.d.ts +10 -0
  119. package/esm/core/Slider/Slider.js +20 -14
  120. package/esm/core/Slider/Thumb.d.ts +2 -1
  121. package/esm/core/Slider/Thumb.js +5 -3
  122. package/esm/core/Slider/Track.d.ts +2 -1
  123. package/esm/core/Slider/Track.js +23 -4
  124. package/esm/core/Table/Table.d.ts +24 -0
  125. package/esm/core/Table/Table.js +23 -12
  126. package/esm/core/Table/TableRowMemoized.d.ts +4 -0
  127. package/esm/core/Table/TableRowMemoized.js +15 -3
  128. package/esm/core/Table/cells/EditableCell.js +7 -2
  129. package/esm/core/Table/columns/actionColumn.d.ts +8 -3
  130. package/esm/core/Table/columns/actionColumn.js +33 -2
  131. package/esm/core/Table/hooks/index.d.ts +1 -0
  132. package/esm/core/Table/hooks/index.js +1 -0
  133. package/esm/core/Table/hooks/useScrollToRow.d.ts +11 -0
  134. package/esm/core/Table/hooks/useScrollToRow.js +42 -0
  135. package/esm/core/Tree/Tree.d.ts +9 -0
  136. package/esm/core/Tree/Tree.js +68 -20
  137. package/esm/core/Tree/TreeContext.d.ts +4 -0
  138. package/esm/core/Tree/TreeNode.js +8 -9
  139. package/esm/core/Typography/Small/Small.js +1 -1
  140. package/esm/core/index.d.ts +3 -1
  141. package/esm/core/index.js +2 -1
  142. package/esm/core/utils/components/FocusTrap.js +1 -1
  143. package/esm/core/utils/components/MiddleTextTruncation.js +1 -1
  144. package/esm/core/utils/hooks/index.d.ts +1 -0
  145. package/esm/core/utils/hooks/index.js +1 -0
  146. package/esm/core/utils/hooks/useLatestRef.d.ts +9 -0
  147. package/esm/core/utils/hooks/useLatestRef.js +19 -0
  148. package/package.json +8 -7
@@ -45,9 +45,13 @@ var utils_1 = require("../utils");
45
45
  require("@itwin/itwinui-css/css/slider.css");
46
46
  var Track_1 = require("./Track");
47
47
  var Thumb_1 = require("./Thumb");
48
- var getPercentageOfRectangle = function (rect, pointer) {
49
- var position = (0, utils_1.getBoundedValue)(pointer, rect.left, rect.right);
50
- return (position - rect.left) / rect.width;
48
+ var getPercentageOfRectangle = function (rect, pointerX, pointerY, orientation) {
49
+ if (orientation === 'horizontal') {
50
+ var position_1 = (0, utils_1.getBoundedValue)(pointerX, rect.left, rect.right);
51
+ return (position_1 - rect.left) / rect.width;
52
+ }
53
+ var position = (0, utils_1.getBoundedValue)(pointerY, rect.top, rect.bottom);
54
+ return (rect.bottom - position) / rect.height;
51
55
  };
52
56
  var getClosestValueIndex = function (values, pointerValue) {
53
57
  if (1 === values.length) {
@@ -94,20 +98,20 @@ var focusThumb = function (sliderContainer, activeIndex) {
94
98
  */
95
99
  exports.Slider = react_1.default.forwardRef(function (props, ref) {
96
100
  var _a, _b;
97
- var _c = props.min, min = _c === void 0 ? 0 : _c, _d = props.max, max = _d === void 0 ? 100 : _d, values = props.values, _e = props.step, step = _e === void 0 ? 1 : _e, _f = props.setFocus, setFocus = _f === void 0 ? false : _f, tooltipProps = props.tooltipProps, _g = props.disabled, disabled = _g === void 0 ? false : _g, tickLabels = props.tickLabels, minLabel = props.minLabel, maxLabel = props.maxLabel, _h = props.trackDisplayMode, trackDisplayMode = _h === void 0 ? 'auto' : _h, _j = props.thumbMode, thumbMode = _j === void 0 ? 'inhibit-crossing' : _j, onChange = props.onChange, onUpdate = props.onUpdate, thumbProps = props.thumbProps, className = props.className, railContainerProps = props.railContainerProps, rest = __rest(props, ["min", "max", "values", "step", "setFocus", "tooltipProps", "disabled", "tickLabels", "minLabel", "maxLabel", "trackDisplayMode", "thumbMode", "onChange", "onUpdate", "thumbProps", "className", "railContainerProps"]);
98
- var _k = react_1.default.useState(values), currentValues = _k[0], setCurrentValues = _k[1];
101
+ var _c = props.min, min = _c === void 0 ? 0 : _c, _d = props.max, max = _d === void 0 ? 100 : _d, values = props.values, _e = props.step, step = _e === void 0 ? 1 : _e, _f = props.setFocus, setFocus = _f === void 0 ? false : _f, tooltipProps = props.tooltipProps, _g = props.disabled, disabled = _g === void 0 ? false : _g, tickLabels = props.tickLabels, minLabel = props.minLabel, maxLabel = props.maxLabel, _h = props.trackDisplayMode, trackDisplayMode = _h === void 0 ? 'auto' : _h, _j = props.thumbMode, thumbMode = _j === void 0 ? 'inhibit-crossing' : _j, onChange = props.onChange, onUpdate = props.onUpdate, thumbProps = props.thumbProps, className = props.className, railContainerProps = props.railContainerProps, _k = props.orientation, orientation = _k === void 0 ? 'horizontal' : _k, rest = __rest(props, ["min", "max", "values", "step", "setFocus", "tooltipProps", "disabled", "tickLabels", "minLabel", "maxLabel", "trackDisplayMode", "thumbMode", "onChange", "onUpdate", "thumbProps", "className", "railContainerProps", "orientation"]);
102
+ var _l = react_1.default.useState(values), currentValues = _l[0], setCurrentValues = _l[1];
99
103
  react_1.default.useEffect(function () {
100
104
  setCurrentValues(values);
101
105
  }, [values]);
102
- var _l = react_1.default.useState(function () { return minLabel !== null && minLabel !== void 0 ? minLabel : min.toString(); }), minValueLabel = _l[0], setMinValueLabel = _l[1];
106
+ var _m = react_1.default.useState(function () { return minLabel !== null && minLabel !== void 0 ? minLabel : min.toString(); }), minValueLabel = _m[0], setMinValueLabel = _m[1];
103
107
  react_1.default.useEffect(function () {
104
108
  setMinValueLabel(minLabel !== null && minLabel !== void 0 ? minLabel : min.toString());
105
109
  }, [minLabel, min]);
106
- var _m = react_1.default.useState(function () { return maxLabel !== null && maxLabel !== void 0 ? maxLabel : max.toString(); }), maxValueLabel = _m[0], setMaxValueLabel = _m[1];
110
+ var _o = react_1.default.useState(function () { return maxLabel !== null && maxLabel !== void 0 ? maxLabel : max.toString(); }), maxValueLabel = _o[0], setMaxValueLabel = _o[1];
107
111
  react_1.default.useEffect(function () {
108
112
  setMaxValueLabel(maxLabel !== null && maxLabel !== void 0 ? maxLabel : max.toString());
109
113
  }, [maxLabel, max]);
110
- var _o = react_1.default.useState(function () { return getDefaultTrackDisplay(trackDisplayMode, currentValues); }), trackDisplay = _o[0], setTrackDisplay = _o[1];
114
+ var _p = react_1.default.useState(function () { return getDefaultTrackDisplay(trackDisplayMode, currentValues); }), trackDisplay = _p[0], setTrackDisplay = _p[1];
111
115
  react_1.default.useEffect(function () {
112
116
  setTrackDisplay(getDefaultTrackDisplay(trackDisplayMode, currentValues));
113
117
  }, [trackDisplayMode, currentValues]);
@@ -133,10 +137,10 @@ exports.Slider = react_1.default.forwardRef(function (props, ref) {
133
137
  }
134
138
  return [min, max];
135
139
  }, [max, min, step, thumbMode, currentValues]);
136
- var _p = react_1.default.useState(undefined), activeThumbIndex = _p[0], setActiveThumbIndex = _p[1];
140
+ var _q = react_1.default.useState(undefined), activeThumbIndex = _q[0], setActiveThumbIndex = _q[1];
137
141
  var updateThumbValue = react_1.default.useCallback(function (event, callbackType) {
138
142
  if (containerRef.current && undefined !== activeThumbIndex) {
139
- var percent = getPercentageOfRectangle(containerRef.current.getBoundingClientRect(), event.clientX);
143
+ var percent = getPercentageOfRectangle(containerRef.current.getBoundingClientRect(), event.clientX, event.clientY, orientation);
140
144
  var pointerValue = min + (max - min) * percent;
141
145
  pointerValue = roundValueToClosestStep(pointerValue, step, min);
142
146
  var _a = getAllowableThumbRange(activeThumbIndex), minVal = _a[0], maxVal = _a[1];
@@ -162,6 +166,7 @@ exports.Slider = react_1.default.forwardRef(function (props, ref) {
162
166
  currentValues,
163
167
  onUpdate,
164
168
  onChange,
169
+ orientation,
165
170
  ]);
166
171
  var handlePointerMove = react_1.default.useCallback(function (event) {
167
172
  if (activeThumbIndex === undefined) {
@@ -195,7 +200,7 @@ exports.Slider = react_1.default.forwardRef(function (props, ref) {
195
200
  }, [activeThumbIndex, updateThumbValue]);
196
201
  var handlePointerDownOnSlider = react_1.default.useCallback(function (event) {
197
202
  if (containerRef.current) {
198
- var percent = getPercentageOfRectangle(containerRef.current.getBoundingClientRect(), event.clientX);
203
+ var percent = getPercentageOfRectangle(containerRef.current.getBoundingClientRect(), event.clientX, event.clientY, orientation);
199
204
  var pointerValue = min + (max - min) * percent;
200
205
  pointerValue = roundValueToClosestStep(pointerValue, step, min);
201
206
  var closestValueIndex = getClosestValueIndex(currentValues, pointerValue);
@@ -221,6 +226,7 @@ exports.Slider = react_1.default.forwardRef(function (props, ref) {
221
226
  getAllowableThumbRange,
222
227
  onChange,
223
228
  onUpdate,
229
+ orientation,
224
230
  ]);
225
231
  (0, utils_1.useEventListener)('pointermove', handlePointerMove, (_a = containerRef.current) === null || _a === void 0 ? void 0 : _a.ownerDocument);
226
232
  (0, utils_1.useEventListener)('pointerup', handlePointerUp, (_b = containerRef.current) === null || _b === void 0 ? void 0 : _b.ownerDocument);
@@ -241,7 +247,7 @@ exports.Slider = react_1.default.forwardRef(function (props, ref) {
241
247
  ? outProps.content
242
248
  : formatNumberValue(val, step, getNumDecimalPlaces) });
243
249
  }, [getNumDecimalPlaces, step, tooltipProps]);
244
- return (react_1.default.createElement("div", __assign({ ref: ref, className: (0, classnames_1.default)('iui-slider-component-container', { 'iui-disabled': disabled }, className) }, rest),
250
+ return (react_1.default.createElement("div", __assign({ ref: ref, className: (0, classnames_1.default)('iui-slider-component-container', "iui-slider-".concat(orientation), { 'iui-disabled': disabled }, className) }, rest),
245
251
  minValueLabel && (react_1.default.createElement("span", { className: 'iui-slider-min' }, minValueLabel)),
246
252
  react_1.default.createElement("div", __assign({ ref: containerRef, className: (0, classnames_1.default)('iui-slider-container', {
247
253
  'iui-grabbing': undefined !== activeThumbIndex,
@@ -251,9 +257,9 @@ exports.Slider = react_1.default.forwardRef(function (props, ref) {
251
257
  var _a;
252
258
  var _b = getAllowableThumbRange(index), minVal = _b[0], maxVal = _b[1];
253
259
  var thisThumbProps = thumbProps === null || thumbProps === void 0 ? void 0 : thumbProps(index);
254
- return (react_1.default.createElement(Thumb_1.Thumb, { key: (_a = thisThumbProps === null || thisThumbProps === void 0 ? void 0 : thisThumbProps.id) !== null && _a !== void 0 ? _a : index, index: index, disabled: disabled, isActive: activeThumbIndex === index, onThumbActivated: onThumbActivated, onThumbValueChanged: onThumbValueChanged, minVal: minVal, maxVal: maxVal, value: thumbValue, tooltipProps: generateTooltipProps(index, thumbValue), thumbProps: thisThumbProps, step: step, sliderMin: min, sliderMax: max }));
260
+ return (react_1.default.createElement(Thumb_1.Thumb, { key: (_a = thisThumbProps === null || thisThumbProps === void 0 ? void 0 : thisThumbProps.id) !== null && _a !== void 0 ? _a : index, index: index, disabled: disabled, isActive: activeThumbIndex === index, onThumbActivated: onThumbActivated, onThumbValueChanged: onThumbValueChanged, minVal: minVal, maxVal: maxVal, value: thumbValue, tooltipProps: generateTooltipProps(index, thumbValue), thumbProps: thisThumbProps, step: step, sliderMin: min, sliderMax: max, orientation: orientation }));
255
261
  }),
256
- react_1.default.createElement(Track_1.Track, { trackDisplayMode: trackDisplay, sliderMin: min, sliderMax: max, values: currentValues }),
262
+ react_1.default.createElement(Track_1.Track, { trackDisplayMode: trackDisplay, sliderMin: min, sliderMax: max, values: currentValues, orientation: orientation }),
257
263
  tickMarkArea),
258
264
  maxValueLabel && (react_1.default.createElement("span", { className: 'iui-slider-max' }, maxValueLabel))));
259
265
  });
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import { TooltipProps } from '../Tooltip';
3
+ import { SliderProps } from './Slider';
3
4
  export declare type ThumbProps = {
4
5
  /**
5
6
  * Thumb value.
@@ -53,7 +54,7 @@ export declare type ThumbProps = {
53
54
  * Additional props for Thumb.
54
55
  */
55
56
  thumbProps?: React.HTMLAttributes<HTMLDivElement>;
56
- };
57
+ } & Pick<SliderProps, 'orientation'>;
57
58
  /**
58
59
  * Thumb is a local component used to show and modify the values maintained by the Slider.
59
60
  * Only one Thumb can be active at a time. A Thumb is made active when the user selects
@@ -39,7 +39,7 @@ var Tooltip_1 = require("../Tooltip");
39
39
  * it with pointer. Whenever a Thumb is active, focused, or hovered its tooltip is shown.
40
40
  */
41
41
  var Thumb = function (props) {
42
- var value = props.value, index = props.index, minVal = props.minVal, maxVal = props.maxVal, step = props.step, sliderMin = props.sliderMin, sliderMax = props.sliderMax, isActive = props.isActive, onThumbActivated = props.onThumbActivated, onThumbValueChanged = props.onThumbValueChanged, tooltipProps = props.tooltipProps, thumbProps = props.thumbProps, disabled = props.disabled;
42
+ var value = props.value, index = props.index, minVal = props.minVal, maxVal = props.maxVal, step = props.step, sliderMin = props.sliderMin, sliderMax = props.sliderMax, isActive = props.isActive, onThumbActivated = props.onThumbActivated, onThumbValueChanged = props.onThumbValueChanged, tooltipProps = props.tooltipProps, thumbProps = props.thumbProps, disabled = props.disabled, orientation = props.orientation;
43
43
  var thumbRef = react_1.default.useRef(null);
44
44
  var handleOnKeyDown = react_1.default.useCallback(function (event) {
45
45
  if (disabled || event.altKey) {
@@ -79,7 +79,7 @@ var Thumb = function (props) {
79
79
  }
80
80
  return value;
81
81
  }, [sliderMax, sliderMin, value]);
82
- var leftPercent = react_1.default.useMemo(function () {
82
+ var lowPercent = react_1.default.useMemo(function () {
83
83
  if (sliderMax === sliderMin) {
84
84
  return 0;
85
85
  }
@@ -87,6 +87,8 @@ var Thumb = function (props) {
87
87
  }, [adjustedValue, sliderMax, sliderMin]);
88
88
  var _c = thumbProps || {}, style = _c.style, className = _c.className, rest = __rest(_c, ["style", "className"]);
89
89
  return (react_1.default.createElement(Tooltip_1.Tooltip, __assign({ visible: isActive || hasFocus || isHovered, placement: 'top' }, tooltipProps),
90
- react_1.default.createElement("div", __assign({}, rest, { "data-index": index, ref: thumbRef, style: __assign(__assign({}, style), { left: "".concat(leftPercent, "%") }), className: (0, classnames_1.default)('iui-slider-thumb', { 'iui-active': isActive }, className), role: 'slider', tabIndex: disabled ? undefined : 0, "aria-valuemin": minVal, "aria-valuenow": value, "aria-valuemax": maxVal, "aria-disabled": disabled, onPointerDown: handlePointerDownOnThumb, onKeyDown: handleOnKeyDown, onFocus: function () { return setHasFocus(true); }, onBlur: function () { return setHasFocus(false); }, onMouseEnter: function () { return setIsHovered(true); }, onMouseLeave: function () { return setIsHovered(false); } }))));
90
+ react_1.default.createElement("div", __assign({}, rest, { "data-index": index, ref: thumbRef, style: __assign(__assign({}, style), (orientation === 'horizontal'
91
+ ? { left: "".concat(lowPercent, "%") }
92
+ : { bottom: "".concat(lowPercent, "%") })), className: (0, classnames_1.default)('iui-slider-thumb', { 'iui-active': isActive }, className), role: 'slider', tabIndex: disabled ? undefined : 0, "aria-valuemin": minVal, "aria-valuenow": value, "aria-valuemax": maxVal, "aria-disabled": disabled, onPointerDown: handlePointerDownOnThumb, onKeyDown: handleOnKeyDown, onFocus: function () { return setHasFocus(true); }, onBlur: function () { return setHasFocus(false); }, onMouseEnter: function () { return setIsHovered(true); }, onMouseLeave: function () { return setIsHovered(false); } }))));
91
93
  };
92
94
  exports.Thumb = Thumb;
@@ -1,10 +1,11 @@
1
1
  /// <reference types="react" />
2
- import { TrackDisplayMode } from './Slider';
2
+ import { SliderProps, TrackDisplayMode } from './Slider';
3
3
  export declare type TrackProps = {
4
4
  trackDisplayMode: TrackDisplayMode;
5
5
  sliderMin: number;
6
6
  sliderMax: number;
7
7
  values: number[];
8
+ orientation: SliderProps['orientation'];
8
9
  };
9
10
  /**
10
11
  * Track displays color segments above Rail. Which, if any, segments that are
@@ -1,4 +1,15 @@
1
1
  "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
2
13
  var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
3
14
  if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
4
15
  if (ar || !(i in from)) {
@@ -50,7 +61,7 @@ function generateSegments(values, min, max) {
50
61
  * colorized is based on `trackDisplayMode`.
51
62
  */
52
63
  var Track = function (props) {
53
- var trackDisplayMode = props.trackDisplayMode, sliderMin = props.sliderMin, sliderMax = props.sliderMax, values = props.values;
64
+ var trackDisplayMode = props.trackDisplayMode, sliderMin = props.sliderMin, sliderMax = props.sliderMax, values = props.values, orientation = props.orientation;
54
65
  var _a = react_1.default.useState(function () {
55
66
  return generateSegments(values, sliderMin, sliderMax);
56
67
  }), segments = _a[0], setSegments = _a[1];
@@ -59,14 +70,22 @@ var Track = function (props) {
59
70
  }, [values, sliderMin, sliderMax]);
60
71
  return (react_1.default.createElement(react_1.default.Fragment, null, 'none' !== trackDisplayMode &&
61
72
  segments.map(function (segment, index) {
62
- var leftPercent = segment.left >= sliderMin && sliderMax !== sliderMin
73
+ var lowPercent = segment.left >= sliderMin && sliderMax !== sliderMin
63
74
  ? (100.0 * (segment.left - sliderMin)) / (sliderMax - sliderMin)
64
75
  : 0;
65
- var rightPercent = segment.right >= sliderMin && sliderMax !== sliderMin
76
+ var highPercent = segment.right >= sliderMin && sliderMax !== sliderMin
66
77
  ? 100.0 -
67
78
  (100.0 * (segment.right - sliderMin)) / (sliderMax - sliderMin)
68
79
  : 100;
69
- return (react_1.default.createElement(react_1.default.Fragment, { key: index }, shouldDisplaySegment(index, trackDisplayMode) ? (react_1.default.createElement("div", { className: 'iui-slider-track', style: { left: "".concat(leftPercent, "%"), right: "".concat(rightPercent, "%") } })) : null));
80
+ return (react_1.default.createElement(react_1.default.Fragment, { key: index }, shouldDisplaySegment(index, trackDisplayMode) ? (react_1.default.createElement("div", { className: 'iui-slider-track', style: __assign({}, (orientation === 'horizontal'
81
+ ? {
82
+ left: "".concat(lowPercent, "%"),
83
+ right: "".concat(highPercent, "%"),
84
+ }
85
+ : {
86
+ top: "".concat(highPercent, "%"),
87
+ bottom: "".concat(lowPercent, "%"),
88
+ })) })) : null));
70
89
  })));
71
90
  };
72
91
  exports.Track = Track;
@@ -182,6 +182,30 @@ export declare type TableProps<T extends Record<string, unknown> = Record<string
182
182
  * @default false
183
183
  */
184
184
  enableColumnReordering?: boolean;
185
+ /**
186
+ * Function that returns index of the row that you want to scroll to.
187
+ *
188
+ * When using with lazy-loading table, you need to take care that row is already loaded.
189
+ * It doesn't work with paginated tables.
190
+ * @beta
191
+ * @example
192
+ * <Table
193
+ * scrollToRow={React.useCallback(
194
+ * (rows, data) => rows.findIndex((row) => row.original === data[250]),
195
+ * []
196
+ * )}
197
+ * {...restProps}
198
+ * />
199
+ * @example
200
+ * <Table
201
+ * scrollToRow={React.useCallback(
202
+ * (rows, data) => rows.findIndex((row) => row.original.id === data[250].id),
203
+ * []
204
+ * )}
205
+ * {...restProps}
206
+ * />
207
+ */
208
+ scrollToRow?: (rows: Row<T>[], data: T[]) => number;
185
209
  } & Omit<CommonProps, 'title'>;
186
210
  /**
187
211
  * Table based on [react-table](https://react-table.tanstack.com/docs/api/overview).
@@ -240,6 +240,7 @@ var Table = function (props) {
240
240
  state.pageIndex,
241
241
  state.pageSize,
242
242
  ]);
243
+ var _r = (0, hooks_1.useScrollToRow)(__assign(__assign({}, props), { page: page })), scrollToIndex = _r.scrollToIndex, tableRowRef = _r.tableRowRef;
243
244
  var columnRefs = react_1.default.useRef({});
244
245
  var previousTableWidth = react_1.default.useRef(0);
245
246
  var onTableResize = react_1.default.useCallback(function (_a) {
@@ -275,22 +276,27 @@ var Table = function (props) {
275
276
  });
276
277
  var headerRef = react_1.default.useRef(null);
277
278
  var bodyRef = react_1.default.useRef(null);
279
+ // Using `useState` to rerender rows when table body ref is available
280
+ var _s = react_1.default.useState(null), bodyRefState = _s[0], setBodyRefState = _s[1];
278
281
  var getPreparedRow = react_1.default.useCallback(function (index) {
279
282
  var row = page[index];
280
283
  prepareRow(row);
281
- return (react_1.default.createElement(TableRowMemoized_1.TableRowMemoized, { row: row, rowProps: rowProps, isLast: index === page.length - 1, onRowInViewport: onRowInViewportRef, onBottomReached: onBottomReachedRef, intersectionMargin: intersectionMargin, state: state, key: row.getRowProps().key, onClick: onRowClickHandler, subComponent: subComponent, isDisabled: !!(isRowDisabled === null || isRowDisabled === void 0 ? void 0 : isRowDisabled(row.original)), tableHasSubRows: hasAnySubRows, tableInstance: instance, expanderCell: expanderCell }));
284
+ return (react_1.default.createElement(TableRowMemoized_1.TableRowMemoized, { row: row, rowProps: rowProps, isLast: index === page.length - 1, onRowInViewport: onRowInViewportRef, onBottomReached: onBottomReachedRef, intersectionMargin: intersectionMargin, state: state, key: row.getRowProps().key, onClick: onRowClickHandler, subComponent: subComponent, isDisabled: !!(isRowDisabled === null || isRowDisabled === void 0 ? void 0 : isRowDisabled(row.original)), tableHasSubRows: hasAnySubRows, tableInstance: instance, expanderCell: expanderCell, bodyRef: bodyRefState, tableRowRef: enableVirtualization ? undefined : tableRowRef(row) }));
282
285
  }, [
283
286
  page,
284
- expanderCell,
285
- hasAnySubRows,
286
- instance,
287
- intersectionMargin,
288
- isRowDisabled,
289
- onRowClickHandler,
290
287
  prepareRow,
291
288
  rowProps,
289
+ intersectionMargin,
292
290
  state,
291
+ onRowClickHandler,
293
292
  subComponent,
293
+ isRowDisabled,
294
+ hasAnySubRows,
295
+ instance,
296
+ expanderCell,
297
+ bodyRefState,
298
+ enableVirtualization,
299
+ tableRowRef,
294
300
  ]);
295
301
  var virtualizedItemRenderer = react_1.default.useCallback(function (index) { return getPreparedRow(index); }, [getPreparedRow]);
296
302
  var updateStickyState = function () {
@@ -327,7 +333,12 @@ var Table = function (props) {
327
333
  className: (0, classnames_1.default)('iui-table', (_a = {}, _a["iui-".concat(density)] = density !== 'default', _a), className),
328
334
  style: __assign({ minWidth: 0 }, style),
329
335
  }), ariaDataAttributes),
330
- react_1.default.createElement("div", { className: 'iui-table-header-wrapper', ref: headerRef },
336
+ react_1.default.createElement("div", { className: 'iui-table-header-wrapper', ref: headerRef, onScroll: function () {
337
+ if (headerRef.current && bodyRef.current) {
338
+ bodyRef.current.scrollLeft = headerRef.current.scrollLeft;
339
+ updateStickyState();
340
+ }
341
+ } },
331
342
  react_1.default.createElement("div", { className: 'iui-table-header' }, headerGroups.slice(1).map(function (headerGroup) {
332
343
  var headerGroupProps = headerGroup.getHeaderGroupProps({
333
344
  className: 'iui-row',
@@ -366,13 +377,13 @@ var Table = function (props) {
366
377
  'iui-zebra-striping': styleType === 'zebra-rows',
367
378
  }),
368
379
  style: { outline: 0 },
369
- }), { ref: bodyRef, onScroll: function () {
380
+ }), { ref: (0, utils_1.mergeRefs)(bodyRef, setBodyRefState), onScroll: function () {
370
381
  if (headerRef.current && bodyRef.current) {
371
382
  headerRef.current.scrollLeft = bodyRef.current.scrollLeft;
372
383
  updateStickyState();
373
384
  }
374
385
  }, tabIndex: -1 }),
375
- data.length !== 0 && (react_1.default.createElement(react_1.default.Fragment, null, enableVirtualization ? (react_1.default.createElement(VirtualScroll_1.default, { itemsLength: page.length, itemRenderer: virtualizedItemRenderer })) : (page.map(function (_, index) { return getPreparedRow(index); })))),
386
+ data.length !== 0 && (react_1.default.createElement(react_1.default.Fragment, null, enableVirtualization ? (react_1.default.createElement(VirtualScroll_1.default, { itemsLength: page.length, itemRenderer: virtualizedItemRenderer, scrollToIndex: scrollToIndex })) : (page.map(function (_, index) { return getPreparedRow(index); })))),
376
387
  isLoading && data.length === 0 && (react_1.default.createElement("div", { className: 'iui-table-empty' },
377
388
  react_1.default.createElement(ProgressIndicators_1.ProgressRadial, { indeterminate: true }))),
378
389
  isLoading && data.length !== 0 && (react_1.default.createElement("div", { className: 'iui-row' },
@@ -20,6 +20,8 @@ export declare const TableRow: <T extends Record<string, unknown>>(props: {
20
20
  tableHasSubRows: boolean;
21
21
  tableInstance: TableInstance<T>;
22
22
  expanderCell?: ((cellProps: CellProps<T, any>) => React.ReactNode) | undefined;
23
+ bodyRef: HTMLDivElement | null;
24
+ tableRowRef?: React.Ref<HTMLDivElement> | undefined;
23
25
  }) => JSX.Element;
24
26
  export declare const TableRowMemoized: <T extends Record<string, unknown>>(props: {
25
27
  row: Row<T>;
@@ -35,4 +37,6 @@ export declare const TableRowMemoized: <T extends Record<string, unknown>>(props
35
37
  tableHasSubRows: boolean;
36
38
  tableInstance: TableInstance<T>;
37
39
  expanderCell?: ((cellProps: CellProps<T, any>) => React.ReactNode) | undefined;
40
+ bodyRef: HTMLDivElement | null;
41
+ tableRowRef?: React.Ref<HTMLDivElement> | undefined;
38
42
  }) => JSX.Element;
@@ -30,14 +30,25 @@ var TableCell_1 = require("./TableCell");
30
30
  * When adding new features check whether it changes state that affects row. If it does then add equality check to `React.memo`.
31
31
  */
32
32
  var TableRow = function (props) {
33
- 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;
33
+ 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;
34
34
  var onIntersect = react_1.default.useCallback(function () {
35
35
  var _a, _b;
36
36
  (_a = onRowInViewport.current) === null || _a === void 0 ? void 0 : _a.call(onRowInViewport, row.original);
37
37
  isLast && ((_b = onBottomReached.current) === null || _b === void 0 ? void 0 : _b.call(onBottomReached));
38
38
  }, [isLast, onBottomReached, onRowInViewport, row.original]);
39
- var rowRef = (0, utils_1.useIntersection)(onIntersect, {
39
+ var intersectionRoot = react_1.default.useMemo(function () {
40
+ var _a, _b;
41
+ 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);
42
+ // If table body is scrollable, make it the intersection root
43
+ if (isTableBodyScrollable) {
44
+ return bodyRef;
45
+ }
46
+ // Otherwise, make the viewport the intersection root
47
+ return undefined;
48
+ }, [bodyRef]);
49
+ var intersectionRef = (0, utils_1.useIntersection)(onIntersect, {
40
50
  rootMargin: "".concat(intersectionMargin, "px"),
51
+ root: intersectionRoot,
41
52
  });
42
53
  var userRowProps = rowProps === null || rowProps === void 0 ? void 0 : rowProps(row);
43
54
  var mergedProps = __assign(__assign(__assign({}, row.getRowProps({ style: { flex: "0 0 auto", minWidth: '100%' } })), userRowProps), {
@@ -47,7 +58,7 @@ var TableRow = function (props) {
47
58
  'iui-disabled': isDisabled,
48
59
  }, userRowProps === null || userRowProps === void 0 ? void 0 : userRowProps.className),
49
60
  });
50
- var refs = (0, utils_1.useMergedRefs)(rowRef, mergedProps.ref);
61
+ var refs = (0, utils_1.useMergedRefs)(intersectionRef, mergedProps.ref, tableRowRef);
51
62
  return (react_1.default.createElement(react_1.default.Fragment, null,
52
63
  react_1.default.createElement("div", __assign({}, mergedProps, { ref: refs, onClick: function (event) {
53
64
  var _a;
@@ -97,6 +108,7 @@ exports.TableRowMemoized = react_1.default.memo(exports.TableRow, function (prev
97
108
  prevProp.rowProps === nextProp.rowProps &&
98
109
  prevProp.expanderCell === nextProp.expanderCell &&
99
110
  prevProp.tableHasSubRows === nextProp.tableHasSubRows &&
111
+ prevProp.bodyRef === nextProp.bodyRef &&
100
112
  prevProp.state.columnOrder === nextProp.state.columnOrder &&
101
113
  !nextProp.state.columnResizing.isResizingColumn &&
102
114
  prevProp.state.isTableResizing === nextProp.state.isTableResizing &&
@@ -31,6 +31,7 @@ exports.EditableCell = void 0;
31
31
  * See LICENSE.md in the project root for license terms and full copyright notice.
32
32
  *--------------------------------------------------------------------------------------------*/
33
33
  var react_1 = __importDefault(require("react"));
34
+ var utils_1 = require("../../utils");
34
35
  /**
35
36
  * Editable cell.
36
37
  * It should be passed to `cellRenderer`.
@@ -53,8 +54,9 @@ var EditableCell = function (props) {
53
54
  react_1.default.useEffect(function () {
54
55
  setValue(sanitizeString(cellProps.value));
55
56
  }, [cellProps.value]);
56
- var _b = react_1.default.useState(false), isDirty = _b[0], setIsDirty = _b[1];
57
- return (react_1.default.createElement("div", __assign({}, cellElementProps, { contentEditable: true, suppressContentEditableWarning: true }, rest, { onInput: function (e) {
57
+ var _b = react_1.default.useState((0, utils_1.getRandomValue)(10)), key = _b[0], setKey = _b[1];
58
+ var _c = react_1.default.useState(false), isDirty = _c[0], setIsDirty = _c[1];
59
+ return (react_1.default.createElement("div", __assign({}, cellElementProps, { contentEditable: true, suppressContentEditableWarning: true, key: key }, rest, { onInput: function (e) {
58
60
  var _a;
59
61
  setValue(sanitizeString(e.target.innerText));
60
62
  setIsDirty(true);
@@ -65,6 +67,9 @@ var EditableCell = function (props) {
65
67
  onCellEdit(cellProps.column.id, value, cellProps.row.original);
66
68
  }
67
69
  (_a = props.onBlur) === null || _a === void 0 ? void 0 : _a.call(props, e);
70
+ // Prevents error when text is cleared.
71
+ // New key makes React to reattach with the DOM so it won't complain about deleted text node.
72
+ setKey((0, utils_1.getRandomValue)(10));
68
73
  }, onKeyDown: function (e) {
69
74
  var _a;
70
75
  // Prevents from adding HTML elements (div, br) inside a cell on Enter press
@@ -1,5 +1,11 @@
1
1
  /// <reference types="react" />
2
2
  import { HeaderProps } from 'react-table';
3
+ import { DropdownMenuProps } from '../../DropdownMenu';
4
+ declare type ActionColumnProps = {
5
+ columnManager?: boolean | {
6
+ dropdownMenuProps: Omit<DropdownMenuProps, 'menuItems' | 'children'>;
7
+ };
8
+ };
3
9
  /**
4
10
  * Action column that adds column manager to the Table header.
5
11
  * It is recommended to add this column to the end of the Table
@@ -19,9 +25,7 @@ import { HeaderProps } from 'react-table';
19
25
  * ),
20
26
  * },
21
27
  */
22
- export declare const ActionColumn: <T extends Record<string, unknown>>({ columnManager, }?: {
23
- columnManager?: boolean | undefined;
24
- }) => {
28
+ export declare const ActionColumn: <T extends Record<string, unknown>>({ columnManager, }?: ActionColumnProps) => {
25
29
  id: string;
26
30
  disableResizing: boolean;
27
31
  disableGroupBy: boolean;
@@ -33,3 +37,4 @@ export declare const ActionColumn: <T extends Record<string, unknown>>({ columnM
33
37
  disableReordering: boolean;
34
38
  Header: ({ allColumns, dispatch, state }: HeaderProps<T>) => JSX.Element | null;
35
39
  };
40
+ export {};
@@ -1,4 +1,15 @@
1
1
  "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
2
13
  var __importDefault = (this && this.__importDefault) || function (mod) {
3
14
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
15
  };
@@ -17,6 +28,7 @@ var Menu_1 = require("../../Menu");
17
28
  var Table_1 = require("../Table");
18
29
  var selectionColumn_1 = require("./selectionColumn");
19
30
  var expanderColumn_1 = require("./expanderColumn");
31
+ var classnames_1 = __importDefault(require("classnames"));
20
32
  var ACTION_CELL_ID = 'iui-table-action';
21
33
  /**
22
34
  * Action column that adds column manager to the Table header.
@@ -52,6 +64,7 @@ var ActionColumn = function (_a) {
52
64
  Header: function (_a) {
53
65
  var allColumns = _a.allColumns, dispatch = _a.dispatch, state = _a.state;
54
66
  var _b = react_1.default.useState(false), isOpen = _b[0], setIsOpen = _b[1];
67
+ var buttonRef = react_1.default.useRef(null);
55
68
  if (!columnManager) {
56
69
  return null;
57
70
  }
@@ -77,13 +90,31 @@ var ActionColumn = function (_a) {
77
90
  }
78
91
  // Triggers an update to resize the widths of all visible columns
79
92
  dispatch({ type: Table_1.tableResizeStartAction });
93
+ // If some columns were resized and some columns visibility was enabled, then horizontal scrollbar appears
94
+ // and table is scrolled to the very left which means our visibility dropdown menu is not visible.
95
+ // So for better UX we need to scroll to that dropdown menu.
96
+ queueMicrotask(function () {
97
+ var _a;
98
+ (_a = buttonRef.current) === null || _a === void 0 ? void 0 : _a.scrollIntoView();
99
+ });
80
100
  };
81
101
  return (react_1.default.createElement(Menu_1.MenuItem, { key: column.id, icon: react_1.default.createElement(Checkbox_1.Checkbox, { checked: checked, disabled: column.disableToggleVisibility, onClick: function (e) { return e.stopPropagation(); }, onChange: onClick, "aria-labelledby": "iui-column-".concat(column.id) }), onClick: onClick, disabled: column.disableToggleVisibility },
82
102
  react_1.default.createElement("div", { id: "iui-column-".concat(column.id) }, column.render('Header'))));
83
103
  });
84
104
  };
85
- return (react_1.default.createElement(DropdownMenu_1.DropdownMenu, { menuItems: headerCheckBoxes, onHide: function () { return setIsOpen(false); }, onShow: function () { return setIsOpen(true); } },
86
- react_1.default.createElement(IconButton_1.IconButton, { styleType: 'borderless', isActive: isOpen },
105
+ var dropdownMenuProps = typeof columnManager !== 'boolean'
106
+ ? columnManager.dropdownMenuProps
107
+ : {};
108
+ return (react_1.default.createElement(DropdownMenu_1.DropdownMenu, __assign({}, dropdownMenuProps, { menuItems: headerCheckBoxes, onHide: function (i) {
109
+ var _a;
110
+ setIsOpen(false);
111
+ (_a = dropdownMenuProps.onHide) === null || _a === void 0 ? void 0 : _a.call(dropdownMenuProps, i);
112
+ }, onShow: function (i) {
113
+ var _a;
114
+ setIsOpen(true);
115
+ (_a = dropdownMenuProps.onShow) === null || _a === void 0 ? void 0 : _a.call(dropdownMenuProps, i);
116
+ }, style: __assign({ maxHeight: '315px' }, dropdownMenuProps.style), className: (0, classnames_1.default)('iui-scroll', dropdownMenuProps.className) }),
117
+ react_1.default.createElement(IconButton_1.IconButton, { styleType: 'borderless', isActive: isOpen, ref: buttonRef },
87
118
  react_1.default.createElement(ColumnManager_1.default, null))));
88
119
  },
89
120
  };
@@ -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';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.useStickyColumns = exports.useColumnDragAndDrop = exports.useResizeColumns = exports.useSubRowSelection = exports.useSubRowFiltering = exports.useSelectionCell = exports.useExpanderCell = void 0;
3
+ exports.useStickyColumns = exports.useScrollToRow = exports.useColumnDragAndDrop = exports.useResizeColumns = exports.useSubRowSelection = exports.useSubRowFiltering = exports.useSelectionCell = exports.useExpanderCell = void 0;
4
4
  /*---------------------------------------------------------------------------------------------
5
5
  * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
6
6
  * See LICENSE.md in the project root for license terms and full copyright notice.
@@ -17,5 +17,7 @@ var useResizeColumns_1 = require("./useResizeColumns");
17
17
  Object.defineProperty(exports, "useResizeColumns", { enumerable: true, get: function () { return useResizeColumns_1.useResizeColumns; } });
18
18
  var useColumnDragAndDrop_1 = require("./useColumnDragAndDrop");
19
19
  Object.defineProperty(exports, "useColumnDragAndDrop", { enumerable: true, get: function () { return useColumnDragAndDrop_1.useColumnDragAndDrop; } });
20
+ var useScrollToRow_1 = require("./useScrollToRow");
21
+ Object.defineProperty(exports, "useScrollToRow", { enumerable: true, get: function () { return useScrollToRow_1.useScrollToRow; } });
20
22
  var useStickyColumns_1 = require("./useStickyColumns");
21
23
  Object.defineProperty(exports, "useStickyColumns", { enumerable: true, get: function () { return useStickyColumns_1.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, }: ScrollToRowProps<T>): ScrollToRow<T>;
11
+ export {};
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.useScrollToRow = void 0;
7
+ /*---------------------------------------------------------------------------------------------
8
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
9
+ * See LICENSE.md in the project root for license terms and full copyright notice.
10
+ *--------------------------------------------------------------------------------------------*/
11
+ var react_1 = __importDefault(require("react"));
12
+ function useScrollToRow(_a) {
13
+ var data = _a.data, enableVirtualization = _a.enableVirtualization, page = _a.page, paginatorRenderer = _a.paginatorRenderer, scrollToRow = _a.scrollToRow;
14
+ var rowRefs = react_1.default.useRef({});
15
+ // Refs prevents from having `page` and `data` as dependencies
16
+ // therefore we avoid unnecessary scroll to row.
17
+ var pageRef = react_1.default.useRef(page);
18
+ pageRef.current = page;
19
+ var dataRef = react_1.default.useRef(data);
20
+ dataRef.current = data;
21
+ // For virtualized tables, all we need to do is pass the index of the item
22
+ // to the VirtualScroll component
23
+ var scrollToIndex = react_1.default.useMemo(function () {
24
+ if (!scrollToRow || paginatorRenderer) {
25
+ return undefined;
26
+ }
27
+ var index = scrollToRow(pageRef.current, dataRef.current);
28
+ return index < 0 ? undefined : index;
29
+ }, [paginatorRenderer, scrollToRow]);
30
+ // For non-virtualized tables, we need to add a ref to each row
31
+ // and scroll to the element
32
+ react_1.default.useEffect(function () {
33
+ var _a;
34
+ if (enableVirtualization ||
35
+ scrollToIndex === undefined ||
36
+ scrollToIndex === null ||
37
+ scrollToIndex < 0) {
38
+ return;
39
+ }
40
+ (_a = rowRefs.current[pageRef.current[scrollToIndex].id]) === null || _a === void 0 ? void 0 : _a.scrollIntoView();
41
+ }, [enableVirtualization, scrollToIndex]);
42
+ var tableRowRef = react_1.default.useCallback(function (row) {
43
+ return function (element) {
44
+ rowRefs.current[row.id] = element;
45
+ };
46
+ }, []);
47
+ return { scrollToIndex: scrollToIndex, tableRowRef: tableRowRef };
48
+ }
49
+ exports.useScrollToRow = useScrollToRow;
@@ -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`.