@react-fabric/data 1.0.0-beta.27 → 1.0.0-beta.28

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.
@@ -5,6 +5,7 @@ var core = require('@react-fabric/core');
5
5
  var utilities = require('@react-fabric/utilities');
6
6
  var classNames = require('classnames');
7
7
  var react = require('react');
8
+ var reactI18next = require('react-i18next');
8
9
  var jsxRuntime = require('react/jsx-runtime');
9
10
 
10
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; }
@@ -24,6 +25,8 @@ var TreeNode = function TreeNode(_ref) {
24
25
  children = _ref.children,
25
26
  leafClassName = _ref.leafClassName,
26
27
  nodeClassName = _ref.nodeClassName;
28
+ var _useTranslation = reactI18next.useTranslation("data"),
29
+ t = _useTranslation.t;
27
30
  var badgeProps = react.useMemo(function () {
28
31
  return core.getBadgeProps(node.badge);
29
32
  }, [node.badge]);
@@ -89,7 +92,7 @@ var TreeNode = function TreeNode(_ref) {
89
92
  icon: node.checked === 2 ? core.CoreIcons.checkboxInt : node.checked === 1 ? core.CoreIcons.checkboxOn : core.CoreIcons.checkboxOff,
90
93
  className: classNames(node.disabled ? "text-muted" : "text-primary-500 hover:text-primary-600")
91
94
  })
92
- }), /*#__PURE__*/jsxRuntime.jsxs("div", {
95
+ }), !node.empty && /*#__PURE__*/jsxRuntime.jsxs("div", {
93
96
  role: "none",
94
97
  className: classNames("group/tool data-[selected]:bg-primary-100 flex flex-nowrap flex-1 overflow-hidden select-none", node.childSelected && "font-medium", (canSelect || _onClick) && "hover:bg-primary-50 cursor-pointer"),
95
98
  "data-selected": node.selected,
@@ -115,6 +118,9 @@ var TreeNode = function TreeNode(_ref) {
115
118
  }), !utilities.isEmpty(node.badge) && /*#__PURE__*/jsxRuntime.jsx(core.Badge, _objectSpread(_objectSpread({}, badgeProps), {}, {
116
119
  className: classNames("me-1 self-center flex-content bg-opacity-50", badgeProps.className)
117
120
  }))]
121
+ }), node.empty && /*#__PURE__*/jsxRuntime.jsx("div", {
122
+ className: "text-muted text-sm select-none",
123
+ children: t("tree.noItems")
118
124
  })]
119
125
  });
120
126
  };
@@ -11,7 +11,7 @@ var types = require('./types.js');
11
11
  var useTree = require('./useTree.js');
12
12
  var jsxRuntime = require('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", "onClick", "sorter", "makeLabel", "makeIcon", "defaultExpanded", "onExpandToggle", "leafClassName", "nodeClassName"];
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) {
@@ -33,6 +33,7 @@ var TreePanel = function TreePanel(_ref) {
33
33
  expander = _ref$expander === void 0 ? "box" : _ref$expander,
34
34
  onChecked = _ref.onChecked,
35
35
  onLoad = _ref.onLoad,
36
+ onQuery = _ref.onQuery,
36
37
  onSelect = _ref.onSelect,
37
38
  onClick = _ref.onClick,
38
39
  sorter = _ref.sorter,
@@ -50,6 +51,7 @@ var TreePanel = function TreePanel(_ref) {
50
51
  matcher: matcher,
51
52
  sorter: sorter,
52
53
  onLoad: onLoad,
54
+ onQuery: onQuery,
53
55
  onSelect: onSelect,
54
56
  onChecked: onChecked,
55
57
  defaultExpanded: defaultExpanded,
@@ -22,6 +22,7 @@ var useTree = function useTree(_ref) {
22
22
  sorter = _ref.sorter,
23
23
  matcher = _ref.matcher,
24
24
  onLoad = _ref.onLoad,
25
+ onQuery = _ref.onQuery,
25
26
  onSelect = _ref.onSelect,
26
27
  onChecked = _ref.onChecked,
27
28
  defaultExpanded = _ref.defaultExpanded,
@@ -132,9 +133,14 @@ var useTree = function useTree(_ref) {
132
133
  return _objectSpread({}, state);
133
134
  }
134
135
  if (action.type === "filter") {
135
- utils.filterTree(state.itemMap, action.query, matcher);
136
- state.tree = utils.flattenTree(state.items);
137
- return _objectSpread({}, state);
136
+ if (onQuery) {
137
+ var _action$query;
138
+ onQuery((_action$query = action.query) !== null && _action$query !== void 0 ? _action$query : "");
139
+ } else {
140
+ utils.filterTree(state.itemMap, action.query, matcher);
141
+ state.tree = utils.flattenTree(state.items);
142
+ return _objectSpread({}, state);
143
+ }
138
144
  }
139
145
  if (action.type === "select") {
140
146
  var _componentEvents$curr, _componentEvents$curr2, _state$itemMap$get;
@@ -190,7 +196,7 @@ var useTree = function useTree(_ref) {
190
196
  type: "load",
191
197
  items: itemList
192
198
  });
193
- ((_intialExpand$current3 = intialExpand.current) === null || _intialExpand$current3 === void 0 ? void 0 : _intialExpand$current3.length) > 0 && dispatch({
199
+ itemList.length && ((_intialExpand$current3 = intialExpand.current) === null || _intialExpand$current3 === void 0 ? void 0 : _intialExpand$current3.length) > 0 && dispatch({
194
200
  type: "expand",
195
201
  id: intialExpand.current.shift()
196
202
  });
@@ -40,9 +40,9 @@ var refactorTree = function refactorTree(nodes, _ref) {
40
40
  var list = [];
41
41
  if (sorter !== false) nodes = nodes.sort(sorter);
42
42
  nodes.forEach(function (node) {
43
+ var _node$children;
43
44
  list.push(_objectSpread(_objectSpread({
44
- open: false,
45
- // defaultExpanded.includes(node.id),
45
+ open: defaultExpanded.includes(node.id) && !!((_node$children = node.children) !== null && _node$children !== void 0 && _node$children.length),
46
46
  level: options.level,
47
47
  parent: options.parent,
48
48
  checked: 0,
@@ -81,11 +81,17 @@ var flattenTree = function flattenTree(nodes) {
81
81
  return !node.filtered;
82
82
  });
83
83
  filtered.forEach(function (node, idx) {
84
+ var _node$children2;
84
85
  node.lines = [].concat(_toConsumableArray(lines), [idx === filtered.length - 1 ? 2 : 3]);
85
86
  list.push(node);
86
87
  (node.open || node.childFiltered) && node.children && list.push.apply(list, _toConsumableArray(flattenTree(node.children.filter(function (child) {
87
88
  return !child.filtered;
88
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
+ });
89
95
  });
90
96
  return list;
91
97
  };
@@ -5,6 +5,7 @@ import { getBadgeProps, Icon, CoreIcons, Badge } from '@react-fabric/core';
5
5
  import { isString, isEmpty } from '@react-fabric/utilities';
6
6
  import classNames from 'classnames';
7
7
  import { useMemo, isValidElement } from 'react';
8
+ import { useTranslation } from 'react-i18next';
8
9
  import { jsx, jsxs } from 'react/jsx-runtime';
9
10
 
10
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; }
@@ -24,6 +25,8 @@ var TreeNode = function TreeNode(_ref) {
24
25
  children = _ref.children,
25
26
  leafClassName = _ref.leafClassName,
26
27
  nodeClassName = _ref.nodeClassName;
28
+ var _useTranslation = useTranslation("data"),
29
+ t = _useTranslation.t;
27
30
  var badgeProps = useMemo(function () {
28
31
  return getBadgeProps(node.badge);
29
32
  }, [node.badge]);
@@ -89,7 +92,7 @@ var TreeNode = function TreeNode(_ref) {
89
92
  icon: node.checked === 2 ? CoreIcons.checkboxInt : node.checked === 1 ? CoreIcons.checkboxOn : CoreIcons.checkboxOff,
90
93
  className: classNames(node.disabled ? "text-muted" : "text-primary-500 hover:text-primary-600")
91
94
  })
92
- }), /*#__PURE__*/jsxs("div", {
95
+ }), !node.empty && /*#__PURE__*/jsxs("div", {
93
96
  role: "none",
94
97
  className: classNames("group/tool data-[selected]:bg-primary-100 flex flex-nowrap flex-1 overflow-hidden select-none", node.childSelected && "font-medium", (canSelect || _onClick) && "hover:bg-primary-50 cursor-pointer"),
95
98
  "data-selected": node.selected,
@@ -115,6 +118,9 @@ var TreeNode = function TreeNode(_ref) {
115
118
  }), !isEmpty(node.badge) && /*#__PURE__*/jsx(Badge, _objectSpread(_objectSpread({}, badgeProps), {}, {
116
119
  className: classNames("me-1 self-center flex-content bg-opacity-50", badgeProps.className)
117
120
  }))]
121
+ }), node.empty && /*#__PURE__*/jsx("div", {
122
+ className: "text-muted text-sm select-none",
123
+ children: t("tree.noItems")
118
124
  })]
119
125
  });
120
126
  };
@@ -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", "onClick", "sorter", "makeLabel", "makeIcon", "defaultExpanded", "onExpandToggle", "leafClassName", "nodeClassName"];
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) {
@@ -33,6 +33,7 @@ var TreePanel = function TreePanel(_ref) {
33
33
  expander = _ref$expander === void 0 ? "box" : _ref$expander,
34
34
  onChecked = _ref.onChecked,
35
35
  onLoad = _ref.onLoad,
36
+ onQuery = _ref.onQuery,
36
37
  onSelect = _ref.onSelect,
37
38
  onClick = _ref.onClick,
38
39
  sorter = _ref.sorter,
@@ -50,6 +51,7 @@ var TreePanel = function TreePanel(_ref) {
50
51
  matcher: matcher,
51
52
  sorter: sorter,
52
53
  onLoad: onLoad,
54
+ onQuery: onQuery,
53
55
  onSelect: onSelect,
54
56
  onChecked: onChecked,
55
57
  defaultExpanded: defaultExpanded,
@@ -22,6 +22,7 @@ var useTree = function useTree(_ref) {
22
22
  sorter = _ref.sorter,
23
23
  matcher = _ref.matcher,
24
24
  onLoad = _ref.onLoad,
25
+ onQuery = _ref.onQuery,
25
26
  onSelect = _ref.onSelect,
26
27
  onChecked = _ref.onChecked,
27
28
  defaultExpanded = _ref.defaultExpanded,
@@ -132,9 +133,14 @@ var useTree = function useTree(_ref) {
132
133
  return _objectSpread({}, state);
133
134
  }
134
135
  if (action.type === "filter") {
135
- filterTree(state.itemMap, action.query, matcher);
136
- state.tree = flattenTree(state.items);
137
- return _objectSpread({}, state);
136
+ if (onQuery) {
137
+ var _action$query;
138
+ onQuery((_action$query = action.query) !== null && _action$query !== void 0 ? _action$query : "");
139
+ } else {
140
+ filterTree(state.itemMap, action.query, matcher);
141
+ state.tree = flattenTree(state.items);
142
+ return _objectSpread({}, state);
143
+ }
138
144
  }
139
145
  if (action.type === "select") {
140
146
  var _componentEvents$curr, _componentEvents$curr2, _state$itemMap$get;
@@ -190,7 +196,7 @@ var useTree = function useTree(_ref) {
190
196
  type: "load",
191
197
  items: itemList
192
198
  });
193
- ((_intialExpand$current3 = intialExpand.current) === null || _intialExpand$current3 === void 0 ? void 0 : _intialExpand$current3.length) > 0 && dispatch({
199
+ itemList.length && ((_intialExpand$current3 = intialExpand.current) === null || _intialExpand$current3 === void 0 ? void 0 : _intialExpand$current3.length) > 0 && dispatch({
194
200
  type: "expand",
195
201
  id: intialExpand.current.shift()
196
202
  });
@@ -40,9 +40,9 @@ var refactorTree = function refactorTree(nodes, _ref) {
40
40
  var list = [];
41
41
  if (sorter !== false) nodes = nodes.sort(sorter);
42
42
  nodes.forEach(function (node) {
43
+ var _node$children;
43
44
  list.push(_objectSpread(_objectSpread({
44
- open: false,
45
- // defaultExpanded.includes(node.id),
45
+ open: defaultExpanded.includes(node.id) && !!((_node$children = node.children) !== null && _node$children !== void 0 && _node$children.length),
46
46
  level: options.level,
47
47
  parent: options.parent,
48
48
  checked: 0,
@@ -81,11 +81,17 @@ var flattenTree = function flattenTree(nodes) {
81
81
  return !node.filtered;
82
82
  });
83
83
  filtered.forEach(function (node, idx) {
84
+ var _node$children2;
84
85
  node.lines = [].concat(_toConsumableArray(lines), [idx === filtered.length - 1 ? 2 : 3]);
85
86
  list.push(node);
86
87
  (node.open || node.childFiltered) && node.children && list.push.apply(list, _toConsumableArray(flattenTree(node.children.filter(function (child) {
87
88
  return !child.filtered;
88
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
+ });
89
95
  });
90
96
  return list;
91
97
  };
@@ -1,2 +1,2 @@
1
1
  import { type TreePanelProps } from "./types";
2
- export declare const TreePanel: <T extends KeyValue<any>>({ ref, items, selected, checked, checkable, noLines, renderer, searchable, selectable, matcher, filterPlaceholder, defaultLeafIcon, defaultNodeIcon, expander, onChecked, onLoad, onSelect, onClick, sorter, makeLabel, makeIcon, defaultExpanded, onExpandToggle, leafClassName, nodeClassName, ...aria }: TreePanelProps<T>) => import("react/jsx-runtime").JSX.Element;
2
+ export declare const TreePanel: <T extends KeyValue<any>>({ 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, ...aria }: TreePanelProps<T>) => import("react/jsx-runtime").JSX.Element;
@@ -125,6 +125,10 @@ export interface TreePanelProps<T extends KeyValue = KeyValue> extends TestProps
125
125
  * callback for lazy loading tree items
126
126
  */
127
127
  onLoad?: (id: string) => Promise<Array<TreeNodeType<T>> | undefined> | Array<TreeNodeType<T>> | undefined;
128
+ /**
129
+ * callback to load tree using search query
130
+ */
131
+ onQuery?: (query: string) => void;
128
132
  /**
129
133
  * callback on click of tree node
130
134
  */
@@ -1,5 +1,5 @@
1
1
  import { type InternalNode, type TreePanelProps } from "./types";
2
- export declare const useTree: <T extends KeyValue<any>>({ items, checked, selected, sorter, matcher, onLoad, onSelect, onChecked, defaultExpanded, onExpandToggle, }: Partial<TreePanelProps<T>>) => {
2
+ export declare const useTree: <T extends KeyValue<any>>({ items, checked, selected, sorter, matcher, onLoad, onQuery, onSelect, onChecked, defaultExpanded, onExpandToggle, }: Partial<TreePanelProps<T>>) => {
3
3
  tree: InternalNode[];
4
4
  toggleExpand: (id: string) => void;
5
5
  expandAll: () => void;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-fabric/data",
3
- "version": "1.0.0-beta.27",
3
+ "version": "1.0.0-beta.28",
4
4
  "description": "RUF: Data package",
5
5
  "author": "Adarsh Pastakia <adarshpastakia@outlook.com>",
6
6
  "license": "MIT",
@@ -33,10 +33,10 @@
33
33
  "watch": "npm-run-all -p watch:rollup watch:dts"
34
34
  },
35
35
  "dependencies": {
36
- "@react-fabric/core": "^1.0.0-beta.27",
37
- "@react-fabric/date": "^1.0.0-beta.27",
38
- "@react-fabric/form": "^1.0.0-beta.27",
39
- "@react-fabric/utilities": "^1.0.0-beta.27",
36
+ "@react-fabric/core": "^1.0.0-beta.28",
37
+ "@react-fabric/date": "^1.0.0-beta.28",
38
+ "@react-fabric/form": "^1.0.0-beta.28",
39
+ "@react-fabric/utilities": "^1.0.0-beta.28",
40
40
  "@tanstack/react-virtual": "^3.8.6",
41
41
  "classnames": "^2.5.1",
42
42
  "color": "^4.2.3",
@@ -52,5 +52,5 @@
52
52
  "node": ">=18.12.0",
53
53
  "npm": ">=8.19.0"
54
54
  },
55
- "gitHead": "02ddac152718fe86b6003f35ea5e1ef1581168f2"
55
+ "gitHead": "80f9d8a9f96dbd0e7a4287087e23996682bf2c0a"
56
56
  }
@@ -25,6 +25,7 @@ import { Badge, CoreIcons, getBadgeProps, Icon } from "@react-fabric/core";
25
25
  import { isEmpty, isString } from "@react-fabric/utilities";
26
26
  import classNames from "classnames";
27
27
  import { isValidElement, useMemo } from "react";
28
+ import { useTranslation } from "react-i18next";
28
29
  import { type TreeNodeProps } from "./types";
29
30
 
30
31
  export const TreeNode = ({
@@ -43,6 +44,7 @@ export const TreeNode = ({
43
44
  leafClassName,
44
45
  nodeClassName,
45
46
  }: TreeNodeProps) => {
47
+ const { t } = useTranslation("data");
46
48
  const badgeProps = useMemo(() => {
47
49
  return getBadgeProps(node.badge);
48
50
  }, [node.badge]);
@@ -141,52 +143,59 @@ export const TreeNode = ({
141
143
  />
142
144
  </div>
143
145
  )}
144
- <div
145
- role="none"
146
- className={classNames(
147
- "group/tool data-[selected]:bg-primary-100 flex flex-nowrap flex-1 overflow-hidden select-none",
148
- node.childSelected && "font-medium",
149
- (canSelect || onClick) && "hover:bg-primary-50 cursor-pointer",
150
- )}
151
- data-selected={node.selected}
152
- onClick={() => {
153
- onClick?.(node.id, node.data);
154
- canSelect
155
- ? onSelect(node.id)
156
- : canCheck
157
- ? onChecked(node.id)
158
- : onToggle(node.id);
159
- }}
160
- >
161
- {nodeIcon && (
162
- <div className="flex-content w-6 self-center leading-none">
163
- {isValidElement(nodeIcon) && nodeIcon}
164
- {isString(nodeIcon) && (
165
- <Icon
166
- icon={nodeIcon}
167
- bg={node.iconBg}
168
- color={node.iconColor}
169
- rtlFlip={node.rtlFlip}
170
- />
171
- )}
146
+ {!node.empty && (
147
+ <div
148
+ role="none"
149
+ className={classNames(
150
+ "group/tool data-[selected]:bg-primary-100 flex flex-nowrap flex-1 overflow-hidden select-none",
151
+ node.childSelected && "font-medium",
152
+ (canSelect || onClick) && "hover:bg-primary-50 cursor-pointer",
153
+ )}
154
+ data-selected={node.selected}
155
+ onClick={() => {
156
+ onClick?.(node.id, node.data);
157
+ canSelect
158
+ ? onSelect(node.id)
159
+ : canCheck
160
+ ? onChecked(node.id)
161
+ : onToggle(node.id);
162
+ }}
163
+ >
164
+ {nodeIcon && (
165
+ <div className="flex-content w-6 self-center leading-none">
166
+ {isValidElement(nodeIcon) && nodeIcon}
167
+ {isString(nodeIcon) && (
168
+ <Icon
169
+ icon={nodeIcon}
170
+ bg={node.iconBg}
171
+ color={node.iconColor}
172
+ rtlFlip={node.rtlFlip}
173
+ />
174
+ )}
175
+ </div>
176
+ )}
177
+ {node.childSelected && !node.open && (
178
+ <span className=" flex-content text-primary-500">•</span>
179
+ )}
180
+ <div role="none" className="flex-1 truncate">
181
+ {children}
172
182
  </div>
173
- )}
174
- {node.childSelected && !node.open && (
175
- <span className=" flex-content text-primary-500">•</span>
176
- )}
177
- <div role="none" className="flex-1 truncate">
178
- {children}
183
+ {!isEmpty(node.badge) && (
184
+ <Badge
185
+ {...badgeProps}
186
+ className={classNames(
187
+ "me-1 self-center flex-content bg-opacity-50",
188
+ badgeProps.className,
189
+ )}
190
+ />
191
+ )}
179
192
  </div>
180
- {!isEmpty(node.badge) && (
181
- <Badge
182
- {...badgeProps}
183
- className={classNames(
184
- "me-1 self-center flex-content bg-opacity-50",
185
- badgeProps.className,
186
- )}
187
- />
188
- )}
189
- </div>
193
+ )}
194
+ {node.empty && (
195
+ <div className="text-muted text-sm select-none">
196
+ {t("tree.noItems")}
197
+ </div>
198
+ )}
190
199
  </div>
191
200
  );
192
201
  };
@@ -55,6 +55,7 @@ export const TreePanel = <T extends KeyValue>({
55
55
  expander = "box",
56
56
  onChecked,
57
57
  onLoad,
58
+ onQuery,
58
59
  onSelect,
59
60
  onClick,
60
61
  sorter,
@@ -82,6 +83,7 @@ export const TreePanel = <T extends KeyValue>({
82
83
  matcher,
83
84
  sorter,
84
85
  onLoad,
86
+ onQuery,
85
87
  onSelect,
86
88
  onChecked,
87
89
  defaultExpanded,
package/src/tree/types.ts CHANGED
@@ -174,6 +174,10 @@ export interface TreePanelProps<T extends KeyValue = KeyValue>
174
174
  | Promise<Array<TreeNodeType<T>> | undefined>
175
175
  | Array<TreeNodeType<T>>
176
176
  | undefined;
177
+ /**
178
+ * callback to load tree using search query
179
+ */
180
+ onQuery?: (query: string) => void;
177
181
  /**
178
182
  * callback on click of tree node
179
183
  */
@@ -98,6 +98,7 @@ export const useTree = <T extends KeyValue>({
98
98
  sorter,
99
99
  matcher,
100
100
  onLoad,
101
+ onQuery,
101
102
  onSelect,
102
103
  onChecked,
103
104
  defaultExpanded,
@@ -204,9 +205,13 @@ export const useTree = <T extends KeyValue>({
204
205
  return { ...state };
205
206
  }
206
207
  if (action.type === "filter") {
207
- filterTree(state.itemMap, action.query, matcher);
208
- state.tree = flattenTree(state.items);
209
- return { ...state };
208
+ if (onQuery) {
209
+ onQuery(action.query ?? "");
210
+ } else {
211
+ filterTree(state.itemMap, action.query, matcher);
212
+ state.tree = flattenTree(state.items);
213
+ return { ...state };
214
+ }
210
215
  }
211
216
  if (action.type === "select") {
212
217
  if (state.selected) {
@@ -249,7 +254,8 @@ export const useTree = <T extends KeyValue>({
249
254
 
250
255
  useEffect(() => {
251
256
  dispatch({ type: "load", items: itemList });
252
- intialExpand.current?.length > 0 &&
257
+ itemList.length &&
258
+ intialExpand.current?.length > 0 &&
253
259
  dispatch({
254
260
  type: "expand",
255
261
  id: intialExpand.current.shift() as unknown as string,
package/src/tree/utils.ts CHANGED
@@ -58,7 +58,7 @@ export const refactorTree = (
58
58
  if (sorter !== false) nodes = nodes.sort(sorter);
59
59
  nodes.forEach((node) => {
60
60
  list.push({
61
- open: false, // defaultExpanded.includes(node.id),
61
+ open: defaultExpanded.includes(node.id) && !!node.children?.length,
62
62
  level: options.level,
63
63
  parent: options.parent,
64
64
  checked: 0,
@@ -114,6 +114,13 @@ export const flattenTree = (
114
114
  [...lines, idx === filtered.length - 1 ? 0 : 1],
115
115
  ),
116
116
  );
117
+ node.open &&
118
+ node.children?.length === 0 &&
119
+ list.push({
120
+ empty: true,
121
+ leaf: true,
122
+ lines: [...lines, idx === filtered.length - 1 ? 0 : 1, 2],
123
+ } as any);
117
124
  });
118
125
  return list;
119
126
  };