@carbon/ibm-products 1.70.0 → 1.72.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (88) hide show
  1. package/README.md +8 -4
  2. package/css/index-full-carbon.css +1 -8
  3. package/css/index-full-carbon.css.map +1 -1
  4. package/css/index-full-carbon.min.css +1 -1
  5. package/css/index-full-carbon.min.css.map +1 -1
  6. package/css/index-without-carbon-released-only.css +1 -8
  7. package/css/index-without-carbon-released-only.css.map +1 -1
  8. package/css/index-without-carbon-released-only.min.css +1 -1
  9. package/css/index-without-carbon-released-only.min.css.map +1 -1
  10. package/css/index-without-carbon.css +1 -8
  11. package/css/index-without-carbon.css.map +1 -1
  12. package/css/index-without-carbon.min.css +1 -1
  13. package/css/index-without-carbon.min.css.map +1 -1
  14. package/css/index.css +1 -8
  15. package/css/index.css.map +1 -1
  16. package/css/index.min.css +1 -1
  17. package/css/index.min.css.map +1 -1
  18. package/es/components/CoachmarkStack/CoachmarkStack.js +11 -11
  19. package/es/components/CreateTearsheet/preview-components/MultiStepWithIntro.js +6 -3
  20. package/es/components/Datagrid/Datagrid/Datagrid.js +10 -3
  21. package/es/components/Datagrid/Datagrid/DatagridContent.js +6 -2
  22. package/es/components/Datagrid/Datagrid/DatagridEmptyBody.js +1 -1
  23. package/es/components/Datagrid/Datagrid/DatagridHeaderRow.js +10 -3
  24. package/es/components/Datagrid/Datagrid/DatagridRefBody.js +1 -1
  25. package/es/components/Datagrid/Datagrid/DatagridRow.js +2 -2
  26. package/es/components/Datagrid/Datagrid/DatagridSelectAll.js +5 -3
  27. package/es/components/Datagrid/Datagrid/DatagridSimpleBody.js +1 -1
  28. package/es/components/Datagrid/Datagrid/DatagridToolbar.js +26 -7
  29. package/es/components/Datagrid/Datagrid/DatagridVirtualBody.js +1 -1
  30. package/es/components/Datagrid/Datagrid/addons/Filtering/FilterFlyout.js +4 -0
  31. package/es/components/Datagrid/Datagrid/addons/Filtering/FilterPanel.js +0 -1
  32. package/es/components/Datagrid/Datagrid/addons/Filtering/FilterProvider.js +41 -17
  33. package/es/components/Datagrid/Datagrid/addons/Filtering/constants.js +7 -2
  34. package/es/components/Datagrid/Datagrid/addons/Filtering/hooks/useFilterContext.js +7 -0
  35. package/es/components/Datagrid/Datagrid/addons/Filtering/hooks/useFilters.js +103 -5
  36. package/es/components/Datagrid/Datagrid/addons/Filtering/hooks/useShouldDisableButtons.js +1 -0
  37. package/es/components/Datagrid/Datagrid/addons/Filtering/hooks/useSubscribeToEventEmitter.js +1 -0
  38. package/es/components/Datagrid/Datagrid/addons/Filtering/index.js +1 -0
  39. package/es/components/Datagrid/Datagrid/addons/Filtering/utils.js +12 -1
  40. package/es/components/Datagrid/Datagrid/addons/stateReducer.js +4 -7
  41. package/es/components/Datagrid/useDisableSelectRows.js +1 -1
  42. package/es/components/Datagrid/useFiltering.js +49 -52
  43. package/es/components/Datagrid/useInfiniteScroll.js +7 -3
  44. package/es/components/Datagrid/useInitialColumnSort.js +39 -0
  45. package/es/components/Datagrid/useSelectAllToggle.js +11 -10
  46. package/es/components/Datagrid/useSelectRows.js +4 -4
  47. package/es/components/Datagrid/useSortableColumns.js +16 -16
  48. package/es/components/Tearsheet/TearsheetShell.js +6 -4
  49. package/es/global/js/hooks/index.js +3 -2
  50. package/es/global/js/hooks/useFocus.js +72 -0
  51. package/es/global/js/hooks/useIsomorphicEffect.js +12 -0
  52. package/es/global/js/package-settings.js +0 -1
  53. package/lib/components/CoachmarkStack/CoachmarkStack.js +11 -11
  54. package/lib/components/CreateTearsheet/preview-components/MultiStepWithIntro.js +6 -3
  55. package/lib/components/Datagrid/Datagrid/Datagrid.js +10 -3
  56. package/lib/components/Datagrid/Datagrid/DatagridContent.js +6 -2
  57. package/lib/components/Datagrid/Datagrid/DatagridEmptyBody.js +1 -1
  58. package/lib/components/Datagrid/Datagrid/DatagridHeaderRow.js +10 -3
  59. package/lib/components/Datagrid/Datagrid/DatagridRefBody.js +1 -1
  60. package/lib/components/Datagrid/Datagrid/DatagridRow.js +2 -2
  61. package/lib/components/Datagrid/Datagrid/DatagridSelectAll.js +4 -2
  62. package/lib/components/Datagrid/Datagrid/DatagridSimpleBody.js +1 -1
  63. package/lib/components/Datagrid/Datagrid/DatagridToolbar.js +26 -14
  64. package/lib/components/Datagrid/Datagrid/DatagridVirtualBody.js +1 -1
  65. package/lib/components/Datagrid/Datagrid/addons/Filtering/FilterFlyout.js +4 -0
  66. package/lib/components/Datagrid/Datagrid/addons/Filtering/FilterPanel.js +0 -1
  67. package/lib/components/Datagrid/Datagrid/addons/Filtering/FilterProvider.js +37 -14
  68. package/lib/components/Datagrid/Datagrid/addons/Filtering/constants.js +11 -4
  69. package/lib/components/Datagrid/Datagrid/addons/Filtering/hooks/useFilterContext.js +7 -0
  70. package/lib/components/Datagrid/Datagrid/addons/Filtering/hooks/useFilters.js +99 -2
  71. package/lib/components/Datagrid/Datagrid/addons/Filtering/hooks/useShouldDisableButtons.js +1 -0
  72. package/lib/components/Datagrid/Datagrid/addons/Filtering/utils.js +11 -0
  73. package/lib/components/Datagrid/Datagrid/addons/stateReducer.js +4 -7
  74. package/lib/components/Datagrid/useDisableSelectRows.js +1 -1
  75. package/lib/components/Datagrid/useFiltering.js +47 -50
  76. package/lib/components/Datagrid/useInfiniteScroll.js +7 -3
  77. package/lib/components/Datagrid/useInitialColumnSort.js +47 -0
  78. package/lib/components/Datagrid/useSelectAllToggle.js +9 -9
  79. package/lib/components/Datagrid/useSelectRows.js +3 -3
  80. package/lib/components/Datagrid/useSortableColumns.js +18 -17
  81. package/lib/components/Tearsheet/TearsheetShell.js +6 -4
  82. package/lib/global/js/hooks/index.js +8 -1
  83. package/lib/global/js/hooks/useFocus.js +79 -0
  84. package/lib/global/js/hooks/useIsomorphicEffect.js +18 -0
  85. package/lib/global/js/package-settings.js +0 -1
  86. package/package.json +9 -8
  87. package/scss/components/Datagrid/styles/addons/_FilterPanel.scss +7 -8
  88. package/telemetry.yml +816 -0
@@ -119,7 +119,8 @@ export var MultiStepWithIntro = function MultiStepWithIntro(_ref) {
119
119
  }, /*#__PURE__*/React.createElement(RadioTile, {
120
120
  className: "".concat(pkg.prefix, "--tearsheet-create-multi-step--custom-tile"),
121
121
  value: "standard",
122
- id: "tile-1"
122
+ id: "tile-1",
123
+ tabIndex: selectedCategory === 'standard' ? 0 : -1
123
124
  }, /*#__PURE__*/React.createElement(NoDataIllustration, {
124
125
  size: "lg"
125
126
  }), /*#__PURE__*/React.createElement("span", {
@@ -127,7 +128,8 @@ export var MultiStepWithIntro = function MultiStepWithIntro(_ref) {
127
128
  }, "Standard")), /*#__PURE__*/React.createElement(RadioTile, {
128
129
  className: "".concat(pkg.prefix, "--tearsheet-create-multi-step--custom-tile"),
129
130
  value: "premium",
130
- id: "tile-2"
131
+ id: "tile-2",
132
+ tabIndex: selectedCategory === 'premium' ? 0 : -1
131
133
  }, /*#__PURE__*/React.createElement(NoDataIllustration, {
132
134
  size: "lg"
133
135
  }), /*#__PURE__*/React.createElement("span", {
@@ -135,7 +137,8 @@ export var MultiStepWithIntro = function MultiStepWithIntro(_ref) {
135
137
  }, "Premium")), /*#__PURE__*/React.createElement(RadioTile, {
136
138
  className: "".concat(pkg.prefix, "--tearsheet-create-multi-step--custom-tile"),
137
139
  value: "plus",
138
- id: "tile-3"
140
+ id: "tile-3",
141
+ tabIndex: selectedCategory === 'plus' ? 0 : -1
139
142
  }, /*#__PURE__*/React.createElement(NoDataIllustration, {
140
143
  size: "lg"
141
144
  }), /*#__PURE__*/React.createElement("span", {
@@ -1,6 +1,6 @@
1
1
  import _extends from "@babel/runtime/helpers/extends";
2
2
  import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
3
- var _excluded = ["datagridState", "title"];
3
+ var _excluded = ["ariaToolbarLabel", "datagridState", "title"];
4
4
  /**
5
5
  * Copyright IBM Corp. 2020, 2022
6
6
  *
@@ -20,7 +20,8 @@ import { FilterProvider } from './addons/Filtering/FilterProvider';
20
20
  var blockClass = "".concat(pkg.prefix, "--datagrid");
21
21
  var componentName = 'Datagrid';
22
22
  export var Datagrid = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
23
- var datagridState = _ref.datagridState,
23
+ var ariaToolbarLabel = _ref.ariaToolbarLabel,
24
+ datagridState = _ref.datagridState,
24
25
  title = _ref.title,
25
26
  rest = _objectWithoutProperties(_ref, _excluded);
26
27
  if (!datagridState) {
@@ -37,7 +38,8 @@ export var Datagrid = /*#__PURE__*/React.forwardRef(function (_ref, ref) {
37
38
  var rows = DatagridPagination && datagridState.page || datagridState.rows;
38
39
  var props = {
39
40
  title: title,
40
- datagridState: datagridState
41
+ datagridState: datagridState,
42
+ ariaToolbarLabel: ariaToolbarLabel
41
43
  };
42
44
  return /*#__PURE__*/React.createElement(FilterProvider, {
43
45
  filters: filters,
@@ -58,6 +60,11 @@ Datagrid = pkg.checkComponentEnabled(Datagrid, componentName);
58
60
  // is used in preference to relying on function.name.
59
61
  Datagrid.displayName = componentName;
60
62
  Datagrid.propTypes = {
63
+ /**
64
+ * Specify a label to be read by screen readers on the container node
65
+ * 'aria-label' of the TableToolbar component.
66
+ */
67
+ ariaToolbarLabel: PropTypes.string,
61
68
  /**
62
69
  * The data grid state, much of it being supplied by the useDatagrid hook
63
70
  */
@@ -32,7 +32,8 @@ var TableContainer = DataTable.TableContainer,
32
32
  var blockClass = "".concat(pkg.prefix, "--datagrid");
33
33
  export var DatagridContent = function DatagridContent(_ref) {
34
34
  var _cx5;
35
- var datagridState = _ref.datagridState,
35
+ var ariaToolbarLabel = _ref.ariaToolbarLabel,
36
+ datagridState = _ref.datagridState,
36
37
  title = _ref.title;
37
38
  var _useContext = useContext(InlineEditContext),
38
39
  inlineEditState = _useContext.state,
@@ -154,7 +155,9 @@ export var DatagridContent = function DatagridContent(_ref) {
154
155
  className: cx("".concat(blockClass, "__grid-container"), withVirtualScroll || fullHeightDatagrid ? "".concat(blockClass, "__full-height") : '', DatagridPagination ? "".concat(blockClass, "__with-pagination") : '', useDenseHeader ? "".concat(blockClass, "__dense-header") : '', (_cx5 = {}, _defineProperty(_cx5, "".concat(blockClass, "__grid-container-grid-active"), gridActive), _defineProperty(_cx5, "".concat(blockClass, "__grid-container-inline-edit"), withInlineEdit), _defineProperty(_cx5, "".concat(blockClass, "__grid-container-grid-active--without-toolbar"), withInlineEdit && !DatagridActions), _cx5)),
155
156
  title: gridTitle,
156
157
  description: gridDescription
157
- }, /*#__PURE__*/React.createElement(DatagridToolbar, datagridState), /*#__PURE__*/React.createElement("div", {
158
+ }, /*#__PURE__*/React.createElement(DatagridToolbar, _extends({}, datagridState, {
159
+ ariaToolbarLabel: ariaToolbarLabel
160
+ })), /*#__PURE__*/React.createElement("div", {
158
161
  className: cx("".concat(blockClass, "__table-container"), _defineProperty({}, "".concat(blockClass, "__table-container--filter-open"), panelOpen)),
159
162
  ref: gridAreaRef
160
163
  }, (filterProps === null || filterProps === void 0 ? void 0 : filterProps.variation) === 'panel' && /*#__PURE__*/React.createElement(FilterPanel, _extends({}, getFilterFlyoutProps(), {
@@ -173,6 +176,7 @@ export var DatagridContent = function DatagridContent(_ref) {
173
176
  }));
174
177
  };
175
178
  DatagridContent.propTypes = {
179
+ ariaToolbarLabel: PropTypes.string,
176
180
  datagridState: PropTypes.shape({
177
181
  getTableProps: PropTypes.func,
178
182
  getFilterFlyoutProps: PropTypes.func,
@@ -35,7 +35,7 @@ var DatagridEmptyBody = function DatagridEmptyBody(datagridState) {
35
35
  };
36
36
  var validEmptyStates = ['error', 'noData', 'notFound'];
37
37
  return /*#__PURE__*/React.createElement(TableBody, _extends({}, getTableBodyProps({
38
- role: false
38
+ role: undefined
39
39
  }), {
40
40
  className: "".concat(blockClass, "__empty-state-body")
41
41
  }), /*#__PURE__*/React.createElement(TableRow, null, /*#__PURE__*/React.createElement(TableCell, {
@@ -18,6 +18,7 @@ import { selectionColumnId } from '../common-column-ids';
18
18
  import { pkg } from '../../../settings';
19
19
  import { handleColumnResizeEndEvent, handleColumnResizingEvent } from './addons/stateReducer';
20
20
  import { getNodeTextContent } from '../../../global/js/utils/getNodeTextContent';
21
+ import { useInitialColumnSort } from '../useInitialColumnSort';
21
22
  var blockClass = "".concat(pkg.prefix, "--datagrid");
22
23
  var getAccessibilityProps = function getAccessibilityProps(header) {
23
24
  var props = {};
@@ -30,7 +31,9 @@ var getAccessibilityProps = function getAccessibilityProps(header) {
30
31
  return props;
31
32
  };
32
33
  var HeaderRow = function HeaderRow(datagridState, headRef, headerGroup) {
33
- var resizerAriaLabel = datagridState.resizerAriaLabel;
34
+ var resizerAriaLabel = datagridState.resizerAriaLabel,
35
+ isFetching = datagridState.isFetching;
36
+ useInitialColumnSort(datagridState);
34
37
  // Used to measure the height of the table and uses that value
35
38
  // to display a vertical line to indicate the column you are resizing
36
39
  useEffect(function () {
@@ -71,7 +74,7 @@ var HeaderRow = function HeaderRow(datagridState, headRef, headerGroup) {
71
74
  onMouseDown === null || onMouseDown === void 0 ? void 0 : onMouseDown(event);
72
75
  };
73
76
  return /*#__PURE__*/React.createElement(TableRow, _extends({}, headerGroup.getHeaderGroupProps({
74
- role: false
77
+ role: undefined
75
78
  }), {
76
79
  className: cx("".concat(blockClass, "__head"), headerGroup.getHeaderGroupProps().className),
77
80
  ref: headRef
@@ -97,15 +100,19 @@ var HeaderRow = function HeaderRow(datagridState, headRef, headerGroup) {
97
100
  columnWidths = _ref4.columnWidths;
98
101
  var originalCol = visibleColumns[index];
99
102
  return /*#__PURE__*/React.createElement(TableHeader, _extends({}, header.getHeaderProps({
100
- role: false
103
+ role: undefined
101
104
  }), {
102
105
  className: cx((_cx = {}, _defineProperty(_cx, "".concat(blockClass, "__resizableColumn"), header.getResizerProps), _defineProperty(_cx, "".concat(blockClass, "__isResizing"), header.isResizing), _defineProperty(_cx, "".concat(blockClass, "__sortableColumn"), datagridState.isTableSortable && header.id !== 'spacer'), _defineProperty(_cx, "".concat(blockClass, "__isSorted"), header.isSorted), _defineProperty(_cx, "".concat(blockClass, "__header-actions-column"), header.isAction), _cx), header.getHeaderProps().className),
103
106
  key: header.id,
104
107
  "aria-hidden": header.id === 'spacer' && 'true'
105
108
  }, getAccessibilityProps(header)), header.render('Header'), header.getResizerProps && !header.isAction && /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement("input", _extends({}, header.getResizerProps(), {
109
+ disabled: isFetching,
106
110
  onMouseDown: function onMouseDown(event) {
107
111
  return handleOnMouseDownResize(event, header.getResizerProps);
108
112
  },
113
+ onMouseUp: function onMouseUp() {
114
+ return handleColumnResizeEndEvent(dispatch, onColResizeEnd, header.id, true);
115
+ },
109
116
  onKeyDown: function onKeyDown(event) {
110
117
  var key = event.key;
111
118
  if (key === 'ArrowLeft' || key === 'ArrowRight') {
@@ -23,7 +23,7 @@ var DatagridRefBody = function DatagridRefBody(datagridState) {
23
23
  rows = datagridState.rows,
24
24
  prepareRow = datagridState.prepareRow;
25
25
  return /*#__PURE__*/React.createElement("tbody", _extends({}, getTableBodyProps({
26
- role: false
26
+ role: undefined
27
27
  }), {
28
28
  className: cx("".concat(blockClass, "__simple-body"), getTableBodyProps().className)
29
29
  }), rows.map(function (row) {
@@ -113,7 +113,7 @@ var DatagridRow = function DatagridRow(datagridState) {
113
113
  }, /*#__PURE__*/React.createElement(TableRow, _extends({
114
114
  className: rowClassNames
115
115
  }, row.getRowProps({
116
- role: false
116
+ role: undefined
117
117
  }), {
118
118
  key: row.id,
119
119
  onMouseEnter: hoverHandler,
@@ -124,7 +124,7 @@ var DatagridRow = function DatagridRow(datagridState) {
124
124
  }, setAdditionalRowProps()), row.cells.map(function (cell, index) {
125
125
  var _cell$column;
126
126
  var cellProps = cell.getCellProps({
127
- role: false
127
+ role: undefined
128
128
  });
129
129
  var children = cellProps.children,
130
130
  restProps = _objectWithoutProperties(cellProps, _excluded);
@@ -4,7 +4,7 @@ import _defineProperty from "@babel/runtime/helpers/defineProperty";
4
4
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
5
5
  var _excluded = ["onChange"];
6
6
  /**
7
- * Copyright IBM Corp. 2020, 2023
7
+ * Copyright IBM Corp. 2020, 2024
8
8
  *
9
9
  * This source code is licensed under the Apache-2.0 license found in the
10
10
  * LICENSE file in the root directory of this source tree.
@@ -18,7 +18,7 @@ import { handleSelectAllRowData } from './addons/stateReducer';
18
18
  var blockClass = "".concat(pkg.prefix, "--datagrid");
19
19
  var SelectAll = function SelectAll(datagridState) {
20
20
  var _columns$;
21
- var _useState = useState(window.innerWidth),
21
+ var _useState = useState(typeof window !== 'undefined' ? window.innerWidth : ''),
22
22
  _useState2 = _slicedToArray(_useState, 2),
23
23
  windowSize = _useState2[0],
24
24
  setWindowSize = _useState2[1];
@@ -27,7 +27,9 @@ var SelectAll = function SelectAll(datagridState) {
27
27
  function updateSize() {
28
28
  setWindowSize(window.innerWidth);
29
29
  }
30
- window.addEventListener('resize', updateSize);
30
+ if (typeof window !== 'undefined') {
31
+ window.addEventListener('resize', updateSize);
32
+ }
31
33
  return function () {
32
34
  return window.removeEventListener('resize', updateSize);
33
35
  };
@@ -20,7 +20,7 @@ var DatagridSimpleBody = function DatagridSimpleBody(datagridState) {
20
20
  rows = datagridState.rows,
21
21
  prepareRow = datagridState.prepareRow;
22
22
  return /*#__PURE__*/React.createElement(TableBody, _extends({}, getTableBodyProps({
23
- role: false
23
+ role: undefined
24
24
  }), {
25
25
  className: cx("".concat(blockClass, "__simple-body"), getTableBodyProps().className)
26
26
  }), rows.map(function (row) {
@@ -1,5 +1,7 @@
1
+ import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
1
2
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
3
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
4
+ var _excluded = ["ariaToolbarLabel"];
3
5
  /**
4
6
  * Copyright IBM Corp. 2022, 2023
5
7
  *
@@ -8,6 +10,7 @@ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
8
10
  */
9
11
 
10
12
  import React, { useEffect, useRef, useState } from 'react';
13
+ import PropTypes from 'prop-types';
11
14
  import { Add16, OverflowMenuVertical16 } from '@carbon/icons-react';
12
15
  import { DataTable, TableBatchActions, TableBatchAction } from 'carbon-components-react';
13
16
  import { useResizeObserver } from '../../../global/js/hooks/useResizeObserver';
@@ -99,6 +102,16 @@ var DatagridBatchActionsToolbar = function DatagridBatchActionsToolbar(datagridS
99
102
  }
100
103
  }));
101
104
  };
105
+ var onCancelHandler = function onCancelHandler() {
106
+ handleSelectAllRowData({
107
+ dispatch: dispatch,
108
+ rows: [],
109
+ getRowId: getRowId,
110
+ isChecked: false
111
+ });
112
+ toggleAllRowsSelected(false);
113
+ setGlobalFilter(null);
114
+ };
102
115
 
103
116
  // Only display the first two batch actions, the rest are
104
117
  // displayed inside of the ButtonMenu if there are more than
@@ -106,10 +119,7 @@ var DatagridBatchActionsToolbar = function DatagridBatchActionsToolbar(datagridS
106
119
  return /*#__PURE__*/React.createElement(TableBatchActions, {
107
120
  shouldShowBatchActions: totalSelected > 0,
108
121
  totalSelected: totalSelected,
109
- onCancel: function onCancel() {
110
- toggleAllRowsSelected(false);
111
- setGlobalFilter(null);
112
- },
122
+ onCancel: onCancelHandler,
113
123
  translateWithId: translateWithIdBatchActions
114
124
  }, !displayAllInMenu && toolbarBatchActions && (toolbarBatchActions === null || toolbarBatchActions === void 0 ? void 0 : toolbarBatchActions.map(function (batchAction, index) {
115
125
  if (index < 2 && toolbarBatchActions.length > 3 || index < 3 && toolbarBatchActions.length <= 3) {
@@ -132,7 +142,9 @@ var DatagridBatchActionsToolbar = function DatagridBatchActionsToolbar(datagridS
132
142
  }
133
143
  })), renderBatchActionOverflow());
134
144
  };
135
- var DatagridToolbar = function DatagridToolbar(datagridState) {
145
+ var DatagridToolbar = function DatagridToolbar(_ref2) {
146
+ var ariaToolbarLabel = _ref2.ariaToolbarLabel,
147
+ datagridState = _objectWithoutProperties(_ref2, _excluded);
136
148
  var ref = useRef(null);
137
149
  var _useResizeObserver = useResizeObserver(ref),
138
150
  width = _useResizeObserver.width;
@@ -144,8 +156,15 @@ var DatagridToolbar = function DatagridToolbar(datagridState) {
144
156
  return batchActions && DatagridActions ? /*#__PURE__*/React.createElement("div", {
145
157
  ref: ref,
146
158
  className: cx([toolbarClass, "".concat(toolbarClass, "--").concat(getRowHeight)])
147
- }, /*#__PURE__*/React.createElement(TableToolbar, null, DatagridActions && /*#__PURE__*/React.createElement(DatagridActions, datagridState), DatagridBatchActionsToolbar && DatagridBatchActionsToolbar(datagridState, width, ref))) : DatagridActions ? /*#__PURE__*/React.createElement("div", {
159
+ }, /*#__PURE__*/React.createElement(TableToolbar, {
160
+ "aria-label": ariaToolbarLabel
161
+ }, DatagridActions && /*#__PURE__*/React.createElement(DatagridActions, datagridState), DatagridBatchActionsToolbar && DatagridBatchActionsToolbar(datagridState, width, ref))) : DatagridActions ? /*#__PURE__*/React.createElement("div", {
148
162
  className: toolbarClass
149
- }, /*#__PURE__*/React.createElement(TableToolbar, null, DatagridActions && /*#__PURE__*/React.createElement(DatagridActions, datagridState), DatagridBatchActions && DatagridBatchActions(datagridState))) : null;
163
+ }, /*#__PURE__*/React.createElement(TableToolbar, {
164
+ "aria-label": ariaToolbarLabel
165
+ }, DatagridActions && /*#__PURE__*/React.createElement(DatagridActions, datagridState), DatagridBatchActions && DatagridBatchActions(datagridState))) : null;
166
+ };
167
+ DatagridToolbar.propTypes = {
168
+ ariaToolbarLabel: PropTypes.string
150
169
  };
151
170
  export default DatagridToolbar;
@@ -73,7 +73,7 @@ var DatagridVirtualBody = function DatagridVirtualBody(datagridState) {
73
73
  overflow: 'hidden'
74
74
  }
75
75
  }, /*#__PURE__*/React.createElement(DatagridHead, datagridState)), /*#__PURE__*/React.createElement(TableBody, _extends({}, getTableBodyProps({
76
- role: false
76
+ role: undefined
77
77
  }), {
78
78
  onScroll: syncScroll
79
79
  }), /*#__PURE__*/React.createElement(VariableSizeList, {
@@ -185,9 +185,13 @@ var FilterFlyout = function FilterFlyout(_ref) {
185
185
  };
186
186
 
187
187
  /** Effects */
188
+ // Close flyout when clicking outside
188
189
  useClickOutside(filterFlyoutRef, function (target) {
189
190
  var hasClickedOnDatePicker = target.closest('.flatpickr-calendar');
190
191
  var hasClickedOnDropdown = target.className === "".concat(carbon.prefix, "--list-box__menu-item__option");
192
+
193
+ // Do not do anything if flyout is closed or if clicking on anything
194
+ // rendered via a portal
191
195
  if (!open || hasClickedOnDatePicker || hasClickedOnDropdown) {
192
196
  return;
193
197
  }
@@ -1,6 +1,5 @@
1
1
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
2
2
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
3
- /* eslint-disable react/jsx-key */
4
3
  /**
5
4
  * Copyright IBM Corp. 2022, 2024
6
5
  *
@@ -4,14 +4,15 @@ import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
4
4
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
5
5
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { _defineProperty(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; }
6
6
  /**
7
- * Copyright IBM Corp. 2022, 2023
7
+ * Copyright IBM Corp. 2022, 2024
8
8
  *
9
9
  * This source code is licensed under the Apache-2.0 license found in the
10
10
  * LICENSE file in the root directory of this source tree.
11
11
  */
12
- import React, { createContext, useState } from 'react';
12
+
13
+ import React, { createContext, useState, useReducer } from 'react';
13
14
  import PropTypes from 'prop-types';
14
- import { DATE, DROPDOWN, NUMBER, RADIO, CHECKBOX, CLEAR_SINGLE_FILTER } from './constants';
15
+ import { DATE, DROPDOWN, NUMBER, RADIO, CHECKBOX, CLEAR_SINGLE_FILTER, SAVED_FILTERS, MULTISELECT } from './constants';
15
16
  export var FilterContext = /*#__PURE__*/createContext();
16
17
  var EventEmitter = {
17
18
  events: {},
@@ -35,7 +36,7 @@ var removeFilterItem = function removeFilterItem(state, index) {
35
36
  return state.splice(index, 1);
36
37
  };
37
38
  var updateFilterState = function updateFilterState(state, type, value) {
38
- if (type === CHECKBOX) {
39
+ if (type === CHECKBOX || type === MULTISELECT) {
39
40
  return;
40
41
  }
41
42
  if (type === DATE) {
@@ -58,7 +59,7 @@ export var clearSingleFilter = function clearSingleFilter(_ref, setAllFilters, s
58
59
  var filterValues = f.value;
59
60
  var filterType = f.type;
60
61
  updateFilterState(tempState, filterType, value);
61
- if (filterType === CHECKBOX) {
62
+ if (filterType === CHECKBOX || filterType === MULTISELECT) {
62
63
  /**
63
64
  When all checkboxes of a group are all unselected the value still exists in the filtersObjectArray
64
65
  This checks if all the checkboxes are selected = false and removes it from the array
@@ -124,15 +125,15 @@ var prepareFiltersForTags = function prepareFiltersForTags(filters, renderDateLa
124
125
  key: id,
125
126
  value: (_renderDateLabel = renderDateLabel === null || renderDateLabel === void 0 ? void 0 : renderDateLabel(startDate, endDate)) !== null && _renderDateLabel !== void 0 ? _renderDateLabel : formatDateRange(startDate, endDate)
126
127
  }, sharedFilterProps));
127
- } else if (type === CHECKBOX) {
128
- value.forEach(function (checkbox) {
129
- if (checkbox.selected) {
128
+ } else if (type === CHECKBOX || type === MULTISELECT) {
129
+ value.forEach(function (option) {
130
+ if (option.selected) {
130
131
  tags.push(_objectSpread(_objectSpread({
131
132
  key: id,
132
- value: checkbox.value
133
+ value: option.value
133
134
  }, sharedFilterProps), {}, {
134
135
  onClose: function onClose() {
135
- return handleSingleFilterRemoval(id, checkbox.value);
136
+ return handleSingleFilterRemoval(id, option.value);
136
137
  }
137
138
  }));
138
139
  }
@@ -141,22 +142,45 @@ var prepareFiltersForTags = function prepareFiltersForTags(filters, renderDateLa
141
142
  });
142
143
  return tags;
143
144
  };
144
- export var FilterProvider = function FilterProvider(_ref3) {
145
- var children = _ref3.children,
146
- filters = _ref3.filters,
147
- filterProps = _ref3.filterProps;
148
- var _ref4 = filterProps || {},
149
- renderDateLabel = _ref4.renderDateLabel;
145
+ var filteringReducer = function filteringReducer(state, action) {
146
+ switch (action.type) {
147
+ case SAVED_FILTERS:
148
+ {
149
+ var _ref3 = action.payload || {},
150
+ savedFilters = _ref3.savedFilters;
151
+ return _objectSpread(_objectSpread({}, state), {}, {
152
+ savedFilters: savedFilters
153
+ });
154
+ }
155
+ default:
156
+ return state;
157
+ }
158
+ };
159
+ export var FilterProvider = function FilterProvider(_ref4) {
160
+ var children = _ref4.children,
161
+ filters = _ref4.filters,
162
+ filterProps = _ref4.filterProps;
163
+ var _ref5 = filterProps || {},
164
+ renderDateLabel = _ref5.renderDateLabel;
150
165
  var filterTags = prepareFiltersForTags(filters, renderDateLabel);
151
166
  var _useState = useState(false),
152
167
  _useState2 = _slicedToArray(_useState, 2),
153
168
  panelOpen = _useState2[0],
154
169
  setPanelOpen = _useState2[1];
170
+ var initialState = {
171
+ savedFilters: []
172
+ };
173
+ var _useReducer = useReducer(filteringReducer, initialState),
174
+ _useReducer2 = _slicedToArray(_useReducer, 2),
175
+ state = _useReducer2[0],
176
+ dispatch = _useReducer2[1];
155
177
  var value = {
156
178
  filterTags: filterTags,
157
179
  EventEmitter: EventEmitter,
158
180
  panelOpen: panelOpen,
159
- setPanelOpen: setPanelOpen
181
+ setPanelOpen: setPanelOpen,
182
+ state: state,
183
+ dispatch: dispatch
160
184
  };
161
185
  return /*#__PURE__*/React.createElement(FilterContext.Provider, {
162
186
  value: value
@@ -1,9 +1,10 @@
1
1
  /**
2
- * Copyright IBM Corp. 2022, 2022
2
+ * Copyright IBM Corp. 2022, 2024
3
3
  *
4
4
  * This source code is licensed under the Apache-2.0 license found in the
5
5
  * LICENSE file in the root directory of this source tree.
6
6
  */
7
+
7
8
  /** Constants for update methods can either be batch or instant */
8
9
  export var BATCH = 'batch';
9
10
  export var INSTANT = 'instant';
@@ -18,6 +19,7 @@ export var NUMBER = 'number';
18
19
  export var CHECKBOX = 'checkbox';
19
20
  export var RADIO = 'radio';
20
21
  export var DROPDOWN = 'dropdown';
22
+ export var MULTISELECT = 'multiSelect';
21
23
 
22
24
  /** Constants for event emitters */
23
25
  export var CLEAR_FILTERS = 'clearFilters';
@@ -25,4 +27,7 @@ export var CLEAR_SINGLE_FILTER = 'clearSingleFilter';
25
27
 
26
28
  /** Constants for panel dimensions */
27
29
  export var PANEL_WIDTH = 320;
28
- export var ACTION_SET_HEIGHT = 64;
30
+ export var ACTION_SET_HEIGHT = 64;
31
+
32
+ /** Constants for local reducer */
33
+ export var SAVED_FILTERS = 'savedFilters';
@@ -1,3 +1,10 @@
1
+ /**
2
+ * Copyright IBM Corp. 2023, 2024
3
+ *
4
+ * This source code is licensed under the Apache-2.0 license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ */
7
+
1
8
  import { FilterContext } from '../FilterProvider';
2
9
  import { useContext } from 'react';
3
10
  var useFilterContext = function useFilterContext() {
@@ -10,11 +10,13 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
10
10
  * This source code is licensed under the Apache-2.0 license found in the
11
11
  * LICENSE file in the root directory of this source tree.
12
12
  */
13
- import React, { useState, useRef, useEffect, useCallback } from 'react';
14
- import { Checkbox, DatePicker, DatePickerInput, Dropdown, FormGroup, NumberInput, RadioButton, RadioButtonGroup } from 'carbon-components-react';
15
- import { INSTANT, BATCH, DATE, CHECKBOX, NUMBER, RADIO, DROPDOWN, PANEL } from '../constants';
13
+
14
+ import React, { useState, useRef, useEffect, useCallback, useContext } from 'react';
15
+ import { Checkbox, DatePicker, DatePickerInput, Dropdown, FormGroup, NumberInput, RadioButton, RadioButtonGroup, MultiSelect } from 'carbon-components-react';
16
+ import { INSTANT, BATCH, DATE, CHECKBOX, NUMBER, RADIO, DROPDOWN, PANEL, SAVED_FILTERS, MULTISELECT } from '../constants';
16
17
  import { getInitialStateFromFilters } from '../utils';
17
18
  import { usePreviousValue } from '../../../../../../global/js/hooks';
19
+ import { FilterContext } from '../FilterProvider';
18
20
  var useFilters = function useFilters(_ref) {
19
21
  var updateMethod = _ref.updateMethod,
20
22
  _ref$filters = _ref.filters,
@@ -25,6 +27,10 @@ var useFilters = function useFilters(_ref) {
25
27
  onCancel = _ref.onCancel,
26
28
  panelOpen = _ref.panelOpen,
27
29
  isFetching = _ref.isFetching;
30
+ var _useContext = useContext(FilterContext),
31
+ state = _useContext.state,
32
+ localDispatch = _useContext.dispatch;
33
+ var savedFilters = state.savedFilters;
28
34
  /** State */
29
35
  var _useState = useState(getInitialStateFromFilters(filters, variation, reactTableFiltersState)),
30
36
  _useState2 = _slicedToArray(_useState, 2),
@@ -108,7 +114,7 @@ var useFilters = function useFilters(_ref) {
108
114
  }
109
115
 
110
116
  // ATTENTION: this is where you would reset or remove individual filters from the filters array
111
- if (type === CHECKBOX) {
117
+ if (type === CHECKBOX || type === MULTISELECT) {
112
118
  /**
113
119
  When all checkboxes of a group are all unselected the value still exists in the filtersObjectArray
114
120
  This checks if all the checkboxes are selected = false and removes it from the array
@@ -164,6 +170,16 @@ var useFilters = function useFilters(_ref) {
164
170
  }
165
171
  setFiltersObjectArray(filtersObjectArrayCopy);
166
172
 
173
+ // Dispatch action from local filter context to track filters in order
174
+ // to keep history if `isFetching` becomes true. If so, react-table
175
+ // clears all filter history
176
+ localDispatch({
177
+ type: SAVED_FILTERS,
178
+ payload: {
179
+ savedFilters: filtersObjectArrayCopy
180
+ }
181
+ });
182
+
167
183
  // // Automatically apply the filters if the updateMethod is instant
168
184
  if (updateMethod === INSTANT) {
169
185
  setAllFilters(filtersObjectArrayCopy);
@@ -308,6 +324,71 @@ var useFilters = function useFilters(_ref) {
308
324
  },
309
325
  light: isPanel
310
326
  }));
327
+ break;
328
+ case MULTISELECT:
329
+ {
330
+ var _filtersState$column3;
331
+ var isStringArray = components.MultiSelect.items.length && typeof components.MultiSelect.items[0] === 'string';
332
+ var selectedFilters = (_filtersState$column3 = filtersState[column]) === null || _filtersState$column3 === void 0 ? void 0 : _filtersState$column3.value.filter(function (i) {
333
+ return i.selected;
334
+ });
335
+ var filteredItems = components.MultiSelect.items.map(function (item) {
336
+ if (selectedFilters.filter(function (a) {
337
+ return isStringArray ? a.id === item : a.id === item.id;
338
+ }).length) {
339
+ return item;
340
+ }
341
+ return null;
342
+ }).filter(Boolean);
343
+ filter = /*#__PURE__*/React.createElement(MultiSelect, _extends({}, components.MultiSelect, {
344
+ selectedItems: filteredItems,
345
+ onChange: function onChange(_ref6) {
346
+ var _components$MultiSele, _components$MultiSele2;
347
+ var selectedItems = _ref6.selectedItems;
348
+ var allOptions = filtersState[column].value;
349
+ // Find selected items from list of options
350
+ var foundItems = selectedItems.map(function (item) {
351
+ if (allOptions.filter(function (option) {
352
+ return isStringArray ? option.id === item : option.id === item.id;
353
+ })) {
354
+ return allOptions.filter(function (option) {
355
+ return isStringArray ? option.id === item : option.id === item.id;
356
+ })[0];
357
+ }
358
+ return null;
359
+ }).filter(Boolean);
360
+
361
+ // Change selected state for those items that have been selected
362
+ allOptions.map(function (a) {
363
+ return a.selected = false;
364
+ });
365
+ foundItems.map(function (item) {
366
+ var foundOriginalItem = allOptions.filter(function (a) {
367
+ return isStringArray ? a === item : a.id === item.id;
368
+ });
369
+ if (foundOriginalItem && foundOriginalItem.length) {
370
+ foundOriginalItem[0].selected = true;
371
+ }
372
+ });
373
+ if (!selectedItems.length) {
374
+ allOptions.map(function (a) {
375
+ return a.selected = false;
376
+ });
377
+ }
378
+ setFiltersState(_objectSpread(_objectSpread({}, filtersState), {}, _defineProperty({}, column, {
379
+ value: allOptions,
380
+ type: type
381
+ })));
382
+ applyFilters({
383
+ column: column,
384
+ value: _toConsumableArray(filtersState[column].value),
385
+ type: type
386
+ });
387
+ (_components$MultiSele = components.MultiSelect) === null || _components$MultiSele === void 0 ? void 0 : (_components$MultiSele2 = _components$MultiSele.onChange) === null || _components$MultiSele2 === void 0 ? void 0 : _components$MultiSele2.call(_components$MultiSele, selectedItems);
388
+ }
389
+ }));
390
+ break;
391
+ }
311
392
  }
312
393
  return /*#__PURE__*/React.createElement(React.Fragment, {
313
394
  key: column
@@ -343,10 +424,27 @@ var useFilters = function useFilters(_ref) {
343
424
  setAllFilters(JSON.parse(prevFiltersObjectArrayRef.current));
344
425
  setFetchingReset(true);
345
426
  }
427
+ if (isFetching && fetchingReset) {
428
+ var cleanFilters = function cleanFilters(originalFilterState) {
429
+ var copy = _objectSpread({}, originalFilterState);
430
+ var updatedFilters = savedFilters.map(function (f) {
431
+ if (Object.hasOwn(copy, f.id)) {
432
+ copy[f.id] = f;
433
+ return copy;
434
+ }
435
+ return copy;
436
+ });
437
+ return updatedFilters[0];
438
+ };
439
+ setFiltersObjectArray(savedFilters);
440
+ var filterStateCopy = cleanFilters(filtersState);
441
+ setFiltersState(filterStateCopy);
442
+ }
346
443
  if (!isFetching) {
347
444
  setFetchingReset(false);
348
445
  }
349
- }, [isFetching, reactTableFiltersState, setAllFilters, fetchingReset]);
446
+ // eslint-disable-next-line react-hooks/exhaustive-deps
447
+ }, [isFetching, reactTableFiltersState, setAllFilters, fetchingReset, savedFilters, filtersObjectArray]);
350
448
  var cancel = function cancel() {
351
449
  // Reverting to previous filters only applies when using batch actions
352
450
  if (updateMethod === BATCH) {
@@ -5,6 +5,7 @@ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
5
5
  * This source code is licensed under the Apache-2.0 license found in the
6
6
  * LICENSE file in the root directory of this source tree.
7
7
  */
8
+
8
9
  /* eslint-disable jsdoc/check-param-names */
9
10
 
10
11
  import { useState, useEffect } from 'react';