@itwin/itwinui-react 1.39.0 → 1.41.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 (70) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/cjs/core/ComboBox/ComboBox.d.ts +10 -1
  3. package/cjs/core/ComboBox/ComboBox.js +42 -22
  4. package/cjs/core/ComboBox/ComboBoxInput.js +1 -0
  5. package/cjs/core/ComboBox/helpers.js +1 -1
  6. package/cjs/core/ErrorPage/ErrorPage.d.ts +3 -1
  7. package/cjs/core/ErrorPage/ErrorPage.js +31 -1
  8. package/cjs/core/Menu/MenuItemSkeleton.d.ts +32 -0
  9. package/cjs/core/Menu/MenuItemSkeleton.js +53 -0
  10. package/cjs/core/Menu/index.d.ts +2 -0
  11. package/cjs/core/Menu/index.js +3 -1
  12. package/cjs/core/Modal/Modal.d.ts +1 -0
  13. package/cjs/core/Modal/Modal.js +11 -8
  14. package/cjs/core/Table/Table.js +50 -14
  15. package/cjs/core/Table/TableCell.js +10 -3
  16. package/cjs/core/Table/TableRowMemoized.d.ts +2 -0
  17. package/cjs/core/Table/TableRowMemoized.js +20 -4
  18. package/cjs/core/Table/actionHandlers/resizeHandler.d.ts +8 -0
  19. package/cjs/core/Table/actionHandlers/selectHandler.d.ts +4 -0
  20. package/cjs/core/Table/cells/EditableCell.js +7 -2
  21. package/cjs/core/Table/columns/selectionColumn.js +4 -2
  22. package/cjs/core/Table/hooks/index.d.ts +1 -0
  23. package/cjs/core/Table/hooks/index.js +3 -1
  24. package/cjs/core/Table/hooks/useStickyColumns.d.ts +2 -0
  25. package/cjs/core/Table/hooks/useStickyColumns.js +84 -0
  26. package/cjs/core/Table/utils.d.ts +1 -0
  27. package/cjs/core/Table/utils.js +36 -1
  28. package/cjs/core/index.d.ts +2 -2
  29. package/cjs/core/index.js +4 -3
  30. package/cjs/core/utils/components/VirtualScroll.js +2 -2
  31. package/cjs/core/utils/components/VisuallyHidden.d.ts +9 -0
  32. package/cjs/core/utils/components/VisuallyHidden.js +44 -0
  33. package/cjs/core/utils/components/index.d.ts +1 -0
  34. package/cjs/core/utils/components/index.js +1 -0
  35. package/cjs/types/react-table-config.d.ts +9 -0
  36. package/esm/core/ComboBox/ComboBox.d.ts +10 -1
  37. package/esm/core/ComboBox/ComboBox.js +42 -22
  38. package/esm/core/ComboBox/ComboBoxInput.js +1 -0
  39. package/esm/core/ComboBox/helpers.js +1 -1
  40. package/esm/core/ErrorPage/ErrorPage.d.ts +3 -1
  41. package/esm/core/ErrorPage/ErrorPage.js +31 -1
  42. package/esm/core/Menu/MenuItemSkeleton.d.ts +32 -0
  43. package/esm/core/Menu/MenuItemSkeleton.js +46 -0
  44. package/esm/core/Menu/index.d.ts +2 -0
  45. package/esm/core/Menu/index.js +1 -0
  46. package/esm/core/Modal/Modal.d.ts +1 -0
  47. package/esm/core/Modal/Modal.js +11 -8
  48. package/esm/core/Table/Table.js +53 -17
  49. package/esm/core/Table/TableCell.js +11 -4
  50. package/esm/core/Table/TableRowMemoized.d.ts +2 -0
  51. package/esm/core/Table/TableRowMemoized.js +20 -4
  52. package/esm/core/Table/actionHandlers/resizeHandler.d.ts +8 -0
  53. package/esm/core/Table/actionHandlers/selectHandler.d.ts +4 -0
  54. package/esm/core/Table/cells/EditableCell.js +7 -2
  55. package/esm/core/Table/columns/selectionColumn.js +4 -2
  56. package/esm/core/Table/hooks/index.d.ts +1 -0
  57. package/esm/core/Table/hooks/index.js +1 -0
  58. package/esm/core/Table/hooks/useStickyColumns.d.ts +2 -0
  59. package/esm/core/Table/hooks/useStickyColumns.js +80 -0
  60. package/esm/core/Table/utils.d.ts +1 -0
  61. package/esm/core/Table/utils.js +34 -0
  62. package/esm/core/index.d.ts +2 -2
  63. package/esm/core/index.js +1 -1
  64. package/esm/core/utils/components/VirtualScroll.js +2 -2
  65. package/esm/core/utils/components/VisuallyHidden.d.ts +9 -0
  66. package/esm/core/utils/components/VisuallyHidden.js +38 -0
  67. package/esm/core/utils/components/index.d.ts +1 -0
  68. package/esm/core/utils/components/index.js +1 -0
  69. package/esm/types/react-table-config.d.ts +9 -0
  70. package/package.json +4 -4
package/CHANGELOG.md CHANGED
@@ -1,5 +1,38 @@
1
1
  # Changelog
2
2
 
3
+ ## [1.41.0](https://www.github.com/iTwin/iTwinUI-react/compare/v1.40.1...v1.41.0) (2022-07-13)
4
+
5
+ ### What's new
6
+
7
+ * **ErrorPage:** Add time-out and redirect status codes ([#715](https://www.github.com/iTwin/iTwinUI-react/issues/715)) ([a5fb85f](https://www.github.com/iTwin/iTwinUI-react/commit/a5fb85f1f0ef9517a065db02384875d7c5d87f95))
8
+ * **Modal:** Update classes through the css package update ([#724](https://www.github.com/iTwin/iTwinUI-react/issues/724)) ([d13e0bf](https://www.github.com/iTwin/iTwinUI-react/commit/d13e0bf7941581a3b8d275b744bf77ebd7ae95d4))
9
+ - Now `style` and `className` props are applied on the dialog element itself.
10
+ * Border radius was changed from `3px` to `4px` through the css package update in all elements ([#724](https://www.github.com/iTwin/iTwinUI-react/issues/724)) ([d13e0bf](https://www.github.com/iTwin/iTwinUI-react/commit/d13e0bf7941581a3b8d275b744bf77ebd7ae95d4))
11
+
12
+ ### Fixes
13
+
14
+ * **Combobox:** Allow users to reset the value ([#728](https://www.github.com/iTwin/iTwinUI-react/issues/728)) ([f6c0b0d](https://www.github.com/iTwin/iTwinUI-react/commit/f6c0b0d66ac9ac725a23e07980c9dd7298084ae4))
15
+ * **Table:** Prevent crashing when clearing editable cell ([#732](https://www.github.com/iTwin/iTwinUI-react/issues/732)) ([0dedd3b](https://www.github.com/iTwin/iTwinUI-react/commit/0dedd3b8804ce98ce836d4bbbf58db83a4f9bfde))
16
+ * **Table:** Set correct intersection root for margin to work ([#708](https://www.github.com/iTwin/iTwinUI-react/issues/708)) ([55e4848](https://www.github.com/iTwin/iTwinUI-react/commit/55e48481f95c3351c127d495bd3c20134fd4a77f))
17
+
18
+ ### [1.40.1](https://www.github.com/iTwin/iTwinUI-react/compare/v1.40.0...v1.40.1) (2022-06-17)
19
+
20
+ ### Fixes
21
+
22
+ * **Table:** Horizontal scroll is working when virtual scroll is enabled ([#711](https://www.github.com/iTwin/iTwinUI-react/issues/711)) ([d3db504](https://www.github.com/iTwin/iTwinUI-react/commit/d3db504d3a44a4da2c1f34a392f99aae478ef2a3))
23
+
24
+ ## [1.40.0](https://www.github.com/iTwin/iTwinUI-react/compare/v1.39.0...v1.40.0) (2022-06-10)
25
+
26
+ ### What's new
27
+
28
+ * **Combobox:** Loading state with skeletons ([#655](https://www.github.com/iTwin/iTwinUI-react/issues/655)) ([cc1c7fb](https://www.github.com/iTwin/iTwinUI-react/commit/cc1c7fb6b5c494c94c01fe06483b788e0a27ec36))
29
+ * **Table:** Add sticky columns feature ([#695](https://www.github.com/iTwin/iTwinUI-react/issues/695)) ([eb6b0c0](https://www.github.com/iTwin/iTwinUI-react/commit/eb6b0c03e83b6e1417a444901c033a52545de186))
30
+
31
+ ### Fixes
32
+
33
+ * **Table:** Overriding min-width for the whole table ([#706](https://www.github.com/iTwin/iTwinUI-react/issues/706)) ([ad8173b](https://www.github.com/iTwin/iTwinUI-react/commit/ad8173b5764277a06a4b87a408e80affb2271749))
34
+ * **Table:** Removed title from selection checkboxes ([#704](https://www.github.com/iTwin/iTwinUI-react/issues/704)) ([5f72e59](https://www.github.com/iTwin/iTwinUI-react/commit/5f72e59a6d6e66b5f69c30ad82f7b37017242df6))
35
+
3
36
  ## [1.39.0](https://www.github.com/iTwin/iTwinUI-react/compare/v1.38.0...v1.39.0) (2022-06-03)
4
37
 
5
38
  ### What's new
@@ -35,9 +35,10 @@ export declare type ComboBoxProps<T> = {
35
35
  dropdownMenuProps?: PopoverProps;
36
36
  /**
37
37
  * Message shown when no options are available.
38
+ * If `JSX.Element` is provided, it will be rendered as is and won't be wrapped with `MenuExtraContent`.
38
39
  * @default 'No options found'
39
40
  */
40
- emptyStateMessage?: string;
41
+ emptyStateMessage?: React.ReactNode;
41
42
  /**
42
43
  * A custom item renderer can be specified to control the rendering.
43
44
  *
@@ -58,6 +59,14 @@ export declare type ComboBoxProps<T> = {
58
59
  * @beta
59
60
  */
60
61
  enableVirtualization?: boolean;
62
+ /**
63
+ * Callback fired when dropdown menu is opened.
64
+ */
65
+ onShow?: () => void;
66
+ /**
67
+ * Callback fired when dropdown menu is closed.
68
+ */
69
+ onHide?: () => void;
61
70
  } & Pick<InputContainerProps, 'status'> & Omit<CommonProps, 'title'>;
62
71
  /**
63
72
  * ComboBox component that allows typing a value to filter the options in dropdown list.
@@ -62,8 +62,8 @@ var getOptionId = function (option, idPrefix) {
62
62
  * />
63
63
  */
64
64
  var ComboBox = function (props) {
65
- var _a;
66
- var options = props.options, valueProp = props.value, onChange = props.onChange, filterFunction = props.filterFunction, inputProps = props.inputProps, dropdownMenuProps = props.dropdownMenuProps, _b = props.emptyStateMessage, emptyStateMessage = _b === void 0 ? 'No options found' : _b, itemRenderer = props.itemRenderer, _c = props.enableVirtualization, enableVirtualization = _c === void 0 ? false : _c, rest = __rest(props, ["options", "value", "onChange", "filterFunction", "inputProps", "dropdownMenuProps", "emptyStateMessage", "itemRenderer", "enableVirtualization"]);
65
+ var _a, _b;
66
+ var options = props.options, valueProp = props.value, onChange = props.onChange, filterFunction = props.filterFunction, inputProps = props.inputProps, dropdownMenuProps = props.dropdownMenuProps, _c = props.emptyStateMessage, emptyStateMessage = _c === void 0 ? 'No options found' : _c, itemRenderer = props.itemRenderer, _d = props.enableVirtualization, enableVirtualization = _d === void 0 ? false : _d, onShow = props.onShow, onHide = props.onHide, rest = __rest(props, ["options", "value", "onChange", "filterFunction", "inputProps", "dropdownMenuProps", "emptyStateMessage", "itemRenderer", "enableVirtualization", "onShow", "onHide"]);
67
67
  // Generate a stateful random id if not specified
68
68
  var id = react_1.default.useState(function () {
69
69
  var _a, _b;
@@ -74,6 +74,7 @@ var ComboBox = function (props) {
74
74
  var inputRef = react_1.default.useRef(null);
75
75
  var menuRef = react_1.default.useRef(null);
76
76
  var toggleButtonRef = react_1.default.useRef(null);
77
+ var mounted = react_1.default.useRef(false);
77
78
  // Latest value of the onChange prop
78
79
  var onChangeProp = react_1.default.useRef(onChange);
79
80
  react_1.default.useEffect(function () {
@@ -95,12 +96,14 @@ var ComboBox = function (props) {
95
96
  });
96
97
  }
97
98
  // Reducer where all the component-wide state is stored
98
- var _d = react_1.default.useReducer(helpers_1.comboBoxReducer, {
99
+ var _e = react_1.default.useReducer(helpers_1.comboBoxReducer, {
99
100
  isOpen: false,
100
- selectedIndex: -1,
101
+ selectedIndex: valueProp
102
+ ? options.findIndex(function (option) { return option.value === valueProp; })
103
+ : -1,
101
104
  focusedIndex: -1,
102
- }), _e = _d[0], isOpen = _e.isOpen, selectedIndex = _e.selectedIndex, focusedIndex = _e.focusedIndex, dispatch = _d[1];
103
- react_1.default.useEffect(function () {
105
+ }), _f = _e[0], isOpen = _f.isOpen, selectedIndex = _f.selectedIndex, focusedIndex = _f.focusedIndex, dispatch = _e[1];
106
+ react_1.default.useLayoutEffect(function () {
104
107
  var _a, _b;
105
108
  // When the dropdown opens
106
109
  if (isOpen) {
@@ -119,20 +122,30 @@ var ComboBox = function (props) {
119
122
  }
120
123
  }, [isOpen, options, selectedIndex]);
121
124
  // Set min-width of menu to be same as input
122
- var _f = react_1.default.useState(0), minWidth = _f[0], setMinWidth = _f[1];
125
+ var _g = react_1.default.useState(0), minWidth = _g[0], setMinWidth = _g[1];
123
126
  react_1.default.useEffect(function () {
124
127
  if (inputRef.current) {
125
128
  setMinWidth(inputRef.current.offsetWidth);
126
129
  }
127
130
  }, [isOpen]);
128
- // Initialize filtered options to the latest value options
129
- var _g = react_1.default.useState(options), filteredOptions = _g[0], setFilteredOptions = _g[1];
131
+ // Update filtered options to the latest value options according to input value
132
+ var _h = react_1.default.useState(options), filteredOptions = _h[0], setFilteredOptions = _h[1];
130
133
  react_1.default.useEffect(function () {
131
- setFilteredOptions(options);
134
+ var _a;
135
+ if (inputValue) {
136
+ setFilteredOptions((_a = filterFunction === null || filterFunction === void 0 ? void 0 : filterFunction(options, inputValue)) !== null && _a !== void 0 ? _a : options.filter(function (option) {
137
+ return option.label.toLowerCase().includes(inputValue.toLowerCase());
138
+ }));
139
+ }
140
+ else {
141
+ setFilteredOptions(options);
142
+ }
132
143
  dispatch(['focus']);
144
+ // Only need to call on options update
145
+ // eslint-disable-next-line react-hooks/exhaustive-deps
133
146
  }, [options]);
134
147
  // Filter options based on input value
135
- var _h = react_1.default.useState((_a = inputProps === null || inputProps === void 0 ? void 0 : inputProps.value) !== null && _a !== void 0 ? _a : ''), inputValue = _h[0], setInputValue = _h[1];
148
+ var _j = react_1.default.useState((_b = (_a = inputProps === null || inputProps === void 0 ? void 0 : inputProps.value) === null || _a === void 0 ? void 0 : _a.toString()) !== null && _b !== void 0 ? _b : ''), inputValue = _j[0], setInputValue = _j[1];
136
149
  var handleOnInput = react_1.default.useCallback(function (event) {
137
150
  var _a, _b;
138
151
  var value = event.currentTarget.value;
@@ -156,14 +169,14 @@ var ComboBox = function (props) {
156
169
  // Call user-defined onChange when the value actually changes
157
170
  react_1.default.useEffect(function () {
158
171
  var _a, _b;
159
- if (selectedIndex != undefined && selectedIndex >= 0) {
160
- var value = (_a = options[selectedIndex]) === null || _a === void 0 ? void 0 : _a.value;
161
- if (value === valueProp) {
162
- return;
163
- }
164
- (_b = onChangeProp.current) === null || _b === void 0 ? void 0 : _b.call(onChangeProp, value);
172
+ // Prevent user-defined onChange to be called on mount
173
+ if (!mounted.current) {
174
+ mounted.current = true;
175
+ return;
165
176
  }
166
- }, [options, selectedIndex, valueProp]);
177
+ var value = (_a = options[selectedIndex]) === null || _a === void 0 ? void 0 : _a.value;
178
+ (_b = onChangeProp.current) === null || _b === void 0 ? void 0 : _b.call(onChangeProp, value);
179
+ }, [options, selectedIndex]);
167
180
  var getMenuItem = react_1.default.useCallback(function (option, filteredIndex) {
168
181
  var optionId = getOptionId(option, id);
169
182
  var __originalIndex = optionsExtraInfoRef.current[optionId].__originalIndex;
@@ -179,6 +192,7 @@ var ComboBox = function (props) {
179
192
  onClick: function (e) {
180
193
  var _a, _b;
181
194
  dispatch(['select', __originalIndex]);
195
+ dispatch(['close']);
182
196
  (_b = (_a = customItem.props).onClick) === null || _b === void 0 ? void 0 : _b.call(_a, e);
183
197
  },
184
198
  // ComboBox.MenuItem handles scrollIntoView, data-iui-index and iui-focused through context
@@ -193,8 +207,13 @@ var ComboBox = function (props) {
193
207
  el === null || el === void 0 ? void 0 : el.scrollIntoView({ block: 'nearest' });
194
208
  }
195
209
  }),
196
- })) : (react_1.default.createElement(ComboBoxMenuItem_1.ComboBoxMenuItem, __assign({ key: optionId, id: optionId }, option, { isSelected: selectedIndex === __originalIndex, onClick: function () { return dispatch(['select', __originalIndex]); }, index: __originalIndex, "data-iui-filtered-index": filteredIndex }), option.label));
210
+ })) : (react_1.default.createElement(ComboBoxMenuItem_1.ComboBoxMenuItem, __assign({ key: optionId, id: optionId }, option, { isSelected: selectedIndex === __originalIndex, onClick: function () {
211
+ dispatch(['select', __originalIndex]);
212
+ dispatch(['close']);
213
+ }, index: __originalIndex, "data-iui-filtered-index": filteredIndex }), option.label));
197
214
  }, [enableVirtualization, focusedIndex, id, itemRenderer, selectedIndex]);
215
+ var emptyContent = react_1.default.useMemo(function () { return (react_1.default.createElement(react_1.default.Fragment, null, react_1.default.isValidElement(emptyStateMessage) ? (emptyStateMessage) : (react_1.default.createElement(Menu_1.MenuExtraContent, null,
216
+ react_1.default.createElement(Typography_1.Text, { isMuted: true }, emptyStateMessage))))); }, [emptyStateMessage]);
198
217
  return (react_1.default.createElement(helpers_1.ComboBoxRefsContext.Provider, { value: { inputRef: inputRef, menuRef: menuRef, toggleButtonRef: toggleButtonRef, optionsExtraInfoRef: optionsExtraInfoRef } },
199
218
  react_1.default.createElement(helpers_1.ComboBoxActionContext.Provider, { value: dispatch },
200
219
  react_1.default.createElement(helpers_1.ComboBoxStateContext.Provider, { value: {
@@ -209,9 +228,10 @@ var ComboBox = function (props) {
209
228
  react_1.default.createElement(ComboBoxInputContainer_1.ComboBoxInputContainer, __assign({ disabled: inputProps === null || inputProps === void 0 ? void 0 : inputProps.disabled }, rest),
210
229
  react_1.default.createElement(ComboBoxInput_1.ComboBoxInput, __assign({ value: inputValue }, inputProps, { onChange: handleOnInput })),
211
230
  react_1.default.createElement(ComboBoxEndIcon_1.ComboBoxEndIcon, { disabled: inputProps === null || inputProps === void 0 ? void 0 : inputProps.disabled, isOpen: isOpen })),
212
- react_1.default.createElement(ComboBoxDropdown_1.ComboBoxDropdown, __assign({}, dropdownMenuProps),
213
- react_1.default.createElement(ComboBoxMenu_1.ComboBoxMenu, null, filteredOptions.length > 0 && !enableVirtualization ? (filteredOptions.map(getMenuItem)) : (react_1.default.createElement(Menu_1.MenuExtraContent, null,
214
- react_1.default.createElement(Typography_1.Text, { isMuted: true }, emptyStateMessage)))))))));
231
+ react_1.default.createElement(ComboBoxDropdown_1.ComboBoxDropdown, __assign({}, dropdownMenuProps, { onShow: onShow, onHide: onHide }),
232
+ react_1.default.createElement(ComboBoxMenu_1.ComboBoxMenu, null, filteredOptions.length > 0 && !enableVirtualization
233
+ ? filteredOptions.map(getMenuItem)
234
+ : emptyContent))))));
215
235
  };
216
236
  exports.ComboBox = ComboBox;
217
237
  exports.default = exports.ComboBox;
@@ -118,6 +118,7 @@ exports.ComboBoxInput = react_1.default.forwardRef(function (props, forwardedRef
118
118
  event.preventDefault();
119
119
  if (isOpen) {
120
120
  dispatch(['select', focusedIndexRef.current]);
121
+ dispatch(['close']);
121
122
  }
122
123
  else {
123
124
  dispatch(['open']);
@@ -31,7 +31,7 @@ var comboBoxReducer = function (state, _a) {
31
31
  return __assign(__assign({}, state), { isOpen: false });
32
32
  }
33
33
  case 'select': {
34
- return __assign(__assign({}, state), { isOpen: false, selectedIndex: value !== null && value !== void 0 ? value : state.selectedIndex, focusedIndex: value !== null && value !== void 0 ? value : state.focusedIndex });
34
+ return __assign(__assign({}, state), { selectedIndex: value !== null && value !== void 0 ? value : state.selectedIndex, focusedIndex: value !== null && value !== void 0 ? value : state.focusedIndex });
35
35
  }
36
36
  case 'focus': {
37
37
  return __assign(__assign({}, state), { focusedIndex: (_b = value !== null && value !== void 0 ? value : state.selectedIndex) !== null && _b !== void 0 ? _b : -1 });
@@ -1,14 +1,16 @@
1
1
  import React from 'react';
2
2
  import { CommonProps } from '../utils';
3
3
  import '@itwin/itwinui-css/css/non-ideal-state.css';
4
- export declare type ErrorPageType = '401' | '403' | '404' | '500' | '502' | '503' | 'generic';
4
+ export declare type ErrorPageType = '300' | '301' | '302' | '303' | '304' | '305' | '307' | '308' | '401' | '403' | '404' | '408' | '500' | '502' | '503' | '504' | 'generic';
5
5
  export declare type ErrorTypeTranslations = {
6
6
  badGateway: string;
7
7
  error: string;
8
8
  forbidden: string;
9
9
  internalServerError: string;
10
+ redirect?: string;
10
11
  pageNotFound: string;
11
12
  serviceUnavailable: string;
13
+ timedOut?: string;
12
14
  unauthorized: string;
13
15
  };
14
16
  export declare type ErrorPageProps = {
@@ -37,6 +37,8 @@ var _500_1 = __importDefault(require("@itwin/itwinui-illustrations-react/cjs/ill
37
37
  var _502_1 = __importDefault(require("@itwin/itwinui-illustrations-react/cjs/illustrations/502"));
38
38
  var _503_1 = __importDefault(require("@itwin/itwinui-illustrations-react/cjs/illustrations/503"));
39
39
  var Error_1 = __importDefault(require("@itwin/itwinui-illustrations-react/cjs/illustrations/Error"));
40
+ var Redirect_1 = __importDefault(require("@itwin/itwinui-illustrations-react/cjs/illustrations/Redirect"));
41
+ var TimedOut_1 = __importDefault(require("@itwin/itwinui-illustrations-react/cjs/illustrations/TimedOut"));
40
42
  var react_1 = __importDefault(require("react"));
41
43
  var Button_1 = require("../Buttons/Button");
42
44
  var utils_1 = require("../utils");
@@ -50,9 +52,19 @@ require("@itwin/itwinui-css/css/non-ideal-state.css");
50
52
  var ErrorPage = function (props) {
51
53
  var errorType = props.errorType, errorName = props.errorName, errorMessage = props.errorMessage, primaryButtonHandle = props.primaryButtonHandle, primaryButtonLabel = props.primaryButtonLabel, secondaryButtonHandle = props.secondaryButtonHandle, secondaryButtonLabel = props.secondaryButtonLabel, translatedErrorMessages = props.translatedErrorMessages, className = props.className, rest = __rest(props, ["errorType", "errorName", "errorMessage", "primaryButtonHandle", "primaryButtonLabel", "secondaryButtonHandle", "secondaryButtonLabel", "translatedErrorMessages", "className"]);
52
54
  (0, utils_1.useTheme)();
53
- var defaultErrorMessages = __assign({ badGateway: 'Bad gateway', error: 'Error', forbidden: 'Forbidden', internalServerError: 'Internal server error', pageNotFound: 'Page not found', serviceUnavailable: 'Service unavailable', unauthorized: 'Unauthorized' }, translatedErrorMessages);
55
+ var defaultErrorMessages = __assign({ badGateway: 'Bad gateway', error: 'Error', forbidden: 'Forbidden', internalServerError: 'Internal server error', redirect: 'Redirect', pageNotFound: 'Page not found', serviceUnavailable: 'Service unavailable', timedOut: 'Timed out', unauthorized: 'Unauthorized' }, translatedErrorMessages);
54
56
  function getErrorIcon() {
55
57
  switch (errorType) {
58
+ case '300':
59
+ case '301':
60
+ case '302':
61
+ case '303':
62
+ case '304':
63
+ case '305':
64
+ case '307':
65
+ case '308': {
66
+ return react_1.default.createElement(Redirect_1.default, { className: 'iui-non-ideal-state-illustration' });
67
+ }
56
68
  case '401': {
57
69
  return react_1.default.createElement(_401_1.default, { className: 'iui-non-ideal-state-illustration' });
58
70
  }
@@ -62,6 +74,10 @@ var ErrorPage = function (props) {
62
74
  case '404': {
63
75
  return react_1.default.createElement(_404_1.default, { className: 'iui-non-ideal-state-illustration' });
64
76
  }
77
+ case '408':
78
+ case '504': {
79
+ return react_1.default.createElement(TimedOut_1.default, { className: 'iui-non-ideal-state-illustration' });
80
+ }
65
81
  case '500': {
66
82
  return react_1.default.createElement(_500_1.default, { className: 'iui-non-ideal-state-illustration' });
67
83
  }
@@ -82,6 +98,16 @@ var ErrorPage = function (props) {
82
98
  return errorName;
83
99
  }
84
100
  switch (errorType) {
101
+ case '300':
102
+ case '301':
103
+ case '302':
104
+ case '303':
105
+ case '304':
106
+ case '305':
107
+ case '307':
108
+ case '308': {
109
+ return defaultErrorMessages.redirect || '';
110
+ }
85
111
  case '401': {
86
112
  return defaultErrorMessages.unauthorized;
87
113
  }
@@ -91,6 +117,10 @@ var ErrorPage = function (props) {
91
117
  case '404': {
92
118
  return defaultErrorMessages.pageNotFound;
93
119
  }
120
+ case '408':
121
+ case '504': {
122
+ return defaultErrorMessages.timedOut || '';
123
+ }
94
124
  case '500': {
95
125
  return defaultErrorMessages.internalServerError;
96
126
  }
@@ -0,0 +1,32 @@
1
+ /// <reference types="react" />
2
+ import { CommonProps } from '../utils';
3
+ import '@itwin/itwinui-css/css/menu.css';
4
+ export declare type MenuItemSkeletonProps = {
5
+ /**
6
+ * Flag whether to show skeleton for sub-label.
7
+ */
8
+ hasSublabel?: boolean;
9
+ /**
10
+ * Flag whether to show skeleton for icon.
11
+ */
12
+ hasIcon?: boolean;
13
+ /**
14
+ * Skeleton content width.
15
+ */
16
+ contentWidth?: string;
17
+ /**
18
+ * Translated strings used for accessibility.
19
+ */
20
+ translatedStrings?: {
21
+ /**
22
+ * Label for loading state. Defaults to "Loading…".
23
+ * It is only visible for the screen readers.
24
+ */
25
+ loading: string;
26
+ };
27
+ } & CommonProps;
28
+ /**
29
+ * Menu item that uses skeletons to indicate loading state.
30
+ */
31
+ export declare const MenuItemSkeleton: (props: MenuItemSkeletonProps) => JSX.Element;
32
+ export default MenuItemSkeleton;
@@ -0,0 +1,53 @@
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 __rest = (this && this.__rest) || function (s, e) {
14
+ var t = {};
15
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
16
+ t[p] = s[p];
17
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
18
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
19
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
20
+ t[p[i]] = s[p[i]];
21
+ }
22
+ return t;
23
+ };
24
+ var __importDefault = (this && this.__importDefault) || function (mod) {
25
+ return (mod && mod.__esModule) ? mod : { "default": mod };
26
+ };
27
+ Object.defineProperty(exports, "__esModule", { value: true });
28
+ exports.MenuItemSkeleton = void 0;
29
+ /*---------------------------------------------------------------------------------------------
30
+ * Copyright (c) Bentley Systems, Incorporated. All rights reserved.
31
+ * See LICENSE.md in the project root for license terms and full copyright notice.
32
+ *--------------------------------------------------------------------------------------------*/
33
+ var react_1 = __importDefault(require("react"));
34
+ var classnames_1 = __importDefault(require("classnames"));
35
+ var utils_1 = require("../utils");
36
+ require("@itwin/itwinui-css/css/menu.css");
37
+ /**
38
+ * Menu item that uses skeletons to indicate loading state.
39
+ */
40
+ var MenuItemSkeleton = function (props) {
41
+ var hasSublabel = props.hasSublabel, hasIcon = props.hasIcon, contentWidth = props.contentWidth, _a = props.translatedStrings, translatedStrings = _a === void 0 ? { loading: 'Loading…' } : _a, className = props.className, style = props.style, rest = __rest(props, ["hasSublabel", "hasIcon", "contentWidth", "translatedStrings", "className", "style"]);
42
+ (0, utils_1.useTheme)();
43
+ return (react_1.default.createElement("li", __assign({ className: (0, classnames_1.default)('iui-menu-item', 'iui-menu-item-skeleton', { 'iui-large': hasSublabel }, className), style: __assign({
44
+ '--iui-menu-item-content-skeleton-max-width': contentWidth,
45
+ }, style) }, rest),
46
+ hasIcon && react_1.default.createElement("div", { className: 'iui-icon iui-skeleton', "aria-hidden": true }),
47
+ react_1.default.createElement("span", { className: 'iui-content' },
48
+ react_1.default.createElement("div", { className: 'iui-menu-label iui-skeleton', "aria-hidden": true }),
49
+ hasSublabel && (react_1.default.createElement("div", { className: 'iui-menu-description iui-skeleton', "aria-hidden": true })),
50
+ react_1.default.createElement(utils_1.VisuallyHidden, null, translatedStrings.loading))));
51
+ };
52
+ exports.MenuItemSkeleton = MenuItemSkeleton;
53
+ exports.default = exports.MenuItemSkeleton;
@@ -6,3 +6,5 @@ export { MenuDivider } from './MenuDivider';
6
6
  export type { MenuDividerProps } from './MenuDivider';
7
7
  export { MenuExtraContent } from './MenuExtraContent';
8
8
  export type { MenuExtraContentProps } from './MenuExtraContent';
9
+ export { MenuItemSkeleton } from './MenuItemSkeleton';
10
+ export type { MenuItemSkeletonProps } from './MenuItemSkeleton';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.MenuExtraContent = exports.MenuDivider = exports.MenuItem = exports.Menu = void 0;
3
+ exports.MenuItemSkeleton = exports.MenuExtraContent = exports.MenuDivider = exports.MenuItem = exports.Menu = 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.
@@ -13,3 +13,5 @@ var MenuDivider_1 = require("./MenuDivider");
13
13
  Object.defineProperty(exports, "MenuDivider", { enumerable: true, get: function () { return MenuDivider_1.MenuDivider; } });
14
14
  var MenuExtraContent_1 = require("./MenuExtraContent");
15
15
  Object.defineProperty(exports, "MenuExtraContent", { enumerable: true, get: function () { return MenuExtraContent_1.MenuExtraContent; } });
16
+ var MenuItemSkeleton_1 = require("./MenuItemSkeleton");
17
+ Object.defineProperty(exports, "MenuItemSkeleton", { enumerable: true, get: function () { return MenuItemSkeleton_1.MenuItemSkeleton; } });
@@ -1,6 +1,7 @@
1
1
  import React from 'react';
2
2
  import { CommonProps } from '../utils';
3
3
  import '@itwin/itwinui-css/css/dialog.css';
4
+ import '@itwin/itwinui-css/css/backdrop.css';
4
5
  export declare type ModalProps = {
5
6
  /**
6
7
  * Flag whether modal should be shown.
@@ -36,6 +36,7 @@ var classnames_1 = __importDefault(require("classnames"));
36
36
  var Close_1 = __importDefault(require("@itwin/itwinui-icons-react/cjs/icons/Close"));
37
37
  var utils_1 = require("../utils");
38
38
  require("@itwin/itwinui-css/css/dialog.css");
39
+ require("@itwin/itwinui-css/css/backdrop.css");
39
40
  var IconButton_1 = require("../Buttons/IconButton");
40
41
  var react_transition_group_1 = require("react-transition-group");
41
42
  /**
@@ -118,15 +119,17 @@ var Modal = function (props) {
118
119
  onClose(event);
119
120
  }
120
121
  };
121
- return !!container ? (react_dom_1.default.createPortal(react_1.default.createElement(react_transition_group_1.CSSTransition, { in: isOpen, classNames: 'iui-dialog-animation', timeout: { exit: 600 }, unmountOnExit: true },
122
+ return !!container ? (react_dom_1.default.createPortal(react_1.default.createElement(react_1.default.Fragment, null,
123
+ react_1.default.createElement("div", { className: (0, classnames_1.default)('iui-backdrop', { 'iui-backdrop-visible': isOpen }), tabIndex: -1, onKeyDown: handleKeyDown, ref: overlayRef, onMouseDown: handleMouseDown }),
122
124
  react_1.default.createElement(utils_1.FocusTrap, null,
123
- react_1.default.createElement("div", __assign({ className: (0, classnames_1.default)('iui-dialog-backdrop', { 'iui-dialog-default': styleType === 'default' }, { 'iui-dialog-full-page': styleType === 'fullPage' }, { 'iui-dialog-visible': isOpen }, className), tabIndex: -1, onKeyDown: handleKeyDown, ref: overlayRef, onMouseDown: handleMouseDown }, rest),
124
- react_1.default.createElement("div", { className: 'iui-dialog', id: id, style: style, role: 'dialog', "aria-modal": 'true' },
125
- react_1.default.createElement("div", { className: 'iui-dialog-title-bar' },
126
- react_1.default.createElement("div", { className: 'iui-dialog-title' }, title),
127
- isDismissible && (react_1.default.createElement(IconButton_1.IconButton, { size: 'small', styleType: 'borderless', onClick: onClose, "aria-label": 'Close' },
128
- react_1.default.createElement(Close_1.default, null)))),
129
- children)))), container)) : (react_1.default.createElement(react_1.default.Fragment, null));
125
+ react_1.default.createElement("div", null,
126
+ react_1.default.createElement(react_transition_group_1.CSSTransition, { in: isOpen, classNames: 'iui-dialog-animation', timeout: { exit: 600 }, unmountOnExit: true },
127
+ react_1.default.createElement("div", __assign({ className: (0, classnames_1.default)('iui-dialog', { 'iui-dialog-default': styleType === 'default' }, { 'iui-dialog-full-page': styleType === 'fullPage' }, { 'iui-dialog-visible': isOpen }, className), id: id, style: style, role: 'dialog', "aria-modal": 'true' }, rest),
128
+ react_1.default.createElement("div", { className: 'iui-dialog-title-bar' },
129
+ react_1.default.createElement("div", { className: 'iui-dialog-title' }, title),
130
+ isDismissible && (react_1.default.createElement(IconButton_1.IconButton, { size: 'small', styleType: 'borderless', onClick: onClose, "aria-label": 'Close' },
131
+ react_1.default.createElement(Close_1.default, null)))),
132
+ children))))), container)) : (react_1.default.createElement(react_1.default.Fragment, null));
130
133
  };
131
134
  exports.Modal = Modal;
132
135
  exports.default = exports.Modal;
@@ -177,8 +177,8 @@ var Table = function (props) {
177
177
  return getSubRows ? getSubRows(item, index) : item.subRows;
178
178
  });
179
179
  }, [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));
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;
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;
182
182
  var ariaDataAttributes = Object.entries(rest).reduce(function (result, _a) {
183
183
  var key = _a[0], value = _a[1];
184
184
  if (key.startsWith('data-') || key.startsWith('aria-')) {
@@ -275,24 +275,51 @@ var Table = function (props) {
275
275
  });
276
276
  var headerRef = react_1.default.useRef(null);
277
277
  var bodyRef = react_1.default.useRef(null);
278
+ // Using `useState` to rerender rows when table body ref is available
279
+ var _r = react_1.default.useState(null), bodyRefState = _r[0], setBodyRefState = _r[1];
278
280
  var getPreparedRow = react_1.default.useCallback(function (index) {
279
281
  var row = page[index];
280
282
  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 }));
283
+ 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 }));
282
284
  }, [
283
285
  page,
284
- expanderCell,
285
- hasAnySubRows,
286
- instance,
287
- intersectionMargin,
288
- isRowDisabled,
289
- onRowClickHandler,
290
286
  prepareRow,
291
287
  rowProps,
288
+ intersectionMargin,
292
289
  state,
290
+ onRowClickHandler,
293
291
  subComponent,
292
+ isRowDisabled,
293
+ hasAnySubRows,
294
+ instance,
295
+ expanderCell,
296
+ bodyRefState,
294
297
  ]);
295
298
  var virtualizedItemRenderer = react_1.default.useCallback(function (index) { return getPreparedRow(index); }, [getPreparedRow]);
299
+ var updateStickyState = function () {
300
+ if (!bodyRef.current || flatHeaders.every(function (header) { return !header.sticky; })) {
301
+ return;
302
+ }
303
+ if (bodyRef.current.scrollLeft !== 0) {
304
+ dispatch({ type: react_table_1.actions.setScrolledRight, value: true });
305
+ }
306
+ else {
307
+ dispatch({ type: react_table_1.actions.setScrolledRight, value: false });
308
+ }
309
+ // If scrolled a bit to the left looking from the right side
310
+ if (bodyRef.current.scrollLeft !==
311
+ bodyRef.current.scrollWidth - bodyRef.current.clientWidth) {
312
+ dispatch({ type: react_table_1.actions.setScrolledLeft, value: true });
313
+ }
314
+ else {
315
+ dispatch({ type: react_table_1.actions.setScrolledLeft, value: false });
316
+ }
317
+ };
318
+ react_1.default.useEffect(function () {
319
+ updateStickyState();
320
+ // Call only on init
321
+ // eslint-disable-next-line react-hooks/exhaustive-deps
322
+ }, []);
296
323
  return (react_1.default.createElement(react_1.default.Fragment, null,
297
324
  react_1.default.createElement("div", __assign({ ref: function (element) {
298
325
  setOwnerDocument(element === null || element === void 0 ? void 0 : element.ownerDocument);
@@ -301,7 +328,7 @@ var Table = function (props) {
301
328
  }
302
329
  }, id: id }, getTableProps({
303
330
  className: (0, classnames_1.default)('iui-table', (_a = {}, _a["iui-".concat(density)] = density !== 'default', _a), className),
304
- style: style,
331
+ style: __assign({ minWidth: 0 }, style),
305
332
  }), ariaDataAttributes),
306
333
  react_1.default.createElement("div", { className: 'iui-table-header-wrapper', ref: headerRef },
307
334
  react_1.default.createElement("div", { className: 'iui-table-header' }, headerGroups.slice(1).map(function (headerGroup) {
@@ -309,9 +336,13 @@ var Table = function (props) {
309
336
  className: 'iui-row',
310
337
  });
311
338
  return (react_1.default.createElement("div", __assign({}, headerGroupProps, { key: headerGroupProps.key }), headerGroup.headers.map(function (column, index) {
312
- var columnProps = column.getHeaderProps(__assign(__assign({}, column.getSortByToggleProps()), { className: (0, classnames_1.default)('iui-cell', { 'iui-actionable': column.canSort }, { 'iui-sorted': column.isSorted }, column.columnClassName), style: (0, utils_2.getCellStyle)(column, !!state.isTableResizing) }));
339
+ var columnProps = column.getHeaderProps(__assign(__assign({}, column.getSortByToggleProps()), { className: (0, classnames_1.default)('iui-cell', {
340
+ 'iui-actionable': column.canSort,
341
+ 'iui-sorted': column.isSorted,
342
+ 'iui-cell-sticky': !!column.sticky,
343
+ }, column.columnClassName), style: __assign(__assign(__assign({}, (0, utils_2.getCellStyle)(column, !!state.isTableResizing)), (0, utils_2.getStickyStyle)(column, visibleColumns)), { flexWrap: 'unset' }) }));
313
344
  return (react_1.default.createElement("div", __assign({}, columnProps, column.getDragAndDropProps(), { key: columnProps.key, title: undefined, ref: function (el) {
314
- if (el && isResizable) {
345
+ if (el) {
315
346
  columnRefs.current[column.id] = el;
316
347
  column.resizeWidth = el.getBoundingClientRect().width;
317
348
  }
@@ -326,7 +357,11 @@ var Table = function (props) {
326
357
  index !== headerGroup.headers.length - 1 && (react_1.default.createElement("div", __assign({}, column.getResizerProps(), { className: 'iui-resizer' }),
327
358
  react_1.default.createElement("div", { className: 'iui-resizer-bar' }))),
328
359
  enableColumnReordering &&
329
- !column.disableReordering && (react_1.default.createElement("div", { className: 'iui-reorder-bar' }))));
360
+ !column.disableReordering && (react_1.default.createElement("div", { className: 'iui-reorder-bar' })),
361
+ column.sticky === 'left' &&
362
+ state.sticky.isScrolledToRight && (react_1.default.createElement("div", { className: 'iui-cell-shadow-right' })),
363
+ column.sticky === 'right' &&
364
+ state.sticky.isScrolledToLeft && (react_1.default.createElement("div", { className: 'iui-cell-shadow-left' }))));
330
365
  })));
331
366
  }))),
332
367
  react_1.default.createElement("div", __assign({}, getTableBodyProps({
@@ -334,9 +369,10 @@ var Table = function (props) {
334
369
  'iui-zebra-striping': styleType === 'zebra-rows',
335
370
  }),
336
371
  style: { outline: 0 },
337
- }), { ref: bodyRef, onScroll: function () {
372
+ }), { ref: (0, utils_1.mergeRefs)(bodyRef, setBodyRefState), onScroll: function () {
338
373
  if (headerRef.current && bodyRef.current) {
339
374
  headerRef.current.scrollLeft = bodyRef.current.scrollLeft;
375
+ updateStickyState();
340
376
  }
341
377
  }, tabIndex: -1 }),
342
378
  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); })))),
@@ -40,8 +40,10 @@ var TableCell = function (props) {
40
40
  };
41
41
  };
42
42
  var cellElementProps = cell.getCellProps({
43
- className: (0, classnames_1.default)('iui-cell', cell.column.cellClassName),
44
- style: __assign(__assign({}, (0, utils_1.getCellStyle)(cell.column, !!tableInstance.state.isTableResizing)), getSubRowStyle()),
43
+ className: (0, classnames_1.default)('iui-cell', cell.column.cellClassName, {
44
+ 'iui-cell-sticky': !!cell.column.sticky,
45
+ }),
46
+ style: __assign(__assign(__assign({}, (0, utils_1.getCellStyle)(cell.column, !!tableInstance.state.isTableResizing)), getSubRowStyle()), (0, utils_1.getStickyStyle)(cell.column, tableInstance.visibleColumns)),
45
47
  });
46
48
  var cellProps = __assign(__assign({}, tableInstance), { cell: cell, row: cell.row, value: cell.value, column: cell.column });
47
49
  var cellContent = (react_1.default.createElement(react_1.default.Fragment, null,
@@ -50,7 +52,12 @@ var TableCell = function (props) {
50
52
  var cellRendererProps = {
51
53
  cellElementProps: cellElementProps,
52
54
  cellProps: cellProps,
53
- children: cellContent,
55
+ children: (react_1.default.createElement(react_1.default.Fragment, null,
56
+ cellContent,
57
+ cell.column.sticky === 'left' &&
58
+ tableInstance.state.sticky.isScrolledToRight && (react_1.default.createElement("div", { className: 'iui-cell-shadow-right' })),
59
+ cell.column.sticky === 'right' &&
60
+ tableInstance.state.sticky.isScrolledToLeft && (react_1.default.createElement("div", { className: 'iui-cell-shadow-left' })))),
54
61
  };
55
62
  return (react_1.default.createElement(react_1.default.Fragment, null, cell.column.cellRenderer ? (cell.column.cellRenderer(__assign(__assign({}, cellRendererProps), { isDisabled: function () { return isDisabled; } }))) : (react_1.default.createElement(cells_1.DefaultCell, __assign({}, cellRendererProps, { isDisabled: function () { return isDisabled; } })))));
56
63
  };