@feugene/granularity 0.43.0 → 0.45.0

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 (78) hide show
  1. package/README.md +2 -2
  2. package/dist/chunks/config-BkQ2jvXv.js +49 -0
  3. package/dist/chunks/config-BkQ2jvXv.js.map +1 -0
  4. package/dist/chunks/config-ChnYtO4o.js +28 -0
  5. package/dist/chunks/config-ChnYtO4o.js.map +1 -0
  6. package/dist/chunks/{en-C_QkUTRL.js → en-DiHzFact.js} +3 -1
  7. package/dist/chunks/en-DiHzFact.js.map +1 -0
  8. package/dist/chunks/{es-DemSEhZE.js → es-1ZL6NtkB.js} +3 -1
  9. package/dist/chunks/es-1ZL6NtkB.js.map +1 -0
  10. package/dist/chunks/{es-B4t_3Wnh.js → es-CeKkMxZ_.js} +3 -3
  11. package/dist/chunks/{es-B4t_3Wnh.js.map → es-CeKkMxZ_.js.map} +1 -1
  12. package/dist/chunks/{generated-VcxJTo_q.js → generated-DAKeOOqm.js} +45 -3
  13. package/dist/chunks/{generated-VcxJTo_q.js.map → generated-DAKeOOqm.js.map} +1 -1
  14. package/dist/chunks/{granular-provider-BohXQcNt.js → granular-provider-D_8_l-gM.js} +4 -0
  15. package/dist/chunks/granular-provider-D_8_l-gM.js.map +1 -0
  16. package/dist/chunks/{ru-CLUErjhY.js → ru-Dr2RYn0P.js} +3 -1
  17. package/dist/chunks/ru-Dr2RYn0P.js.map +1 -0
  18. package/dist/chunks/useScrollSpy-CIJpw0RI.js +360 -0
  19. package/dist/chunks/useScrollSpy-CIJpw0RI.js.map +1 -0
  20. package/dist/chunks/useTree-BebEiBcL.js +525 -0
  21. package/dist/chunks/useTree-BebEiBcL.js.map +1 -0
  22. package/dist/components/GrJsonViewer/chunks/{GrJsonViewer-CwCBMh4h.js → GrJsonViewer-CdlWMGnF.js} +1 -1
  23. package/dist/components/GrJsonViewer/chunks/{GrJsonViewer-CwCBMh4h.js.map → GrJsonViewer-CdlWMGnF.js.map} +1 -1
  24. package/dist/components/GrJsonViewer/index.js +1 -1
  25. package/dist/components/GrScrollSpy/chunks/GrScrollSpy-CQCH3zLC.js +207 -0
  26. package/dist/components/GrScrollSpy/chunks/GrScrollSpy-CQCH3zLC.js.map +1 -0
  27. package/dist/components/GrScrollSpy/index.js +3 -0
  28. package/dist/components/GrTree/chunks/{GrTree-CkHzgYg1.js → GrTree-DnDGW0xO.js} +103 -540
  29. package/dist/components/GrTree/chunks/GrTree-DnDGW0xO.js.map +1 -0
  30. package/dist/components/GrTree/index.js +2 -2
  31. package/dist/components/GrTree/styles.css +1 -1
  32. package/dist/components/GrTreeSections/chunks/GrTreeSections-D2PQ87mw.js +147 -0
  33. package/dist/components/GrTreeSections/chunks/GrTreeSections-D2PQ87mw.js.map +1 -0
  34. package/dist/components/GrTreeSections/index.js +3 -0
  35. package/dist/components/GrTreeSelect/chunks/{GrTreeSelect-DUsv3_mF.js → GrTreeSelect-DzheDCuZ.js} +1 -1
  36. package/dist/components/GrTreeSelect/chunks/{GrTreeSelect-DUsv3_mF.js.map → GrTreeSelect-DzheDCuZ.js.map} +1 -1
  37. package/dist/components/GrTreeSelect/index.js +1 -1
  38. package/dist/composables/useScrollSpy.js +2 -0
  39. package/dist/composables/useTree.js +2 -0
  40. package/dist/granular-provider-node.js +1 -1
  41. package/dist/granular-provider.js +1 -1
  42. package/dist/i18n/all.js +1 -1
  43. package/dist/i18n/index.js +1 -1
  44. package/dist/index.js +10 -4
  45. package/dist/theme.js +1 -1
  46. package/dist/tokens.js +1 -1
  47. package/dist/types/components/GrScrollSpy/GrScrollSpy.vue.d.ts +105 -0
  48. package/dist/types/components/GrScrollSpy/config.d.ts +1 -0
  49. package/dist/types/components/GrScrollSpy/grScrollSpyStyles.d.ts +26 -0
  50. package/dist/types/components/GrScrollSpy/index.d.ts +9 -0
  51. package/dist/types/components/GrScrollSpy/safelist.d.ts +1 -0
  52. package/dist/types/components/GrScrollSpy/scrollSpyItems.d.ts +44 -0
  53. package/dist/types/components/GrTree/grTreeProps.d.ts +8 -1
  54. package/dist/types/components/GrTree/grTreeStyles.d.ts +12 -0
  55. package/dist/types/components/GrTree/index.d.ts +3 -2
  56. package/dist/types/components/GrTreeSections/GrTreeSections.vue.d.ts +71 -0
  57. package/dist/types/components/GrTreeSections/config.d.ts +1 -0
  58. package/dist/types/components/GrTreeSections/grTreeSectionsStyles.d.ts +8 -0
  59. package/dist/types/components/GrTreeSections/index.d.ts +8 -0
  60. package/dist/types/components/GrTreeSections/safelist.d.ts +1 -0
  61. package/dist/types/composables/internal/scrollSpyGeometry.d.ts +67 -0
  62. package/dist/types/{components/GrTree/grTreeDataAdapter.d.ts → composables/internal/treeAdapter.d.ts} +3 -3
  63. package/dist/types/{components/GrTree/grTreeChecking.d.ts → composables/internal/treeChecking.d.ts} +1 -1
  64. package/dist/types/composables/useScrollSpy.d.ts +59 -0
  65. package/dist/types/composables/useTree.d.ts +107 -0
  66. package/dist/types/granular-provider/shared.d.ts +2 -0
  67. package/dist/types/i18n/messages/en.d.ts +6 -0
  68. package/dist/types/i18n/messages/es.d.ts +6 -0
  69. package/dist/types/i18n/messages/ru.d.ts +6 -0
  70. package/dist/types/index.d.ts +6 -0
  71. package/dist/web-types.json +238 -3
  72. package/package.json +17 -1
  73. package/dist/chunks/en-C_QkUTRL.js.map +0 -1
  74. package/dist/chunks/es-DemSEhZE.js.map +0 -1
  75. package/dist/chunks/granular-provider-BohXQcNt.js.map +0 -1
  76. package/dist/chunks/ru-CLUErjhY.js.map +0 -1
  77. package/dist/components/GrTree/chunks/GrTree-CkHzgYg1.js.map +0 -1
  78. package/dist/types/components/GrTree/grTreeStore.d.ts +0 -71
@@ -0,0 +1,525 @@
1
+ import { computed, ref, shallowRef, toValue, watch } from "vue";
2
+ //#region src/composables/internal/treeAdapter.ts
3
+ var DEFAULT_CHILDREN_KEY = "children";
4
+ var DEFAULT_LABEL_KEY = "label";
5
+ var DEFAULT_IS_LEAF_KEY = "isLeaf";
6
+ function isTreeKey(value) {
7
+ return typeof value === "string" || typeof value === "number";
8
+ }
9
+ function resolveMapValue(map, key, fallback) {
10
+ return map?.[key] ?? fallback;
11
+ }
12
+ function createGrTreeDataAdapter(options) {
13
+ function hasNodeKey() {
14
+ return options.nodeKey != null;
15
+ }
16
+ function getChildrenKey() {
17
+ return resolveMapValue(options.props, "children", DEFAULT_CHILDREN_KEY);
18
+ }
19
+ function getLabelKey() {
20
+ return resolveMapValue(options.props, "label", DEFAULT_LABEL_KEY);
21
+ }
22
+ function getLabel(data) {
23
+ const value = data[getLabelKey()];
24
+ return value == null ? "" : String(value);
25
+ }
26
+ function getIsLeaf(data) {
27
+ const value = data[resolveMapValue(options.props, "isLeaf", DEFAULT_IS_LEAF_KEY)];
28
+ return typeof value === "boolean" ? value : void 0;
29
+ }
30
+ function getChildren(data) {
31
+ const value = data[getChildrenKey()];
32
+ return Array.isArray(value) ? value : [];
33
+ }
34
+ function ensureChildren(data) {
35
+ const key = getChildrenKey();
36
+ const record = data;
37
+ if (Array.isArray(record[key])) return record[key];
38
+ record[key] = [];
39
+ return record[key];
40
+ }
41
+ function getExplicitNodeKey(data) {
42
+ if (options.nodeKey == null) return void 0;
43
+ const value = data[options.nodeKey];
44
+ return isTreeKey(value) ? value : void 0;
45
+ }
46
+ function getNodeKey(data, index, parentKey) {
47
+ const explicitKey = getExplicitNodeKey(data);
48
+ if (explicitKey != null) return explicitKey;
49
+ return parentKey == null ? index : `${String(parentKey)}:${index}`;
50
+ }
51
+ return {
52
+ hasNodeKey,
53
+ getChildrenKey,
54
+ getLabelKey,
55
+ getLabel,
56
+ getIsLeaf,
57
+ getChildren,
58
+ ensureChildren,
59
+ getNodeKey,
60
+ getExplicitNodeKey
61
+ };
62
+ }
63
+ //#endregion
64
+ //#region src/composables/internal/treeChecking.ts
65
+ /**
66
+ * Раскладывает отмеченные ключи по всему дереву: родитель отмечен, когда
67
+ * отмечены все дети, и наполовину — когда часть.
68
+ *
69
+ * Считается от листьев вверх, поэтому `checkedKeys` снаружи может содержать
70
+ * только листья (типовой формат ответа сервера) — родители посчитаются сами.
71
+ * При `strict` дерево не связывает узлы вовсе: каждый отвечает сам за себя.
72
+ */
73
+ function resolveCheckStates(roots, checkedKeys, strict) {
74
+ const states = /* @__PURE__ */ new Map();
75
+ const walk = (node) => {
76
+ if (strict || node.childNodes.length === 0) {
77
+ const state = checkedKeys.has(node.key) ? "checked" : "unchecked";
78
+ if (strict) node.childNodes.forEach(walk);
79
+ states.set(node.key, state);
80
+ return state;
81
+ }
82
+ const childStates = node.childNodes.map(walk);
83
+ const allChecked = childStates.every((s) => s === "checked");
84
+ const someMarked = childStates.some((s) => s !== "unchecked");
85
+ const state = allChecked ? "checked" : someMarked || checkedKeys.has(node.key) ? "half" : "unchecked";
86
+ states.set(node.key, state);
87
+ return state;
88
+ };
89
+ roots.forEach(walk);
90
+ return states;
91
+ }
92
+ /**
93
+ * Новый набор отмеченных ключей после переключения узла.
94
+ *
95
+ * Каскад идёт вниз (все потомки повторяют решение) и вверх (родитель отмечен,
96
+ * только если отмечены все его дети). Возвращается набор с родителями —
97
+ * `getCheckedKeys({ leafOnly: true })` при необходимости отбросит их обратно.
98
+ */
99
+ function toggleCheckedKeys(roots, checkedKeys, node, checked, strict) {
100
+ const next = new Set(checkedKeys);
101
+ if (strict) {
102
+ if (checked) next.add(node.key);
103
+ else next.delete(node.key);
104
+ return next;
105
+ }
106
+ const applyDown = (target) => {
107
+ if (checked) next.add(target.key);
108
+ else next.delete(target.key);
109
+ target.childNodes.forEach(applyDown);
110
+ };
111
+ applyDown(node);
112
+ for (let parent = node.parent; parent; parent = parent.parent) if (parent.childNodes.every((child) => next.has(child.key))) next.add(parent.key);
113
+ else next.delete(parent.key);
114
+ return pruneToTree(roots, next);
115
+ }
116
+ /** Отбрасывает ключи, которых нет в текущей модели (данные могли смениться). */
117
+ function pruneToTree(roots, keys) {
118
+ const known = /* @__PURE__ */ new Set();
119
+ const walk = (node) => {
120
+ known.add(node.key);
121
+ node.childNodes.forEach(walk);
122
+ };
123
+ roots.forEach(walk);
124
+ const next = /* @__PURE__ */ new Set();
125
+ for (const key of keys) if (known.has(key)) next.add(key);
126
+ return next;
127
+ }
128
+ /** Ключи в состоянии `checked`; `leafOnly` оставляет только листья. */
129
+ function collectCheckedKeys(roots, states, leafOnly) {
130
+ const out = [];
131
+ const walk = (node) => {
132
+ const isLeaf = node.childNodes.length === 0;
133
+ if (states.get(node.key) === "checked" && (!leafOnly || isLeaf)) out.push(node.key);
134
+ node.childNodes.forEach(walk);
135
+ };
136
+ roots.forEach(walk);
137
+ return out;
138
+ }
139
+ /** Ключи в состоянии `half` — родители с частично отмеченными потомками. */
140
+ function collectHalfCheckedKeys(states) {
141
+ const out = [];
142
+ for (const [key, state] of states) if (state === "half") out.push(key);
143
+ return out;
144
+ }
145
+ //#endregion
146
+ //#region src/composables/useTree.ts
147
+ function useTree(options) {
148
+ const adapter = options.adapter ?? createGrTreeDataAdapter({
149
+ props: options.props,
150
+ nodeKey: options.nodeKey
151
+ });
152
+ const filterValue = ref("");
153
+ const expandedKeys = shallowRef(/* @__PURE__ */ new Set());
154
+ const checkedKeys = shallowRef(new Set(toValue(options.defaultCheckedKeys) ?? []));
155
+ const loadingKeys = shallowRef(/* @__PURE__ */ new Set());
156
+ const loadedKeys = shallowRef(/* @__PURE__ */ new Set());
157
+ const loadedChildren = shallowRef(/* @__PURE__ */ new Map());
158
+ const currentKey = ref(void 0);
159
+ const getData = () => toValue(options.data) ?? [];
160
+ const getFilterNodeMethod = () => options.filterNodeMethod;
161
+ watch(() => toValue(options.defaultExpandedKeys), (keys) => {
162
+ expandedKeys.value = new Set(keys ?? []);
163
+ }, { immediate: true });
164
+ watch(() => toValue(options.checkedKeys), (keys) => {
165
+ if (keys) checkedKeys.value = new Set(keys);
166
+ }, { immediate: true });
167
+ const treeModel = computed(() => {
168
+ const byKey = /* @__PURE__ */ new Map();
169
+ const byData = /* @__PURE__ */ new WeakMap();
170
+ const build = (items, parent, level) => {
171
+ return items.map((item, index) => {
172
+ const node = {
173
+ key: adapter.getNodeKey(item, index, parent?.key),
174
+ label: adapter.getLabel(item),
175
+ data: item,
176
+ level,
177
+ parent,
178
+ childNodes: []
179
+ };
180
+ byKey.set(node.key, node);
181
+ byData.set(item, node);
182
+ const ownChildren = adapter.getChildren(item);
183
+ const lazyChildren = loadedChildren.value.get(node.key) ?? [];
184
+ node.childNodes = build([...ownChildren, ...lazyChildren], node, level + 1);
185
+ return node;
186
+ });
187
+ };
188
+ return {
189
+ roots: build(getData(), void 0, 1),
190
+ byKey,
191
+ byData
192
+ };
193
+ });
194
+ const autoExpandedKeys = /* @__PURE__ */ new Set();
195
+ watch(treeModel, (model) => {
196
+ if (!toValue(options.defaultExpandAll)) return;
197
+ const next = new Set(expandedKeys.value);
198
+ let changed = false;
199
+ for (const key of model.byKey.keys()) {
200
+ if (autoExpandedKeys.has(key)) continue;
201
+ autoExpandedKeys.add(key);
202
+ next.add(key);
203
+ changed = true;
204
+ }
205
+ if (changed) expandedKeys.value = next;
206
+ }, { immediate: true });
207
+ const filterInfo = computed(() => {
208
+ const value = filterValue.value;
209
+ const isActive = value.trim().length > 0;
210
+ const valueLower = value.toLowerCase();
211
+ const subtreeHasMatch = /* @__PURE__ */ new Map();
212
+ const matchedKeys = /* @__PURE__ */ new Set();
213
+ const autoExpandKeys = /* @__PURE__ */ new Set();
214
+ if (!isActive) return {
215
+ isActive,
216
+ subtreeHasMatch,
217
+ matchedKeys,
218
+ autoExpandKeys
219
+ };
220
+ const match = (node) => {
221
+ const custom = getFilterNodeMethod()?.(value, node.data, node);
222
+ if (custom !== void 0) return custom;
223
+ return node.label.toLowerCase().includes(valueLower);
224
+ };
225
+ const walk = (nodes) => {
226
+ let any = false;
227
+ for (const node of nodes) {
228
+ const self = match(node);
229
+ const childAny = walk(node.childNodes);
230
+ const has = self || childAny;
231
+ subtreeHasMatch.set(node.key, has);
232
+ if (self) matchedKeys.add(node.key);
233
+ if (childAny) autoExpandKeys.add(node.key);
234
+ any ||= has;
235
+ }
236
+ return any;
237
+ };
238
+ walk(treeModel.value.roots);
239
+ return {
240
+ isActive,
241
+ subtreeHasMatch,
242
+ matchedKeys,
243
+ autoExpandKeys
244
+ };
245
+ });
246
+ function getNode(key) {
247
+ return treeModel.value.byKey.get(key);
248
+ }
249
+ function findNodeByData(data) {
250
+ return treeModel.value.byData.get(data);
251
+ }
252
+ function isTreeNode(target) {
253
+ return typeof target === "object" && target !== null && "key" in target && "data" in target && "childNodes" in target;
254
+ }
255
+ function resolveNodeTarget(target) {
256
+ if (target == null) return void 0;
257
+ if (typeof target === "string" || typeof target === "number") return getNode(target);
258
+ if (isTreeNode(target)) return getNode(target.key) ?? target;
259
+ const key = adapter.getExplicitNodeKey(target);
260
+ if (key != null) return getNode(key);
261
+ return findNodeByData(target);
262
+ }
263
+ function getNodeContainer(node) {
264
+ const items = node.parent ? adapter.ensureChildren(node.parent.data) : getData();
265
+ let index = items.findIndex((item) => item === node.data);
266
+ if (index >= 0) return {
267
+ items,
268
+ index
269
+ };
270
+ const key = adapter.getExplicitNodeKey(node.data);
271
+ if (key == null) return void 0;
272
+ index = items.findIndex((item) => adapter.getExplicitNodeKey(item) === key);
273
+ if (index < 0) return void 0;
274
+ return {
275
+ items,
276
+ index
277
+ };
278
+ }
279
+ function isDescendantNode(ancestor, node) {
280
+ let current = node.parent;
281
+ while (current) {
282
+ if (current.key === ancestor.key) return true;
283
+ current = current.parent;
284
+ }
285
+ return false;
286
+ }
287
+ function canMoveNode(node, referenceNode, dropType) {
288
+ const sourceNode = resolveNodeTarget(node);
289
+ const targetNode = resolveNodeTarget(referenceNode);
290
+ if (!sourceNode || !targetNode) return false;
291
+ if (sourceNode.key === targetNode.key) return false;
292
+ if (isDescendantNode(sourceNode, targetNode)) return false;
293
+ if (!getNodeContainer(sourceNode)) return false;
294
+ if (dropType === "inner") return true;
295
+ return Boolean(getNodeContainer(targetNode));
296
+ }
297
+ function sanitizeTreeState() {
298
+ const byKey = treeModel.value.byKey;
299
+ if (currentKey.value != null && !byKey.has(currentKey.value)) currentKey.value = void 0;
300
+ const nextExpandedKeys = new Set(Array.from(expandedKeys.value).filter((key) => byKey.has(key)));
301
+ if (nextExpandedKeys.size !== expandedKeys.value.size) expandedKeys.value = nextExpandedKeys;
302
+ const nextCheckedKeys = new Set(Array.from(checkedKeys.value).filter((key) => byKey.has(key)));
303
+ if (nextCheckedKeys.size !== checkedKeys.value.size) checkedKeys.value = nextCheckedKeys;
304
+ }
305
+ function isExpandedKey(key) {
306
+ return expandedKeys.value.has(key);
307
+ }
308
+ function setExpandedKey(key, expanded) {
309
+ const next = new Set(expandedKeys.value);
310
+ if (expanded) next.add(key);
311
+ else next.delete(key);
312
+ expandedKeys.value = next;
313
+ }
314
+ function toggleExpand(node) {
315
+ setExpandedKey(node.key, !isExpandedKey(node.key));
316
+ }
317
+ function setCurrentKey(key) {
318
+ currentKey.value = key;
319
+ }
320
+ function getCurrentKey() {
321
+ return currentKey.value;
322
+ }
323
+ function getCurrentNode() {
324
+ const key = currentKey.value;
325
+ return key == null ? void 0 : getNode(key);
326
+ }
327
+ function setCurrentNode(node) {
328
+ if (node == null) {
329
+ currentKey.value = void 0;
330
+ return true;
331
+ }
332
+ const targetNode = resolveNodeTarget(node);
333
+ if (!targetNode) return false;
334
+ currentKey.value = targetNode.key;
335
+ return true;
336
+ }
337
+ function resolveInsertedNode(data) {
338
+ const key = adapter.getExplicitNodeKey(data);
339
+ if (key != null) return getNode(key);
340
+ return findNodeByData(data);
341
+ }
342
+ function moveNode(node, referenceNode, dropType) {
343
+ const sourceNode = resolveNodeTarget(node);
344
+ const targetNode = resolveNodeTarget(referenceNode);
345
+ if (!sourceNode || !targetNode) return void 0;
346
+ if (!canMoveNode(sourceNode, targetNode, dropType)) return void 0;
347
+ const sourceContainer = getNodeContainer(sourceNode);
348
+ if (!sourceContainer) return void 0;
349
+ let destinationItems;
350
+ let destinationIndex;
351
+ if (dropType === "inner") {
352
+ destinationItems = adapter.ensureChildren(targetNode.data);
353
+ destinationIndex = destinationItems.length;
354
+ } else {
355
+ const targetContainer = getNodeContainer(targetNode);
356
+ if (!targetContainer) return void 0;
357
+ destinationItems = targetContainer.items;
358
+ destinationIndex = dropType === "prev" ? targetContainer.index : targetContainer.index + 1;
359
+ }
360
+ if (destinationItems === sourceContainer.items && sourceContainer.index < destinationIndex) destinationIndex -= 1;
361
+ const [movedData] = sourceContainer.items.splice(sourceContainer.index, 1);
362
+ destinationItems.splice(destinationIndex, 0, movedData);
363
+ if (dropType === "inner") setExpandedKey(targetNode.key, true);
364
+ sanitizeTreeState();
365
+ return resolveInsertedNode(movedData);
366
+ }
367
+ function appendNode(data, parent) {
368
+ const parentNode = resolveNodeTarget(parent);
369
+ if (!parentNode) return void 0;
370
+ adapter.ensureChildren(parentNode.data).push(data);
371
+ setExpandedKey(parentNode.key, true);
372
+ sanitizeTreeState();
373
+ return resolveInsertedNode(data);
374
+ }
375
+ function removeNode(node) {
376
+ if (!adapter.hasNodeKey()) return false;
377
+ const targetNode = resolveNodeTarget(node);
378
+ if (!targetNode) return false;
379
+ const container = getNodeContainer(targetNode);
380
+ if (!container) return false;
381
+ container.items.splice(container.index, 1);
382
+ sanitizeTreeState();
383
+ return true;
384
+ }
385
+ function insertNodeBefore(data, referenceNode) {
386
+ const targetNode = resolveNodeTarget(referenceNode);
387
+ if (!targetNode) return void 0;
388
+ const container = getNodeContainer(targetNode);
389
+ if (!container) return void 0;
390
+ container.items.splice(container.index, 0, data);
391
+ sanitizeTreeState();
392
+ return resolveInsertedNode(data);
393
+ }
394
+ function insertNodeAfter(data, referenceNode) {
395
+ const targetNode = resolveNodeTarget(referenceNode);
396
+ if (!targetNode) return void 0;
397
+ const container = getNodeContainer(targetNode);
398
+ if (!container) return void 0;
399
+ container.items.splice(container.index + 1, 0, data);
400
+ sanitizeTreeState();
401
+ return resolveInsertedNode(data);
402
+ }
403
+ const checkStates = computed(() => resolveCheckStates(treeModel.value.roots, checkedKeys.value, Boolean(toValue(options.checkStrictly))));
404
+ function getCheckState(key) {
405
+ return checkStates.value.get(key) ?? "unchecked";
406
+ }
407
+ function setChecked(node, checked) {
408
+ const targetNode = resolveNodeTarget(node);
409
+ if (!targetNode) return void 0;
410
+ checkedKeys.value = toggleCheckedKeys(treeModel.value.roots, checkedKeys.value, targetNode, checked, Boolean(toValue(options.checkStrictly)));
411
+ return targetNode;
412
+ }
413
+ function toggleChecked(node) {
414
+ return setChecked(node, getCheckState(node.key) !== "checked");
415
+ }
416
+ function getCheckedKeys(opts) {
417
+ return collectCheckedKeys(treeModel.value.roots, checkStates.value, Boolean(opts?.leafOnly));
418
+ }
419
+ function setCheckedKeys(keys) {
420
+ checkedKeys.value = pruneToTree(treeModel.value.roots, new Set(keys));
421
+ }
422
+ function getHalfCheckedKeys() {
423
+ return collectHalfCheckedKeys(checkStates.value);
424
+ }
425
+ function isLeafNode(node) {
426
+ if (node.childNodes.length > 0) return false;
427
+ if (!toValue(options.lazy)) return true;
428
+ const declared = adapter.getIsLeaf(node.data);
429
+ if (declared !== void 0) return declared;
430
+ return loadedKeys.value.has(node.key);
431
+ }
432
+ function isLoadingKey(key) {
433
+ return loadingKeys.value.has(key);
434
+ }
435
+ function markLoading(key, loading) {
436
+ const next = new Set(loadingKeys.value);
437
+ if (loading) next.add(key);
438
+ else next.delete(key);
439
+ loadingKeys.value = next;
440
+ }
441
+ function ensureLoaded(node) {
442
+ const load = options.load;
443
+ if (!toValue(options.lazy) || !load) return;
444
+ if (loadedKeys.value.has(node.key) || loadingKeys.value.has(node.key) || isLeafNode(node)) return;
445
+ markLoading(node.key, true);
446
+ let settled = false;
447
+ load(node, (children) => {
448
+ if (settled) return;
449
+ settled = true;
450
+ const next = new Map(loadedChildren.value);
451
+ next.set(node.key, [...children ?? []]);
452
+ loadedChildren.value = next;
453
+ loadedKeys.value = new Set(loadedKeys.value).add(node.key);
454
+ markLoading(node.key, false);
455
+ });
456
+ }
457
+ function filter(value) {
458
+ filterValue.value = value;
459
+ }
460
+ return {
461
+ visibleRows: computed(() => {
462
+ const { roots } = treeModel.value;
463
+ const { isActive, subtreeHasMatch, matchedKeys, autoExpandKeys } = filterInfo.value;
464
+ const rows = [];
465
+ const walk = (nodes, ancestorColors) => {
466
+ const siblings = isActive ? nodes.filter((node) => subtreeHasMatch.get(node.key)) : nodes;
467
+ siblings.forEach((node, index) => {
468
+ const isLeaf = isLeafNode(node);
469
+ const isExpanded = isExpandedKey(node.key) || isActive && autoExpandKeys.has(node.key);
470
+ rows.push({
471
+ node,
472
+ isExpanded,
473
+ isLeaf,
474
+ isMatched: matchedKeys.has(node.key),
475
+ posInSet: index + 1,
476
+ setSize: siblings.length,
477
+ isLoading: isLoadingKey(node.key),
478
+ branchColors: ancestorColors
479
+ });
480
+ if (!isExpanded || node.childNodes.length === 0) return;
481
+ const color = options.branchColorFor?.(node);
482
+ walk(node.childNodes, color ? [...ancestorColors, color] : ancestorColors);
483
+ });
484
+ };
485
+ walk(roots, []);
486
+ return rows;
487
+ }),
488
+ filterValue,
489
+ expandedKeys,
490
+ loadedChildren,
491
+ checkedKeys,
492
+ checkStates,
493
+ loadingKeys,
494
+ loadedKeys,
495
+ currentKey,
496
+ treeModel,
497
+ filterInfo,
498
+ filter,
499
+ isExpandedKey,
500
+ setExpandedKey,
501
+ toggleExpand,
502
+ setCurrentKey,
503
+ getCurrentKey,
504
+ getCurrentNode,
505
+ setCurrentNode,
506
+ getNode,
507
+ canMoveNode,
508
+ moveNode,
509
+ appendNode,
510
+ removeNode,
511
+ insertNodeBefore,
512
+ insertNodeAfter,
513
+ getCheckState,
514
+ setChecked,
515
+ toggleChecked,
516
+ getCheckedKeys,
517
+ setCheckedKeys,
518
+ getHalfCheckedKeys,
519
+ isLeafNode,
520
+ isLoadingKey,
521
+ ensureLoaded
522
+ };
523
+ }
524
+ //#endregion
525
+ export { createGrTreeDataAdapter as n, useTree as t };
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTree-BebEiBcL.js","names":[],"sources":["../../src/composables/internal/treeAdapter.ts","../../src/composables/internal/treeChecking.ts","../../src/composables/useTree.ts"],"sourcesContent":["import type { GrTreeKey } from '../../components/GrTree/grTreeTypes'\nimport type {\n GrTreeDataProps,\n GrTreePropsMap,\n} from '../../components/GrTree/grTreeProps'\n\nconst DEFAULT_CHILDREN_KEY = 'children'\nconst DEFAULT_LABEL_KEY = 'label'\nconst DEFAULT_IS_LEAF_KEY = 'isLeaf'\n\nexport type GrTreeDataAdapterOptions<T extends object> = Pick<GrTreeDataProps<T>, 'props' | 'nodeKey'>\n\nexport type GrTreeDataAdapter<T extends object> = {\n hasNodeKey: () => boolean\n getChildrenKey: () => string\n getLabelKey: () => string\n getLabel: (data: T) => string\n /** Признак «лист» из данных. `undefined` — данные молчат, решает вызывающий. */\n getIsLeaf: (data: T) => boolean | undefined\n getChildren: (data: T) => T[]\n ensureChildren: (data: T) => T[]\n getNodeKey: (data: T, index: number, parentKey: GrTreeKey | undefined) => GrTreeKey\n getExplicitNodeKey: (data: T) => GrTreeKey | undefined\n}\n\nfunction isTreeKey(value: unknown): value is GrTreeKey {\n return typeof value === 'string' || typeof value === 'number'\n}\n\nfunction resolveMapValue(map: GrTreePropsMap | undefined, key: keyof GrTreePropsMap, fallback: string) {\n return map?.[key] ?? fallback\n}\n\nexport function createGrTreeDataAdapter<T extends object>(\n options: GrTreeDataAdapterOptions<T>,\n): GrTreeDataAdapter<T> {\n function hasNodeKey() {\n return options.nodeKey != null\n }\n\n function getChildrenKey() {\n return resolveMapValue(options.props, 'children', DEFAULT_CHILDREN_KEY)\n }\n\n function getLabelKey() {\n return resolveMapValue(options.props, 'label', DEFAULT_LABEL_KEY)\n }\n\n function getLabel(data: T): string {\n const key = getLabelKey() as keyof T\n const value = data[key]\n return value == null ? '' : String(value)\n }\n\n function getIsLeaf(data: T): boolean | undefined {\n const key = resolveMapValue(options.props, 'isLeaf', DEFAULT_IS_LEAF_KEY)\n const value = (data as Record<string, unknown>)[key]\n return typeof value === 'boolean' ? value : undefined\n }\n\n function getChildren(data: T): T[] {\n const key = getChildrenKey() as keyof T\n const value = data[key]\n return Array.isArray(value) ? (value as T[]) : []\n }\n\n function ensureChildren(data: T): T[] {\n const key = getChildrenKey()\n const record = data as Record<string, unknown>\n if (Array.isArray(record[key])) {\n return record[key] as T[]\n }\n\n record[key] = []\n\n // Читаем обратно, а не возвращаем только что созданный массив: у\n // реактивных данных чтение отдаёт прокси, и только запись через него\n // видна дереву. Иначе `push` уходит мимо реактивности, и добавленные\n // дети не появляются на экране.\n return record[key] as T[]\n }\n\n function getExplicitNodeKey(data: T): GrTreeKey | undefined {\n if (options.nodeKey == null)\n return undefined\n\n const keyName = options.nodeKey as keyof T\n const value = data[keyName] as unknown\n return isTreeKey(value) ? value : undefined\n }\n\n function getNodeKey(data: T, index: number, parentKey: GrTreeKey | undefined): GrTreeKey {\n const explicitKey = getExplicitNodeKey(data)\n if (explicitKey != null)\n return explicitKey\n\n return parentKey == null ? index : `${String(parentKey)}:${index}`\n }\n\n return {\n hasNodeKey,\n getChildrenKey,\n getLabelKey,\n getLabel,\n getIsLeaf,\n getChildren,\n ensureChildren,\n getNodeKey,\n getExplicitNodeKey,\n }\n}\n","import type { GrTreeKey, GrTreeNode } from '../../components/GrTree/grTreeTypes'\n\n/**\n * Состояние отметки узла. `half` — часть потомков отмечена: в ARIA это\n * `aria-checked=\"mixed\"`.\n */\nexport const GR_TREE_CHECK_STATES = ['checked', 'half', 'unchecked'] as const\n\nexport type GrTreeCheckState = typeof GR_TREE_CHECK_STATES[number]\n\nexport type GrTreeCheckStates = Map<GrTreeKey, GrTreeCheckState>\n\n/**\n * Раскладывает отмеченные ключи по всему дереву: родитель отмечен, когда\n * отмечены все дети, и наполовину — когда часть.\n *\n * Считается от листьев вверх, поэтому `checkedKeys` снаружи может содержать\n * только листья (типовой формат ответа сервера) — родители посчитаются сами.\n * При `strict` дерево не связывает узлы вовсе: каждый отвечает сам за себя.\n */\nexport function resolveCheckStates<T>(\n roots: GrTreeNode<T>[],\n checkedKeys: Set<GrTreeKey>,\n strict: boolean,\n): GrTreeCheckStates {\n const states: GrTreeCheckStates = new Map()\n\n const walk = (node: GrTreeNode<T>): GrTreeCheckState => {\n if (strict || node.childNodes.length === 0) {\n const state: GrTreeCheckState = checkedKeys.has(node.key) ? 'checked' : 'unchecked'\n // В strict-режиме потомков всё равно нужно обойти: у них своё состояние.\n if (strict)\n node.childNodes.forEach(walk)\n states.set(node.key, state)\n return state\n }\n\n const childStates = node.childNodes.map(walk)\n const allChecked = childStates.every(s => s === 'checked')\n const someMarked = childStates.some(s => s !== 'unchecked')\n\n const state: GrTreeCheckState = allChecked\n ? 'checked'\n : (someMarked || checkedKeys.has(node.key) ? 'half' : 'unchecked')\n\n states.set(node.key, state)\n return state\n }\n\n roots.forEach(walk)\n return states\n}\n\n/**\n * Новый набор отмеченных ключей после переключения узла.\n *\n * Каскад идёт вниз (все потомки повторяют решение) и вверх (родитель отмечен,\n * только если отмечены все его дети). Возвращается набор с родителями —\n * `getCheckedKeys({ leafOnly: true })` при необходимости отбросит их обратно.\n */\nexport function toggleCheckedKeys<T>(\n roots: GrTreeNode<T>[],\n checkedKeys: Set<GrTreeKey>,\n node: GrTreeNode<T>,\n checked: boolean,\n strict: boolean,\n): Set<GrTreeKey> {\n const next = new Set(checkedKeys)\n\n if (strict) {\n if (checked)\n next.add(node.key)\n else next.delete(node.key)\n return next\n }\n\n const applyDown = (target: GrTreeNode<T>): void => {\n if (checked)\n next.add(target.key)\n else next.delete(target.key)\n target.childNodes.forEach(applyDown)\n }\n applyDown(node)\n\n for (let parent = node.parent; parent; parent = parent.parent) {\n const allChecked = parent.childNodes.every(child => next.has(child.key))\n if (allChecked)\n next.add(parent.key)\n else next.delete(parent.key)\n }\n\n // Отметки узлов, которых уже нет в дереве, тянуть незачем.\n return pruneToTree(roots, next)\n}\n\n/** Отбрасывает ключи, которых нет в текущей модели (данные могли смениться). */\nexport function pruneToTree<T>(roots: GrTreeNode<T>[], keys: Set<GrTreeKey>): Set<GrTreeKey> {\n const known = new Set<GrTreeKey>()\n const walk = (node: GrTreeNode<T>): void => {\n known.add(node.key)\n node.childNodes.forEach(walk)\n }\n roots.forEach(walk)\n\n const next = new Set<GrTreeKey>()\n for (const key of keys) {\n if (known.has(key))\n next.add(key)\n }\n return next\n}\n\n/** Ключи в состоянии `checked`; `leafOnly` оставляет только листья. */\nexport function collectCheckedKeys<T>(\n roots: GrTreeNode<T>[],\n states: GrTreeCheckStates,\n leafOnly: boolean,\n): GrTreeKey[] {\n const out: GrTreeKey[] = []\n\n const walk = (node: GrTreeNode<T>): void => {\n const isLeaf = node.childNodes.length === 0\n if (states.get(node.key) === 'checked' && (!leafOnly || isLeaf))\n out.push(node.key)\n node.childNodes.forEach(walk)\n }\n\n roots.forEach(walk)\n return out\n}\n\n/** Ключи в состоянии `half` — родители с частично отмеченными потомками. */\nexport function collectHalfCheckedKeys(states: GrTreeCheckStates): GrTreeKey[] {\n const out: GrTreeKey[] = []\n for (const [key, state] of states) {\n if (state === 'half')\n out.push(key)\n }\n return out\n}\n","import type { ComputedRef, MaybeRefOrGetter, Ref, ShallowRef } from 'vue'\nimport { computed, ref, shallowRef, toValue, watch } from 'vue'\nimport type {\n GrTreeKey,\n GrTreeNode,\n GrTreeNodeDropType,\n GrTreeNodeTarget,\n} from '../components/GrTree/grTreeTypes'\nimport type { GrTreeDataAdapter } from './internal/treeAdapter'\nimport { createGrTreeDataAdapter } from './internal/treeAdapter'\nimport type { GrTreeDataProps, GrTreeLoad, GrTreePropsMap, GrTreeVisibleRow } from '../components/GrTree/grTreeProps'\nimport type { GrTreeCheckState, GrTreeCheckStates } from './internal/treeChecking'\nimport {\n collectCheckedKeys,\n collectHalfCheckedKeys,\n pruneToTree,\n resolveCheckStates,\n toggleCheckedKeys,\n} from './internal/treeChecking'\n\nexport type GrTreeModel<T extends object> = {\n roots: GrTreeNode<T>[]\n byKey: Map<GrTreeKey, GrTreeNode<T>>\n byData: WeakMap<T, GrTreeNode<T>>\n}\n\nexport type GrTreeFilterInfo = {\n isActive: boolean\n subtreeHasMatch: Map<GrTreeKey, boolean>\n matchedKeys: Set<GrTreeKey>\n autoExpandKeys: Set<GrTreeKey>\n}\n\nexport type UseTreeOptions<T extends object> = {\n data: MaybeRefOrGetter<GrTreeDataProps<T>['data']>\n defaultExpandedKeys?: MaybeRefOrGetter<GrTreeDataProps<T>['defaultExpandedKeys']>\n defaultExpandAll?: MaybeRefOrGetter<boolean | undefined>\n /**\n * Совпал ли узел с запросом фильтра.\n *\n * Обычная функция, а не `MaybeRefOrGetter`: `toValue` не отличает геттер от\n * значения-функции и вызвал бы её вместо того, чтобы вернуть. Реактивность\n * при этом не теряется — потребитель читает своё состояние внутри вызова.\n */\n /**\n * Совпал ли узел с запросом. Вернуть `undefined` — оставить решение модели\n * (подстрочный матч по подписи).\n */\n filterNodeMethod?: (value: string, data: T, node: GrTreeNode<T>) => boolean | undefined\n defaultCheckedKeys?: MaybeRefOrGetter<GrTreeKey[] | undefined>\n /** Внешние отмеченные ключи (`v-model:checked-keys`), если потребитель их ведёт. */\n checkedKeys?: MaybeRefOrGetter<GrTreeKey[] | undefined>\n checkStrictly?: MaybeRefOrGetter<boolean | undefined>\n lazy?: MaybeRefOrGetter<boolean | undefined>\n /** Загрузка детей ветки. Обычная функция — по той же причине, что `filterNodeMethod`. */\n load?: GrTreeLoad<T>\n /** Форма данных: поля детей, подписи и признака листа. */\n props?: GrTreePropsMap\n /** Поле-идентификатор узла. */\n nodeKey?: GrTreeDataProps<T>['nodeKey']\n /**\n * Готовый адаптер. Не задан — собирается из `props` и `nodeKey`.\n *\n * Необязателен намеренно: фабрика адаптера наружу не публикуется, и\n * требовать её значило бы сделать композабл невызываемым вне пакета.\n * Компонент передаёт свой, потому что уже собрал его для себя.\n */\n adapter?: GrTreeDataAdapter<T>\n /**\n * Цвет направляющей уровня для узла. Не задан — `branchColors` у строк\n * остаётся пустым: направляющие рисует потребитель, и модель о них не знает.\n *\n * Обычная функция, а не `MaybeRefOrGetter`: `toValue` не отличает геттер от\n * значения-функции и вызвал бы её вместо того, чтобы вернуть.\n */\n branchColorFor?: (node: GrTreeNode<T>) => string | undefined | null\n}\n\nexport type UseTreeReturn<T extends object> = {\n filterValue: Ref<string>\n expandedKeys: ShallowRef<Set<GrTreeKey>>\n checkedKeys: ShallowRef<Set<GrTreeKey>>\n checkStates: ComputedRef<GrTreeCheckStates>\n loadingKeys: ShallowRef<Set<GrTreeKey>>\n loadedKeys: ShallowRef<Set<GrTreeKey>>\n loadedChildren: ShallowRef<Map<GrTreeKey, T[]>>\n currentKey: Ref<GrTreeKey | undefined>\n /**\n * Видимые строки одним плоским списком в порядке отображения — то, из чего\n * строится разметка. Иерархию несут `node.level`, `posInSet` и `setSize`:\n * в плоском DOM группы нет, и структуру диктору сообщают они.\n */\n visibleRows: ComputedRef<GrTreeVisibleRow<T>[]>\n treeModel: ComputedRef<GrTreeModel<T>>\n filterInfo: ComputedRef<GrTreeFilterInfo>\n filter: (value: string) => void\n isExpandedKey: (key: GrTreeKey) => boolean\n setExpandedKey: (key: GrTreeKey, expanded: boolean) => void\n toggleExpand: (node: GrTreeNode<T>) => void\n setCurrentKey: (key?: GrTreeKey) => void\n getCurrentKey: () => GrTreeKey | undefined\n getCurrentNode: () => GrTreeNode<T> | undefined\n setCurrentNode: (node?: GrTreeNodeTarget<T>) => boolean\n getNode: (key: GrTreeKey) => GrTreeNode<T> | undefined\n canMoveNode: (node: GrTreeNodeTarget<T>, referenceNode: GrTreeNodeTarget<T>, dropType: GrTreeNodeDropType) => boolean\n moveNode: (node: GrTreeNodeTarget<T>, referenceNode: GrTreeNodeTarget<T>, dropType: GrTreeNodeDropType) => GrTreeNode<T> | undefined\n appendNode: (data: T, parent: GrTreeNodeTarget<T>) => GrTreeNode<T> | undefined\n removeNode: (node: GrTreeNodeTarget<T>) => boolean\n insertNodeBefore: (data: T, referenceNode: GrTreeNodeTarget<T>) => GrTreeNode<T> | undefined\n insertNodeAfter: (data: T, referenceNode: GrTreeNodeTarget<T>) => GrTreeNode<T> | undefined\n getCheckState: (key: GrTreeKey) => GrTreeCheckState\n setChecked: (node: GrTreeNodeTarget<T>, checked: boolean) => GrTreeNode<T> | undefined\n toggleChecked: (node: GrTreeNode<T>) => GrTreeNode<T> | undefined\n getCheckedKeys: (options?: { leafOnly?: boolean }) => GrTreeKey[]\n setCheckedKeys: (keys: GrTreeKey[]) => void\n getHalfCheckedKeys: () => GrTreeKey[]\n /** Лист ли узел с точки зрения раскрытия: в ленивом режиме решают данные и факт загрузки. */\n isLeafNode: (node: GrTreeNode<T>) => boolean\n isLoadingKey: (key: GrTreeKey) => boolean\n /** Грузит детей ветки, если это нужно и ещё не делалось. */\n ensureLoaded: (node: GrTreeNode<T>) => void\n}\n\nexport function useTree<T extends object>(\n options: UseTreeOptions<T>,\n): UseTreeReturn<T> {\n const adapter = options.adapter\n ?? createGrTreeDataAdapter<T>({ props: options.props, nodeKey: options.nodeKey })\n\n const filterValue = ref('')\n const expandedKeys = shallowRef<Set<GrTreeKey>>(new Set())\n const checkedKeys = shallowRef<Set<GrTreeKey>>(new Set(toValue(options.defaultCheckedKeys) ?? []))\n const loadingKeys = shallowRef<Set<GrTreeKey>>(new Set())\n const loadedKeys = shallowRef<Set<GrTreeKey>>(new Set())\n // Дети, пришедшие ленивой загрузкой, живут в сторе, а не в данных потребителя:\n // `data` — обычный проп и реактивным быть не обязан, а дерево обязано\n // показать загруженное в любом случае.\n const loadedChildren = shallowRef<Map<GrTreeKey, T[]>>(new Map())\n const currentKey = ref<GrTreeKey | undefined>(undefined)\n const getData = () => toValue(options.data) ?? []\n const getFilterNodeMethod = () => options.filterNodeMethod\n\n watch(\n () => toValue(options.defaultExpandedKeys),\n (keys) => {\n expandedKeys.value = new Set(keys ?? [])\n },\n { immediate: true },\n )\n\n // Внешние отметки: компонент управляемый, пока проп задан. Не задан — ведёт\n // набор сам, начиная с `defaultCheckedKeys`.\n watch(\n () => toValue(options.checkedKeys),\n (keys) => {\n if (keys)\n checkedKeys.value = new Set(keys)\n },\n { immediate: true },\n )\n\n const treeModel = computed<GrTreeModel<T>>(() => {\n const byKey = new Map<GrTreeKey, GrTreeNode<T>>()\n const byData = new WeakMap<T, GrTreeNode<T>>()\n\n const build = (items: T[], parent: GrTreeNode<T> | undefined, level: number): GrTreeNode<T>[] => {\n return items.map((item, index) => {\n const node: GrTreeNode<T> = {\n key: adapter.getNodeKey(item, index, parent?.key),\n label: adapter.getLabel(item),\n data: item,\n level,\n parent,\n childNodes: [],\n }\n\n byKey.set(node.key, node)\n byData.set(item, node)\n\n const ownChildren = adapter.getChildren(item)\n const lazyChildren = loadedChildren.value.get(node.key) ?? []\n node.childNodes = build([...ownChildren, ...lazyChildren], node, level + 1)\n\n return node\n })\n }\n\n return {\n roots: build(getData(), undefined, 1),\n byKey,\n byData,\n }\n })\n\n // `defaultExpandAll` раскрывает узел один раз — в момент его появления в\n // данных. Иначе любое обновление `data` отменяло бы всё, что пользователь\n // свернул руками.\n const autoExpandedKeys = new Set<GrTreeKey>()\n watch(treeModel, (model) => {\n if (!toValue(options.defaultExpandAll))\n return\n\n const next = new Set(expandedKeys.value)\n let changed = false\n\n for (const key of model.byKey.keys()) {\n if (autoExpandedKeys.has(key))\n continue\n\n autoExpandedKeys.add(key)\n next.add(key)\n changed = true\n }\n\n if (changed)\n expandedKeys.value = next\n }, { immediate: true })\n\n const filterInfo = computed<GrTreeFilterInfo>(() => {\n const value = filterValue.value\n const isActive = value.trim().length > 0\n const valueLower = value.toLowerCase()\n const subtreeHasMatch = new Map<GrTreeKey, boolean>()\n const matchedKeys = new Set<GrTreeKey>()\n const autoExpandKeys = new Set<GrTreeKey>()\n\n if (!isActive) {\n return {\n isActive,\n subtreeHasMatch,\n matchedKeys,\n autoExpandKeys,\n }\n }\n\n const match = (node: GrTreeNode<T>): boolean => {\n // `undefined` от метода означает «решай сам»: обёртка компонента отдаёт\n // его, когда своего правила потребитель не задал, — иначе она не смогла\n // бы вернуть модель к дефолту, оставаясь обычной функцией.\n const custom = getFilterNodeMethod()?.(value, node.data, node)\n\n if (custom !== undefined)\n return custom\n\n return node.label.toLowerCase().includes(valueLower)\n }\n\n const walk = (nodes: GrTreeNode<T>[]): boolean => {\n let any = false\n\n for (const node of nodes) {\n const self = match(node)\n const childAny = walk(node.childNodes)\n const has = self || childAny\n\n subtreeHasMatch.set(node.key, has)\n\n if (self)\n matchedKeys.add(node.key)\n\n if (childAny)\n autoExpandKeys.add(node.key)\n\n any ||= has\n }\n\n return any\n }\n\n walk(treeModel.value.roots)\n\n return {\n isActive,\n subtreeHasMatch,\n matchedKeys,\n autoExpandKeys,\n }\n })\n\n function getNode(key: GrTreeKey) {\n return treeModel.value.byKey.get(key)\n }\n\n function findNodeByData(data: T): GrTreeNode<T> | undefined {\n return treeModel.value.byData.get(data)\n }\n\n function isTreeNode(target: GrTreeNodeTarget<T>): target is GrTreeNode<T> {\n return typeof target === 'object'\n && target !== null\n && 'key' in target\n && 'data' in target\n && 'childNodes' in target\n }\n\n function resolveNodeTarget(target?: GrTreeNodeTarget<T>): GrTreeNode<T> | undefined {\n if (target == null)\n return undefined\n\n if (typeof target === 'string' || typeof target === 'number')\n return getNode(target)\n\n if (isTreeNode(target))\n return getNode(target.key) ?? target\n\n const key = adapter.getExplicitNodeKey(target)\n if (key != null)\n return getNode(key)\n\n return findNodeByData(target)\n }\n\n function getNodeContainer(node: GrTreeNode<T>) {\n const items = node.parent ? adapter.ensureChildren(node.parent.data) : getData()\n\n let index = items.findIndex(item => item === node.data)\n if (index >= 0)\n return { items, index }\n\n const key = adapter.getExplicitNodeKey(node.data)\n if (key == null)\n return undefined\n\n index = items.findIndex(item => adapter.getExplicitNodeKey(item) === key)\n if (index < 0)\n return undefined\n\n return { items, index }\n }\n\n function isDescendantNode(ancestor: GrTreeNode<T>, node: GrTreeNode<T>) {\n let current = node.parent\n\n while (current) {\n if (current.key === ancestor.key)\n return true\n\n current = current.parent\n }\n\n return false\n }\n\n function canMoveNode(node: GrTreeNodeTarget<T>, referenceNode: GrTreeNodeTarget<T>, dropType: GrTreeNodeDropType) {\n const sourceNode = resolveNodeTarget(node)\n const targetNode = resolveNodeTarget(referenceNode)\n\n if (!sourceNode || !targetNode)\n return false\n\n if (sourceNode.key === targetNode.key)\n return false\n\n if (isDescendantNode(sourceNode, targetNode))\n return false\n\n const sourceContainer = getNodeContainer(sourceNode)\n if (!sourceContainer)\n return false\n\n if (dropType === 'inner')\n return true\n\n return Boolean(getNodeContainer(targetNode))\n }\n\n function sanitizeTreeState() {\n const byKey = treeModel.value.byKey\n\n if (currentKey.value != null && !byKey.has(currentKey.value))\n currentKey.value = undefined\n\n const nextExpandedKeys = new Set(Array.from(expandedKeys.value).filter(key => byKey.has(key)))\n if (nextExpandedKeys.size !== expandedKeys.value.size)\n expandedKeys.value = nextExpandedKeys\n\n const nextCheckedKeys = new Set(Array.from(checkedKeys.value).filter(key => byKey.has(key)))\n if (nextCheckedKeys.size !== checkedKeys.value.size)\n checkedKeys.value = nextCheckedKeys\n }\n\n function isExpandedKey(key: GrTreeKey): boolean {\n return expandedKeys.value.has(key)\n }\n\n function setExpandedKey(key: GrTreeKey, expanded: boolean) {\n const next = new Set(expandedKeys.value)\n\n if (expanded)\n next.add(key)\n else\n next.delete(key)\n\n expandedKeys.value = next\n }\n\n function toggleExpand(node: GrTreeNode<T>) {\n setExpandedKey(node.key, !isExpandedKey(node.key))\n }\n\n function setCurrentKey(key?: GrTreeKey) {\n currentKey.value = key\n }\n\n function getCurrentKey() {\n return currentKey.value\n }\n\n function getCurrentNode() {\n const key = currentKey.value\n return key == null ? undefined : getNode(key)\n }\n\n function setCurrentNode(node?: GrTreeNodeTarget<T>) {\n if (node == null) {\n currentKey.value = undefined\n return true\n }\n\n const targetNode = resolveNodeTarget(node)\n if (!targetNode)\n return false\n\n currentKey.value = targetNode.key\n return true\n }\n\n function resolveInsertedNode(data: T) {\n const key = adapter.getExplicitNodeKey(data)\n if (key != null)\n return getNode(key)\n\n return findNodeByData(data)\n }\n\n function moveNode(node: GrTreeNodeTarget<T>, referenceNode: GrTreeNodeTarget<T>, dropType: GrTreeNodeDropType) {\n const sourceNode = resolveNodeTarget(node)\n const targetNode = resolveNodeTarget(referenceNode)\n\n if (!sourceNode || !targetNode)\n return undefined\n\n if (!canMoveNode(sourceNode, targetNode, dropType))\n return undefined\n\n const sourceContainer = getNodeContainer(sourceNode)\n if (!sourceContainer)\n return undefined\n\n let destinationItems: T[]\n let destinationIndex: number\n\n if (dropType === 'inner') {\n destinationItems = adapter.ensureChildren(targetNode.data)\n destinationIndex = destinationItems.length\n }\n else {\n const targetContainer = getNodeContainer(targetNode)\n if (!targetContainer)\n return undefined\n\n destinationItems = targetContainer.items\n destinationIndex = dropType === 'prev'\n ? targetContainer.index\n : targetContainer.index + 1\n }\n\n if (destinationItems === sourceContainer.items && sourceContainer.index < destinationIndex)\n destinationIndex -= 1\n\n const [movedData] = sourceContainer.items.splice(sourceContainer.index, 1)\n destinationItems.splice(destinationIndex, 0, movedData)\n\n if (dropType === 'inner')\n setExpandedKey(targetNode.key, true)\n\n sanitizeTreeState()\n return resolveInsertedNode(movedData)\n }\n\n function appendNode(data: T, parent: GrTreeNodeTarget<T>) {\n const parentNode = resolveNodeTarget(parent)\n if (!parentNode)\n return undefined\n\n adapter.ensureChildren(parentNode.data).push(data)\n setExpandedKey(parentNode.key, true)\n sanitizeTreeState()\n return resolveInsertedNode(data)\n }\n\n function removeNode(node: GrTreeNodeTarget<T>) {\n if (!adapter.hasNodeKey())\n return false\n\n const targetNode = resolveNodeTarget(node)\n if (!targetNode)\n return false\n\n const container = getNodeContainer(targetNode)\n if (!container)\n return false\n\n container.items.splice(container.index, 1)\n sanitizeTreeState()\n return true\n }\n\n function insertNodeBefore(data: T, referenceNode: GrTreeNodeTarget<T>) {\n const targetNode = resolveNodeTarget(referenceNode)\n if (!targetNode)\n return undefined\n\n const container = getNodeContainer(targetNode)\n if (!container)\n return undefined\n\n container.items.splice(container.index, 0, data)\n sanitizeTreeState()\n return resolveInsertedNode(data)\n }\n\n function insertNodeAfter(data: T, referenceNode: GrTreeNodeTarget<T>) {\n const targetNode = resolveNodeTarget(referenceNode)\n if (!targetNode)\n return undefined\n\n const container = getNodeContainer(targetNode)\n if (!container)\n return undefined\n\n container.items.splice(container.index + 1, 0, data)\n sanitizeTreeState()\n return resolveInsertedNode(data)\n }\n\n // ————— Отметки (чекбоксы).\n\n const checkStates = computed<GrTreeCheckStates>(() => resolveCheckStates(\n treeModel.value.roots,\n checkedKeys.value,\n Boolean(toValue(options.checkStrictly)),\n ))\n\n function getCheckState(key: GrTreeKey): GrTreeCheckState {\n return checkStates.value.get(key) ?? 'unchecked'\n }\n\n function setChecked(node: GrTreeNodeTarget<T>, checked: boolean) {\n const targetNode = resolveNodeTarget(node)\n if (!targetNode)\n return undefined\n\n checkedKeys.value = toggleCheckedKeys(\n treeModel.value.roots,\n checkedKeys.value,\n targetNode,\n checked,\n Boolean(toValue(options.checkStrictly)),\n )\n\n return targetNode\n }\n\n function toggleChecked(node: GrTreeNode<T>) {\n return setChecked(node, getCheckState(node.key) !== 'checked')\n }\n\n function getCheckedKeys(opts?: { leafOnly?: boolean }) {\n return collectCheckedKeys(treeModel.value.roots, checkStates.value, Boolean(opts?.leafOnly))\n }\n\n function setCheckedKeys(keys: GrTreeKey[]) {\n checkedKeys.value = pruneToTree(treeModel.value.roots, new Set(keys))\n }\n\n function getHalfCheckedKeys() {\n return collectHalfCheckedKeys(checkStates.value)\n }\n\n // ————— Ленивая подгрузка ветки.\n\n function isLeafNode(node: GrTreeNode<T>): boolean {\n if (node.childNodes.length > 0)\n return false\n\n if (!toValue(options.lazy))\n return true\n\n const declared = adapter.getIsLeaf(node.data)\n if (declared !== undefined)\n return declared\n\n // Данные молчат: пока ветку не грузили, считаем её разворачиваемой —\n // иначе до первого запроса дело бы не дошло.\n return loadedKeys.value.has(node.key)\n }\n\n function isLoadingKey(key: GrTreeKey): boolean {\n return loadingKeys.value.has(key)\n }\n\n function markLoading(key: GrTreeKey, loading: boolean) {\n const next = new Set(loadingKeys.value)\n if (loading)\n next.add(key)\n else\n next.delete(key)\n loadingKeys.value = next\n }\n\n function ensureLoaded(node: GrTreeNode<T>) {\n const load = options.load\n if (!toValue(options.lazy) || !load)\n return\n\n if (loadedKeys.value.has(node.key) || loadingKeys.value.has(node.key) || isLeafNode(node))\n return\n\n markLoading(node.key, true)\n\n let settled = false\n load(node, (children) => {\n // Ответ приходит от потребителя: второй вызов `resolve` — его ошибка, но\n // дублировать детей из-за неё дерево не обязано.\n if (settled)\n return\n settled = true\n\n const next = new Map(loadedChildren.value)\n next.set(node.key, [...(children ?? [])])\n loadedChildren.value = next\n loadedKeys.value = new Set(loadedKeys.value).add(node.key)\n markLoading(node.key, false)\n })\n }\n function filter(value: string) {\n filterValue.value = value\n }\n\n /**\n * Плоско — потому что рекурсивный рендер стоил по инстансу компонента на\n * каждый раскрытый узел: дерево на 2 000 видимых строк превращалось в 2 000\n * компонентов со своими вычислениями и подписками.\n */\n const visibleRows = computed<GrTreeVisibleRow<T>[]>(() => {\n const { roots } = treeModel.value\n const { isActive, subtreeHasMatch, matchedKeys, autoExpandKeys } = filterInfo.value\n const rows: GrTreeVisibleRow<T>[] = []\n\n const walk = (nodes: GrTreeNode<T>[], ancestorColors: string[]): void => {\n const siblings = isActive ? nodes.filter(node => subtreeHasMatch.get(node.key)) : nodes\n\n siblings.forEach((node, index) => {\n const isLeaf = isLeafNode(node)\n const isExpanded = isExpandedKey(node.key) || (isActive && autoExpandKeys.has(node.key))\n\n rows.push({\n node,\n isExpanded,\n isLeaf,\n isMatched: matchedKeys.has(node.key),\n posInSet: index + 1,\n setSize: siblings.length,\n isLoading: isLoadingKey(node.key),\n branchColors: ancestorColors,\n })\n\n if (!isExpanded || node.childNodes.length === 0)\n return\n\n const color = options.branchColorFor?.(node)\n\n walk(node.childNodes, color ? [...ancestorColors, color] : ancestorColors)\n })\n }\n\n walk(roots, [])\n\n return rows\n })\n\n return {\n visibleRows,\n filterValue,\n expandedKeys,\n loadedChildren,\n checkedKeys,\n checkStates,\n loadingKeys,\n loadedKeys,\n currentKey,\n treeModel,\n filterInfo,\n filter,\n isExpandedKey,\n setExpandedKey,\n toggleExpand,\n setCurrentKey,\n getCurrentKey,\n getCurrentNode,\n setCurrentNode,\n getNode,\n canMoveNode,\n moveNode,\n appendNode,\n removeNode,\n insertNodeBefore,\n insertNodeAfter,\n getCheckState,\n setChecked,\n toggleChecked,\n getCheckedKeys,\n setCheckedKeys,\n getHalfCheckedKeys,\n isLeafNode,\n isLoadingKey,\n ensureLoaded,\n }\n}\n"],"mappings":"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"}
@@ -4,7 +4,7 @@ import { t as check_default } from "../../../chunks/check-BZI24Qs4.js";
4
4
  import { t as GrButton_default } from "../../GrButton/chunks/GrButton-CS4TqMtG.js";
5
5
  import { useAnnouncer } from "../../../composables/useAnnouncer.js";
6
6
  import { t as GrInput_default } from "../../GrInput/chunks/GrInput-TFeBm3gQ.js";
7
- import { t as GrTree_default } from "../../GrTree/chunks/GrTree-CkHzgYg1.js";
7
+ import { t as GrTree_default } from "../../GrTree/chunks/GrTree-DnDGW0xO.js";
8
8
  import { a as jsonViewerCopyClass, c as jsonViewerMutedClass, d as jsonViewerRowClass, f as jsonViewerSearchClass, i as jsonViewerContentClass, l as jsonViewerPunctuationClass, m as jsonViewerValueClass, o as jsonViewerGroupClass, p as jsonViewerToolbarClass, r as jsonValueClass, s as jsonViewerKeyClass, u as jsonViewerRootClass } from "../../../chunks/config-DpAYidyY.js";
9
9
  import { computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, markRaw, normalizeClass, onBeforeUnmount, onMounted, openBlock, ref, renderSlot, resolveDynamicComponent, toDisplayString, unref, watch, withCtx, withModifiers } from "vue";
10
10
  //#region ~icons/lucide/copy