@elliemae/ds-data-table 2.4.3 → 2.4.5

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 (51) hide show
  1. package/cjs/DataTable.js +10 -1
  2. package/cjs/DataTableSchema.js +5 -0
  3. package/cjs/addons/Columns/ColumnExpand/ColumnExpand.js +27 -13
  4. package/cjs/addons/Editables/ComboboxEditableCell/ComboboxEditableCell.js +1 -1
  5. package/cjs/addons/Editables/DateEditableCell/DateEditableCell.js +1 -1
  6. package/cjs/addons/Editables/TextEditableCell/TextEditableCell.js +1 -1
  7. package/cjs/addons/Filters/Components/SelectFilter/BaseSelectFilter.js +14 -6
  8. package/cjs/addons/Filters/Components/SelectFilter/MultiSelectFilter.js +1 -1
  9. package/cjs/addons/Filters/Components/SelectFilter/SingleSelectFilter.js +1 -1
  10. package/cjs/configs/useDatatableConfig.js +5 -1
  11. package/cjs/exported-related/EditableCell.js +1 -2
  12. package/cjs/exported-related/FilterPopover.js +29 -27
  13. package/cjs/exported-related/RowRenderer/DefaultRowContentRenderer.js +9 -2
  14. package/cjs/exported-related/RowRenderer/useRowRendererHandlers.js +25 -7
  15. package/cjs/exported-related/Toolbar/Toolbar.js +3 -10
  16. package/cjs/parts/Cells/Cell.js +3 -2
  17. package/cjs/parts/FilterBar/FiltersBar.js +29 -2
  18. package/cjs/parts/Filters/index.js +1 -1
  19. package/cjs/parts/Headers/HeaderCellGroup.js +3 -2
  20. package/cjs/parts/Headers/HeaderResizer.js +1 -1
  21. package/cjs/parts/Row.js +17 -1
  22. package/cjs/parts/RowVariants/index.js +1 -1
  23. package/cjs/parts/TableContent.js +1 -1
  24. package/cjs/styled.js +39 -41
  25. package/esm/DataTable.js +10 -1
  26. package/esm/DataTableSchema.js +5 -0
  27. package/esm/addons/Columns/ColumnExpand/ColumnExpand.js +28 -14
  28. package/esm/addons/Editables/ComboboxEditableCell/ComboboxEditableCell.js +1 -1
  29. package/esm/addons/Editables/DateEditableCell/DateEditableCell.js +1 -1
  30. package/esm/addons/Editables/TextEditableCell/TextEditableCell.js +1 -1
  31. package/esm/addons/Filters/Components/SelectFilter/BaseSelectFilter.js +14 -6
  32. package/esm/addons/Filters/Components/SelectFilter/MultiSelectFilter.js +1 -1
  33. package/esm/addons/Filters/Components/SelectFilter/SingleSelectFilter.js +1 -1
  34. package/esm/configs/useDatatableConfig.js +5 -1
  35. package/esm/exported-related/EditableCell.js +1 -2
  36. package/esm/exported-related/FilterPopover.js +30 -28
  37. package/esm/exported-related/RowRenderer/DefaultRowContentRenderer.js +10 -3
  38. package/esm/exported-related/RowRenderer/useRowRendererHandlers.js +25 -7
  39. package/esm/exported-related/Toolbar/Toolbar.js +3 -10
  40. package/esm/parts/Cells/Cell.js +3 -2
  41. package/esm/parts/FilterBar/FiltersBar.js +30 -3
  42. package/esm/parts/Filters/index.js +1 -1
  43. package/esm/parts/Headers/HeaderCellGroup.js +3 -2
  44. package/esm/parts/Headers/HeaderResizer.js +1 -1
  45. package/esm/parts/Row.js +17 -1
  46. package/esm/parts/RowVariants/index.js +1 -1
  47. package/esm/parts/TableContent.js +2 -2
  48. package/esm/styled.js +39 -42
  49. package/package.json +19 -19
  50. package/types/styled.d.ts +2 -1
  51. package/types/types/props.d.ts +1 -0
package/cjs/DataTable.js CHANGED
@@ -21,6 +21,7 @@ var useDatatableConfig = require('./configs/useDatatableConfig.js');
21
21
  require('./configs/useRowFlattenization.js');
22
22
  var FiltersBar = require('./parts/FilterBar/FiltersBar.js');
23
23
  var DataTableSchema = require('./DataTableSchema.js');
24
+ var styled = require('./styled.js');
24
25
  var jsxRuntime = require('react/jsx-runtime');
25
26
 
26
27
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
@@ -41,13 +42,21 @@ const DataTable = props => {
41
42
  const tableWrapperRef = React.useRef();
42
43
  const tableContentWrapperRef = React.useRef();
43
44
  const ctx = useDatatableConfig.useDatatableConfig(props);
45
+ const {
46
+ tableProps: {
47
+ height,
48
+ width
49
+ }
50
+ } = ctx;
44
51
  return /*#__PURE__*/_jsx__default["default"](reactRedux.Provider, {
45
52
  store: reduxStore
46
53
  }, void 0, /*#__PURE__*/_jsx__default["default"](DataTableContext["default"].Provider, {
47
54
  value: ctx
48
- }, void 0, /*#__PURE__*/jsxRuntime.jsxs("div", {
55
+ }, void 0, /*#__PURE__*/jsxRuntime.jsxs(styled.StyledDataTableWrapper, {
49
56
  ref: tableWrapperRef,
50
57
  "data-testid": constants.DATA_TESTID.DATA_TABLE_WRAPPER,
58
+ height: height,
59
+ width: width,
51
60
  children: [withFilterBar ? _FiltersBar || (_FiltersBar = /*#__PURE__*/_jsx__default["default"](FiltersBar.FiltersBar, {})) : null, /*#__PURE__*/jsxRuntime.jsx(TableContent, {
52
61
  ref: tableContentWrapperRef
53
62
  })]
@@ -57,6 +57,11 @@ const DataTableSchema = {
57
57
  withFilterBar: dsPropsHelpers.PropTypes.bool.description('Whether to display the filter bar'),
58
58
  filterBarProps: dsPropsHelpers.PropTypes.shape({
59
59
  customPillRenderer: dsPropsHelpers.PropTypes.oneOfType([dsPropsHelpers.PropTypes.func, dsPropsHelpers.PropTypes.element]).description('If you specify custom filters, you will need to render their pills here'),
60
+ isDropdownMenuOpen: dsPropsHelpers.PropTypes.bool.description('Wether the DropdownMenu is Open or not.'),
61
+ onDropdownMenuToggle: dsPropsHelpers.PropTypes.func.description('Callback to toggle the DropdownMenu.'),
62
+ onClearAllFiltersClick: dsPropsHelpers.PropTypes.func.description('Callback for Clear Al Filters option.'),
63
+ onDropdownMenuClickOutside: dsPropsHelpers.PropTypes.func.description('Callback triggered when clicking outside DropdownMenu.'),
64
+ onDropdownMenuTriggerClick: dsPropsHelpers.PropTypes.func.description('Callback triggered when clicking DropdownMenu ellipsis.'),
60
65
  extraOptions: dsPropsHelpers.PropTypes.arrayOf(dsPropsHelpers.PropTypes.shape({
61
66
  type: dsPropsHelpers.PropTypes.string,
62
67
  id: dsPropsHelpers.PropTypes.string,
@@ -41,32 +41,44 @@ var styled__default = /*#__PURE__*/_interopDefaultLegacy(styled$1);
41
41
  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; }
42
42
 
43
43
  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__default["default"](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; }
44
+ const disabledCaret = /*#__PURE__*/styled$1.css(["cursor:not-allowed;svg{fill:", ";}"], _ref => {
45
+ let {
46
+ theme
47
+ } = _ref;
48
+ return theme.colors.neutral['400'];
49
+ });
44
50
  const StyledSpan = /*#__PURE__*/styled__default["default"].span.withConfig({
45
51
  componentId: "sc-1xp824d-0"
46
- })(["cursor:pointer;box-sizing:border-box;outline:none;display:flex;justify-content:center;align-items:center;"]);
52
+ })(["cursor:pointer;box-sizing:border-box;outline:none;display:flex;justify-content:center;align-items:center;", ""], _ref2 => {
53
+ let {
54
+ disabled
55
+ } = _ref2;
56
+ return disabled && disabledCaret;
57
+ });
47
58
  const expandRowColumn = {
48
59
  // Build our expander column
49
60
  id: 'expander',
50
61
  // Make sure it has an ID
51
62
  accessor: 'expandRowColumn',
52
- Header: _ref => {
63
+ Header: _ref3 => {
53
64
  let {
54
65
  ctx
55
- } = _ref;
66
+ } = _ref3;
56
67
  const {
57
68
  tableProps: {
58
69
  expandedRows,
59
- onRowExpand
70
+ onRowExpand,
71
+ disabledRows
60
72
  },
61
73
  allDataFlattened
62
74
  } = ctx;
63
75
  const allExpandable = React.useMemo(() => {
64
76
  const expandable = {};
65
77
  allDataFlattened.forEach(row => {
66
- if (row.original.subRows || row.original.tableRowDetails || row.original.dimsumHeaderValue) expandable[row.uid] = true;
78
+ if (!disabledRows[row.uid] && (row.original.subRows || row.original.tableRowDetails || row.original.dimsumHeaderValue)) expandable[row.uid] = true;
67
79
  });
68
80
  return expandable;
69
- }, [allDataFlattened]);
81
+ }, [allDataFlattened, disabledRows]);
70
82
  const isAllRowsExpanded = React.useMemo(() => Object.keys(allExpandable).length === Object.keys(expandedRows).length, [allExpandable, expandedRows]);
71
83
  const onExpandedAllHandler = React.useCallback(() => {
72
84
  if (isAllRowsExpanded) onRowExpand({}, 'All');else onRowExpand(_objectSpread({}, allExpandable), 'All');
@@ -114,19 +126,20 @@ const expandRowColumn = {
114
126
  }
115
127
  }, void 0, GlobalExpandIcon));
116
128
  },
117
- Cell: _ref2 => {
129
+ Cell: _ref4 => {
118
130
  let {
119
131
  cell,
120
132
  row,
121
133
  isRowSelected,
122
134
  ctx,
123
135
  draggableProps
124
- } = _ref2;
136
+ } = _ref4;
125
137
  const {
126
138
  tableProps: {
127
139
  dragAndDropRows,
128
140
  expandedRows,
129
- onRowExpand
141
+ onRowExpand,
142
+ disabledRows
130
143
  }
131
144
  } = ctx;
132
145
  const uniqueId = row.uid;
@@ -160,7 +173,7 @@ const expandRowColumn = {
160
173
  role: 'button',
161
174
  key: `${row.uid}-expand-button`,
162
175
  title: 'Toggle Row Expanded',
163
- onClick: onRowExpandHandler,
176
+ onClick: !disabledRows[row.uid] ? onRowExpandHandler : undefined,
164
177
  onKeyDown: e => {
165
178
  if (['Enter', 'Space'].includes(e.code)) {
166
179
  e.preventDefault();
@@ -168,11 +181,12 @@ const expandRowColumn = {
168
181
  }
169
182
  },
170
183
  ref: cell.ref,
171
- tabIndex: isRowSelected ? 0 : -1,
184
+ tabIndex: isRowSelected || disabledRows[row.uid] ? 0 : -1,
172
185
  'data-testid': 'data-table-row-expand-cell',
173
186
  'aria-expanded': isExpanded,
174
- isRightArrow: !isExpanded || isDragging || isDragOverlay
175
- }), [row.uid, onRowExpandHandler, cell.ref, isRowSelected, isExpanded, isDragging, isDragOverlay]);
187
+ isRightArrow: !isExpanded || isDragging || isDragOverlay,
188
+ disabled: disabledRows[row.uid]
189
+ }), [row.uid, disabledRows, onRowExpandHandler, cell.ref, isRowSelected, isExpanded, isDragging, isDragOverlay]);
176
190
  const PureCaretIcon = React.useMemo(() => isExpanded && !isDragging && !isDragOverlay ? /*#__PURE__*/_jsx__default["default"](dsIcons.ArrowheadDown, {
177
191
  "data-is-col-expanded": isExpanded,
178
192
  "data-role": "row-expander-col",
@@ -18,7 +18,6 @@ require('@elliemae/ds-popperjs');
18
18
  require('styled-components');
19
19
  require('../../../redux/reducers/index.js');
20
20
  require('../../../configs/constants.js');
21
- require('react/jsx-runtime');
22
21
  var EditableCell = require('../../../exported-related/EditableCell.js');
23
22
  require('@elliemae/ds-icons');
24
23
  require('@elliemae/ds-utilities');
@@ -27,6 +26,7 @@ require('../../../configs/useRowFlattenization.js');
27
26
  require('core-js/modules/esnext.async-iterator.map.js');
28
27
  require('core-js/modules/esnext.iterator.map.js');
29
28
  require('../../../styled.js');
29
+ require('react/jsx-runtime');
30
30
  require('@elliemae/ds-form');
31
31
  require('../../../parts/TableContent.js');
32
32
  require('@elliemae/ds-grid');
@@ -15,7 +15,6 @@ require('@elliemae/ds-popperjs');
15
15
  require('styled-components');
16
16
  require('../../../redux/reducers/index.js');
17
17
  require('../../../configs/constants.js');
18
- require('react/jsx-runtime');
19
18
  var EditableCell = require('../../../exported-related/EditableCell.js');
20
19
  require('@elliemae/ds-icons');
21
20
  require('@elliemae/ds-utilities');
@@ -26,6 +25,7 @@ require('../../../configs/useRowFlattenization.js');
26
25
  require('core-js/modules/esnext.async-iterator.map.js');
27
26
  require('core-js/modules/esnext.iterator.map.js');
28
27
  require('../../../styled.js');
28
+ require('react/jsx-runtime');
29
29
  require('@elliemae/ds-form');
30
30
  require('../../../parts/TableContent.js');
31
31
  require('@elliemae/ds-grid');
@@ -15,7 +15,6 @@ require('@elliemae/ds-button');
15
15
  require('@elliemae/ds-popperjs');
16
16
  require('../../../redux/reducers/index.js');
17
17
  require('../../../configs/constants.js');
18
- require('react/jsx-runtime');
19
18
  var EditableCell = require('../../../exported-related/EditableCell.js');
20
19
  require('@elliemae/ds-icons');
21
20
  require('@elliemae/ds-utilities');
@@ -26,6 +25,7 @@ require('../../../configs/useRowFlattenization.js');
26
25
  require('core-js/modules/esnext.async-iterator.map.js');
27
26
  require('core-js/modules/esnext.iterator.map.js');
28
27
  require('../../../styled.js');
28
+ require('react/jsx-runtime');
29
29
  require('@elliemae/ds-form');
30
30
  require('../../../parts/TableContent.js');
31
31
  require('@elliemae/ds-grid');
@@ -21,6 +21,9 @@ require('core-js/modules/esnext.set.reduce.js');
21
21
  require('core-js/modules/esnext.set.some.js');
22
22
  require('core-js/modules/esnext.set.symmetric-difference.js');
23
23
  require('core-js/modules/esnext.set.union.js');
24
+ require('core-js/modules/esnext.async-iterator.filter.js');
25
+ require('core-js/modules/esnext.iterator.constructor.js');
26
+ require('core-js/modules/esnext.iterator.filter.js');
24
27
  var React = require('react');
25
28
  var Grid = require('@elliemae/ds-grid');
26
29
  var dsControlledForm = require('@elliemae/ds-controlled-form');
@@ -33,9 +36,6 @@ require('styled-components');
33
36
  require('@elliemae/ds-button');
34
37
  require('@elliemae/ds-utilities');
35
38
  var constants = require('../../../../configs/constants.js');
36
- require('core-js/modules/esnext.async-iterator.filter.js');
37
- require('core-js/modules/esnext.iterator.constructor.js');
38
- require('core-js/modules/esnext.iterator.filter.js');
39
39
  require('core-js/modules/esnext.async-iterator.reduce.js');
40
40
  require('core-js/modules/esnext.iterator.reduce.js');
41
41
  require('react-virtual');
@@ -55,6 +55,8 @@ require('../../../../exported-related/Filters/applyOutOfTheBoxFilters.js');
55
55
  require('moment');
56
56
  require('core-js/modules/esnext.async-iterator.some.js');
57
57
  require('core-js/modules/esnext.iterator.some.js');
58
+ require('../../../../redux/reducers/index.js');
59
+ var useDispatchHeadersActions = require('../../../../redux/reducers/headersReducers/useDispatchHeadersActions.js');
58
60
 
59
61
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
60
62
 
@@ -69,7 +71,8 @@ const BaseSelectFilter = props => {
69
71
  type,
70
72
  column: {
71
73
  id,
72
- filterOptions: userFilterOptions
74
+ filterOptions: userFilterOptions,
75
+ filterMinWidth
73
76
  },
74
77
  ctx: {
75
78
  tableProps: {
@@ -80,10 +83,13 @@ const BaseSelectFilter = props => {
80
83
  innerRef,
81
84
  onValueChange
82
85
  } = props;
86
+ const {
87
+ patchHeaderFilterButtonAndMenu
88
+ } = useDispatchHeadersActions.useDispatchHeadersActions();
83
89
  const filterOptions = React.useMemo(() => {
84
90
  // If the user didn't provide options, use the available ones
85
91
  if (!userFilterOptions) {
86
- const automaticFilters = [...new Set(data.map(datum => datum[id].toString()))].map(item => ({
92
+ const automaticFilters = [...new Set(data.filter(datum => !!datum[id]).map(datum => datum[id].toString()))].map(item => ({
87
93
  type: 'option',
88
94
  dsId: item,
89
95
  value: item,
@@ -100,6 +106,7 @@ const BaseSelectFilter = props => {
100
106
 
101
107
  const handleOnChange = value => {
102
108
  onValueChange(type, value);
109
+ if (!isMulti) patchHeaderFilterButtonAndMenu(column.id, true);
103
110
  };
104
111
 
105
112
  const [filters, setFilteredOptions] = React.useState(filterOptions);
@@ -111,7 +118,8 @@ const BaseSelectFilter = props => {
111
118
  "data-testid": isMulti ? constants.DATA_TESTID.DATA_TABLE_MULTISELECT_CONTROLLER : constants.DATA_TESTID.DATA_TABLE_SINGLESELECT_CONTROLLER,
112
119
  style: {
113
120
  background: '#fff',
114
- position: 'relative'
121
+ position: 'relative',
122
+ width: filterMinWidth
115
123
  }
116
124
  }, void 0, /*#__PURE__*/_jsx__default["default"](dsControlledForm.DSComboBox, {
117
125
  inline: true,
@@ -16,9 +16,9 @@ require('@elliemae/ds-popperjs');
16
16
  require('styled-components');
17
17
  require('../../../../redux/reducers/index.js');
18
18
  var constants = require('../../../../configs/constants.js');
19
- require('react/jsx-runtime');
20
19
  require('../../../../styled.js');
21
20
  require('../../../../DataTableContext.js');
21
+ require('react/jsx-runtime');
22
22
  require('@elliemae/ds-icons');
23
23
  require('@elliemae/ds-utilities');
24
24
  require('core-js/modules/esnext.async-iterator.reduce.js');
@@ -16,9 +16,9 @@ require('@elliemae/ds-popperjs');
16
16
  require('styled-components');
17
17
  require('../../../../redux/reducers/index.js');
18
18
  var constants = require('../../../../configs/constants.js');
19
- require('react/jsx-runtime');
20
19
  require('../../../../styled.js');
21
20
  require('../../../../DataTableContext.js');
21
+ require('react/jsx-runtime');
22
22
  require('@elliemae/ds-icons');
23
23
  require('@elliemae/ds-utilities');
24
24
  require('core-js/modules/esnext.async-iterator.reduce.js');
@@ -54,7 +54,11 @@ const useDatatableConfig = props => {
54
54
  // Layout config
55
55
  // ===========================================================================
56
56
 
57
- const [gridLayout, setGridLayout] = React.useState(columnsToGrid.columnsToGrid(visibleColumns, props.colsLayoutStyle));
57
+ const [gridLayout, setGridLayout] = React.useState(columnsToGrid.columnsToGrid(visibleColumns, props.colsLayoutStyle)); // We need to listen and update the state based on this props
58
+
59
+ React.useEffect(() => {
60
+ setGridLayout(columnsToGrid.columnsToGrid(visibleColumns, props.colsLayoutStyle));
61
+ }, [visibleColumns, props.colsLayoutStyle]);
58
62
  const totalColumnsWidth = React.useMemo(() => props.colsLayoutStyle === constants.ColsLayoutStyle.Fixed ? gridLayout.reduce((acc, cur) => acc + Number.parseInt(cur, 10), 0) : '100%', [props.colsLayoutStyle, gridLayout]);
59
63
  const layoutHelpers = React.useMemo(() => ({
60
64
  gridLayout,
@@ -18,8 +18,7 @@ const EditableCell = props => {
18
18
  StandardRender,
19
19
  EditableRenderer,
20
20
  cell,
21
- isRowSelected,
22
- setValue
21
+ isRowSelected
23
22
  } = props;
24
23
  const {
25
24
  virtualListHelpers
@@ -15,7 +15,6 @@ var dsPopperjs = require('@elliemae/ds-popperjs');
15
15
  var styled = require('styled-components');
16
16
  require('../redux/reducers/index.js');
17
17
  var constants = require('../configs/constants.js');
18
- var jsxRuntime = require('react/jsx-runtime');
19
18
  var useDispatchHeadersActions = require('../redux/reducers/headersReducers/useDispatchHeadersActions.js');
20
19
 
21
20
  function _interopDefaultLegacy (e) { return e && typeof e === 'object' && 'default' in e ? e : { 'default': e }; }
@@ -36,7 +35,22 @@ const Button = /*#__PURE__*/styled__default["default"](DSButton.DSButton).withCo
36
35
  const PopperContent = /*#__PURE__*/styled__default["default"].div.withConfig({
37
36
  componentId: "sc-16i88ut-2"
38
37
  })(["background-color:#fff;"]);
39
- const FilterPopover = _ref2 => {
38
+
39
+ const ButtonTrap = _ref2 => {
40
+ let {
41
+ cb
42
+ } = _ref2;
43
+ return /*#__PURE__*/_jsx__default["default"]("span", {
44
+ "aria-hidden": "true",
45
+ tabIndex: 0,
46
+ onFocus: e => {
47
+ e.stopPropagation();
48
+ cb();
49
+ }
50
+ });
51
+ };
52
+
53
+ const FilterPopover = _ref3 => {
40
54
  let {
41
55
  column,
42
56
  columnId,
@@ -48,7 +62,7 @@ const FilterPopover = _ref2 => {
48
62
  innerRef,
49
63
  ariaLabel,
50
64
  customStyles
51
- } = _ref2;
65
+ } = _ref3;
52
66
  const {
53
67
  hideFilterButton,
54
68
  hideFilterMenu
@@ -56,7 +70,6 @@ const FilterPopover = _ref2 => {
56
70
  hideFilterButton: true,
57
71
  hideFilterMenu: true
58
72
  };
59
- const popperRef = React.useRef(null);
60
73
  const {
61
74
  patchHeaderFilterButtonAndMenu,
62
75
  patchHeader
@@ -87,6 +100,13 @@ const FilterPopover = _ref2 => {
87
100
  };
88
101
 
89
102
  const [referenceElement, setReferenceElement] = React.useState(null);
103
+ const buttonTrapCallback = React.useCallback(() => {
104
+ patchHeader(columnId, {
105
+ hideFilterMenu: true,
106
+ hideFilterButton: false
107
+ });
108
+ referenceElement?.focus();
109
+ }, [columnId, patchHeader, referenceElement]);
90
110
  return /*#__PURE__*/_jsx__default["default"]("div", {
91
111
  // This is here to prevent propagation, and not trigger the sort functionality
92
112
  onClick: e => e.stopPropagation(),
@@ -109,11 +129,6 @@ const FilterPopover = _ref2 => {
109
129
  },
110
130
  style: {
111
131
  display: 'flex'
112
- },
113
- onBlur: e => {
114
- if (e.target !== referenceElement && !popperRef.current?.contains(e.relatedTarget)) {
115
- referenceElement?.focus();
116
- }
117
132
  }
118
133
  }, void 0, /*#__PURE__*/_jsx__default["default"](FilterButton, {
119
134
  hide: !isIconVisible,
@@ -145,24 +160,11 @@ const FilterPopover = _ref2 => {
145
160
  minWidth: column.ref?.current?.offsetWidth ?? '0px'
146
161
  }),
147
162
  placementOrderPreference: ['bottom-end']
148
- }, void 0, /*#__PURE__*/jsxRuntime.jsx(PopperContent, {
149
- onKeyDown: e => {
150
- if (e.code === 'Tab') {
151
- setTimeout(() => {
152
- if (!popperRef?.current?.contains(document.activeElement)) {
153
- patchHeader(columnId, {
154
- hideFilterMenu: true,
155
- hideFilterButton: false
156
- });
157
- e.preventDefault();
158
- referenceElement.focus();
159
- }
160
- });
161
- }
162
- },
163
- ref: popperRef,
164
- children: menuContent
165
- })));
163
+ }, void 0, /*#__PURE__*/_jsx__default["default"](PopperContent, {}, void 0, /*#__PURE__*/_jsx__default["default"](ButtonTrap, {
164
+ cb: buttonTrapCallback
165
+ }), menuContent, /*#__PURE__*/_jsx__default["default"](ButtonTrap, {
166
+ cb: buttonTrapCallback
167
+ }))));
166
168
  };
167
169
 
168
170
  exports.FilterPopover = FilterPopover;
@@ -100,12 +100,18 @@ const DefaultRowContentRenderer = props => {
100
100
 
101
101
  return padding;
102
102
  }, [row.depth, visibleColumns]);
103
+ const handleSelectDisableRow = React.useCallback(e => {
104
+ if (disabledRows[row.uid]) {
105
+ e.preventDefault();
106
+ e.stopPropagation();
107
+ }
108
+ }, [disabledRows, row.uid]);
103
109
  const PureRowContent = React.useMemo(() => {
104
110
  const DetailsView = row.original.tableRowDetails;
105
111
  return /*#__PURE__*/jsxRuntime.jsxs(jsxRuntime.Fragment, {
106
112
  children: [/*#__PURE__*/jsxRuntime.jsx(styled.StyledCellContainer, _objectSpread(_objectSpread({
107
113
  ref: rowRef,
108
- tabIndex: 0,
114
+ tabIndex: disabledRows[row.uid] ? -1 : 0,
109
115
  role: "row",
110
116
  "aria-rowindex": row.realIndex + 1,
111
117
  "aria-label": ariaLabelMessage(row, selection?.[row.uid] === true),
@@ -124,6 +130,7 @@ const DefaultRowContentRenderer = props => {
124
130
  selected: noSelectionColumn && selection?.[row.uid] === true,
125
131
  disabled: disabledRows[row.uid],
126
132
  "data-testid": constants.DATA_TESTID.DATA_TABLE_ROW_CONTENT,
133
+ onMouseDown: handleSelectDisableRow,
127
134
  children: /*#__PURE__*/_jsx__default["default"](index$1, {
128
135
  row: row,
129
136
  isRowSelected: selectedRowId === row.uid,
@@ -134,7 +141,7 @@ const DefaultRowContentRenderer = props => {
134
141
  detailsIndent: detailsIndent
135
142
  }))]
136
143
  });
137
- }, [row, selection, isExpandable, expandedRows, disabledRows, gridTemplateColProps, backgroundColor, compact, dropIndicatorPosition, isDndActive, isDragging, isDragOverlay, noSelectionColumn, selectedRowId, detailsIndent]);
144
+ }, [row, disabledRows, selection, isExpandable, expandedRows, gridTemplateColProps, backgroundColor, compact, dropIndicatorPosition, isDndActive, isDragging, isDragOverlay, noSelectionColumn, handleSelectDisableRow, selectedRowId, detailsIndent]);
138
145
  return PureRowContent;
139
146
  };
140
147
 
@@ -48,12 +48,26 @@ const useRowRendererHandlers = _ref => {
48
48
  const {
49
49
  tableProps: {
50
50
  onRowClick,
51
- onRowFocus
51
+ onRowFocus,
52
+ disabledRows
52
53
  },
53
54
  virtualListHelpers: {
54
55
  scrollToIndex
55
56
  }
56
57
  } = React.useContext(DataTableContext["default"]);
58
+
59
+ const isOptionFocuseable = opt => !disabledRows[opt.uid];
60
+
61
+ const findInCircularList = function (list, from, criteria) {
62
+ let step = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 1;
63
+
64
+ for (let i = (from + step + list.length) % list.length; i !== from && from > -1; i = (i + step + list.length) % list.length) {
65
+ if (criteria(list[i])) return i;
66
+ }
67
+
68
+ return from; // return same item
69
+ };
70
+
57
71
  const {
58
72
  setSelectedRowId,
59
73
  setFocusedRowId
@@ -64,6 +78,7 @@ const useRowRendererHandlers = _ref => {
64
78
  uid
65
79
  } = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : row;
66
80
  // setSelectedRowId(null);
81
+ if (disabledRows[uid]) return;
67
82
  onRowClick(original, e, uid);
68
83
  onRowFocus({
69
84
  itemIndex,
@@ -75,7 +90,7 @@ const useRowRendererHandlers = _ref => {
75
90
  },
76
91
  original
77
92
  }, e);
78
- }, [row, onRowClick, onRowFocus, itemIndex, scrollToIndex]);
93
+ }, [row, disabledRows, onRowClick, onRowFocus, itemIndex, scrollToIndex]);
79
94
  const isActive = draggableProps && draggableProps.active;
80
95
  const handleKeyDown = React.useCallback(e => {
81
96
  if (isDragOverlay || isActive) {
@@ -102,24 +117,27 @@ const useRowRendererHandlers = _ref => {
102
117
 
103
118
  if (e.code === 'ArrowDown') {
104
119
  e.preventDefault();
105
- if (itemIndex + 1 < items.length) setFocusedRowId(items[itemIndex + 1].uid);
120
+ e.stopPropagation();
121
+ const next = findInCircularList(items, itemIndex, isOptionFocuseable);
122
+ setFocusedRowId(items[next].uid);
106
123
  }
107
124
 
108
125
  if (e.code === 'ArrowUp') {
109
126
  e.preventDefault();
110
- if (itemIndex - 1 >= 0) setFocusedRowId(items[itemIndex - 1].uid);
127
+ const prev = findInCircularList(items, itemIndex, isOptionFocuseable, -1);
128
+ setFocusedRowId(items[prev].uid);
111
129
  }
112
- }, [isDragOverlay, isActive, selectedRowId, row, setSelectedRowId, handleItemClick, itemIndex, items, setFocusedRowId]);
130
+ }, [isDragOverlay, isActive, selectedRowId, row, setSelectedRowId, handleItemClick, items, itemIndex, isOptionFocuseable, setFocusedRowId]);
113
131
  const handleOnBlur = React.useCallback(e => {
114
132
  if (e.relatedTarget?.getAttribute('data-testid') === 'data-table-row-content') {
115
133
  setSelectedRowId(null);
116
134
  }
117
135
  }, [setSelectedRowId]);
118
136
  const handleOnFocus = React.useCallback(e => {
119
- if (e.target && e.target.getAttribute('data-testid') === constants.DATA_TESTID.DATA_TABLE_ROW_CONTENT) {
137
+ if (!disabledRows[row.uid] && e.target && e.target.getAttribute('data-testid') === constants.DATA_TESTID.DATA_TABLE_ROW_CONTENT) {
120
138
  setFocusedRowId(row.uid);
121
139
  }
122
- }, [row.uid, setFocusedRowId]);
140
+ }, [row.uid, setFocusedRowId, disabledRows]);
123
141
  return {
124
142
  handleItemClick,
125
143
  handleKeyDown,
@@ -55,22 +55,15 @@ const Toolbar = _ref => {
55
55
  children
56
56
  } = _ref;
57
57
  const [show, setShow] = React.useState(false);
58
- const [clicked, setClicked] = React.useState(false);
59
58
  const toolbarRef = React.useRef(null);
60
- const handleOnClickOutside = React.useCallback(() => {
61
- setShow(false);
62
- setClicked(false);
63
- }, []);
64
- const handleOnClick = React.useCallback(() => {
65
- setShow(true);
66
- setClicked(true);
67
- }, []);
59
+ const handleOnClickOutside = React.useCallback(() => setShow(false), []);
60
+ const handleOnClick = React.useCallback(() => setShow(true), []);
68
61
  dsUtilities.useOnClickOutside(toolbarRef, handleOnClickOutside);
69
62
  return /*#__PURE__*/jsxRuntime.jsx(ToolbarPosition, {
70
63
  ref: toolbarRef,
71
64
  children: /*#__PURE__*/_jsx__default["default"](ToolbarWrapper, {
72
65
  onMouseEnter: () => setShow(true),
73
- onMouseLeave: () => setShow(clicked)
66
+ onMouseLeave: () => setShow(false)
74
67
  }, void 0, show && /*#__PURE__*/_jsx__default["default"](ToolbarBtns, {}, void 0, children), /*#__PURE__*/_jsx__default["default"](DSButton__default["default"], {
75
68
  buttonType: "text",
76
69
  className: "toolbar-trigger",
@@ -71,7 +71,8 @@ const Cell = _ref2 => {
71
71
  const ctx = React.useContext(DataTableContext["default"]);
72
72
  const {
73
73
  tableProps: {
74
- cellRendererProps
74
+ cellRendererProps,
75
+ disabledRows
75
76
  }
76
77
  } = ctx;
77
78
  const {
@@ -120,7 +121,7 @@ const Cell = _ref2 => {
120
121
  return null;
121
122
  }, [DefaultCellContentJSX, cellProps, column]);
122
123
  return /*#__PURE__*/jsxRuntime.jsx(PureStandardCell, _objectSpread(_objectSpread({}, cellProps), {}, {
123
- children: column.editable ? EditableContentJSX : DefaultCellContentJSX
124
+ children: column.editable && !disabledRows[row.uid] ? EditableContentJSX : DefaultCellContentJSX
124
125
  }));
125
126
  };
126
127
 
@@ -20,9 +20,9 @@ require('@elliemae/ds-popperjs');
20
20
  require('styled-components');
21
21
  require('../../redux/reducers/index.js');
22
22
  var constants = require('../../configs/constants.js');
23
- require('react/jsx-runtime');
24
23
  require('../../styled.js');
25
24
  var DataTableContext = require('../../DataTableContext.js');
25
+ require('react/jsx-runtime');
26
26
  require('@elliemae/ds-utilities');
27
27
  require('core-js/modules/esnext.async-iterator.reduce.js');
28
28
  require('core-js/modules/esnext.iterator.reduce.js');
@@ -76,6 +76,7 @@ const FiltersBar = () => {
76
76
  },
77
77
  visibleColumns
78
78
  } = React.useContext(DataTableContext["default"]);
79
+ const [isOpen, setIsOpen] = React.useState(false);
79
80
  const pillGroupRefs = React.useMemo(() => {
80
81
  const refs = [];
81
82
 
@@ -86,7 +87,29 @@ const FiltersBar = () => {
86
87
  const dropdownMenuRef = React.useRef(null);
87
88
  const removeAllFilters = React.useCallback(() => {
88
89
  onFiltersChange([]);
89
- }, [onFiltersChange]);
90
+ filterBarProps?.onClearAllFiltersClick?.();
91
+ }, [onFiltersChange, filterBarProps?.onClearAllFiltersClick]);
92
+ const onFilterBarClose = React.useCallback(() => {
93
+ filterBarProps?.onDropdownMenuToggle?.(false, 'onClose');
94
+ setIsOpen(false);
95
+ }, [filterBarProps?.onDropdownMenuToggle]);
96
+ const onFilterBarOpen = React.useCallback(() => {
97
+ filterBarProps?.onDropdownMenuToggle?.(true, 'onOpen');
98
+ setIsOpen(true);
99
+ }, [filterBarProps?.onDropdownMenuToggle]);
100
+ const onFilterBarOnClickOutside = React.useCallback(() => {
101
+ filterBarProps?.onDropdownMenuToggle?.(false, 'onClickOutside');
102
+ filterBarProps?.onDropdownMenuClickOutside?.();
103
+ setIsOpen(false);
104
+ }, [filterBarProps?.onDropdownMenuToggle, filterBarProps?.onDropdownMenuClickOutside]);
105
+ const onTriggerClick = React.useCallback(() => {
106
+ filterBarProps?.onDropdownMenuTriggerClick?.();
107
+ onFilterBarOpen();
108
+ }, [filterBarProps?.onDropdownMenuTriggerClick]);
109
+ const finalIsOpen = React.useMemo(() => {
110
+ if (typeof filterBarProps?.isDropdownMenuOpen === 'boolean') return filterBarProps.isDropdownMenuOpen;
111
+ return isOpen;
112
+ }, [filterBarProps?.isDropdownMenuOpen, isOpen]);
90
113
  return /*#__PURE__*/_jsx__default["default"](styled.StyledWrapper, {
91
114
  width: width,
92
115
  "aria-live": "polite",
@@ -122,6 +145,9 @@ const FiltersBar = () => {
122
145
  }, column);
123
146
  }), /*#__PURE__*/_jsx__default["default"](styled.StyledDropdownMenu, {
124
147
  preventOverflow: "scrollParent",
148
+ isOpen: finalIsOpen,
149
+ onClose: onFilterBarClose,
150
+ onClickOutsideMenu: onFilterBarOnClickOutside,
125
151
  options: [{
126
152
  id: '__internal__option__clear__filters',
127
153
  label: 'Clear Filters',
@@ -133,6 +159,7 @@ const FiltersBar = () => {
133
159
  },
134
160
  buttonType: "text",
135
161
  innerRef: dropdownMenuRef,
162
+ onClick: onTriggerClick,
136
163
  icon: _MoreOptionsVert || (_MoreOptionsVert = /*#__PURE__*/_jsx__default["default"](dsIcons.MoreOptionsVert, {}))
137
164
  })
138
165
  }));
@@ -25,9 +25,9 @@ require('@elliemae/ds-popperjs');
25
25
  require('styled-components');
26
26
  require('../../redux/reducers/index.js');
27
27
  require('../../configs/constants.js');
28
- var jsxRuntime = require('react/jsx-runtime');
29
28
  require('../../styled.js');
30
29
  require('../../DataTableContext.js');
30
+ var jsxRuntime = require('react/jsx-runtime');
31
31
  require('@elliemae/ds-icons');
32
32
  require('@elliemae/ds-utilities');
33
33
  require('core-js/modules/esnext.async-iterator.reduce.js');