@react-fabric/data 1.0.0-beta.6 → 1.0.0-beta.61

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 (104) hide show
  1. package/{src/histogram/Histogram.module.css → css/_histogram.css} +16 -13
  2. package/{dist/esm/tree/types.js → css/styles.css} +2 -7
  3. package/dist/cjs/checklist/CheckList.js +27 -4
  4. package/dist/cjs/histogram/Histogram.js +39 -9
  5. package/dist/cjs/hooks/useFilteredList.js +88 -10
  6. package/dist/cjs/hooks/usePagination.js +27 -4
  7. package/dist/cjs/hooks/useSelectableList.js +29 -0
  8. package/dist/cjs/i18n/ar.json.js +8 -1
  9. package/dist/cjs/i18n/en.json.js +8 -1
  10. package/dist/cjs/json/JsonViewer.js +68 -28
  11. package/dist/cjs/pagination/Pagination.js +14 -4
  12. package/dist/cjs/table/AddColumn.js +3 -3
  13. package/dist/cjs/table/BodyCell.js +14 -6
  14. package/dist/cjs/table/BodyRow.js +4 -4
  15. package/dist/cjs/table/CheckboxCell.js +2 -2
  16. package/dist/cjs/table/ColumnFilters.js +97 -0
  17. package/dist/cjs/table/HeaderCell.js +71 -43
  18. package/dist/cjs/table/Table.js +62 -13
  19. package/dist/cjs/table/types.js +29 -0
  20. package/dist/cjs/table/useResizer.js +4 -4
  21. package/dist/cjs/table/useVirtualTable.js +127 -19
  22. package/dist/cjs/tree/TreeNode.js +50 -32
  23. package/dist/cjs/tree/TreePanel.js +52 -19
  24. package/dist/cjs/tree/useTree.js +199 -38
  25. package/dist/cjs/tree/utils.js +39 -12
  26. package/dist/cjs/virtual/Gallery.js +97 -45
  27. package/dist/cjs/virtual/List.js +93 -39
  28. package/dist/cjs/virtual/Scroller.js +16 -8
  29. package/dist/esm/checklist/CheckList.js +28 -5
  30. package/dist/esm/histogram/Histogram.js +41 -11
  31. package/dist/esm/hooks/useFilteredList.js +89 -11
  32. package/dist/esm/hooks/usePagination.js +27 -4
  33. package/dist/esm/hooks/useSelectableList.js +29 -0
  34. package/dist/esm/i18n/ar.json.js +8 -2
  35. package/dist/esm/i18n/en.json.js +8 -2
  36. package/dist/esm/json/JsonViewer.js +69 -29
  37. package/dist/esm/pagination/Pagination.js +15 -5
  38. package/dist/esm/table/AddColumn.js +4 -4
  39. package/dist/esm/table/BodyCell.js +15 -7
  40. package/dist/esm/table/BodyRow.js +4 -4
  41. package/dist/esm/table/CheckboxCell.js +3 -3
  42. package/dist/esm/table/ColumnFilters.js +97 -0
  43. package/dist/esm/table/HeaderCell.js +72 -44
  44. package/dist/esm/table/Table.js +63 -14
  45. package/dist/esm/table/types.js +29 -0
  46. package/dist/esm/table/useResizer.js +4 -4
  47. package/dist/esm/table/useVirtualTable.js +129 -21
  48. package/dist/esm/tree/TreeNode.js +53 -35
  49. package/dist/esm/tree/TreePanel.js +54 -21
  50. package/dist/esm/tree/useTree.js +202 -41
  51. package/dist/esm/tree/utils.js +40 -13
  52. package/dist/esm/virtual/Gallery.js +97 -45
  53. package/dist/esm/virtual/List.js +93 -39
  54. package/dist/esm/virtual/Scroller.js +17 -9
  55. package/dist/types/checklist/CheckList.d.ts +22 -0
  56. package/dist/types/histogram/Histogram.d.ts +28 -1
  57. package/dist/types/hooks/useFilteredList.d.ts +66 -5
  58. package/dist/types/hooks/usePagination.d.ts +19 -0
  59. package/dist/types/hooks/useSelectableList.d.ts +29 -0
  60. package/dist/types/json/JsonViewer.d.ts +27 -2
  61. package/dist/types/pagination/Pagination.d.ts +10 -1
  62. package/dist/types/table/ColumnFilters.d.ts +9 -0
  63. package/dist/types/table/HeaderCell.d.ts +1 -1
  64. package/dist/types/table/Table.d.ts +14 -1
  65. package/dist/types/table/types.d.ts +46 -7
  66. package/dist/types/table/useVirtualTable.d.ts +23 -9
  67. package/dist/types/tree/TreeNode.d.ts +1 -1
  68. package/dist/types/tree/TreePanel.d.ts +42 -1
  69. package/dist/types/tree/types.d.ts +65 -21
  70. package/dist/types/tree/useTree.d.ts +9 -10
  71. package/dist/types/tree/utils.d.ts +10 -3
  72. package/dist/types/virtual/Gallery.d.ts +42 -3
  73. package/dist/types/virtual/List.d.ts +42 -3
  74. package/package.json +16 -14
  75. package/src/checklist/CheckList.tsx +39 -7
  76. package/src/histogram/Histogram.tsx +43 -19
  77. package/src/hooks/useFilteredList.tsx +109 -9
  78. package/src/hooks/usePagination.tsx +32 -7
  79. package/src/hooks/useSelectableList.ts +29 -0
  80. package/src/i18n/ar.json +5 -0
  81. package/src/i18n/en.json +5 -0
  82. package/src/json/JsonViewer.tsx +76 -37
  83. package/src/pagination/Pagination.tsx +15 -5
  84. package/src/table/AddColumn.tsx +4 -4
  85. package/src/table/BodyCell.tsx +24 -7
  86. package/src/table/BodyRow.tsx +7 -4
  87. package/src/table/CheckboxCell.tsx +5 -5
  88. package/src/table/ColumnFilters.tsx +105 -0
  89. package/src/table/HeaderCell.tsx +74 -21
  90. package/src/table/Table.tsx +107 -12
  91. package/src/table/types.ts +49 -10
  92. package/src/table/useResizer.ts +5 -3
  93. package/src/table/useVirtualTable.ts +158 -27
  94. package/src/tree/TreeNode.tsx +96 -62
  95. package/src/tree/TreePanel.tsx +88 -22
  96. package/src/tree/types.ts +73 -23
  97. package/src/tree/useTree.ts +220 -44
  98. package/src/tree/utils.ts +58 -20
  99. package/src/virtual/Gallery.tsx +118 -54
  100. package/src/virtual/List.tsx +99 -39
  101. package/src/virtual/Scroller.tsx +25 -9
  102. package/dist/cjs/histogram/Histogram.module.css +0 -1
  103. package/dist/cjs/tree/types.js +0 -30
  104. package/dist/esm/histogram/Histogram.module.css +0 -1
@@ -3,6 +3,7 @@
3
3
  var _defineProperty = require('@babel/runtime/helpers/defineProperty');
4
4
  var core = require('@react-fabric/core');
5
5
  var utilities = require('@react-fabric/utilities');
6
+ var classNames = require('classnames');
6
7
  var react = require('react');
7
8
  var reactI18next = require('react-i18next');
8
9
  var AddColumn = require('./AddColumn.js');
@@ -18,23 +19,31 @@ var jsxRuntime = require('react/jsx-runtime');
18
19
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
19
20
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
20
21
  var Table = function Table(_ref) {
21
- var _state$start, _state$cols, _state$end, _items$, _state$start2, _state$cols2, _state$end2;
22
+ var _state$start, _state$cols, _state$end, _items, _state$start2, _state$cols2, _state$end2;
22
23
  var ref = _ref.ref,
23
24
  data = _ref.data,
24
25
  columns = _ref.columns,
25
- keyProperty = _ref.keyProperty,
26
+ _ref$keyProperty = _ref.keyProperty,
27
+ keyProperty = _ref$keyProperty === void 0 ? "id" : _ref$keyProperty,
28
+ groupProperty = _ref.groupProperty,
26
29
  checkableRows = _ref.checkableRows,
27
30
  initialScroll = _ref.initialScroll,
28
31
  hideableColumns = _ref.hideableColumns,
29
32
  sort = _ref.sort,
30
33
  loading = _ref.loading,
34
+ checked = _ref.checked,
31
35
  emptyDisplay = _ref.emptyDisplay,
36
+ groupRenderer = _ref.groupRenderer,
32
37
  canExpand = _ref.canExpand,
33
38
  children = _ref.children,
34
39
  onSort = _ref.onSort,
40
+ onFilter = _ref.onFilter,
35
41
  onScroll = _ref.onScroll,
36
42
  onRowClick = _ref.onRowClick,
37
- onCheckedChanged = _ref.onCheckedChanged;
43
+ onCheckedChanged = _ref.onCheckedChanged,
44
+ _ref$total = _ref.total,
45
+ total = _ref$total === void 0 ? 0 : _ref$total,
46
+ onLoadMore = _ref.onLoadMore;
38
47
  var _useTranslation = reactI18next.useTranslation("data"),
39
48
  t = _useTranslation.t;
40
49
  var fireCheckChanged = core.useDebounce(function (checkedIds) {
@@ -43,17 +52,28 @@ var Table = function Table(_ref) {
43
52
  var _useTableColumns = useTableColumns.useTableColumns(columns),
44
53
  state = _useTableColumns.state,
45
54
  onHide = _useTableColumns.onHide;
46
- var _useVirtualTable = useVirtualTable.useVirtualTable(data, keyProperty, fireCheckChanged),
55
+ var _useVirtualTable = useVirtualTable.useVirtualTable(data, {
56
+ checked: checked,
57
+ keyProperty: keyProperty,
58
+ groupProperty: groupProperty,
59
+ total: total,
60
+ loading: loading,
61
+ onLoadMore: onLoadMore,
62
+ onCheckChanged: fireCheckChanged
63
+ }),
47
64
  scrollerRef = _useVirtualTable.scrollerRef,
48
65
  items = _useVirtualTable.items,
49
66
  top = _useVirtualTable.top,
50
67
  checkState = _useVirtualTable.checkState,
51
68
  virtualizer = _useVirtualTable.virtualizer,
69
+ hasActiveSticky = _useVirtualTable.hasActiveSticky,
52
70
  toggleExpand = _useVirtualTable.toggleExpand,
53
71
  toggleChecked = _useVirtualTable.toggleChecked,
54
72
  toggleAllChecked = _useVirtualTable.toggleAllChecked,
73
+ toggleGroupExpand = _useVirtualTable.toggleGroupExpand,
55
74
  getData = _useVirtualTable.getData,
56
75
  totalSize = _useVirtualTable.totalSize,
76
+ isActiveSticky = _useVirtualTable.isActiveSticky,
57
77
  measureElement = _useVirtualTable.measureElement;
58
78
  var refBody = react.useRef(null);
59
79
  var wrapperStart = react.useMemo(function () {
@@ -108,9 +128,11 @@ var Table = function Table(_ref) {
108
128
  style: {
109
129
  gridTemplate: "\"head\" auto \"loader\" auto \"content\" 1fr \"foot\" auto/1fr"
110
130
  },
131
+ "data-ref": "tableScroller",
111
132
  ref: scrollerRef,
112
133
  children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
113
- className: "bg-base font-medium sticky top-0 area-head border-b select-none flex flex-nowrap z-2",
134
+ "data-ref": "tableHeader",
135
+ className: "bg-base font-medium sticky top-0 h-8 area-head border-b select-none flex flex-nowrap z-3",
114
136
  children: [/*#__PURE__*/jsxRuntime.jsxs("div", {
115
137
  className: wrapperStart,
116
138
  children: [canExpand && /*#__PURE__*/jsxRuntime.jsx("div", {
@@ -121,20 +143,23 @@ var Table = function Table(_ref) {
121
143
  }), (_state$start = state.start) === null || _state$start === void 0 ? void 0 : _state$start.map(function (col, idx) {
122
144
  return /*#__PURE__*/jsxRuntime.jsx(HeaderCell.HeaderCell, _objectSpread(_objectSpread({}, col), {}, {
123
145
  sort: sort,
124
- onSort: onSort
146
+ onSort: onSort,
147
+ onFilter: onFilter
125
148
  }), idx);
126
149
  })]
127
150
  }), (_state$cols = state.cols) === null || _state$cols === void 0 ? void 0 : _state$cols.map(function (col, idx) {
128
151
  return /*#__PURE__*/jsxRuntime.jsx(HeaderCell.HeaderCell, _objectSpread(_objectSpread({}, col), {}, {
129
152
  sort: sort,
130
- onSort: onSort
153
+ onSort: onSort,
154
+ onFilter: onFilter
131
155
  }), idx);
132
156
  }), /*#__PURE__*/jsxRuntime.jsxs("div", {
133
157
  className: wrapperEnd,
134
158
  children: [(_state$end = state.end) === null || _state$end === void 0 ? void 0 : _state$end.map(function (col, idx) {
135
159
  return /*#__PURE__*/jsxRuntime.jsx(HeaderCell.HeaderCell, _objectSpread(_objectSpread({}, col), {}, {
136
160
  sort: sort,
137
- onSort: onSort
161
+ onSort: onSort,
162
+ onFilter: onFilter
138
163
  }), idx);
139
164
  }), hideableColumns && /*#__PURE__*/jsxRuntime.jsx(AddColumn.AddColumn, {
140
165
  onClick: onHide,
@@ -143,22 +168,46 @@ var Table = function Table(_ref) {
143
168
  })
144
169
  })]
145
170
  })]
146
- }), loading && /*#__PURE__*/jsxRuntime.jsx(core.Loading, {}), data.length > 0 && /*#__PURE__*/jsxRuntime.jsxs("div", {
147
- className: "area-content flex flex-col flex-nowrap",
171
+ }), loading && /*#__PURE__*/jsxRuntime.jsx(core.LoadingLine, {}), data.length > 0 && /*#__PURE__*/jsxRuntime.jsxs("div", {
172
+ className: "area-content flex flex-col flex-nowrap min-h-full",
148
173
  style: {
149
174
  height: totalSize()
150
175
  },
151
176
  ref: refBody,
152
177
  children: [/*#__PURE__*/jsxRuntime.jsx("div", {
153
178
  style: {
154
- height: (_items$ = items[0]) === null || _items$ === void 0 ? void 0 : _items$.start
179
+ height: (_items = items[hasActiveSticky ? 1 : 0]) === null || _items === void 0 ? void 0 : _items.start
155
180
  }
156
181
  }), items.map(function (_ref2) {
182
+ var _groupRenderer;
157
183
  var index = _ref2.index,
158
184
  key = _ref2.key;
159
185
  var data = getData(index);
160
- return /*#__PURE__*/jsxRuntime.jsx(BodyRow.BodyRow, {
161
- rowKey: key,
186
+ return "__GROUP__" in data ? /*#__PURE__*/jsxRuntime.jsx("div", {
187
+ ref: measureElement,
188
+ "data-index": index,
189
+ className: classNames("text-md bg-base border-y border-tint-100 border-t-0 cursor-pointer flex items-center justify-start gap-1 z-2", isActiveSticky(index) && "sticky top-8"),
190
+ role: "none",
191
+ onClick: function onClick() {
192
+ return toggleGroupExpand(data.key);
193
+ },
194
+ children: /*#__PURE__*/jsxRuntime.jsxs("div", {
195
+ className: classNames("px-2 py-1 flex items-center gap-1 z-2 sticky start-0"),
196
+ children: [/*#__PURE__*/jsxRuntime.jsx(core.Icon, {
197
+ rtlFlip: true,
198
+ icon: data.open ? "icon-[mdi--chevron-down]" : "icon-[mdi--chevron-right]"
199
+ }), (_groupRenderer = groupRenderer === null || groupRenderer === void 0 ? void 0 : groupRenderer(data)) !== null && _groupRenderer !== void 0 ? _groupRenderer : /*#__PURE__*/jsxRuntime.jsxs("div", {
200
+ className: "flex gap-1 items-center",
201
+ children: [/*#__PURE__*/jsxRuntime.jsx("span", {
202
+ children: data.key
203
+ }), /*#__PURE__*/jsxRuntime.jsxs("span", {
204
+ className: "text-sm",
205
+ children: ["(", data.itemCount, ")"]
206
+ })]
207
+ })]
208
+ })
209
+ }, key) : /*#__PURE__*/jsxRuntime.jsx(BodyRow.BodyRow, {
210
+ rowKey: key.toString(),
162
211
  index: index,
163
212
  checkableRows: checkableRows,
164
213
  checked: keyProperty && checkState.checked.includes(data[keyProperty]) ? 1 : 0,
@@ -27,6 +27,35 @@ var COL_MIN_WIDTH = "3rem";
27
27
  var COL_MAX_WIDTH = "64rem";
28
28
  var COL_DEFAULT_WIDTH = "12rem";
29
29
 
30
+ /**
31
+ * TableColumn interface defines the structure of a column in a table.
32
+ * It includes properties for column identification, display options, alignment,
33
+ * visibility, resizing, sorting, filtering, and rendering.
34
+ *
35
+ * @template T - The type of data the column will represent, defaulting to KeyValue.
36
+ * @property {keyof T | string} id - Unique identifier for the column.
37
+ * @property {"string" | "number" | "boolean" | "datetime" | "date" | "time" | "unknown"} [dataType] - Data type of the column values.
38
+ * @property {string} [label] - Display label for the column header.
39
+ * @property {string} [tooltip] - Tooltip text for the column header.
40
+ * @property {string} [format] - Format string for displaying the column values.
41
+ * @property {"start" | "center" | "end"} [align] - Text alignment within the column.
42
+ * @property {"start" | "end"} [locked] - Indicates if the column is locked at the start or end.
43
+ * @property {boolean} [hidden] - Whether the column is hidden.
44
+ * @property {boolean} [truncate] - Whether to truncate the text in the column.
45
+ * @property {boolean} [hideable] - Whether the column can be hidden by the user.
46
+ * @property {boolean} [resizable] - Whether the column can be resized by the user.
47
+ * @property {boolean} [sortable] - Whether the column can be sorted.
48
+ * @property {boolean} [filterable] - Whether the column can be filtered.
49
+ * @property {AnyObject} [filter] - Filter criteria for the column.
50
+ * @property {ReactElement[]} [actions] - Array of action elements to be displayed in the column.
51
+ * @property {AnyObject[]} [filterOptions] - Options for filtering the column.
52
+ * @property {string | number} [width] - Width of the column.
53
+ * @property {string | number} [minWidth] - Minimum width of the column.
54
+ * @property {string | number} [maxWidth] - Maximum width of the column.
55
+ * @property {KeyValue} [valueMap] - Mapping of values for the column.
56
+ * @property {(value: AnyObject, data: T, index: number) => Elements<AnyObject>} [renderer] - Custom renderer function for the column values.
57
+ */
58
+
30
59
  exports.COL_DEFAULT_WIDTH = COL_DEFAULT_WIDTH;
31
60
  exports.COL_MAX_WIDTH = COL_MAX_WIDTH;
32
61
  exports.COL_MIN_WIDTH = COL_MIN_WIDTH;
@@ -44,14 +44,14 @@ var useResizer = function useResizer(colEl, ghostEl, callback) {
44
44
  /** ***************** attach handlers *******************/
45
45
  var box = colEl.getBoundingClientRect();
46
46
  if (colEl.parentElement != null) {
47
- var _colEl$parentElement;
48
- var parentBox = (_colEl$parentElement = colEl.parentElement) === null || _colEl$parentElement === void 0 ? void 0 : _colEl$parentElement.getBoundingClientRect();
47
+ var _colEl$closest;
48
+ var parentBox = (_colEl$closest = colEl.closest("[data-ref='tableScroller']")) === null || _colEl$closest === void 0 ? void 0 : _colEl$closest.getBoundingClientRect();
49
49
  if (isRtl) {
50
50
  placeholder.style.left = "unset";
51
- placeholder.style.right = "".concat(box.right - parentBox.right, "px");
51
+ placeholder.style.right = "".concat(parentBox.width - box.right, "px");
52
52
  } else {
53
53
  placeholder.style.right = "unset";
54
- placeholder.style.left = "".concat(box.left - parentBox.left, "px");
54
+ placeholder.style.left = "".concat(box.left, "px");
55
55
  }
56
56
  }
57
57
  placeholder.style.width = "".concat(colEl.offsetWidth, "px");
@@ -1,49 +1,85 @@
1
1
  'use strict';
2
2
 
3
3
  var _defineProperty = require('@babel/runtime/helpers/defineProperty');
4
+ var _toConsumableArray = require('@babel/runtime/helpers/toConsumableArray');
4
5
  var _slicedToArray = require('@babel/runtime/helpers/slicedToArray');
6
+ var utilities = require('@react-fabric/utilities');
5
7
  var reactVirtual = require('@tanstack/react-virtual');
6
8
  var react = require('react');
7
9
 
8
10
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
9
11
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
10
- var useVirtualTable = function useVirtualTable(data, keyProperty, onCheckChanged) {
12
+ var useVirtualTable = function useVirtualTable(data, options) {
11
13
  var _virtualizer$range;
12
14
  // TODO: refactor data into item list, apply grouping if groupColumn provided
13
15
  // TODO: when grouping maintain map of group with children, {___GROUP___:true, label, items, open}
14
16
 
15
- var scrollerRef = react.useRef(null);
16
- var virtualizer = reactVirtual.useVirtualizer({
17
- count: data.length,
18
- getScrollElement: function getScrollElement() {
19
- return scrollerRef.current;
20
- },
21
- estimateSize: function estimateSize() {
22
- return 24;
23
- }
24
- });
25
17
  var _useReducer = react.useReducer(function (state, action) {
18
+ if (action.type === "updateState") {
19
+ state.checked = action.checked;
20
+ }
26
21
  if (action.type === "expand") {
27
22
  if (state.expanded.includes(action.key)) state.expanded.splice(state.expanded.indexOf(action.key), 1);else state.expanded.push(action.key);
28
23
  }
29
24
  if (action.type === "check") {
25
+ var _options$onCheckChang;
30
26
  if (state.checked.includes(action.key)) state.checked.splice(state.checked.indexOf(action.key), 1);else state.checked.push(action.key);
31
- onCheckChanged === null || onCheckChanged === void 0 || onCheckChanged(state.checked);
27
+ (_options$onCheckChang = options.onCheckChanged) === null || _options$onCheckChang === void 0 || _options$onCheckChang.call(options, state.checked);
32
28
  }
33
29
  if (action.type === "checkall") {
30
+ var _options$onCheckChang2;
34
31
  if (state.allChecked !== 0) {
35
32
  state.checked = [];
36
- } else if (keyProperty) {
37
- state.checked = data.map(function (item) {
38
- return item[keyProperty];
33
+ } else if (options.keyProperty) {
34
+ state.checked = state.data.map(function (item) {
35
+ return item[options.keyProperty];
36
+ });
37
+ }
38
+ (_options$onCheckChang2 = options.onCheckChanged) === null || _options$onCheckChang2 === void 0 || _options$onCheckChang2.call(options, state.checked);
39
+ }
40
+ var checkList = state.data.filter(function (hit) {
41
+ return state.checked.includes(hit[options.keyProperty]);
42
+ });
43
+ if (action.type === "groupExpand") {
44
+ var group = state.groups.find(function (group) {
45
+ return group.key === action.key;
46
+ });
47
+ if (group) {
48
+ group.open = !group.open;
49
+ state.groups = state.groups.slice();
50
+ state.items = state.groups.map(function (group) {
51
+ return [group, group.open ? state.grouped[group.key] : undefined];
52
+ }).flat(2).filter(Boolean);
53
+ }
54
+ }
55
+ if (action.type === "reset") {
56
+ state.data = action.data;
57
+ if (action.key) {
58
+ state.grouped = utilities.groupBy(state.data, action.key);
59
+ state.groups = Object.keys(state.grouped).sort(utilities.compareValues("asc")).map(function (group) {
60
+ return {
61
+ __GROUP__: true,
62
+ open: true,
63
+ key: group,
64
+ items: state.grouped[group],
65
+ itemCount: state.grouped[group].length
66
+ };
39
67
  });
68
+ state.items = state.groups.map(function (group) {
69
+ return [group].concat(_toConsumableArray(state.grouped[group.key]));
70
+ }).flat();
71
+ } else {
72
+ state.items = state.data;
40
73
  }
41
- onCheckChanged === null || onCheckChanged === void 0 || onCheckChanged(state.checked);
42
74
  }
43
75
  return _objectSpread(_objectSpread({}, state), {}, {
44
- allChecked: state.checked.length === data.length ? 1 : state.checked.length ? 2 : 0
76
+ allChecked: checkList.length === state.data.length ? 1 : state.checked.length ? 2 : 0
45
77
  });
46
78
  }, {
79
+ data: data,
80
+ items: [],
81
+ grouped: {},
82
+ groups: [],
47
83
  checked: [],
48
84
  expanded: [],
49
85
  allChecked: 0
@@ -51,19 +87,91 @@ var useVirtualTable = function useVirtualTable(data, keyProperty, onCheckChanged
51
87
  _useReducer2 = _slicedToArray(_useReducer, 2),
52
88
  state = _useReducer2[0],
53
89
  dispatch = _useReducer2[1];
90
+ var activeStickyIndexRef = react.useRef(0);
91
+ var stickyIndexes = react.useMemo(function () {
92
+ return state.items.map(function (hit, idx) {
93
+ return "__GROUP__" in hit ? idx : undefined;
94
+ }).filter(Boolean);
95
+ }, [state.items]);
96
+ var isActiveSticky = function isActiveSticky(index) {
97
+ return activeStickyIndexRef.current === index;
98
+ };
99
+ var _useState = react.useState(false),
100
+ _useState2 = _slicedToArray(_useState, 2),
101
+ hasActiveSticky = _useState2[0],
102
+ setHasActiveSticky = _useState2[1];
103
+ var scrollerRef = react.useRef(null);
104
+ var virtualizer = reactVirtual.useVirtualizer({
105
+ count: state.items.length,
106
+ getScrollElement: function getScrollElement() {
107
+ return scrollerRef.current;
108
+ },
109
+ estimateSize: function estimateSize() {
110
+ return 32;
111
+ },
112
+ rangeExtractor: react.useCallback(function (range) {
113
+ var _reverse$find;
114
+ activeStickyIndexRef.current = (_reverse$find = _toConsumableArray(stickyIndexes).reverse().find(function (index) {
115
+ return range.startIndex > index;
116
+ })) !== null && _reverse$find !== void 0 ? _reverse$find : 0;
117
+ setHasActiveSticky(range.startIndex !== activeStickyIndexRef.current);
118
+ var next = new Set([activeStickyIndexRef.current].concat(_toConsumableArray(reactVirtual.defaultRangeExtractor(range))));
119
+ return _toConsumableArray(next);
120
+ }, [stickyIndexes])
121
+ });
54
122
  var virtualItems = virtualizer.getVirtualItems();
55
123
  var getData = react.useCallback(function (index) {
56
- return data[index];
57
- }, [data]);
124
+ return state.items[index];
125
+ }, [state.items]);
126
+ react.useEffect(function () {
127
+ dispatch({
128
+ type: "reset",
129
+ key: options.groupProperty,
130
+ data: data
131
+ });
132
+ }, [data, options.groupProperty]);
133
+ react.useEffect(function () {
134
+ var _options$checked;
135
+ dispatch({
136
+ type: "updateState",
137
+ checked: (_options$checked = options.checked) !== null && _options$checked !== void 0 ? _options$checked : []
138
+ });
139
+ }, [options.checked]);
140
+ react.useEffect(function () {
141
+ if (options.onLoadMore) {
142
+ var _virtualItems$, _virtualItems$slice$p;
143
+ var firstItem = (_virtualItems$ = virtualItems[0]) === null || _virtualItems$ === void 0 ? void 0 : _virtualItems$.index;
144
+ var lastItem = virtualItems === null || virtualItems === void 0 || (_virtualItems$slice$p = virtualItems.slice(-1).pop()) === null || _virtualItems$slice$p === void 0 ? void 0 : _virtualItems$slice$p.index;
145
+ var canLoadPrevPage = firstItem !== undefined && state.items[firstItem] === null;
146
+ var canLoadNextPage = lastItem !== undefined && lastItem === state.items.length - 1 && state.items.length < options.total;
147
+ var db = utilities.debounce(options.onLoadMore);
148
+ if (canLoadPrevPage) {
149
+ db(firstItem);
150
+ } else if (!options.loading && canLoadNextPage) {
151
+ db(lastItem + 1);
152
+ }
153
+ return function () {
154
+ return db.cancel();
155
+ };
156
+ }
157
+ }, [options.onLoadMore, virtualItems]);
58
158
  return {
59
159
  scrollerRef: scrollerRef,
60
160
  items: virtualItems,
61
161
  checkState: state,
62
162
  getData: getData,
63
163
  virtualizer: virtualizer,
164
+ hasActiveSticky: hasActiveSticky,
165
+ isActiveSticky: isActiveSticky,
64
166
  top: (_virtualizer$range = virtualizer.range) === null || _virtualizer$range === void 0 ? void 0 : _virtualizer$range.startIndex,
65
167
  totalSize: virtualizer.getTotalSize,
66
168
  measureElement: virtualizer.measureElement,
169
+ toggleGroupExpand: function toggleGroupExpand(key) {
170
+ return dispatch({
171
+ type: "groupExpand",
172
+ key: key
173
+ });
174
+ },
67
175
  toggleExpand: function toggleExpand(key) {
68
176
  return dispatch({
69
177
  type: "expand",
@@ -2,8 +2,10 @@
2
2
 
3
3
  var _defineProperty = require('@babel/runtime/helpers/defineProperty');
4
4
  var core = require('@react-fabric/core');
5
+ var utilities = require('@react-fabric/utilities');
5
6
  var classNames = require('classnames');
6
7
  var react = require('react');
8
+ var reactI18next = require('react-i18next');
7
9
  var jsxRuntime = require('react/jsx-runtime');
8
10
 
9
11
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
@@ -17,35 +19,45 @@ var TreeNode = function TreeNode(_ref) {
17
19
  defaultLeafIcon = _ref.defaultLeafIcon,
18
20
  defaultNodeIcon = _ref.defaultNodeIcon,
19
21
  onToggle = _ref.onToggle,
22
+ onClick = _ref.onClick,
20
23
  onSelect = _ref.onSelect,
21
24
  onChecked = _ref.onChecked,
22
- children = _ref.children;
25
+ children = _ref.children,
26
+ leafClassName = _ref.leafClassName,
27
+ nodeClassName = _ref.nodeClassName;
28
+ var _useTranslation = reactI18next.useTranslation("data"),
29
+ t = _useTranslation.t;
23
30
  var badgeProps = react.useMemo(function () {
24
31
  return core.getBadgeProps(node.badge);
25
32
  }, [node.badge]);
26
33
  var filler = react.useMemo(function () {
27
- return node.lines.slice(noLines ? 1 : 0).map(function (line, idx) {
28
- return /*#__PURE__*/jsxRuntime.jsxs("svg", {
29
- viewBox: "0 0 24 24",
30
- className: "flex-initial w-6 fill-tint-200",
31
- children: [line === 0 && /*#__PURE__*/jsxRuntime.jsx("path", {
32
- d: ""
33
- }), !noLines && line === 1 && /*#__PURE__*/jsxRuntime.jsx("path", {
34
- d: "M7.45 26.1v-28.2h1.1v28.2h-1.1z"
35
- }), !noLines && line === 2 && /*#__PURE__*/jsxRuntime.jsx("path", {
36
- d: "M14.989 12.389l0.161-0.389-0.161-0.389-0.389-0.161h-6.050v-13.55h-1.1v14.1l0.161 0.389 0.389 0.161h6.6z"
37
- }), !noLines && line === 3 && /*#__PURE__*/jsxRuntime.jsx("path", {
38
- d: "M8.55 12.55h6.050l0.389-0.161 0.161-0.389-0.161-0.389-0.389-0.161h-6.050v-13.55h-1.1v28.2h1.1z"
39
- })]
34
+ return node.lines.slice(1).map(function (line, idx) {
35
+ return /*#__PURE__*/jsxRuntime.jsx("div", {
36
+ className: classNames("flex-initial self-stretch flex items-center w-6 relative", !noLines && line > 0 && "before:absolute before:top-0 before:start-[7px] before:bg-tint-200 before:min-h-[50%] before:w-0.5 before:scale-x-[.625]", !noLines && line !== 2 && "before:h-full"),
37
+ children: /*#__PURE__*/jsxRuntime.jsxs("svg", {
38
+ viewBox: "0 0 24 24",
39
+ className: "fill-tint-200 rtl:-scale-x-100",
40
+ children: [line === 0 && /*#__PURE__*/jsxRuntime.jsx("path", {
41
+ d: ""
42
+ }), !noLines && line === 1 && /*#__PURE__*/jsxRuntime.jsx("path", {
43
+ d: "M7.45 26.1v-28.2h1.1v28.2h-1.1z"
44
+ }), !noLines && line === 2 && /*#__PURE__*/jsxRuntime.jsx("path", {
45
+ d: "M14.989 12.389l0.161-0.389-0.161-0.389-0.389-0.161h-6.050v-13.55h-1.1v14.1l0.161 0.389 0.389 0.161h6.6z"
46
+ }), !noLines && line === 3 && /*#__PURE__*/jsxRuntime.jsx("path", {
47
+ d: "M8.55 12.55h6.050l0.389-0.161 0.161-0.389-0.161-0.389-0.389-0.161h-6.050v-13.55h-1.1v28.2h1.1z"
48
+ })]
49
+ })
40
50
  }, idx);
41
51
  });
42
52
  }, [noLines, node.lines]);
43
53
  var nodeIcon = react.useMemo(function () {
44
54
  if (node.icon) return node.icon;
45
- return node.leaf ? defaultLeafIcon : defaultNodeIcon;
55
+ return {
56
+ icon: node.leaf ? defaultLeafIcon : defaultNodeIcon
57
+ };
46
58
  }, [defaultLeafIcon, defaultNodeIcon, node.icon]);
47
59
  var canCheck = react.useMemo(function () {
48
- return checkable === true || checkable === "leafOnly" && node.leaf;
60
+ return utilities.isTrue(checkable) || checkable === "leafOnly" && node.leaf;
49
61
  }, [node.leaf, checkable]);
50
62
  var canSelect = react.useMemo(function () {
51
63
  return !node.disabled && (selectable === true || selectable === "leafOnly" && node.leaf);
@@ -53,10 +65,17 @@ var TreeNode = function TreeNode(_ref) {
53
65
  return /*#__PURE__*/jsxRuntime.jsxs("div", {
54
66
  role: "treeitem",
55
67
  "aria-selected": node.selected,
56
- className: "flex flex-nowrap",
68
+ className: classNames("flex flex-nowrap items-center"),
57
69
  "data-testid": node["data-testid"],
58
70
  "data-test-value": node["data-test-value"],
59
- children: [filler, !node.leaf && !node.childFiltered && /*#__PURE__*/jsxRuntime.jsx("div", {
71
+ "data-id": node.id,
72
+ children: [filler, node.loading && /*#__PURE__*/jsxRuntime.jsx("div", {
73
+ className: "flex-initial w-6",
74
+ children: /*#__PURE__*/jsxRuntime.jsx(core.Icon, {
75
+ icon: "icon-[svg-spinners--eclipse]",
76
+ className: "text-muted"
77
+ })
78
+ }), !node.leaf && !node.childFiltered && !node.loading && /*#__PURE__*/jsxRuntime.jsx("div", {
60
79
  className: "flex-initial w-6",
61
80
  children: /*#__PURE__*/jsxRuntime.jsx(core.Icon, {
62
81
  rtlFlip: true,
@@ -72,24 +91,20 @@ var TreeNode = function TreeNode(_ref) {
72
91
  onClick: function onClick() {
73
92
  return !node.disabled && onChecked(node.id);
74
93
  },
75
- icon: node.checked === 2 ? core.CoreIcons.checkboxInt : node.checked === 1 ? core.CoreIcons.checkboxOn : core.CoreIcons.checkboxOff,
94
+ icon: node.checked === 2 ? "icon-[mdi--checkbox-intermediate]" : node.checked === 1 ? "icon-[mdi--checkbox-marked]" : "icon-[mdi--checkbox-blank-outline]",
76
95
  className: classNames(node.disabled ? "text-muted" : "text-primary-500 hover:text-primary-600")
77
96
  })
78
- }), /*#__PURE__*/jsxRuntime.jsxs("div", {
97
+ }), !node.empty && /*#__PURE__*/jsxRuntime.jsxs("div", {
79
98
  role: "none",
80
- className: classNames("group data-[selected]:bg-primary-100 flex flex-nowrap flex-1 items-center overflow-hidden select-none", node.childSelected && "font-medium", canSelect && "hover:bg-primary-50 cursor-pointer"),
99
+ className: classNames("group/tool data-selected:bg-primary-100 flex flex-nowrap flex-1 overflow-hidden select-none", node.childSelected && "font-medium", node.disabled && "text-muted opacity-65", node.className, node.leaf ? leafClassName : nodeClassName, !node.disabled && (canSelect || onClick) && "hover:bg-primary-50 cursor-pointer"),
81
100
  "data-selected": node.selected,
82
- onClick: function onClick() {
83
- return canSelect ? onSelect(node.id) : canCheck ? onChecked(node.id) : onToggle(node.id);
101
+ onClick: node.disabled ? undefined : function (e) {
102
+ onClick === null || onClick === void 0 || onClick(node.id, node.data);
103
+ canSelect ? onSelect(node.id, e.shiftKey) : canCheck ? onChecked(node.id) : onToggle(node.id);
84
104
  },
85
- children: [nodeIcon && /*#__PURE__*/jsxRuntime.jsx("div", {
86
- className: "flex-content w-6",
87
- children: /*#__PURE__*/jsxRuntime.jsx(core.Icon, {
88
- icon: nodeIcon,
89
- bg: node.iconBg,
90
- color: node.iconColor,
91
- rtlFlip: node.rtlFlip
92
- })
105
+ children: [nodeIcon && /*#__PURE__*/jsxRuntime.jsxs("div", {
106
+ className: "flex-content max-w-6 me-1 self-center leading-none",
107
+ children: [/*#__PURE__*/react.isValidElement(nodeIcon) && nodeIcon, utilities.isString(nodeIcon) && /*#__PURE__*/jsxRuntime.jsx(core.Icon, _objectSpread({}, core.getIconProps(nodeIcon)))]
93
108
  }), node.childSelected && !node.open && /*#__PURE__*/jsxRuntime.jsx("span", {
94
109
  className: " flex-content text-primary-500",
95
110
  children: "\u2022"
@@ -97,9 +112,12 @@ var TreeNode = function TreeNode(_ref) {
97
112
  role: "none",
98
113
  className: "flex-1 truncate",
99
114
  children: children
100
- }), node.badge && /*#__PURE__*/jsxRuntime.jsx(core.Badge, _objectSpread(_objectSpread({}, badgeProps), {}, {
115
+ }), !utilities.isEmpty(node.badge) && /*#__PURE__*/jsxRuntime.jsx(core.Badge, _objectSpread(_objectSpread({}, badgeProps), {}, {
101
116
  className: classNames("me-1 self-center flex-content bg-opacity-50", badgeProps.className)
102
117
  }))]
118
+ }), node.empty && /*#__PURE__*/jsxRuntime.jsx("div", {
119
+ className: "text-muted text-sm select-none",
120
+ children: t("tree.noItems")
103
121
  })]
104
122
  });
105
123
  };