@react-fabric/data 1.0.0-beta.5 → 1.0.0-beta.52

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 (109) hide show
  1. package/{src/histogram/Histogram.module.css → css/_histogram.css} +16 -13
  2. package/css/styles.css +24 -0
  3. package/dist/cjs/checklist/CheckList.js +48 -16
  4. package/dist/cjs/histogram/Histogram.js +48 -10
  5. package/dist/cjs/hooks/useFilteredList.js +20 -0
  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 +67 -27
  11. package/dist/cjs/pagination/Pagination.js +10 -0
  12. package/dist/cjs/table/AddColumn.js +1 -1
  13. package/dist/cjs/table/BodyCell.js +38 -5
  14. package/dist/cjs/table/BodyRow.js +107 -0
  15. package/dist/cjs/table/CheckboxCell.js +1 -1
  16. package/dist/cjs/table/ColumnFilters.js +97 -0
  17. package/dist/cjs/table/HeaderCell.js +70 -37
  18. package/dist/cjs/table/Table.js +113 -71
  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 +122 -18
  22. package/dist/cjs/tree/TreeNode.js +45 -25
  23. package/dist/cjs/tree/TreePanel.js +28 -10
  24. package/dist/cjs/tree/useTree.js +97 -15
  25. package/dist/cjs/tree/utils.js +20 -5
  26. package/dist/cjs/virtual/Gallery.js +84 -35
  27. package/dist/cjs/virtual/List.js +82 -32
  28. package/dist/esm/checklist/CheckList.js +50 -18
  29. package/dist/esm/histogram/Histogram.js +49 -11
  30. package/dist/esm/hooks/useFilteredList.js +20 -0
  31. package/dist/esm/hooks/usePagination.js +27 -4
  32. package/dist/esm/hooks/useSelectableList.js +29 -0
  33. package/dist/esm/i18n/ar.json.js +8 -2
  34. package/dist/esm/i18n/en.json.js +8 -2
  35. package/dist/esm/json/JsonViewer.js +68 -28
  36. package/dist/esm/pagination/Pagination.js +10 -0
  37. package/dist/esm/table/AddColumn.js +1 -1
  38. package/dist/esm/table/BodyCell.js +38 -5
  39. package/dist/esm/table/BodyRow.js +107 -0
  40. package/dist/esm/table/CheckboxCell.js +1 -1
  41. package/dist/esm/table/ColumnFilters.js +97 -0
  42. package/dist/esm/table/HeaderCell.js +71 -38
  43. package/dist/esm/table/Table.js +115 -73
  44. package/dist/esm/table/types.js +29 -0
  45. package/dist/esm/table/useResizer.js +4 -4
  46. package/dist/esm/table/useVirtualTable.js +124 -20
  47. package/dist/esm/tree/TreeNode.js +47 -27
  48. package/dist/esm/tree/TreePanel.js +28 -10
  49. package/dist/esm/tree/useTree.js +99 -17
  50. package/dist/esm/tree/utils.js +20 -5
  51. package/dist/esm/virtual/Gallery.js +84 -35
  52. package/dist/esm/virtual/List.js +82 -32
  53. package/dist/types/checklist/CheckList.d.ts +24 -2
  54. package/dist/types/histogram/Histogram.d.ts +31 -4
  55. package/dist/types/hooks/useFilteredList.d.ts +20 -2
  56. package/dist/types/hooks/usePagination.d.ts +19 -0
  57. package/dist/types/hooks/useSelectableList.d.ts +29 -0
  58. package/dist/types/index.d.ts +1 -1
  59. package/dist/types/json/JsonViewer.d.ts +27 -2
  60. package/dist/types/pagination/Pagination.d.ts +10 -1
  61. package/dist/types/table/AddColumn.d.ts +2 -2
  62. package/dist/types/table/BodyCell.d.ts +4 -3
  63. package/dist/types/table/BodyRow.d.ts +20 -0
  64. package/dist/types/table/ColumnFilters.d.ts +9 -0
  65. package/dist/types/table/EmptyCell.d.ts +2 -2
  66. package/dist/types/table/HeaderCell.d.ts +2 -2
  67. package/dist/types/table/Table.d.ts +14 -1
  68. package/dist/types/table/types.d.ts +48 -7
  69. package/dist/types/table/useTableColumns.d.ts +6 -6
  70. package/dist/types/table/useVirtualTable.d.ts +23 -8
  71. package/dist/types/tree/TreeNode.d.ts +1 -1
  72. package/dist/types/tree/TreePanel.d.ts +42 -1
  73. package/dist/types/tree/types.d.ts +25 -5
  74. package/dist/types/tree/useTree.d.ts +3 -10
  75. package/dist/types/tree/utils.d.ts +4 -1
  76. package/dist/types/virtual/Gallery.d.ts +44 -4
  77. package/dist/types/virtual/List.d.ts +44 -4
  78. package/package.json +13 -10
  79. package/src/checklist/CheckList.tsx +103 -77
  80. package/src/histogram/Histogram.tsx +45 -11
  81. package/src/hooks/useFilteredList.tsx +19 -0
  82. package/src/hooks/usePagination.tsx +32 -7
  83. package/src/hooks/useSelectableList.ts +29 -0
  84. package/src/i18n/ar.json +5 -0
  85. package/src/i18n/en.json +5 -0
  86. package/src/index.ts +1 -1
  87. package/src/json/JsonViewer.tsx +71 -35
  88. package/src/pagination/Pagination.tsx +10 -0
  89. package/src/table/AddColumn.tsx +3 -3
  90. package/src/table/BodyCell.tsx +34 -5
  91. package/src/table/BodyRow.tsx +143 -0
  92. package/src/table/CheckboxCell.tsx +1 -1
  93. package/src/table/ColumnFilters.tsx +105 -0
  94. package/src/table/EmptyCell.tsx +2 -2
  95. package/src/table/HeaderCell.tsx +72 -14
  96. package/src/table/Table.tsx +177 -77
  97. package/src/table/types.ts +52 -6
  98. package/src/table/useResizer.ts +5 -3
  99. package/src/table/useTableColumns.ts +7 -7
  100. package/src/table/useVirtualTable.ts +146 -24
  101. package/src/tree/TreeNode.tsx +98 -56
  102. package/src/tree/TreePanel.tsx +64 -3
  103. package/src/tree/types.ts +32 -4
  104. package/src/tree/useTree.ts +109 -26
  105. package/src/tree/utils.ts +23 -8
  106. package/src/virtual/Gallery.tsx +96 -42
  107. package/src/virtual/List.tsx +82 -33
  108. package/dist/cjs/histogram/Histogram.module.css +0 -1
  109. package/dist/esm/histogram/Histogram.module.css +0 -1
@@ -1,61 +1,165 @@
1
1
  'use client';
2
2
 
3
3
  import _defineProperty from '@babel/runtime/helpers/defineProperty';
4
+ import _toConsumableArray from '@babel/runtime/helpers/toConsumableArray';
4
5
  import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
5
- import { useVirtualizer } from '@tanstack/react-virtual';
6
- import { useRef, useReducer, useCallback } from 'react';
6
+ import { groupBy, compareValues } from '@react-fabric/utilities';
7
+ import { useVirtualizer, defaultRangeExtractor } from '@tanstack/react-virtual';
8
+ import { useReducer, useRef, useMemo, useState, useCallback, useEffect } from '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) {
13
+ var _virtualizer$range;
11
14
  // TODO: refactor data into item list, apply grouping if groupColumn provided
12
15
  // TODO: when grouping maintain map of group with children, {___GROUP___:true, label, items, open}
13
16
 
14
- var scrollerRef = useRef(null);
15
- var virtualizer = useVirtualizer({
16
- count: data.length,
17
- getScrollElement: function getScrollElement() {
18
- return scrollerRef.current;
19
- },
20
- estimateSize: function estimateSize() {
21
- return 24;
22
- }
23
- });
24
17
  var _useReducer = useReducer(function (state, action) {
18
+ if (action.type === "updateState") {
19
+ state.checked = action.checked;
20
+ }
21
+ if (action.type === "expand") {
22
+ if (state.expanded.includes(action.key)) state.expanded.splice(state.expanded.indexOf(action.key), 1);else state.expanded.push(action.key);
23
+ }
25
24
  if (action.type === "check") {
25
+ var _options$onCheckChang;
26
26
  if (state.checked.includes(action.key)) state.checked.splice(state.checked.indexOf(action.key), 1);else state.checked.push(action.key);
27
+ (_options$onCheckChang = options.onCheckChanged) === null || _options$onCheckChang === void 0 || _options$onCheckChang.call(options, state.checked);
27
28
  }
28
29
  if (action.type === "checkall") {
30
+ var _options$onCheckChang2;
29
31
  if (state.allChecked !== 0) {
30
32
  state.checked = [];
31
- } else if (keyProperty) {
32
- state.checked = data.map(function (item) {
33
- 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 = groupBy(state.data, action.key);
59
+ state.groups = Object.keys(state.grouped).sort(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
+ };
34
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;
35
73
  }
36
74
  }
37
- onCheckChanged === null || onCheckChanged === void 0 || onCheckChanged(state.checked);
38
75
  return _objectSpread(_objectSpread({}, state), {}, {
39
- 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
40
77
  });
41
78
  }, {
79
+ data: data,
80
+ items: [],
81
+ grouped: {},
82
+ groups: [],
42
83
  checked: [],
84
+ expanded: [],
43
85
  allChecked: 0
44
86
  }),
45
87
  _useReducer2 = _slicedToArray(_useReducer, 2),
46
88
  state = _useReducer2[0],
47
89
  dispatch = _useReducer2[1];
90
+ var activeStickyIndexRef = useRef(0);
91
+ var stickyIndexes = 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 = useState(false),
100
+ _useState2 = _slicedToArray(_useState, 2),
101
+ hasActiveSticky = _useState2[0],
102
+ setHasActiveSticky = _useState2[1];
103
+ var scrollerRef = useRef(null);
104
+ var virtualizer = 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: 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(defaultRangeExtractor(range))));
119
+ return _toConsumableArray(next);
120
+ }, [stickyIndexes])
121
+ });
48
122
  var virtualItems = virtualizer.getVirtualItems();
49
123
  var getData = useCallback(function (index) {
50
- return data[index];
51
- }, [data]);
124
+ return state.items[index];
125
+ }, [state.items]);
126
+ useEffect(function () {
127
+ dispatch({
128
+ type: "reset",
129
+ key: options.groupProperty,
130
+ data: data
131
+ });
132
+ }, [data, options.groupProperty]);
133
+ 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]);
52
140
  return {
53
141
  scrollerRef: scrollerRef,
54
142
  items: virtualItems,
55
143
  checkState: state,
56
144
  getData: getData,
145
+ virtualizer: virtualizer,
146
+ hasActiveSticky: hasActiveSticky,
147
+ isActiveSticky: isActiveSticky,
148
+ top: (_virtualizer$range = virtualizer.range) === null || _virtualizer$range === void 0 ? void 0 : _virtualizer$range.startIndex,
57
149
  totalSize: virtualizer.getTotalSize,
58
150
  measureElement: virtualizer.measureElement,
151
+ toggleGroupExpand: function toggleGroupExpand(key) {
152
+ return dispatch({
153
+ type: "groupExpand",
154
+ key: key
155
+ });
156
+ },
157
+ toggleExpand: function toggleExpand(key) {
158
+ return dispatch({
159
+ type: "expand",
160
+ key: key
161
+ });
162
+ },
59
163
  toggleChecked: function toggleChecked(key) {
60
164
  return dispatch({
61
165
  type: "check",
@@ -2,9 +2,11 @@
2
2
 
3
3
  import _defineProperty from '@babel/runtime/helpers/defineProperty';
4
4
  import { getBadgeProps, Icon, CoreIcons, Badge } from '@react-fabric/core';
5
+ import { isString, isEmpty } from '@react-fabric/utilities';
5
6
  import classNames from 'classnames';
6
- import { useMemo } from 'react';
7
- import { jsxs, jsx } from 'react/jsx-runtime';
7
+ import { useMemo, isValidElement } from 'react';
8
+ import { useTranslation } from 'react-i18next';
9
+ import { jsx, jsxs } from '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; }
10
12
  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; }
@@ -17,26 +19,34 @@ 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 = useTranslation("data"),
29
+ t = _useTranslation.t;
23
30
  var badgeProps = useMemo(function () {
24
31
  return getBadgeProps(node.badge);
25
32
  }, [node.badge]);
26
33
  var filler = useMemo(function () {
27
- return node.lines.slice(noLines ? 1 : 0).map(function (line, idx) {
28
- return /*#__PURE__*/jsxs("svg", {
29
- viewBox: "0 0 24 24",
30
- className: "flex-initial w-6 fill-tint-200",
31
- children: [line === 0 && /*#__PURE__*/jsx("path", {
32
- d: ""
33
- }), !noLines && line === 1 && /*#__PURE__*/jsx("path", {
34
- d: "M7.45 26.1v-28.2h1.1v28.2h-1.1z"
35
- }), !noLines && line === 2 && /*#__PURE__*/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__*/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__*/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-[2px] before:scale-x-[.625]", !noLines && line !== 2 && "before:h-full"),
37
+ children: /*#__PURE__*/jsxs("svg", {
38
+ viewBox: "0 0 24 24",
39
+ className: "fill-tint-200 rtl:-scale-x-100",
40
+ children: [line === 0 && /*#__PURE__*/jsx("path", {
41
+ d: ""
42
+ }), !noLines && line === 1 && /*#__PURE__*/jsx("path", {
43
+ d: "M7.45 26.1v-28.2h1.1v28.2h-1.1z"
44
+ }), !noLines && line === 2 && /*#__PURE__*/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__*/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]);
@@ -53,10 +63,16 @@ var TreeNode = function TreeNode(_ref) {
53
63
  return /*#__PURE__*/jsxs("div", {
54
64
  role: "treeitem",
55
65
  "aria-selected": node.selected,
56
- className: "flex flex-nowrap",
66
+ className: classNames("flex flex-nowrap items-center", node.className, node.leaf ? leafClassName : nodeClassName),
57
67
  "data-testid": node["data-testid"],
58
68
  "data-test-value": node["data-test-value"],
59
- children: [filler, !node.leaf && !node.childFiltered && /*#__PURE__*/jsx("div", {
69
+ children: [filler, node.loading && /*#__PURE__*/jsx("div", {
70
+ className: "flex-initial w-6",
71
+ children: /*#__PURE__*/jsx(Icon, {
72
+ icon: CoreIcons.spinner,
73
+ className: "animate-spin text-muted"
74
+ })
75
+ }), !node.leaf && !node.childFiltered && !node.loading && /*#__PURE__*/jsx("div", {
60
76
  className: "flex-initial w-6",
61
77
  children: /*#__PURE__*/jsx(Icon, {
62
78
  rtlFlip: true,
@@ -75,21 +91,22 @@ var TreeNode = function TreeNode(_ref) {
75
91
  icon: node.checked === 2 ? CoreIcons.checkboxInt : node.checked === 1 ? CoreIcons.checkboxOn : CoreIcons.checkboxOff,
76
92
  className: classNames(node.disabled ? "text-muted" : "text-primary-500 hover:text-primary-600")
77
93
  })
78
- }), /*#__PURE__*/jsxs("div", {
94
+ }), !node.empty && /*#__PURE__*/jsxs("div", {
79
95
  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"),
96
+ 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.disabled && (canSelect || onClick) && "hover:bg-primary-50 cursor-pointer"),
81
97
  "data-selected": node.selected,
82
- onClick: function onClick() {
83
- return canSelect ? onSelect(node.id) : canCheck ? onChecked(node.id) : onToggle(node.id);
98
+ onClick: node.disabled ? undefined : function () {
99
+ onClick === null || onClick === void 0 || onClick(node.id, node.data);
100
+ canSelect ? onSelect(node.id) : canCheck ? onChecked(node.id) : onToggle(node.id);
84
101
  },
85
- children: [nodeIcon && /*#__PURE__*/jsx("div", {
86
- className: "flex-content w-6",
87
- children: /*#__PURE__*/jsx(Icon, {
102
+ children: [nodeIcon && /*#__PURE__*/jsxs("div", {
103
+ className: "flex-content w-6 self-center leading-none",
104
+ children: [/*#__PURE__*/isValidElement(nodeIcon) && nodeIcon, isString(nodeIcon) && /*#__PURE__*/jsx(Icon, {
88
105
  icon: nodeIcon,
89
106
  bg: node.iconBg,
90
107
  color: node.iconColor,
91
108
  rtlFlip: node.rtlFlip
92
- })
109
+ })]
93
110
  }), node.childSelected && !node.open && /*#__PURE__*/jsx("span", {
94
111
  className: " flex-content text-primary-500",
95
112
  children: "\u2022"
@@ -97,9 +114,12 @@ var TreeNode = function TreeNode(_ref) {
97
114
  role: "none",
98
115
  className: "flex-1 truncate",
99
116
  children: children
100
- }), node.badge && /*#__PURE__*/jsx(Badge, _objectSpread(_objectSpread({}, badgeProps), {}, {
117
+ }), !isEmpty(node.badge) && /*#__PURE__*/jsx(Badge, _objectSpread(_objectSpread({}, badgeProps), {}, {
101
118
  className: classNames("me-1 self-center flex-content bg-opacity-50", badgeProps.className)
102
119
  }))]
120
+ }), node.empty && /*#__PURE__*/jsx("div", {
121
+ className: "text-muted text-sm select-none",
122
+ children: t("tree.noItems")
103
123
  })]
104
124
  });
105
125
  };
@@ -11,7 +11,7 @@ import { iconExpandAll, iconCollapseAll } from './types.js';
11
11
  import { useTree } from './useTree.js';
12
12
  import { jsxs, jsx } from 'react/jsx-runtime';
13
13
 
14
- var _excluded = ["ref", "items", "selected", "checked", "checkable", "noLines", "renderer", "searchable", "selectable", "matcher", "filterPlaceholder", "defaultLeafIcon", "defaultNodeIcon", "expander", "onChecked", "onLoad", "onSelect"];
14
+ var _excluded = ["ref", "items", "selected", "checked", "checkable", "noLines", "renderer", "searchable", "selectable", "matcher", "filterPlaceholder", "defaultLeafIcon", "defaultNodeIcon", "expander", "onChecked", "onLoad", "onQuery", "onSelect", "onClick", "sorter", "makeLabel", "makeIcon", "defaultExpanded", "onExpandToggle", "leafClassName", "nodeClassName"];
15
15
  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; }
16
16
  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; }
17
17
  var TreePanel = function TreePanel(_ref) {
@@ -31,24 +31,38 @@ var TreePanel = function TreePanel(_ref) {
31
31
  defaultNodeIcon = _ref.defaultNodeIcon,
32
32
  _ref$expander = _ref.expander,
33
33
  expander = _ref$expander === void 0 ? "box" : _ref$expander,
34
- onChecked = _ref.onChecked;
35
- _ref.onLoad;
36
- var onSelect = _ref.onSelect,
34
+ onChecked = _ref.onChecked,
35
+ onLoad = _ref.onLoad,
36
+ onQuery = _ref.onQuery,
37
+ onSelect = _ref.onSelect,
38
+ onClick = _ref.onClick,
39
+ sorter = _ref.sorter,
40
+ makeLabel = _ref.makeLabel,
41
+ makeIcon = _ref.makeIcon,
42
+ defaultExpanded = _ref.defaultExpanded,
43
+ onExpandToggle = _ref.onExpandToggle,
44
+ leafClassName = _ref.leafClassName,
45
+ nodeClassName = _ref.nodeClassName,
37
46
  aria = _objectWithoutProperties(_ref, _excluded);
38
47
  var _useTree = useTree({
39
48
  items: items,
40
49
  checked: checked,
41
50
  selected: selected,
42
51
  matcher: matcher,
52
+ sorter: sorter,
53
+ onLoad: onLoad,
54
+ onQuery: onQuery,
43
55
  onSelect: onSelect,
44
- onChecked: onChecked
56
+ onChecked: onChecked,
57
+ defaultExpanded: defaultExpanded,
58
+ onExpandToggle: onExpandToggle
45
59
  }),
46
60
  tree = _useTree.tree,
47
61
  toggleExpand = _useTree.toggleExpand,
48
62
  toggleCheck = _useTree.toggleCheck,
49
63
  expandAll = _useTree.expandAll,
50
64
  collapseAll = _useTree.collapseAll,
51
- select = _useTree.select,
65
+ _select = _useTree.select,
52
66
  expand = _useTree.expand,
53
67
  onFilter = _useTree.onFilter;
54
68
  var scrollerRef = useRef(null);
@@ -74,7 +88,7 @@ var TreePanel = function TreePanel(_ref) {
74
88
  return expand(id);
75
89
  },
76
90
  select: function select(id) {
77
- return expand(id);
91
+ return _select(id);
78
92
  }
79
93
  };
80
94
  }, []);
@@ -120,6 +134,7 @@ var TreePanel = function TreePanel(_ref) {
120
134
  height: (_virtualItems$ = virtualItems[0]) === null || _virtualItems$ === void 0 ? void 0 : _virtualItems$.start
121
135
  }
122
136
  }), virtualItems.map(function (_ref2) {
137
+ var _makeIcon, _ref3, _ref4;
123
138
  var index = _ref2.index,
124
139
  key = _ref2.key;
125
140
  return /*#__PURE__*/jsx("div", {
@@ -132,11 +147,14 @@ var TreePanel = function TreePanel(_ref) {
132
147
  checkable: checkable,
133
148
  selectable: selectable,
134
149
  defaultLeafIcon: defaultLeafIcon,
135
- defaultNodeIcon: defaultNodeIcon,
150
+ defaultNodeIcon: (_makeIcon = makeIcon === null || makeIcon === void 0 ? void 0 : makeIcon(tree[index].data)) !== null && _makeIcon !== void 0 ? _makeIcon : defaultNodeIcon,
136
151
  onToggle: toggleExpand,
137
152
  onChecked: toggleCheck,
138
- onSelect: select,
139
- children: tree[index].data && (renderer === null || renderer === void 0 ? void 0 : renderer(tree[index].data)) || tree[index].label
153
+ onSelect: _select,
154
+ onClick: onClick,
155
+ leafClassName: leafClassName,
156
+ nodeClassName: nodeClassName,
157
+ children: (_ref3 = (_ref4 = tree[index].data && (renderer === null || renderer === void 0 ? void 0 : renderer(tree[index].data))) !== null && _ref4 !== void 0 ? _ref4 : makeLabel === null || makeLabel === void 0 ? void 0 : makeLabel(tree[index].data)) !== null && _ref3 !== void 0 ? _ref3 : tree[index].label
140
158
  })
141
159
  }, key);
142
160
  })]
@@ -5,8 +5,8 @@ import _slicedToArray from '@babel/runtime/helpers/slicedToArray';
5
5
  import { useDebounce } from '@react-fabric/core';
6
6
  import { EMPTY_ARRAY } from '@react-fabric/utilities';
7
7
  import memoizeOne from 'memoize-one';
8
- import { useRef, useReducer, useEffect, useCallback } from 'react';
9
- import { refactorTree, makeTreeMap, flattenTree, filterTree, updateSelection, updateChecked } from './utils.js';
8
+ import { useRef, useCallback, useReducer, useEffect } from 'react';
9
+ import { refactorTree, makeTreeMap, flattenTree, updateSelection, filterTree, updateChecked } from './utils.js';
10
10
 
11
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; }
12
12
  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; }
@@ -19,39 +19,110 @@ var useTree = function useTree(_ref) {
19
19
  _ref$checked = _ref.checked,
20
20
  checked = _ref$checked === void 0 ? EMPTY_ARRAY : _ref$checked,
21
21
  selected = _ref.selected,
22
+ sorter = _ref.sorter,
22
23
  matcher = _ref.matcher,
24
+ onLoad = _ref.onLoad,
25
+ onQuery = _ref.onQuery,
23
26
  onSelect = _ref.onSelect,
24
- onChecked = _ref.onChecked;
27
+ onChecked = _ref.onChecked,
28
+ defaultExpanded = _ref.defaultExpanded,
29
+ onExpandToggle = _ref.onExpandToggle;
25
30
  var componentEvents = useRef({
26
31
  onSelect: onSelect,
27
32
  onChecked: onChecked
28
33
  });
34
+ var intialExpand = useRef(defaultExpanded !== null && defaultExpanded !== void 0 ? defaultExpanded : EMPTY_ARRAY);
29
35
  var itemList = createItemList(items);
36
+ var fireExpandToggle = useCallback(function (itemMap) {
37
+ var expandedList = itemMap.filter(function (node) {
38
+ return node.open;
39
+ }).map(function (node) {
40
+ return node.id;
41
+ });
42
+ setTimeout(function () {
43
+ return onExpandToggle === null || onExpandToggle === void 0 ? void 0 : onExpandToggle(expandedList);
44
+ }, 100);
45
+ }, [onExpandToggle]);
46
+ var loadChildren = useCallback(function (node) {
47
+ var _node$children;
48
+ if (node.open && !node.leaf && !((_node$children = node.children) !== null && _node$children !== void 0 && _node$children.length)) {
49
+ node.loading = true;
50
+ void Promise.resolve(onLoad === null || onLoad === void 0 ? void 0 : onLoad(node.id)).then(function () {
51
+ var resp = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : EMPTY_ARRAY;
52
+ node.children = refactorTree(resp, {
53
+ sorter: sorter,
54
+ defaultExpanded: defaultExpanded
55
+ }, {
56
+ level: node.level + 1,
57
+ parent: node.id
58
+ });
59
+ })["finally"](function () {
60
+ var _intialExpand$current;
61
+ node.loading = false;
62
+ dispatch({
63
+ type: "loaded"
64
+ });
65
+ ((_intialExpand$current = intialExpand.current) === null || _intialExpand$current === void 0 ? void 0 : _intialExpand$current.length) > 0 && dispatch({
66
+ type: "expand",
67
+ id: intialExpand.current.shift()
68
+ });
69
+ });
70
+ } else {
71
+ var _intialExpand$current2;
72
+ dispatch({
73
+ type: "loaded"
74
+ });
75
+ ((_intialExpand$current2 = intialExpand.current) === null || _intialExpand$current2 === void 0 ? void 0 : _intialExpand$current2.length) > 0 && dispatch({
76
+ type: "expand",
77
+ id: intialExpand.current.shift()
78
+ });
79
+ }
80
+ }, [onLoad]);
30
81
  var _useReducer = useReducer(function (state, action) {
31
82
  if (action.type === "load") {
32
- state.items = refactorTree(action.items);
83
+ state.items = refactorTree(action.items, {
84
+ sorter: sorter,
85
+ defaultExpanded: defaultExpanded
86
+ });
33
87
  state.itemMap = makeTreeMap(state.items);
34
88
  state.tree = flattenTree(state.items);
35
89
  return _objectSpread({}, state);
36
90
  }
37
91
  if (action.type === "toggleExpand") {
38
92
  var node = state.itemMap.get(action.id);
39
- node && (node.open = !node.open);
93
+ if (node && !node.leaf) {
94
+ node && (node.open = !node.open);
95
+ loadChildren(node);
96
+ return _objectSpread({}, state);
97
+ }
98
+ }
99
+ if (action.type === "loaded") {
100
+ state.itemMap = makeTreeMap(state.items);
101
+ fireExpandToggle(Array.from(state.itemMap.values()));
40
102
  state.tree = flattenTree(state.items);
103
+ state.selected && updateSelection(state.itemMap, state.selected, true);
41
104
  return _objectSpread({}, state);
42
105
  }
43
106
  if (action.type === "expand") {
44
- // TODO: check if children available, if not call onLoad to fetch node children
45
107
  var _node = state.itemMap.get(action.id);
46
- _node && (_node.open = true);
47
- state.tree = flattenTree(state.items);
48
- return _objectSpread({}, state);
108
+ if (_node && !_node.leaf) {
109
+ _node.open = true;
110
+ var parentId = _node.parent;
111
+ while (parentId) {
112
+ var _node2 = state.itemMap.get(parentId);
113
+ _node2 && (_node2.open = true);
114
+ parentId = _node2 === null || _node2 === void 0 ? void 0 : _node2.parent;
115
+ }
116
+ loadChildren(_node);
117
+ return _objectSpread({}, state);
118
+ }
49
119
  }
50
120
  if (action.type === "expandAll") {
51
- // TODO: prevent opening dynamic nodes that dont have children
52
121
  state.itemMap.forEach(function (node) {
53
- !node.leaf && (node.open = true);
122
+ var _node$children2;
123
+ !node.leaf && ((_node$children2 = node.children) === null || _node$children2 === void 0 ? void 0 : _node$children2.length) && (node.open = true);
54
124
  });
125
+ fireExpandToggle(Array.from(state.itemMap.values()));
55
126
  state.tree = flattenTree(state.items);
56
127
  return _objectSpread({}, state);
57
128
  }
@@ -59,22 +130,28 @@ var useTree = function useTree(_ref) {
59
130
  state.itemMap.forEach(function (node) {
60
131
  !node.leaf && (node.open = false);
61
132
  });
133
+ fireExpandToggle([]);
62
134
  state.tree = flattenTree(state.items);
63
135
  return _objectSpread({}, state);
64
136
  }
65
137
  if (action.type === "filter") {
66
- filterTree(state.itemMap, action.query, matcher);
67
- state.tree = flattenTree(state.items);
68
- return _objectSpread({}, state);
138
+ if (onQuery) {
139
+ var _action$query;
140
+ onQuery((_action$query = action.query) !== null && _action$query !== void 0 ? _action$query : "");
141
+ } else {
142
+ filterTree(state.itemMap, action.query, matcher);
143
+ state.tree = flattenTree(state.items);
144
+ return _objectSpread({}, state);
145
+ }
69
146
  }
70
147
  if (action.type === "select") {
71
- var _componentEvents$curr, _componentEvents$curr2;
148
+ var _componentEvents$curr, _componentEvents$curr2, _state$itemMap$get;
72
149
  if (state.selected) {
73
150
  updateSelection(state.itemMap, state.selected);
74
151
  }
75
152
  updateSelection(state.itemMap, action.id, true);
76
153
  state.tree = flattenTree(state.items);
77
- (_componentEvents$curr = (_componentEvents$curr2 = componentEvents.current).onSelect) === null || _componentEvents$curr === void 0 || _componentEvents$curr.call(_componentEvents$curr2, action.id);
154
+ (_componentEvents$curr = (_componentEvents$curr2 = componentEvents.current).onSelect) === null || _componentEvents$curr === void 0 || _componentEvents$curr.call(_componentEvents$curr2, action.id, (_state$itemMap$get = state.itemMap.get(action.id)) === null || _state$itemMap$get === void 0 ? void 0 : _state$itemMap$get.data);
78
155
  return _objectSpread(_objectSpread({}, state), {}, {
79
156
  selected: action.id
80
157
  });
@@ -116,10 +193,15 @@ var useTree = function useTree(_ref) {
116
193
  };
117
194
  }, [onSelect, onChecked]);
118
195
  useEffect(function () {
196
+ var _intialExpand$current3;
119
197
  dispatch({
120
198
  type: "load",
121
199
  items: itemList
122
200
  });
201
+ itemList.length && ((_intialExpand$current3 = intialExpand.current) === null || _intialExpand$current3 === void 0 ? void 0 : _intialExpand$current3.length) > 0 && dispatch({
202
+ type: "expand",
203
+ id: intialExpand.current.shift()
204
+ });
123
205
  }, [itemList]);
124
206
  useEffect(function () {
125
207
  selected && dispatch({
@@ -172,7 +254,7 @@ var useTree = function useTree(_ref) {
172
254
  type: "filter",
173
255
  query: query
174
256
  });
175
- }, []);
257
+ }, [], 300);
176
258
  return {
177
259
  tree: state.tree,
178
260
  toggleExpand: toggleExpand,
@@ -6,7 +6,7 @@ import { isString, matchString, compareValues } from '@react-fabric/utilities';
6
6
 
7
7
  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; }
8
8
  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; }
9
- var sorter = function sorter(a, b) {
9
+ var defaultSorter = function defaultSorter(a, b) {
10
10
  if (!!a.leaf !== !!b.leaf) return a.leaf ? 1 : -1;
11
11
  return compareValues()(a.label, b.label);
12
12
  };
@@ -28,15 +28,21 @@ var getIntermediate = function getIntermediate() {
28
28
  };
29
29
 
30
30
  // convert node item to internal node used by the tree
31
- var refactorTree = function refactorTree(nodes) {
32
- var options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {
31
+ var refactorTree = function refactorTree(nodes, _ref) {
32
+ var _ref$sorter = _ref.sorter,
33
+ sorter = _ref$sorter === void 0 ? defaultSorter : _ref$sorter,
34
+ _ref$defaultExpanded = _ref.defaultExpanded,
35
+ defaultExpanded = _ref$defaultExpanded === void 0 ? [] : _ref$defaultExpanded;
36
+ var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {
33
37
  level: 0,
34
38
  parent: undefined
35
39
  };
36
40
  var list = [];
37
- nodes.sort(sorter).forEach(function (node) {
41
+ if (sorter !== false) nodes = nodes.sort(sorter);
42
+ nodes.forEach(function (node) {
43
+ var _node$children;
38
44
  list.push(_objectSpread(_objectSpread({
39
- open: false,
45
+ open: defaultExpanded.includes(node.id) && !!((_node$children = node.children) !== null && _node$children !== void 0 && _node$children.length),
40
46
  level: options.level,
41
47
  parent: options.parent,
42
48
  checked: 0,
@@ -47,6 +53,9 @@ var refactorTree = function refactorTree(nodes) {
47
53
  }, node), {}, {
48
54
  leaf: !!node.leaf,
49
55
  children: node.children && refactorTree(node.children, {
56
+ sorter: sorter,
57
+ defaultExpanded: defaultExpanded
58
+ }, {
50
59
  level: options.level + 1,
51
60
  parent: node.id
52
61
  })
@@ -72,11 +81,17 @@ var flattenTree = function flattenTree(nodes) {
72
81
  return !node.filtered;
73
82
  });
74
83
  filtered.forEach(function (node, idx) {
84
+ var _node$children2;
75
85
  node.lines = [].concat(_toConsumableArray(lines), [idx === filtered.length - 1 ? 2 : 3]);
76
86
  list.push(node);
77
87
  (node.open || node.childFiltered) && node.children && list.push.apply(list, _toConsumableArray(flattenTree(node.children.filter(function (child) {
78
88
  return !child.filtered;
79
89
  }), [].concat(_toConsumableArray(lines), [idx === filtered.length - 1 ? 0 : 1]))));
90
+ node.open && ((_node$children2 = node.children) === null || _node$children2 === void 0 ? void 0 : _node$children2.length) === 0 && list.push({
91
+ empty: true,
92
+ leaf: true,
93
+ lines: [].concat(_toConsumableArray(lines), [idx === filtered.length - 1 ? 0 : 1, 2])
94
+ });
80
95
  });
81
96
  return list;
82
97
  };