@itwin/itwinui-react 1.45.0 → 1.47.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 (96) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/cjs/core/Breadcrumbs/Breadcrumbs.d.ts +116 -0
  3. package/cjs/core/Breadcrumbs/Breadcrumbs.js +2 -3
  4. package/cjs/core/ButtonGroup/ButtonGroup.js +1 -1
  5. package/cjs/core/ColorPicker/ColorSwatch.d.ts +1 -1
  6. package/cjs/core/DatePicker/DatePicker.d.ts +24 -4
  7. package/cjs/core/DatePicker/DatePicker.js +116 -19
  8. package/cjs/core/Dialog/Dialog.d.ts +5 -5
  9. package/cjs/core/Dialog/Dialog.js +38 -6
  10. package/cjs/core/Dialog/DialogBackdrop.d.ts +2 -2
  11. package/cjs/core/Dialog/DialogBackdrop.js +2 -2
  12. package/cjs/core/Dialog/DialogContext.d.ts +31 -0
  13. package/cjs/core/Dialog/DialogDragContext.d.ts +8 -0
  14. package/cjs/core/Dialog/DialogDragContext.js +28 -0
  15. package/cjs/core/Dialog/DialogMain.d.ts +2 -2
  16. package/cjs/core/Dialog/DialogMain.js +46 -6
  17. package/cjs/core/Dialog/DialogTitleBar.d.ts +2 -2
  18. package/cjs/core/Dialog/DialogTitleBar.js +12 -2
  19. package/cjs/core/Modal/Modal.js +1 -1
  20. package/cjs/core/Table/Table.d.ts +6 -0
  21. package/cjs/core/Table/Table.js +73 -17
  22. package/cjs/core/Table/actionHandlers/index.d.ts +1 -1
  23. package/cjs/core/Table/actionHandlers/index.js +2 -1
  24. package/cjs/core/Table/actionHandlers/resizeHandler.d.ts +2 -0
  25. package/cjs/core/Table/actionHandlers/selectHandler.d.ts +5 -0
  26. package/cjs/core/Table/actionHandlers/selectHandler.js +35 -2
  27. package/cjs/core/Table/filters/FilterToggle.d.ts +0 -1
  28. package/cjs/core/Table/filters/FilterToggle.js +3 -3
  29. package/cjs/core/Table/hooks/useResizeColumns.d.ts +33 -1
  30. package/cjs/core/Table/hooks/useResizeColumns.js +89 -29
  31. package/cjs/core/index.d.ts +3 -1
  32. package/cjs/core/index.js +6 -3
  33. package/cjs/core/utils/components/Resizer.d.ts +31 -0
  34. package/cjs/core/utils/components/Resizer.js +206 -0
  35. package/cjs/core/utils/components/VirtualScroll.js +26 -24
  36. package/cjs/core/utils/components/index.d.ts +1 -0
  37. package/cjs/core/utils/components/index.js +1 -0
  38. package/cjs/core/utils/functions/index.d.ts +1 -0
  39. package/cjs/core/utils/functions/index.js +1 -0
  40. package/cjs/core/utils/functions/styles.d.ts +6 -0
  41. package/cjs/core/utils/functions/styles.js +21 -0
  42. package/cjs/core/utils/hooks/useContainerWidth.d.ts +1 -1
  43. package/cjs/core/utils/hooks/useDragAndDrop.d.ts +14 -0
  44. package/cjs/core/utils/hooks/useDragAndDrop.js +110 -0
  45. package/cjs/core/utils/hooks/useEventListener.d.ts +1 -1
  46. package/cjs/core/utils/hooks/useOverflow.d.ts +1 -1
  47. package/cjs/core/utils/hooks/useResizeObserver.d.ts +1 -1
  48. package/cjs/types/react-table-config.d.ts +13 -1
  49. package/esm/core/Breadcrumbs/Breadcrumbs.d.ts +116 -0
  50. package/esm/core/Breadcrumbs/Breadcrumbs.js +2 -3
  51. package/esm/core/ButtonGroup/ButtonGroup.js +1 -1
  52. package/esm/core/ColorPicker/ColorSwatch.d.ts +1 -1
  53. package/esm/core/DatePicker/DatePicker.d.ts +24 -4
  54. package/esm/core/DatePicker/DatePicker.js +116 -19
  55. package/esm/core/Dialog/Dialog.d.ts +5 -5
  56. package/esm/core/Dialog/Dialog.js +37 -5
  57. package/esm/core/Dialog/DialogBackdrop.d.ts +2 -2
  58. package/esm/core/Dialog/DialogBackdrop.js +2 -2
  59. package/esm/core/Dialog/DialogContext.d.ts +31 -0
  60. package/esm/core/Dialog/DialogDragContext.d.ts +8 -0
  61. package/esm/core/Dialog/DialogDragContext.js +21 -0
  62. package/esm/core/Dialog/DialogMain.d.ts +2 -2
  63. package/esm/core/Dialog/DialogMain.js +47 -7
  64. package/esm/core/Dialog/DialogTitleBar.d.ts +2 -2
  65. package/esm/core/Dialog/DialogTitleBar.js +12 -2
  66. package/esm/core/Modal/Modal.js +1 -1
  67. package/esm/core/Table/Table.d.ts +6 -0
  68. package/esm/core/Table/Table.js +76 -20
  69. package/esm/core/Table/actionHandlers/index.d.ts +1 -1
  70. package/esm/core/Table/actionHandlers/index.js +1 -1
  71. package/esm/core/Table/actionHandlers/resizeHandler.d.ts +2 -0
  72. package/esm/core/Table/actionHandlers/selectHandler.d.ts +5 -0
  73. package/esm/core/Table/actionHandlers/selectHandler.js +33 -1
  74. package/esm/core/Table/filters/FilterToggle.d.ts +0 -1
  75. package/esm/core/Table/filters/FilterToggle.js +4 -4
  76. package/esm/core/Table/hooks/useResizeColumns.d.ts +33 -1
  77. package/esm/core/Table/hooks/useResizeColumns.js +89 -29
  78. package/esm/core/index.d.ts +3 -1
  79. package/esm/core/index.js +2 -1
  80. package/esm/core/utils/components/Resizer.d.ts +31 -0
  81. package/esm/core/utils/components/Resizer.js +199 -0
  82. package/esm/core/utils/components/VirtualScroll.js +26 -24
  83. package/esm/core/utils/components/index.d.ts +1 -0
  84. package/esm/core/utils/components/index.js +1 -0
  85. package/esm/core/utils/functions/index.d.ts +1 -0
  86. package/esm/core/utils/functions/index.js +1 -0
  87. package/esm/core/utils/functions/styles.d.ts +6 -0
  88. package/esm/core/utils/functions/styles.js +17 -0
  89. package/esm/core/utils/hooks/useContainerWidth.d.ts +1 -1
  90. package/esm/core/utils/hooks/useDragAndDrop.d.ts +14 -0
  91. package/esm/core/utils/hooks/useDragAndDrop.js +103 -0
  92. package/esm/core/utils/hooks/useEventListener.d.ts +1 -1
  93. package/esm/core/utils/hooks/useOverflow.d.ts +1 -1
  94. package/esm/core/utils/hooks/useResizeObserver.d.ts +1 -1
  95. package/esm/types/react-table-config.d.ts +13 -1
  96. package/package.json +1 -1
@@ -29,11 +29,42 @@ export declare type DialogContextProps = {
29
29
  * @default false
30
30
  */
31
31
  trapFocus?: boolean;
32
+ /**
33
+ * If true, focuses the dialog.
34
+ * @default false
35
+ */
36
+ setFocus?: boolean;
32
37
  /**
33
38
  * Prevents body from being scrollable. This is useful when the dialog is modal.
34
39
  * @default false
35
40
  */
36
41
  preventDocumentScroll?: boolean;
42
+ /**
43
+ * Flag whether dialog is draggable.
44
+ *
45
+ * If you want to make dialog draggable relatively to the container, you should use set `relativeTo` to `container`.
46
+ *
47
+ * @default false
48
+ */
49
+ isDraggable?: boolean;
50
+ /**
51
+ * Flag whether dialog is resizable.
52
+ * @default false
53
+ */
54
+ isResizable?: boolean;
55
+ /**
56
+ * Whether dialog should be positioned relatively to a container or the viewport.
57
+ *
58
+ * Using `'container'` will absolutely position this dialog relative to the closest positioned ancestor.
59
+ * In other words, you must place the dialog as a child of an element that has `position` set to
60
+ * something other than `static`, e.g. `position: relative`.
61
+ * @default 'viewport'
62
+ */
63
+ relativeTo?: 'container' | 'viewport';
64
+ /**
65
+ * Dialog root ref. For internal use.
66
+ */
67
+ dialogRootRef?: React.RefObject<HTMLDivElement>;
37
68
  };
38
69
  export declare const DialogContext: React.Context<DialogContextProps | undefined>;
39
70
  export declare const useDialogContext: () => DialogContextProps;
@@ -0,0 +1,8 @@
1
+ import React from 'react';
2
+ export declare type DialogDragContextProps = {
3
+ onPointerDown?: (e: React.PointerEvent<HTMLElement>) => void;
4
+ };
5
+ export declare const DialogDragContext: React.Context<DialogDragContextProps | undefined>;
6
+ export declare const useDialogDragContext: () => {
7
+ onPointerDown?: ((e: React.PointerEvent<HTMLElement>) => void) | undefined;
8
+ };
@@ -0,0 +1,28 @@
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
+ };
13
+ var __importDefault = (this && this.__importDefault) || function (mod) {
14
+ return (mod && mod.__esModule) ? mod : { "default": mod };
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.useDialogDragContext = exports.DialogDragContext = void 0;
18
+ /*---------------------------------------------------------------------------------------------
19
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
20
+ * See LICENSE.md in the project root for license terms and full copyright notice.
21
+ *--------------------------------------------------------------------------------------------*/
22
+ var react_1 = __importDefault(require("react"));
23
+ exports.DialogDragContext = react_1.default.createContext(undefined);
24
+ var useDialogDragContext = function () {
25
+ var context = react_1.default.useContext(exports.DialogDragContext);
26
+ return __assign({}, context);
27
+ };
28
+ exports.useDialogDragContext = useDialogDragContext;
@@ -11,7 +11,7 @@ export declare type DialogMainProps = {
11
11
  * Content of the dialog.
12
12
  */
13
13
  children: React.ReactNode;
14
- } & Omit<DialogContextProps, 'closeOnExternalClick'> & React.ComponentPropsWithRef<'div'>;
14
+ } & Omit<DialogContextProps, 'closeOnExternalClick' | 'dialogRootRef'> & React.ComponentPropsWithRef<'div'>;
15
15
  /**
16
16
  * Dialog component which can wrap any content.
17
17
  * @example
@@ -32,5 +32,5 @@ export declare type DialogMainProps = {
32
32
  * </Dialog.ButtonBar>
33
33
  * </Dialog.Main>
34
34
  */
35
- export declare const DialogMain: React.ForwardRefExoticComponent<Pick<DialogMainProps, "onClose" | "key" | keyof React.HTMLAttributes<HTMLDivElement> | "styleType" | "isOpen" | "isDismissible" | "closeOnEsc" | "trapFocus" | "preventDocumentScroll"> & React.RefAttributes<HTMLDivElement>>;
35
+ export declare const DialogMain: React.ForwardRefExoticComponent<Pick<DialogMainProps, "onClose" | "key" | keyof React.HTMLAttributes<HTMLDivElement> | "styleType" | "setFocus" | "isOpen" | "isDismissible" | "isDraggable" | "closeOnEsc" | "trapFocus" | "preventDocumentScroll" | "isResizable" | "relativeTo"> & React.RefAttributes<HTMLDivElement>>;
36
36
  export default DialogMain;
@@ -36,6 +36,8 @@ var utils_1 = require("../utils");
36
36
  require("@itwin/itwinui-css/css/dialog.css");
37
37
  var DialogContext_1 = require("./DialogContext");
38
38
  var react_transition_group_1 = require("react-transition-group");
39
+ var DialogDragContext_1 = require("./DialogDragContext");
40
+ var useDragAndDrop_1 = __importDefault(require("../utils/hooks/useDragAndDrop"));
39
41
  /**
40
42
  * Dialog component which can wrap any content.
41
43
  * @example
@@ -58,14 +60,19 @@ var react_transition_group_1 = require("react-transition-group");
58
60
  */
59
61
  exports.DialogMain = react_1.default.forwardRef(function (props, ref) {
60
62
  var dialogContext = (0, DialogContext_1.useDialogContext)();
61
- var className = props.className, children = props.children, _a = props.styleType, styleType = _a === void 0 ? 'default' : _a, _b = props.isOpen, isOpen = _b === void 0 ? dialogContext.isOpen : _b, _c = props.isDismissible, isDismissible = _c === void 0 ? dialogContext.isDismissible : _c, _d = props.onClose, onClose = _d === void 0 ? dialogContext.onClose : _d, _e = props.closeOnEsc, closeOnEsc = _e === void 0 ? dialogContext.closeOnEsc : _e, _f = props.trapFocus, trapFocus = _f === void 0 ? dialogContext.trapFocus : _f, _g = props.preventDocumentScroll, preventDocumentScroll = _g === void 0 ? dialogContext.preventDocumentScroll : _g, onKeyDown = props.onKeyDown, rest = __rest(props, ["className", "children", "styleType", "isOpen", "isDismissible", "onClose", "closeOnEsc", "trapFocus", "preventDocumentScroll", "onKeyDown"]);
63
+ var className = props.className, children = props.children, _a = props.styleType, styleType = _a === void 0 ? 'default' : _a, _b = props.isOpen, isOpen = _b === void 0 ? dialogContext.isOpen : _b, _c = props.isDismissible, isDismissible = _c === void 0 ? dialogContext.isDismissible : _c, _d = props.onClose, onClose = _d === void 0 ? dialogContext.onClose : _d, _e = props.closeOnEsc, closeOnEsc = _e === void 0 ? dialogContext.closeOnEsc : _e, _f = props.trapFocus, trapFocus = _f === void 0 ? dialogContext.trapFocus : _f, _g = props.setFocus, setFocus = _g === void 0 ? dialogContext.setFocus : _g, _h = props.preventDocumentScroll, preventDocumentScroll = _h === void 0 ? dialogContext.preventDocumentScroll : _h, onKeyDown = props.onKeyDown, _j = props.isDraggable, isDraggable = _j === void 0 ? dialogContext.isDraggable : _j, _k = props.isResizable, isResizable = _k === void 0 ? dialogContext.isResizable : _k, propStyle = props.style, rest = __rest(props, ["className", "children", "styleType", "isOpen", "isDismissible", "onClose", "closeOnEsc", "trapFocus", "setFocus", "preventDocumentScroll", "onKeyDown", "isDraggable", "isResizable", "style"]);
62
64
  (0, utils_1.useTheme)();
65
+ var _l = react_1.default.useState(), style = _l[0], setStyle = _l[1];
63
66
  var dialogRef = react_1.default.useRef(null);
64
67
  var refs = (0, utils_1.useMergedRefs)(dialogRef, ref);
65
68
  // Focuses dialog when opened and brings back focus to the previously focused element when closed.
66
69
  var previousFocusedElement = react_1.default.useRef();
70
+ var setFocusRef = (0, utils_1.useLatestRef)(setFocus);
67
71
  react_1.default.useEffect(function () {
68
72
  var _a, _b, _c;
73
+ if (!setFocusRef.current) {
74
+ return;
75
+ }
69
76
  if (isOpen) {
70
77
  previousFocusedElement.current = (_a = dialogRef.current) === null || _a === void 0 ? void 0 : _a.ownerDocument.activeElement;
71
78
  (_b = dialogRef.current) === null || _b === void 0 ? void 0 : _b.focus();
@@ -79,17 +86,25 @@ exports.DialogMain = react_1.default.forwardRef(function (props, ref) {
79
86
  (ref === null || ref === void 0 ? void 0 : ref.contains(document.activeElement)) &&
80
87
  ((_a = previousFocusedElement.current) === null || _a === void 0 ? void 0 : _a.focus());
81
88
  };
89
+ }, [isOpen, setFocusRef]);
90
+ var originalBodyOverflow = react_1.default.useRef('');
91
+ react_1.default.useEffect(function () {
92
+ if (isOpen) {
93
+ originalBodyOverflow.current = document.body.style.overflow;
94
+ }
82
95
  }, [isOpen]);
83
96
  // Prevents document from scrolling when the dialog is open.
84
- var originalBodyOverflow = react_1.default.useRef('');
85
97
  react_1.default.useEffect(function () {
86
98
  var _a;
87
99
  var ownerDocument = (_a = dialogRef.current) === null || _a === void 0 ? void 0 : _a.ownerDocument;
88
- if (!ownerDocument || !preventDocumentScroll) {
100
+ // If there is no `ownerDocument` or `preventDocumentScroll` is false or
101
+ // document body originally has `overflow: hidden` (possibly from other/parent dialog), then do nothing.
102
+ if (!ownerDocument ||
103
+ !preventDocumentScroll ||
104
+ originalBodyOverflow.current === 'hidden') {
89
105
  return;
90
106
  }
91
107
  if (isOpen) {
92
- originalBodyOverflow.current = ownerDocument.body.style.overflow;
93
108
  ownerDocument.body.style.overflow = 'hidden';
94
109
  }
95
110
  else {
@@ -107,13 +122,38 @@ exports.DialogMain = react_1.default.forwardRef(function (props, ref) {
107
122
  }
108
123
  onKeyDown === null || onKeyDown === void 0 ? void 0 : onKeyDown(event);
109
124
  };
125
+ var _m = (0, useDragAndDrop_1.default)(dialogRef, dialogContext.dialogRootRef, isDraggable), onPointerDown = _m.onPointerDown, transform = _m.transform;
126
+ var handlePointerDown = react_1.default.useCallback(function (event) {
127
+ if (isDraggable) {
128
+ onPointerDown(event);
129
+ }
130
+ }, [isDraggable, onPointerDown]);
131
+ // Prevents dialog from moving when window is being resized
132
+ react_1.default.useLayoutEffect(function () {
133
+ var _a;
134
+ if (!isDraggable || !isOpen) {
135
+ return;
136
+ }
137
+ var rect = (_a = dialogRef.current) === null || _a === void 0 ? void 0 : _a.getBoundingClientRect();
138
+ var _b = (0, utils_1.getTranslateValues)(dialogRef.current), translateX = _b[0], translateY = _b[1];
139
+ setStyle(function (oldStyle) {
140
+ var _a, _b;
141
+ return (__assign(__assign({}, oldStyle), { width: rect === null || rect === void 0 ? void 0 : rect.width, height: rect === null || rect === void 0 ? void 0 : rect.height, left: (_a = dialogRef.current) === null || _a === void 0 ? void 0 : _a.offsetLeft, top: (_b = dialogRef.current) === null || _b === void 0 ? void 0 : _b.offsetTop, transform: "translate(".concat(translateX, "px,").concat(translateY, "px)") }));
142
+ });
143
+ }, [isDraggable, isOpen]);
144
+ var setResizeStyle = react_1.default.useCallback(function (newStyle) {
145
+ setStyle(function (oldStyle) { return (__assign(__assign({}, oldStyle), newStyle)); });
146
+ }, []);
110
147
  var content = (react_1.default.createElement("div", __assign({ className: (0, classnames_1.default)('iui-dialog', {
111
148
  'iui-dialog-default': styleType === 'default',
112
149
  'iui-dialog-full-page': styleType === 'fullPage',
113
150
  'iui-dialog-visible': isOpen,
114
- }, className), role: 'dialog', ref: refs, onKeyDown: handleKeyDown, tabIndex: -1 }, rest), children));
151
+ 'iui-dialog-draggable': isDraggable,
152
+ }, className), role: 'dialog', ref: refs, onKeyDown: handleKeyDown, tabIndex: -1, style: __assign(__assign({ transform: transform, overflow: 'unset' }, style), propStyle) }, rest),
153
+ isResizable && (react_1.default.createElement(utils_1.Resizer, { elementRef: dialogRef, containerRef: dialogContext.dialogRootRef, onResizeEnd: setResizeStyle })),
154
+ children));
115
155
  return (react_1.default.createElement(react_transition_group_1.CSSTransition, { in: isOpen, classNames: 'iui-dialog-animation', timeout: { exit: 600 }, unmountOnExit: true, nodeRef: dialogRef },
116
- react_1.default.createElement(react_1.default.Fragment, null,
156
+ react_1.default.createElement(DialogDragContext_1.DialogDragContext.Provider, { value: { onPointerDown: handlePointerDown } },
117
157
  trapFocus && react_1.default.createElement(utils_1.FocusTrap, null, content),
118
158
  !trapFocus && content)));
119
159
  });
@@ -10,7 +10,7 @@ export declare type DialogTitleBarProps = {
10
10
  * Dialog title.
11
11
  */
12
12
  titleText?: React.ReactNode;
13
- } & Pick<DialogContextProps, 'isDismissible' | 'onClose'> & React.ComponentPropsWithRef<'div'>;
13
+ } & Pick<DialogContextProps, 'isDismissible' | 'onClose' | 'isDraggable'> & React.ComponentPropsWithRef<'div'>;
14
14
  /**
15
15
  * Dialog title bar. Recommended to be used as a child of `Dialog`.
16
16
  * @example
@@ -28,7 +28,7 @@ export declare type DialogTitleBarProps = {
28
28
  * </IconButton>
29
29
  * </Dialog.TitleBar>
30
30
  */
31
- export declare const DialogTitleBar: React.ForwardRefExoticComponent<Pick<DialogTitleBarProps, "onClose" | "key" | keyof React.HTMLAttributes<HTMLDivElement> | "isDismissible" | "titleText"> & React.RefAttributes<HTMLDivElement>> & {
31
+ export declare const DialogTitleBar: React.ForwardRefExoticComponent<Pick<DialogTitleBarProps, "onClose" | "key" | keyof React.HTMLAttributes<HTMLDivElement> | "isDismissible" | "isDraggable" | "titleText"> & React.RefAttributes<HTMLDivElement>> & {
32
32
  Title: React.ForwardRefExoticComponent<Pick<import("./DialogTitleBarTitle").DialogTitleBarTitleProps, "key" | keyof React.HTMLAttributes<HTMLDivElement>> & React.RefAttributes<HTMLDivElement>>;
33
33
  };
34
34
  export default DialogTitleBar;
@@ -38,6 +38,7 @@ var Buttons_1 = require("../Buttons");
38
38
  require("@itwin/itwinui-css/css/dialog.css");
39
39
  var DialogContext_1 = require("./DialogContext");
40
40
  var DialogTitleBarTitle_1 = require("./DialogTitleBarTitle");
41
+ var DialogDragContext_1 = require("./DialogDragContext");
41
42
  /**
42
43
  * Dialog title bar. Recommended to be used as a child of `Dialog`.
43
44
  * @example
@@ -57,9 +58,18 @@ var DialogTitleBarTitle_1 = require("./DialogTitleBarTitle");
57
58
  */
58
59
  exports.DialogTitleBar = Object.assign(react_1.default.forwardRef(function (props, ref) {
59
60
  var dialogContext = (0, DialogContext_1.useDialogContext)();
60
- var children = props.children, titleText = props.titleText, _a = props.isDismissible, isDismissible = _a === void 0 ? dialogContext.isDismissible : _a, _b = props.onClose, onClose = _b === void 0 ? dialogContext.onClose : _b, className = props.className, rest = __rest(props, ["children", "titleText", "isDismissible", "onClose", "className"]);
61
+ var children = props.children, titleText = props.titleText, _a = props.isDismissible, isDismissible = _a === void 0 ? dialogContext.isDismissible : _a, _b = props.onClose, onClose = _b === void 0 ? dialogContext.onClose : _b, _c = props.isDraggable, isDraggable = _c === void 0 ? dialogContext.isDraggable : _c, className = props.className, onPointerDownProp = props.onPointerDown, rest = __rest(props, ["children", "titleText", "isDismissible", "onClose", "isDraggable", "className", "onPointerDown"]);
62
+ var onPointerDown = (0, DialogDragContext_1.useDialogDragContext)().onPointerDown;
63
+ var handlePointerDown = react_1.default.useCallback(function (event) {
64
+ onPointerDownProp === null || onPointerDownProp === void 0 ? void 0 : onPointerDownProp(event);
65
+ if (!event.defaultPrevented) {
66
+ onPointerDown === null || onPointerDown === void 0 ? void 0 : onPointerDown(event);
67
+ }
68
+ }, [onPointerDown, onPointerDownProp]);
61
69
  (0, utils_1.useTheme)();
62
- return (react_1.default.createElement("div", __assign({ className: (0, classnames_1.default)('iui-dialog-title-bar', className), ref: ref }, rest), children ? (children) : (react_1.default.createElement(react_1.default.Fragment, null,
70
+ return (react_1.default.createElement("div", __assign({ className: (0, classnames_1.default)('iui-dialog-title-bar', className, {
71
+ 'iui-dialog-title-bar-filled': isDraggable,
72
+ }), ref: ref, onPointerDown: handlePointerDown }, rest), children ? (children) : (react_1.default.createElement(react_1.default.Fragment, null,
63
73
  react_1.default.createElement(DialogTitleBarTitle_1.DialogTitleBarTitle, null, titleText),
64
74
  isDismissible && (react_1.default.createElement(Buttons_1.IconButton, { size: 'small', styleType: 'borderless', onClick: onClose, "aria-label": 'Close' },
65
75
  react_1.default.createElement(Close_1.default, null)))))));
@@ -60,7 +60,7 @@ var Modal = function (props) {
60
60
  var _a = props.isOpen, isOpen = _a === void 0 ? false : _a, _b = props.isDismissible, isDismissible = _b === void 0 ? true : _b, _c = props.closeOnEsc, closeOnEsc = _c === void 0 ? true : _c, _d = props.closeOnExternalClick, closeOnExternalClick = _d === void 0 ? true : _d, onClose = props.onClose, title = props.title, children = props.children, _e = props.modalRootId, modalRootId = _e === void 0 ? 'iui-react-portal-container' : _e, _f = props.ownerDocument, ownerDocument = _f === void 0 ? (0, utils_1.getDocument)() : _f, rest = __rest(props, ["isOpen", "isDismissible", "closeOnEsc", "closeOnExternalClick", "onClose", "title", "children", "modalRootId", "ownerDocument"]);
61
61
  (0, utils_1.useTheme)();
62
62
  var container = (0, utils_1.getContainer)(modalRootId, ownerDocument);
63
- return !!container ? (react_dom_1.default.createPortal(react_1.default.createElement(Dialog_1.Dialog, { isOpen: isOpen, closeOnEsc: closeOnEsc, closeOnExternalClick: closeOnExternalClick, isDismissible: isDismissible, onClose: onClose, preventDocumentScroll: true, trapFocus: true },
63
+ return !!container ? (react_dom_1.default.createPortal(react_1.default.createElement(Dialog_1.Dialog, { isOpen: isOpen, closeOnEsc: closeOnEsc, closeOnExternalClick: closeOnExternalClick, isDismissible: isDismissible, onClose: onClose, preventDocumentScroll: true, trapFocus: true, setFocus: true },
64
64
  react_1.default.createElement(Dialog_1.Dialog.Backdrop, null),
65
65
  react_1.default.createElement(Dialog_1.Dialog.Main, __assign({ "aria-modal": true }, rest),
66
66
  react_1.default.createElement(Dialog_1.Dialog.TitleBar, { titleText: title }),
@@ -116,6 +116,12 @@ export declare type TableProps<T extends Record<string, unknown> = Record<string
116
116
  * Must be memoized.
117
117
  */
118
118
  onFilter?: (filters: TableFilterValue<T>[], state: TableState<T>) => void;
119
+ /**
120
+ * Value used for global filtering.
121
+ * Use with `globalFilter` and/or `manualGlobalFilter` to handle filtering yourself e.g. filter in server-side.
122
+ * Must be memoized.
123
+ */
124
+ globalFilterValue?: unknown;
119
125
  /**
120
126
  * Content shown when there is no data after filtering.
121
127
  */
@@ -47,6 +47,7 @@ var actionHandlers_1 = require("./actionHandlers");
47
47
  var VirtualScroll_1 = __importDefault(require("../utils/components/VirtualScroll"));
48
48
  var columns_1 = require("./columns");
49
49
  var singleRowSelectedAction = 'singleRowSelected';
50
+ var shiftRowSelectedAction = 'shiftRowSelected';
50
51
  exports.tableResizeStartAction = 'tableResizeStart';
51
52
  var tableResizeEndAction = 'tableResizeEnd';
52
53
  var flattenColumns = function (columns) {
@@ -103,9 +104,9 @@ var flattenColumns = function (columns) {
103
104
  */
104
105
  var Table = function (props) {
105
106
  var _a;
106
- var data = props.data, columns = props.columns, _b = props.isLoading, isLoading = _b === void 0 ? false : _b, emptyTableContent = props.emptyTableContent, className = props.className, style = props.style, id = props.id, _c = props.isSelectable, isSelectable = _c === void 0 ? false : _c, onSelect = props.onSelect, onRowClick = props.onRowClick, _d = props.selectionMode, selectionMode = _d === void 0 ? 'multi' : _d, _e = props.isSortable, isSortable = _e === void 0 ? false : _e, onSort = props.onSort, stateReducer = props.stateReducer, onBottomReached = props.onBottomReached, onRowInViewport = props.onRowInViewport, _f = props.intersectionMargin, intersectionMargin = _f === void 0 ? 300 : _f, subComponent = props.subComponent, onExpand = props.onExpand, onFilter = props.onFilter, emptyFilteredTableContent = props.emptyFilteredTableContent, filterFunctions = props.filterTypes, expanderCell = props.expanderCell, isRowDisabled = props.isRowDisabled, rowProps = props.rowProps, _g = props.density, density = _g === void 0 ? 'default' : _g, _h = props.selectSubRows, selectSubRows = _h === void 0 ? true : _h, getSubRows = props.getSubRows, _j = props.selectRowOnClick, selectRowOnClick = _j === void 0 ? true : _j, paginatorRenderer = props.paginatorRenderer, _k = props.pageSize, pageSize = _k === void 0 ? 25 : _k, _l = props.isResizable, isResizable = _l === void 0 ? false : _l, _m = props.styleType, styleType = _m === void 0 ? 'default' : _m, _o = props.enableVirtualization, enableVirtualization = _o === void 0 ? false : _o, _p = props.enableColumnReordering, enableColumnReordering = _p === void 0 ? false : _p, rest = __rest(props, ["data", "columns", "isLoading", "emptyTableContent", "className", "style", "id", "isSelectable", "onSelect", "onRowClick", "selectionMode", "isSortable", "onSort", "stateReducer", "onBottomReached", "onRowInViewport", "intersectionMargin", "subComponent", "onExpand", "onFilter", "emptyFilteredTableContent", "filterTypes", "expanderCell", "isRowDisabled", "rowProps", "density", "selectSubRows", "getSubRows", "selectRowOnClick", "paginatorRenderer", "pageSize", "isResizable", "styleType", "enableVirtualization", "enableColumnReordering"]);
107
+ var data = props.data, columns = props.columns, _b = props.isLoading, isLoading = _b === void 0 ? false : _b, emptyTableContent = props.emptyTableContent, className = props.className, style = props.style, id = props.id, _c = props.isSelectable, isSelectable = _c === void 0 ? false : _c, onSelect = props.onSelect, onRowClick = props.onRowClick, _d = props.selectionMode, selectionMode = _d === void 0 ? 'multi' : _d, _e = props.isSortable, isSortable = _e === void 0 ? false : _e, onSort = props.onSort, stateReducer = props.stateReducer, onBottomReached = props.onBottomReached, onRowInViewport = props.onRowInViewport, _f = props.intersectionMargin, intersectionMargin = _f === void 0 ? 300 : _f, subComponent = props.subComponent, onExpand = props.onExpand, onFilter = props.onFilter, globalFilterValue = props.globalFilterValue, emptyFilteredTableContent = props.emptyFilteredTableContent, filterFunctions = props.filterTypes, expanderCell = props.expanderCell, isRowDisabled = props.isRowDisabled, rowProps = props.rowProps, _g = props.density, density = _g === void 0 ? 'default' : _g, _h = props.selectSubRows, selectSubRows = _h === void 0 ? true : _h, getSubRows = props.getSubRows, _j = props.selectRowOnClick, selectRowOnClick = _j === void 0 ? true : _j, paginatorRenderer = props.paginatorRenderer, _k = props.pageSize, pageSize = _k === void 0 ? 25 : _k, _l = props.isResizable, isResizable = _l === void 0 ? false : _l, _m = props.columnResizeMode, columnResizeMode = _m === void 0 ? 'fit' : _m, _o = props.styleType, styleType = _o === void 0 ? 'default' : _o, _p = props.enableVirtualization, enableVirtualization = _p === void 0 ? false : _p, _q = props.enableColumnReordering, enableColumnReordering = _q === void 0 ? false : _q, rest = __rest(props, ["data", "columns", "isLoading", "emptyTableContent", "className", "style", "id", "isSelectable", "onSelect", "onRowClick", "selectionMode", "isSortable", "onSort", "stateReducer", "onBottomReached", "onRowInViewport", "intersectionMargin", "subComponent", "onExpand", "onFilter", "globalFilterValue", "emptyFilteredTableContent", "filterTypes", "expanderCell", "isRowDisabled", "rowProps", "density", "selectSubRows", "getSubRows", "selectRowOnClick", "paginatorRenderer", "pageSize", "isResizable", "columnResizeMode", "styleType", "enableVirtualization", "enableColumnReordering"]);
107
108
  (0, utils_1.useTheme)();
108
- var _q = react_1.default.useState(), ownerDocument = _q[0], setOwnerDocument = _q[1];
109
+ var ownerDocument = react_1.default.useRef();
109
110
  var defaultColumn = react_1.default.useMemo(function () { return ({
110
111
  maxWidth: 0,
111
112
  minWidth: 0,
@@ -122,6 +123,36 @@ var Table = function (props) {
122
123
  var flatColumns = flattenColumns(columns);
123
124
  return flatColumns.some(function (column) { return column.id === columns_1.SELECTION_CELL_ID; });
124
125
  }, [columns]);
126
+ var disableUserSelect = react_1.default.useCallback(function (e) {
127
+ if (e.key === 'Shift') {
128
+ ownerDocument.current &&
129
+ (ownerDocument.current.documentElement.style.userSelect = 'none');
130
+ }
131
+ }, []);
132
+ var enableUserSelect = react_1.default.useCallback(function (e) {
133
+ if (e.key === 'Shift') {
134
+ ownerDocument.current &&
135
+ (ownerDocument.current.documentElement.style.userSelect = '');
136
+ }
137
+ }, []);
138
+ react_1.default.useEffect(function () {
139
+ if (!isSelectable || selectionMode !== 'multi') {
140
+ return;
141
+ }
142
+ var ownerDoc = ownerDocument.current;
143
+ ownerDoc === null || ownerDoc === void 0 ? void 0 : ownerDoc.addEventListener('keydown', disableUserSelect);
144
+ ownerDoc === null || ownerDoc === void 0 ? void 0 : ownerDoc.addEventListener('keyup', enableUserSelect);
145
+ return function () {
146
+ ownerDoc === null || ownerDoc === void 0 ? void 0 : ownerDoc.removeEventListener('keydown', disableUserSelect);
147
+ ownerDoc === null || ownerDoc === void 0 ? void 0 : ownerDoc.removeEventListener('keyup', enableUserSelect);
148
+ };
149
+ }, [
150
+ isSelectable,
151
+ selectionMode,
152
+ ownerDocument,
153
+ disableUserSelect,
154
+ enableUserSelect,
155
+ ]);
125
156
  var tableStateReducer = react_1.default.useCallback(function (newState, action, previousState, instance) {
126
157
  switch (action.type) {
127
158
  case react_table_1.actions.toggleSortBy:
@@ -140,6 +171,12 @@ var Table = function (props) {
140
171
  hasManualSelectionColumn ? undefined : isRowDisabled);
141
172
  break;
142
173
  }
174
+ case shiftRowSelectedAction: {
175
+ newState = (0, actionHandlers_1.onShiftSelectHandler)(newState, action, instance, onSelect,
176
+ // If it has manual selection column, then we can't check whether row is disabled
177
+ hasManualSelectionColumn ? undefined : isRowDisabled);
178
+ break;
179
+ }
143
180
  case react_table_1.actions.toggleRowSelected:
144
181
  case react_table_1.actions.toggleAllRowsSelected:
145
182
  case react_table_1.actions.toggleAllPageRowsSelected: {
@@ -177,8 +214,8 @@ var Table = function (props) {
177
214
  return getSubRows ? getSubRows(item, index) : item.subRows;
178
215
  });
179
216
  }, [data, getSubRows]);
180
- var instance = (0, react_table_1.useTable)(__assign(__assign({ manualPagination: !paginatorRenderer, paginateExpandedRows: false }, props), { columns: columns, defaultColumn: defaultColumn, disableSortBy: !isSortable, stateReducer: tableStateReducer, filterTypes: filterTypes, selectSubRows: selectSubRows, data: data, getSubRows: getSubRows, initialState: __assign({ pageSize: pageSize }, props.initialState) }), react_table_1.useFlexLayout, (0, hooks_1.useResizeColumns)(ownerDocument), react_table_1.useFilters, (0, hooks_1.useSubRowFiltering)(hasAnySubRows), react_table_1.useSortBy, react_table_1.useExpanded, react_table_1.usePagination, react_table_1.useRowSelect, hooks_1.useSubRowSelection, (0, hooks_1.useExpanderCell)(subComponent, expanderCell, isRowDisabled), (0, hooks_1.useSelectionCell)(isSelectable, selectionMode, isRowDisabled), react_table_1.useColumnOrder, (0, hooks_1.useColumnDragAndDrop)(enableColumnReordering), hooks_1.useStickyColumns);
181
- var getTableProps = instance.getTableProps, rows = instance.rows, headerGroups = instance.headerGroups, getTableBodyProps = instance.getTableBodyProps, prepareRow = instance.prepareRow, state = instance.state, allColumns = instance.allColumns, filteredFlatRows = instance.filteredFlatRows, dispatch = instance.dispatch, page = instance.page, gotoPage = instance.gotoPage, setPageSize = instance.setPageSize, flatHeaders = instance.flatHeaders, visibleColumns = instance.visibleColumns;
217
+ var instance = (0, react_table_1.useTable)(__assign(__assign({ manualPagination: !paginatorRenderer, paginateExpandedRows: false }, props), { columns: columns, defaultColumn: defaultColumn, disableSortBy: !isSortable, stateReducer: tableStateReducer, filterTypes: filterTypes, selectSubRows: selectSubRows, data: data, getSubRows: getSubRows, initialState: __assign({ pageSize: pageSize }, props.initialState), columnResizeMode: columnResizeMode }), react_table_1.useFlexLayout, (0, hooks_1.useResizeColumns)(ownerDocument), react_table_1.useFilters, (0, hooks_1.useSubRowFiltering)(hasAnySubRows), react_table_1.useGlobalFilter, react_table_1.useSortBy, react_table_1.useExpanded, react_table_1.usePagination, react_table_1.useRowSelect, hooks_1.useSubRowSelection, (0, hooks_1.useExpanderCell)(subComponent, expanderCell, isRowDisabled), (0, hooks_1.useSelectionCell)(isSelectable, selectionMode, isRowDisabled), react_table_1.useColumnOrder, (0, hooks_1.useColumnDragAndDrop)(enableColumnReordering), hooks_1.useStickyColumns);
218
+ var getTableProps = instance.getTableProps, rows = instance.rows, headerGroups = instance.headerGroups, getTableBodyProps = instance.getTableBodyProps, prepareRow = instance.prepareRow, state = instance.state, allColumns = instance.allColumns, dispatch = instance.dispatch, page = instance.page, gotoPage = instance.gotoPage, setPageSize = instance.setPageSize, flatHeaders = instance.flatHeaders, visibleColumns = instance.visibleColumns, setGlobalFilter = instance.setGlobalFilter;
182
219
  var ariaDataAttributes = Object.entries(rest).reduce(function (result, _a) {
183
220
  var key = _a[0], value = _a[1];
184
221
  if (key.startsWith('data-') || key.startsWith('aria-')) {
@@ -186,7 +223,7 @@ var Table = function (props) {
186
223
  }
187
224
  return result;
188
225
  }, {});
189
- var areFiltersSet = allColumns.some(function (column) { return column.filterValue != null && column.filterValue !== ''; });
226
+ var areFiltersSet = allColumns.some(function (column) { return column.filterValue != null && column.filterValue !== ''; }) || !!globalFilterValue;
190
227
  var showFilterButton = function (column) {
191
228
  return (data.length !== 0 || areFiltersSet) && column.canFilter;
192
229
  };
@@ -202,7 +239,14 @@ var Table = function (props) {
202
239
  !isDisabled &&
203
240
  selectRowOnClick &&
204
241
  !event.isDefaultPrevented()) {
205
- if (!row.isSelected && (selectionMode === 'single' || !event.ctrlKey)) {
242
+ if (selectionMode === 'multi' && event.shiftKey) {
243
+ dispatch({
244
+ type: shiftRowSelectedAction,
245
+ id: row.id,
246
+ });
247
+ }
248
+ else if (!row.isSelected &&
249
+ (selectionMode === 'single' || !event.ctrlKey)) {
206
250
  dispatch({
207
251
  type: singleRowSelectedAction,
208
252
  id: row.id,
@@ -220,6 +264,9 @@ var Table = function (props) {
220
264
  dispatch,
221
265
  onRowClick,
222
266
  ]);
267
+ react_1.default.useEffect(function () {
268
+ setGlobalFilter(globalFilterValue);
269
+ }, [globalFilterValue, setGlobalFilter]);
223
270
  react_1.default.useEffect(function () {
224
271
  setPageSize(pageSize);
225
272
  }, [pageSize, setPageSize]);
@@ -245,6 +292,7 @@ var Table = function (props) {
245
292
  var previousTableWidth = react_1.default.useRef(0);
246
293
  var onTableResize = react_1.default.useCallback(function (_a) {
247
294
  var width = _a.width;
295
+ instance.tableWidth = width;
248
296
  if (width === previousTableWidth.current) {
249
297
  return;
250
298
  }
@@ -260,7 +308,7 @@ var Table = function (props) {
260
308
  return;
261
309
  }
262
310
  dispatch({ type: exports.tableResizeStartAction });
263
- }, [dispatch, state.columnResizing.columnWidths, flatHeaders]);
311
+ }, [dispatch, state.columnResizing.columnWidths, flatHeaders, instance]);
264
312
  var resizeRef = (0, utils_1.useResizeObserver)(onTableResize)[0];
265
313
  // Flexbox handles columns resize so we take new column widths before browser repaints.
266
314
  react_1.default.useLayoutEffect(function () {
@@ -276,12 +324,10 @@ var Table = function (props) {
276
324
  });
277
325
  var headerRef = react_1.default.useRef(null);
278
326
  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];
281
327
  var getPreparedRow = react_1.default.useCallback(function (index) {
282
328
  var row = page[index];
283
329
  prepareRow(row);
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) }));
330
+ 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: bodyRef.current, tableRowRef: enableVirtualization ? undefined : tableRowRef(row) }));
285
331
  }, [
286
332
  page,
287
333
  prepareRow,
@@ -294,7 +340,6 @@ var Table = function (props) {
294
340
  hasAnySubRows,
295
341
  instance,
296
342
  expanderCell,
297
- bodyRefState,
298
343
  enableVirtualization,
299
344
  tableRowRef,
300
345
  ]);
@@ -323,9 +368,10 @@ var Table = function (props) {
323
368
  // Call only on init
324
369
  // eslint-disable-next-line react-hooks/exhaustive-deps
325
370
  }, []);
371
+ var isHeaderDirectClick = react_1.default.useRef(false);
326
372
  return (react_1.default.createElement(react_1.default.Fragment, null,
327
373
  react_1.default.createElement("div", __assign({ ref: function (element) {
328
- setOwnerDocument(element === null || element === void 0 ? void 0 : element.ownerDocument);
374
+ ownerDocument.current = element === null || element === void 0 ? void 0 : element.ownerDocument;
329
375
  if (isResizable) {
330
376
  resizeRef(element);
331
377
  }
@@ -344,7 +390,8 @@ var Table = function (props) {
344
390
  className: 'iui-row',
345
391
  });
346
392
  return (react_1.default.createElement("div", __assign({}, headerGroupProps, { key: headerGroupProps.key }), headerGroup.headers.map(function (column, index) {
347
- var columnProps = column.getHeaderProps(__assign(__assign({}, column.getSortByToggleProps()), { className: (0, classnames_1.default)('iui-cell', {
393
+ var _a = column.getSortByToggleProps(), onClick = _a.onClick, restSortProps = __rest(_a, ["onClick"]);
394
+ var columnProps = column.getHeaderProps(__assign(__assign({}, restSortProps), { className: (0, classnames_1.default)('iui-cell', {
348
395
  'iui-actionable': column.canSort,
349
396
  'iui-sorted': column.isSorted,
350
397
  'iui-cell-sticky': !!column.sticky,
@@ -354,16 +401,25 @@ var Table = function (props) {
354
401
  columnRefs.current[column.id] = el;
355
402
  column.resizeWidth = el.getBoundingClientRect().width;
356
403
  }
404
+ }, onMouseDown: function () {
405
+ isHeaderDirectClick.current = true;
406
+ }, onClick: function (e) {
407
+ // Prevents from triggering sort when resizing and mouse is released in the middle of header
408
+ if (isHeaderDirectClick.current) {
409
+ onClick === null || onClick === void 0 ? void 0 : onClick(e);
410
+ isHeaderDirectClick.current = false;
411
+ }
357
412
  } }),
358
413
  column.render('Header'),
359
414
  (showFilterButton(column) ||
360
415
  showSortButton(column)) && (react_1.default.createElement("div", { className: 'iui-table-header-actions-container' },
361
- showFilterButton(column) && (react_1.default.createElement(filters_1.FilterToggle, { column: column, ownerDocument: ownerDocument })),
416
+ showFilterButton(column) && (react_1.default.createElement(filters_1.FilterToggle, { column: column })),
362
417
  showSortButton(column) && (react_1.default.createElement("div", { className: 'iui-cell-end-icon' }, column.isSortedDesc ||
363
418
  (!column.isSorted && column.sortDescFirst) ? (react_1.default.createElement(SortDown_1.default, { className: 'iui-icon iui-sort', "aria-hidden": true })) : (react_1.default.createElement(SortUp_1.default, { className: 'iui-icon iui-sort', "aria-hidden": true })))))),
364
419
  isResizable &&
365
420
  column.isResizerVisible &&
366
- index !== headerGroup.headers.length - 1 && (react_1.default.createElement("div", __assign({}, column.getResizerProps(), { className: 'iui-resizer' }),
421
+ (index !== headerGroup.headers.length - 1 ||
422
+ columnResizeMode === 'expand') && (react_1.default.createElement("div", __assign({}, column.getResizerProps(), { className: 'iui-resizer' }),
367
423
  react_1.default.createElement("div", { className: 'iui-resizer-bar' }))),
368
424
  enableColumnReordering &&
369
425
  !column.disableReordering && (react_1.default.createElement("div", { className: 'iui-reorder-bar' })),
@@ -378,7 +434,7 @@ var Table = function (props) {
378
434
  'iui-zebra-striping': styleType === 'zebra-rows',
379
435
  }),
380
436
  style: { outline: 0 },
381
- }), { ref: (0, utils_1.mergeRefs)(bodyRef, setBodyRefState), onScroll: function () {
437
+ }), { ref: bodyRef, onScroll: function () {
382
438
  if (headerRef.current && bodyRef.current) {
383
439
  headerRef.current.scrollLeft = bodyRef.current.scrollLeft;
384
440
  updateStickyState();
@@ -393,7 +449,7 @@ var Table = function (props) {
393
449
  !isLoading && data.length === 0 && !areFiltersSet && (react_1.default.createElement("div", { className: 'iui-table-empty' },
394
450
  react_1.default.createElement("div", null, emptyTableContent))),
395
451
  !isLoading &&
396
- (data.length === 0 || filteredFlatRows.length === 0) &&
452
+ (data.length === 0 || rows.length === 0) &&
397
453
  areFiltersSet && (react_1.default.createElement("div", { className: 'iui-table-empty' },
398
454
  react_1.default.createElement("div", null, emptyFilteredTableContent)))), paginatorRenderer === null || paginatorRenderer === void 0 ? void 0 :
399
455
  paginatorRenderer(paginatorRendererProps))));
@@ -1,4 +1,4 @@
1
1
  export { onExpandHandler } from './expandHandler';
2
2
  export { onFilterHandler } from './filterHandler';
3
- export { onSelectHandler, onSingleSelectHandler } from './selectHandler';
3
+ export { onSelectHandler, onSingleSelectHandler, onShiftSelectHandler, } from './selectHandler';
4
4
  export { onTableResizeStart, onTableResizeEnd } from './resizeHandler';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.onTableResizeEnd = exports.onTableResizeStart = exports.onSingleSelectHandler = exports.onSelectHandler = exports.onFilterHandler = exports.onExpandHandler = void 0;
3
+ exports.onTableResizeEnd = exports.onTableResizeStart = exports.onShiftSelectHandler = exports.onSingleSelectHandler = exports.onSelectHandler = exports.onFilterHandler = exports.onExpandHandler = 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.
@@ -12,6 +12,7 @@ Object.defineProperty(exports, "onFilterHandler", { enumerable: true, get: funct
12
12
  var selectHandler_1 = require("./selectHandler");
13
13
  Object.defineProperty(exports, "onSelectHandler", { enumerable: true, get: function () { return selectHandler_1.onSelectHandler; } });
14
14
  Object.defineProperty(exports, "onSingleSelectHandler", { enumerable: true, get: function () { return selectHandler_1.onSingleSelectHandler; } });
15
+ Object.defineProperty(exports, "onShiftSelectHandler", { enumerable: true, get: function () { return selectHandler_1.onShiftSelectHandler; } });
15
16
  var resizeHandler_1 = require("./resizeHandler");
16
17
  Object.defineProperty(exports, "onTableResizeStart", { enumerable: true, get: function () { return resizeHandler_1.onTableResizeStart; } });
17
18
  Object.defineProperty(exports, "onTableResizeEnd", { enumerable: true, get: function () { return resizeHandler_1.onTableResizeEnd; } });
@@ -16,6 +16,7 @@ export declare const onTableResizeStart: <T extends Record<string, unknown>>(sta
16
16
  isScrolledToRight?: boolean | undefined;
17
17
  isScrolledToLeft?: boolean | undefined;
18
18
  };
19
+ lastSelectedRowId?: string | undefined;
19
20
  columnOrder: import("react-table").IdType<T>[];
20
21
  expanded: Record<import("react-table").IdType<T>, boolean>;
21
22
  filters: import("react-table").Filters<T>;
@@ -46,6 +47,7 @@ export declare const onTableResizeEnd: <T extends Record<string, unknown>>(state
46
47
  isScrolledToRight?: boolean | undefined;
47
48
  isScrolledToLeft?: boolean | undefined;
48
49
  };
50
+ lastSelectedRowId?: string | undefined;
49
51
  columnOrder: import("react-table").IdType<T>[];
50
52
  expanded: Record<import("react-table").IdType<T>, boolean>;
51
53
  filters: import("react-table").Filters<T>;
@@ -7,6 +7,7 @@ export declare const onSelectHandler: <T extends Record<string, unknown>>(newSta
7
7
  * Handles selection when clicked on a row.
8
8
  */
9
9
  export declare const onSingleSelectHandler: <T extends Record<string, unknown>>(state: TableState<T>, action: ActionType, instance?: TableInstance<T> | undefined, onSelect?: ((selectedData: T[] | undefined, tableState?: TableState<T> | undefined) => void) | undefined, isRowDisabled?: ((rowData: T) => boolean) | undefined) => {
10
+ lastSelectedRowId: any;
10
11
  selectedRowIds: Record<string, boolean>;
11
12
  hiddenColumns?: import("react-table").IdType<T>[] | undefined;
12
13
  columnResizing: {
@@ -36,3 +37,7 @@ export declare const onSingleSelectHandler: <T extends Record<string, unknown>>(
36
37
  }>;
37
38
  sortBy: import("react-table").SortingRule<T>[];
38
39
  };
40
+ /**
41
+ * Handles selection when clicked on a row while shift key is pressed.
42
+ */
43
+ export declare const onShiftSelectHandler: <T extends Record<string, unknown>>(state: TableState<T>, action: ActionType, instance?: TableInstance<T> | undefined, onSelect?: ((selectedData: T[] | undefined, tableState?: TableState<T> | undefined) => void) | undefined, isRowDisabled?: ((rowData: T) => boolean) | undefined) => TableState<T>;
@@ -11,7 +11,7 @@ var __assign = (this && this.__assign) || function () {
11
11
  return __assign.apply(this, arguments);
12
12
  };
13
13
  Object.defineProperty(exports, "__esModule", { value: true });
14
- exports.onSingleSelectHandler = exports.onSelectHandler = void 0;
14
+ exports.onShiftSelectHandler = exports.onSingleSelectHandler = exports.onSelectHandler = void 0;
15
15
  /**
16
16
  * Handles selection when clicked on a checkbox.
17
17
  */
@@ -61,12 +61,45 @@ var onSingleSelectHandler = function (state, action, instance, onSelect, isRowDi
61
61
  };
62
62
  handleRow_1(instance.rowsById[action.id]);
63
63
  }
64
- var newState = __assign(__assign({}, state), { selectedRowIds: selectedRowIds });
64
+ var newState = __assign(__assign({}, state), { lastSelectedRowId: action.id, selectedRowIds: selectedRowIds });
65
65
  // Passing to `onSelectHandler` to handle filtered sub-rows
66
66
  (0, exports.onSelectHandler)(newState, instance, onSelect, isRowDisabled);
67
67
  return newState;
68
68
  };
69
69
  exports.onSingleSelectHandler = onSingleSelectHandler;
70
+ /**
71
+ * Handles selection when clicked on a row while shift key is pressed.
72
+ */
73
+ var onShiftSelectHandler = function (state, action, instance, onSelect, isRowDisabled) {
74
+ if (instance == null) {
75
+ return state;
76
+ }
77
+ var startIndex = Math.max(0, instance.flatRows.findIndex(function (row) { return row.id === state.lastSelectedRowId; }));
78
+ var endIndex = Math.max(0, instance.flatRows.findIndex(function (row) { return row.id === action.id; }));
79
+ if (startIndex > endIndex) {
80
+ var temp = startIndex;
81
+ startIndex = endIndex;
82
+ endIndex = temp;
83
+ }
84
+ var selectedRowIds = {};
85
+ // 1. Select all rows between start and end
86
+ instance.flatRows
87
+ .slice(startIndex, endIndex + 1)
88
+ .forEach(function (r) { return (selectedRowIds[r.id] = true); });
89
+ // 2. Select all children of the last row (endIndex)
90
+ // Since lastRow's children come after endIndex + 1 (not selected in step 1)
91
+ var handleRow = function (row) {
92
+ selectedRowIds[row.id] = true;
93
+ row.subRows.forEach(function (r) { return handleRow(r); });
94
+ };
95
+ handleRow(instance.flatRows[endIndex]);
96
+ var newState = __assign(__assign({}, state), { selectedRowIds: selectedRowIds });
97
+ // 3.1 Deselect all selected disabled rows and their children
98
+ // 3.2 Convert all partially selected rows marked with tick mark to horizontal line
99
+ (0, exports.onSelectHandler)(newState, instance, onSelect, isRowDisabled);
100
+ return newState;
101
+ };
102
+ exports.onShiftSelectHandler = onShiftSelectHandler;
70
103
  var getSelectedData = function (selectedRowIds, instance) {
71
104
  var selectedData = [];
72
105
  var setSelectedData = function (row) {