@noya-app/noya-file-explorer 0.0.2

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.
package/dist/index.js ADDED
@@ -0,0 +1,1854 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __commonJS = (cb, mod) => function __require() {
9
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
10
+ };
11
+ var __export = (target, all) => {
12
+ for (var name in all)
13
+ __defProp(target, name, { get: all[name], enumerable: true });
14
+ };
15
+ var __copyProps = (to, from, except, desc) => {
16
+ if (from && typeof from === "object" || typeof from === "function") {
17
+ for (let key of __getOwnPropNames(from))
18
+ if (!__hasOwnProp.call(to, key) && key !== except)
19
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
20
+ }
21
+ return to;
22
+ };
23
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
24
+ // If the importer is in node compatibility mode or this is not an ESM
25
+ // file that has been converted to a CommonJS file using a Babel-
26
+ // compatible transform (i.e. "__esModule" has not been set), then set
27
+ // "default" to the CommonJS "module.exports" for node compatibility.
28
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
29
+ mod
30
+ ));
31
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
32
+
33
+ // ../../node_modules/tree-visit/lib/access.js
34
+ var require_access = __commonJS({
35
+ "../../node_modules/tree-visit/lib/access.js"(exports2) {
36
+ "use strict";
37
+ Object.defineProperty(exports2, "__esModule", { value: true });
38
+ exports2.accessPath = exports2.access = void 0;
39
+ function access(node, indexPath, options) {
40
+ if (options.includeTraversalContext) {
41
+ const accessed = accessPath(node, indexPath, options);
42
+ return accessed[accessed.length - 1];
43
+ }
44
+ let path4 = indexPath.slice();
45
+ while (path4.length > 0) {
46
+ let index = path4.shift();
47
+ node = options.getChildren(node, path4)[index];
48
+ }
49
+ return node;
50
+ }
51
+ exports2.access = access;
52
+ function accessPath(node, indexPath, options) {
53
+ let path4 = indexPath.slice();
54
+ let result = [node];
55
+ while (path4.length > 0) {
56
+ let index = path4.shift();
57
+ const context = options.includeTraversalContext ? {
58
+ getRoot: () => result[0],
59
+ getParent: () => result[result.length - 2],
60
+ getAncestors: () => result.slice(0, -1)
61
+ } : void 0;
62
+ node = options.getChildren(node, path4, context)[index];
63
+ result.push(node);
64
+ }
65
+ return result;
66
+ }
67
+ exports2.accessPath = accessPath;
68
+ }
69
+ });
70
+
71
+ // ../../node_modules/tree-visit/lib/sort.js
72
+ var require_sort = __commonJS({
73
+ "../../node_modules/tree-visit/lib/sort.js"(exports2) {
74
+ "use strict";
75
+ Object.defineProperty(exports2, "__esModule", { value: true });
76
+ exports2.sortPaths = exports2.comparePathsByComponent = void 0;
77
+ function comparePathsByComponent(a, b) {
78
+ for (let i = 0; i < Math.min(a.length, b.length); i++) {
79
+ if (a[i] < b[i])
80
+ return -1;
81
+ if (a[i] > b[i])
82
+ return 1;
83
+ }
84
+ return a.length - b.length;
85
+ }
86
+ exports2.comparePathsByComponent = comparePathsByComponent;
87
+ function sortPaths(indexPaths) {
88
+ return [...indexPaths].sort(comparePathsByComponent);
89
+ }
90
+ exports2.sortPaths = sortPaths;
91
+ }
92
+ });
93
+
94
+ // ../../node_modules/tree-visit/lib/ancestors.js
95
+ var require_ancestors = __commonJS({
96
+ "../../node_modules/tree-visit/lib/ancestors.js"(exports2) {
97
+ "use strict";
98
+ Object.defineProperty(exports2, "__esModule", { value: true });
99
+ exports2.ancestorPaths = void 0;
100
+ var sort_1 = require_sort();
101
+ function ancestorPaths2(paths, options) {
102
+ var _a;
103
+ const result = /* @__PURE__ */ new Map();
104
+ const compare = (_a = options === null || options === void 0 ? void 0 : options.compare) !== null && _a !== void 0 ? _a : sort_1.comparePathsByComponent;
105
+ const sortedIndexPaths = paths.sort(compare);
106
+ for (const indexPath of sortedIndexPaths) {
107
+ const foundParent = indexPath.some((_, index) => {
108
+ const parentKey = indexPath.slice(0, index).join();
109
+ return result.has(parentKey);
110
+ });
111
+ if (foundParent)
112
+ continue;
113
+ result.set(indexPath.join(), indexPath);
114
+ }
115
+ return Array.from(result.values());
116
+ }
117
+ exports2.ancestorPaths = ancestorPaths2;
118
+ }
119
+ });
120
+
121
+ // ../../node_modules/tree-visit/lib/diagram/boxDiagram.js
122
+ var require_boxDiagram = __commonJS({
123
+ "../../node_modules/tree-visit/lib/diagram/boxDiagram.js"(exports2) {
124
+ "use strict";
125
+ Object.defineProperty(exports2, "__esModule", { value: true });
126
+ exports2.boxDiagram = void 0;
127
+ var BoxDrawing;
128
+ (function(BoxDrawing2) {
129
+ BoxDrawing2["TopLeft"] = "\u250C";
130
+ BoxDrawing2["TopRight"] = "\u2510";
131
+ BoxDrawing2["BottomLeft"] = "\u2514";
132
+ BoxDrawing2["BottomRight"] = "\u2518";
133
+ BoxDrawing2["Horizontal"] = "\u2500";
134
+ BoxDrawing2["Vertical"] = "\u2502";
135
+ BoxDrawing2["BottomConnectorDown"] = "\u252C";
136
+ BoxDrawing2["BottomConnectorUp"] = "\u2534";
137
+ BoxDrawing2["TopConnectorUp"] = "\u2534";
138
+ })(BoxDrawing || (BoxDrawing = {}));
139
+ function wrapLabelInBox(label) {
140
+ const lines = label.split("\n");
141
+ const length = Math.max(...lines.map((line) => line.length));
142
+ const horizontalMargin = 1;
143
+ const width = length + horizontalMargin * 2 + 2;
144
+ const height = 2 + lines.length;
145
+ const diagram = [
146
+ [
147
+ BoxDrawing.TopLeft,
148
+ BoxDrawing.Horizontal.repeat(length + horizontalMargin * 2),
149
+ BoxDrawing.TopRight
150
+ ],
151
+ ...lines.map((line) => [
152
+ BoxDrawing.Vertical,
153
+ " ".repeat(horizontalMargin),
154
+ line + (line.length < length ? " ".repeat(length - line.length) : ""),
155
+ " ".repeat(horizontalMargin),
156
+ BoxDrawing.Vertical
157
+ ]),
158
+ [
159
+ BoxDrawing.BottomLeft,
160
+ BoxDrawing.Horizontal.repeat(length + horizontalMargin * 2),
161
+ BoxDrawing.BottomRight
162
+ ]
163
+ ];
164
+ return {
165
+ width,
166
+ height,
167
+ contents: diagram.map((parts) => parts.join(""))
168
+ };
169
+ }
170
+ function mergeBoxesHorizontal(boxes) {
171
+ const horizontalMargin = 1;
172
+ if (boxes.length === 0) {
173
+ throw new Error("Can't merge empty array of boxes");
174
+ }
175
+ return boxes.slice(1).reduce((result, box) => {
176
+ const height = Math.max(result.height, box.height);
177
+ const width = result.width + horizontalMargin + box.width;
178
+ const contents = [];
179
+ for (let i = 0; i < height; i++) {
180
+ contents.push((result.contents[i] || " ".repeat(result.width)) + " ".repeat(horizontalMargin) + (box.contents[i] || " ".repeat(box.width)));
181
+ }
182
+ return { height, width, contents: centerBlock(contents, width) };
183
+ }, boxes[0]);
184
+ }
185
+ function mergeBoxesVertical(boxes) {
186
+ const verticalMargin = 1;
187
+ if (boxes.length === 0) {
188
+ throw new Error("Can't merge empty array of boxes");
189
+ }
190
+ const width = Math.max(...boxes.map((box) => box.width));
191
+ return boxes.slice(1).reduce((result, box) => {
192
+ const height = result.height + verticalMargin + box.height;
193
+ const contents = [];
194
+ for (let i = 0; i < height; i++) {
195
+ if (i < result.height) {
196
+ contents.push(result.contents[i]);
197
+ } else if (i === result.height) {
198
+ contents.push(" ".repeat(width));
199
+ } else {
200
+ contents.push(box.contents[i - result.height - 1]);
201
+ }
202
+ }
203
+ return { height, width, contents: centerBlock(contents, width) };
204
+ }, boxes[0]);
205
+ }
206
+ function nodeDiagram(node, indexPath, options) {
207
+ const label = options.getLabel(node, indexPath);
208
+ const box = wrapLabelInBox(label);
209
+ const children = options.getChildren(node, indexPath);
210
+ if (children.length === 0)
211
+ return box;
212
+ const childBoxes = children.map((child, index) => {
213
+ const childBox = nodeDiagram(child, [...indexPath, index], options);
214
+ childBox.contents[0] = insertSubstring(childBox.contents[0], centerIndex(childBox.contents[0].length), BoxDrawing.TopConnectorUp);
215
+ return childBox;
216
+ });
217
+ const result = mergeBoxesVertical([box, mergeBoxesHorizontal(childBoxes)]);
218
+ const contents = result.contents;
219
+ const mid = centerIndex(result.width);
220
+ contents[box.height - 1] = insertSubstring(contents[box.height - 1], mid, BoxDrawing.BottomConnectorDown);
221
+ let min = contents[box.height + 1].indexOf(BoxDrawing.TopConnectorUp);
222
+ let max = contents[box.height + 1].lastIndexOf(BoxDrawing.TopConnectorUp);
223
+ for (let i = min; i <= max; i++) {
224
+ let character;
225
+ if (i === mid) {
226
+ character = childBoxes.length > 1 ? BoxDrawing.BottomConnectorUp : BoxDrawing.Vertical;
227
+ } else if (i === min) {
228
+ character = BoxDrawing.TopLeft;
229
+ } else if (i === max) {
230
+ character = BoxDrawing.TopRight;
231
+ } else {
232
+ character = BoxDrawing.Horizontal;
233
+ }
234
+ result.contents[box.height] = insertSubstring(result.contents[box.height], i, character);
235
+ }
236
+ return result;
237
+ }
238
+ function boxDiagram(node, options) {
239
+ return nodeDiagram(node, [], options).contents.join("\n");
240
+ }
241
+ exports2.boxDiagram = boxDiagram;
242
+ function centerIndex(width) {
243
+ return Math.floor(width / 2);
244
+ }
245
+ function centerLine(line, width) {
246
+ const remainder = width - line.length;
247
+ if (remainder <= 0)
248
+ return line;
249
+ const prefixLength = centerIndex(remainder);
250
+ const suffixLength = centerIndex(remainder);
251
+ const result = " ".repeat(prefixLength) + line + " ".repeat(suffixLength);
252
+ return prefixLength + suffixLength + result.length < width ? result + " " : result;
253
+ }
254
+ function centerBlock(lines, width) {
255
+ return lines.map((line) => centerLine(line, width));
256
+ }
257
+ function insertSubstring(string, index, substring) {
258
+ if (index > string.length - 1)
259
+ return string;
260
+ return string.substring(0, index) + substring + string.substring(index + 1);
261
+ }
262
+ }
263
+ });
264
+
265
+ // ../../node_modules/tree-visit/lib/diagram/directoryDiagram.js
266
+ var require_directoryDiagram = __commonJS({
267
+ "../../node_modules/tree-visit/lib/diagram/directoryDiagram.js"(exports2) {
268
+ "use strict";
269
+ Object.defineProperty(exports2, "__esModule", { value: true });
270
+ exports2.prefixBlock = exports2.isMultiline = exports2.directoryDiagram = void 0;
271
+ var LinePrefix;
272
+ (function(LinePrefix2) {
273
+ LinePrefix2["Child"] = "\u251C\u2500\u2500 ";
274
+ LinePrefix2["LastChild"] = "\u2514\u2500\u2500 ";
275
+ LinePrefix2["NestedChild"] = "\u2502 ";
276
+ LinePrefix2["LastNestedChild"] = " ";
277
+ })(LinePrefix || (LinePrefix = {}));
278
+ function nodeDiagram(node, indexPath, options) {
279
+ const label = options.getLabel(node, indexPath);
280
+ const depth = indexPath.length;
281
+ let rootLine = { label, depth, prefix: "", multilinePrefix: "" };
282
+ const children = options.getChildren(node, indexPath);
283
+ if (children.length === 0)
284
+ return [rootLine];
285
+ if (options.flattenSingleChildNodes && children.length === 1 && !isMultiline(label)) {
286
+ const [line] = nodeDiagram(children[0], [...indexPath, 0], options);
287
+ const hideRoot = indexPath.length === 0 && label === "";
288
+ rootLine.label = hideRoot ? `/ ${line.label}` : `${rootLine.label} / ${line.label}`;
289
+ return [rootLine];
290
+ }
291
+ const nestedLines = children.flatMap((file, index, array) => {
292
+ const childIsLast = index === array.length - 1;
293
+ const childLines = nodeDiagram(file, [...indexPath, index], options);
294
+ const childPrefix = childIsLast ? LinePrefix.LastChild : LinePrefix.Child;
295
+ const childMultilinePrefix = childIsLast ? LinePrefix.LastNestedChild : LinePrefix.NestedChild;
296
+ childLines.forEach((line) => {
297
+ if (line.depth === depth + 1) {
298
+ line.prefix = childPrefix + line.prefix;
299
+ line.multilinePrefix = childMultilinePrefix + line.multilinePrefix;
300
+ } else if (childIsLast) {
301
+ line.prefix = LinePrefix.LastNestedChild + line.prefix;
302
+ line.multilinePrefix = LinePrefix.LastNestedChild + line.multilinePrefix;
303
+ } else {
304
+ line.prefix = LinePrefix.NestedChild + line.prefix;
305
+ line.multilinePrefix = LinePrefix.NestedChild + line.multilinePrefix;
306
+ }
307
+ });
308
+ return childLines;
309
+ });
310
+ return [rootLine, ...nestedLines];
311
+ }
312
+ function directoryDiagram(node, options) {
313
+ const lines = nodeDiagram(node, [], options);
314
+ const strings = lines.map((line) => prefixBlock(line.label, line.prefix, line.multilinePrefix));
315
+ return strings.join("\n");
316
+ }
317
+ exports2.directoryDiagram = directoryDiagram;
318
+ function isMultiline(line) {
319
+ return line.includes("\n");
320
+ }
321
+ exports2.isMultiline = isMultiline;
322
+ function prefixBlock(block, prefix, multilinePrefix) {
323
+ if (!isMultiline(block))
324
+ return prefix + block;
325
+ return block.split("\n").map((line, index) => (index === 0 ? prefix : multilinePrefix) + line).join("\n");
326
+ }
327
+ exports2.prefixBlock = prefixBlock;
328
+ }
329
+ });
330
+
331
+ // ../../node_modules/tree-visit/lib/diagram.js
332
+ var require_diagram = __commonJS({
333
+ "../../node_modules/tree-visit/lib/diagram.js"(exports2) {
334
+ "use strict";
335
+ Object.defineProperty(exports2, "__esModule", { value: true });
336
+ exports2.diagram = void 0;
337
+ var boxDiagram_1 = require_boxDiagram();
338
+ var directoryDiagram_1 = require_directoryDiagram();
339
+ function diagram(node, options) {
340
+ if (options.type === "box") {
341
+ return (0, boxDiagram_1.boxDiagram)(node, options);
342
+ }
343
+ return (0, directoryDiagram_1.directoryDiagram)(node, options);
344
+ }
345
+ exports2.diagram = diagram;
346
+ }
347
+ });
348
+
349
+ // ../../node_modules/tree-visit/lib/visit.js
350
+ var require_visit = __commonJS({
351
+ "../../node_modules/tree-visit/lib/visit.js"(exports2) {
352
+ "use strict";
353
+ Object.defineProperty(exports2, "__esModule", { value: true });
354
+ exports2.visit = exports2.STOP = exports2.SKIP = void 0;
355
+ exports2.SKIP = "skip";
356
+ exports2.STOP = "stop";
357
+ function visit(node, options) {
358
+ const { onEnter, onLeave, getChildren, onDetectCycle, getIdentifier } = options;
359
+ let indexPath = [];
360
+ let stack = [{ node }];
361
+ const visited = onDetectCycle ? /* @__PURE__ */ new Set() : void 0;
362
+ const context = options.includeTraversalContext ? {
363
+ getRoot() {
364
+ return node;
365
+ },
366
+ getParent() {
367
+ var _a;
368
+ return (_a = stack[stack.length - 2]) === null || _a === void 0 ? void 0 : _a.node;
369
+ },
370
+ getAncestors() {
371
+ return stack.slice(0, -1).map((wrapper) => wrapper.node);
372
+ }
373
+ } : void 0;
374
+ const getIndexPath = options.reuseIndexPath ? () => indexPath : () => indexPath.slice();
375
+ while (stack.length > 0) {
376
+ let wrapper = stack[stack.length - 1];
377
+ if (wrapper.state === void 0) {
378
+ if (visited) {
379
+ const id = getIdentifier ? getIdentifier(wrapper.node) : wrapper.node;
380
+ if (visited.has(id)) {
381
+ const action = typeof onDetectCycle === "function" ? onDetectCycle(wrapper.node, getIndexPath(), context) : onDetectCycle;
382
+ if (action === "error") {
383
+ throw new Error("Cycle detected in tree");
384
+ } else {
385
+ wrapper.state = -1;
386
+ continue;
387
+ }
388
+ }
389
+ visited.add(id);
390
+ }
391
+ const enterResult = onEnter === null || onEnter === void 0 ? void 0 : onEnter(wrapper.node, getIndexPath());
392
+ if (enterResult === exports2.STOP)
393
+ return;
394
+ wrapper.state = enterResult === exports2.SKIP ? -1 : 0;
395
+ }
396
+ const children = wrapper.children || getChildren(wrapper.node, getIndexPath(), context);
397
+ if (!wrapper.children) {
398
+ wrapper.children = children;
399
+ }
400
+ if (wrapper.state !== -1) {
401
+ if (wrapper.state < children.length) {
402
+ let currentIndex = wrapper.state;
403
+ indexPath.push(currentIndex);
404
+ stack.push({ node: children[currentIndex] });
405
+ wrapper.state = currentIndex + 1;
406
+ continue;
407
+ }
408
+ const leaveResult = onLeave === null || onLeave === void 0 ? void 0 : onLeave(wrapper.node, getIndexPath());
409
+ if (leaveResult === exports2.STOP)
410
+ return;
411
+ }
412
+ if (visited) {
413
+ const id = getIdentifier ? getIdentifier(wrapper.node) : wrapper.node;
414
+ visited.delete(id);
415
+ }
416
+ indexPath.pop();
417
+ stack.pop();
418
+ }
419
+ }
420
+ exports2.visit = visit;
421
+ }
422
+ });
423
+
424
+ // ../../node_modules/tree-visit/lib/find.js
425
+ var require_find = __commonJS({
426
+ "../../node_modules/tree-visit/lib/find.js"(exports2) {
427
+ "use strict";
428
+ Object.defineProperty(exports2, "__esModule", { value: true });
429
+ exports2.findAllIndexPaths = exports2.findIndexPath = exports2.findAll = exports2.find = void 0;
430
+ var visit_1 = require_visit();
431
+ function find(node, options) {
432
+ let found;
433
+ (0, visit_1.visit)(node, Object.assign(Object.assign({}, options), { onEnter: (child, indexPath) => {
434
+ if (options.predicate(child, indexPath)) {
435
+ found = child;
436
+ return visit_1.STOP;
437
+ }
438
+ } }));
439
+ return found;
440
+ }
441
+ exports2.find = find;
442
+ function findAll(node, options) {
443
+ let found = [];
444
+ (0, visit_1.visit)(node, {
445
+ onEnter: (child, indexPath) => {
446
+ if (options.predicate(child, indexPath)) {
447
+ found.push(child);
448
+ }
449
+ },
450
+ getChildren: options.getChildren
451
+ });
452
+ return found;
453
+ }
454
+ exports2.findAll = findAll;
455
+ function findIndexPath(node, options) {
456
+ let found;
457
+ (0, visit_1.visit)(node, {
458
+ onEnter: (child, indexPath) => {
459
+ if (options.predicate(child, indexPath)) {
460
+ found = [...indexPath];
461
+ return visit_1.STOP;
462
+ }
463
+ },
464
+ getChildren: options.getChildren
465
+ });
466
+ return found;
467
+ }
468
+ exports2.findIndexPath = findIndexPath;
469
+ function findAllIndexPaths(node, options) {
470
+ let found = [];
471
+ (0, visit_1.visit)(node, {
472
+ onEnter: (child, indexPath) => {
473
+ if (options.predicate(child, indexPath)) {
474
+ found.push([...indexPath]);
475
+ }
476
+ },
477
+ getChildren: options.getChildren
478
+ });
479
+ return found;
480
+ }
481
+ exports2.findAllIndexPaths = findAllIndexPaths;
482
+ }
483
+ });
484
+
485
+ // ../../node_modules/tree-visit/lib/reduce.js
486
+ var require_reduce = __commonJS({
487
+ "../../node_modules/tree-visit/lib/reduce.js"(exports2) {
488
+ "use strict";
489
+ Object.defineProperty(exports2, "__esModule", { value: true });
490
+ exports2.reduce = void 0;
491
+ var visit_1 = require_visit();
492
+ function reduce(node, options) {
493
+ let result = options.initialResult;
494
+ (0, visit_1.visit)(node, Object.assign(Object.assign({}, options), { onEnter: (child, indexPath) => {
495
+ result = options.nextResult(result, child, indexPath);
496
+ } }));
497
+ return result;
498
+ }
499
+ exports2.reduce = reduce;
500
+ }
501
+ });
502
+
503
+ // ../../node_modules/tree-visit/lib/flat.js
504
+ var require_flat = __commonJS({
505
+ "../../node_modules/tree-visit/lib/flat.js"(exports2) {
506
+ "use strict";
507
+ Object.defineProperty(exports2, "__esModule", { value: true });
508
+ exports2.flat = void 0;
509
+ var reduce_1 = require_reduce();
510
+ function flat(node, options) {
511
+ return (0, reduce_1.reduce)(node, Object.assign(Object.assign({}, options), { initialResult: [], nextResult: (result, child) => {
512
+ result.push(child);
513
+ return result;
514
+ } }));
515
+ }
516
+ exports2.flat = flat;
517
+ }
518
+ });
519
+
520
+ // ../../node_modules/tree-visit/lib/flatMap.js
521
+ var require_flatMap = __commonJS({
522
+ "../../node_modules/tree-visit/lib/flatMap.js"(exports2) {
523
+ "use strict";
524
+ Object.defineProperty(exports2, "__esModule", { value: true });
525
+ exports2.flatMap = void 0;
526
+ var reduce_1 = require_reduce();
527
+ function flatMap(node, options) {
528
+ return (0, reduce_1.reduce)(node, Object.assign(Object.assign({}, options), { initialResult: [], nextResult: (result, child, indexPath) => {
529
+ result.push(...options.transform(child, indexPath));
530
+ return result;
531
+ } }));
532
+ }
533
+ exports2.flatMap = flatMap;
534
+ }
535
+ });
536
+
537
+ // ../../node_modules/tree-visit/lib/map.js
538
+ var require_map = __commonJS({
539
+ "../../node_modules/tree-visit/lib/map.js"(exports2) {
540
+ "use strict";
541
+ Object.defineProperty(exports2, "__esModule", { value: true });
542
+ exports2.map = void 0;
543
+ var visit_1 = require_visit();
544
+ function map(node, options) {
545
+ const childrenMap = {};
546
+ (0, visit_1.visit)(node, Object.assign(Object.assign({}, options), { onLeave: (child, indexPath) => {
547
+ var _a, _b;
548
+ const keyIndexPath = [0, ...indexPath];
549
+ const key = keyIndexPath.join();
550
+ const transformed = options.transform(child, (_a = childrenMap[key]) !== null && _a !== void 0 ? _a : [], indexPath);
551
+ const parentKey = keyIndexPath.slice(0, -1).join();
552
+ const parentChildren = (_b = childrenMap[parentKey]) !== null && _b !== void 0 ? _b : [];
553
+ parentChildren.push(transformed);
554
+ childrenMap[parentKey] = parentChildren;
555
+ } }));
556
+ return childrenMap[""][0];
557
+ }
558
+ exports2.map = map;
559
+ }
560
+ });
561
+
562
+ // ../../node_modules/tree-visit/lib/operation.js
563
+ var require_operation = __commonJS({
564
+ "../../node_modules/tree-visit/lib/operation.js"(exports2) {
565
+ "use strict";
566
+ Object.defineProperty(exports2, "__esModule", { value: true });
567
+ exports2.splice = exports2.applyOperations = exports2.getReplaceOperations = exports2.getRemovalOperations = exports2.getInsertionOperations = exports2.replaceOperation = exports2.removeOperation = exports2.insertOperation = void 0;
568
+ var ancestors_1 = require_ancestors();
569
+ var map_1 = require_map();
570
+ function insertOperation(index, nodes) {
571
+ return {
572
+ type: "insert",
573
+ index,
574
+ nodes
575
+ };
576
+ }
577
+ exports2.insertOperation = insertOperation;
578
+ function removeOperation(indexes) {
579
+ return {
580
+ type: "remove",
581
+ indexes
582
+ };
583
+ }
584
+ exports2.removeOperation = removeOperation;
585
+ function replaceOperation() {
586
+ return {
587
+ type: "replace"
588
+ };
589
+ }
590
+ exports2.replaceOperation = replaceOperation;
591
+ function splitIndexPath(indexPath) {
592
+ return [indexPath.slice(0, -1), indexPath[indexPath.length - 1]];
593
+ }
594
+ function getInsertionOperations(indexPath, nodes, operations = /* @__PURE__ */ new Map()) {
595
+ var _a;
596
+ const [parentIndexPath, index] = splitIndexPath(indexPath);
597
+ for (let i = parentIndexPath.length - 1; i >= 0; i--) {
598
+ const parentKey = parentIndexPath.slice(0, i).join();
599
+ switch ((_a = operations.get(parentKey)) === null || _a === void 0 ? void 0 : _a.type) {
600
+ case "remove":
601
+ continue;
602
+ }
603
+ operations.set(parentKey, replaceOperation());
604
+ }
605
+ const operation = operations.get(parentIndexPath.join());
606
+ switch (operation === null || operation === void 0 ? void 0 : operation.type) {
607
+ case "remove":
608
+ operations.set(parentIndexPath.join(), {
609
+ type: "removeThenInsert",
610
+ removeIndexes: operation.indexes,
611
+ insertIndex: index,
612
+ insertNodes: nodes
613
+ });
614
+ break;
615
+ default:
616
+ operations.set(parentIndexPath.join(), insertOperation(index, nodes));
617
+ }
618
+ return operations;
619
+ }
620
+ exports2.getInsertionOperations = getInsertionOperations;
621
+ function getRemovalOperations(indexPaths) {
622
+ var _a, _b;
623
+ const _ancestorIndexPaths = (0, ancestors_1.ancestorPaths)(indexPaths);
624
+ const indexesToRemove = /* @__PURE__ */ new Map();
625
+ for (const indexPath of _ancestorIndexPaths) {
626
+ const parentKey = indexPath.slice(0, -1).join();
627
+ const value = (_a = indexesToRemove.get(parentKey)) !== null && _a !== void 0 ? _a : [];
628
+ value.push(indexPath[indexPath.length - 1]);
629
+ indexesToRemove.set(parentKey, value);
630
+ }
631
+ const operations = /* @__PURE__ */ new Map();
632
+ for (const indexPath of _ancestorIndexPaths) {
633
+ for (let i = indexPath.length - 1; i >= 0; i--) {
634
+ const parentKey = indexPath.slice(0, i).join();
635
+ operations.set(parentKey, replaceOperation());
636
+ }
637
+ }
638
+ for (const indexPath of _ancestorIndexPaths) {
639
+ const parentKey = indexPath.slice(0, -1).join();
640
+ operations.set(parentKey, removeOperation((_b = indexesToRemove.get(parentKey)) !== null && _b !== void 0 ? _b : []));
641
+ }
642
+ return operations;
643
+ }
644
+ exports2.getRemovalOperations = getRemovalOperations;
645
+ function getReplaceOperations(indexPath, node) {
646
+ const operations = /* @__PURE__ */ new Map();
647
+ const [parentIndexPath, index] = splitIndexPath(indexPath);
648
+ for (let i = parentIndexPath.length - 1; i >= 0; i--) {
649
+ const parentKey = parentIndexPath.slice(0, i).join();
650
+ operations.set(parentKey, replaceOperation());
651
+ }
652
+ operations.set(parentIndexPath.join(), {
653
+ type: "removeThenInsert",
654
+ removeIndexes: [index],
655
+ insertIndex: index,
656
+ insertNodes: [node]
657
+ });
658
+ return operations;
659
+ }
660
+ exports2.getReplaceOperations = getReplaceOperations;
661
+ function applyOperations(node, operations, options) {
662
+ return (0, map_1.map)(node, Object.assign(Object.assign({}, options), {
663
+ // Avoid calling `getChildren` for every node in the tree.
664
+ // Return [] if we're just going to return the original node anyway.
665
+ getChildren: (node2, indexPath) => {
666
+ const key = indexPath.join();
667
+ const operation = operations.get(key);
668
+ switch (operation === null || operation === void 0 ? void 0 : operation.type) {
669
+ case "replace":
670
+ case "remove":
671
+ case "removeThenInsert":
672
+ case "insert":
673
+ return options.getChildren(node2, indexPath);
674
+ default:
675
+ return [];
676
+ }
677
+ },
678
+ transform: (node2, children, indexPath) => {
679
+ const key = indexPath.join();
680
+ const operation = operations.get(key);
681
+ switch (operation === null || operation === void 0 ? void 0 : operation.type) {
682
+ case "remove":
683
+ return options.create(node2, children.filter((_, index) => !operation.indexes.includes(index)), indexPath);
684
+ case "removeThenInsert":
685
+ const updatedChildren = children.filter((_, index) => !operation.removeIndexes.includes(index));
686
+ const adjustedIndex = operation.removeIndexes.reduce((index, removedIndex) => removedIndex < index ? index - 1 : index, operation.insertIndex);
687
+ return options.create(node2, splice(updatedChildren, adjustedIndex, 0, ...operation.insertNodes), indexPath);
688
+ case "insert":
689
+ return options.create(node2, splice(children, operation.index, 0, ...operation.nodes), indexPath);
690
+ case "replace":
691
+ return options.create(node2, children, indexPath);
692
+ default:
693
+ return node2;
694
+ }
695
+ }
696
+ }));
697
+ }
698
+ exports2.applyOperations = applyOperations;
699
+ function splice(array, start, deleteCount, ...items) {
700
+ return [
701
+ ...array.slice(0, start),
702
+ ...items,
703
+ ...array.slice(start + deleteCount)
704
+ ];
705
+ }
706
+ exports2.splice = splice;
707
+ }
708
+ });
709
+
710
+ // ../../node_modules/tree-visit/lib/insert.js
711
+ var require_insert = __commonJS({
712
+ "../../node_modules/tree-visit/lib/insert.js"(exports2) {
713
+ "use strict";
714
+ Object.defineProperty(exports2, "__esModule", { value: true });
715
+ exports2.insert = void 0;
716
+ var operation_1 = require_operation();
717
+ function insert(node, options) {
718
+ const { nodes, at } = options;
719
+ if (at.length === 0) {
720
+ throw new Error(`Can't insert nodes at the root`);
721
+ }
722
+ const state = (0, operation_1.getInsertionOperations)(at, nodes);
723
+ return (0, operation_1.applyOperations)(node, state, options);
724
+ }
725
+ exports2.insert = insert;
726
+ }
727
+ });
728
+
729
+ // ../../node_modules/tree-visit/lib/move.js
730
+ var require_move = __commonJS({
731
+ "../../node_modules/tree-visit/lib/move.js"(exports2) {
732
+ "use strict";
733
+ Object.defineProperty(exports2, "__esModule", { value: true });
734
+ exports2.move = void 0;
735
+ var access_1 = require_access();
736
+ var ancestors_1 = require_ancestors();
737
+ var operation_1 = require_operation();
738
+ function move(node, options) {
739
+ if (options.indexPaths.length === 0)
740
+ return node;
741
+ for (const indexPath of options.indexPaths) {
742
+ if (indexPath.length === 0) {
743
+ throw new Error(`Can't move the root node`);
744
+ }
745
+ }
746
+ if (options.to.length === 0) {
747
+ throw new Error(`Can't move nodes to the root`);
748
+ }
749
+ const _ancestorIndexPaths = (0, ancestors_1.ancestorPaths)(options.indexPaths);
750
+ const nodesToInsert = _ancestorIndexPaths.map((indexPath) => (0, access_1.access)(node, indexPath, options));
751
+ const operations = (0, operation_1.getInsertionOperations)(options.to, nodesToInsert, (0, operation_1.getRemovalOperations)(_ancestorIndexPaths));
752
+ return (0, operation_1.applyOperations)(node, operations, options);
753
+ }
754
+ exports2.move = move;
755
+ }
756
+ });
757
+
758
+ // ../../node_modules/tree-visit/lib/remove.js
759
+ var require_remove = __commonJS({
760
+ "../../node_modules/tree-visit/lib/remove.js"(exports2) {
761
+ "use strict";
762
+ Object.defineProperty(exports2, "__esModule", { value: true });
763
+ exports2.remove = void 0;
764
+ var operation_1 = require_operation();
765
+ function remove(node, options) {
766
+ if (options.indexPaths.length === 0)
767
+ return node;
768
+ for (const indexPath of options.indexPaths) {
769
+ if (indexPath.length === 0) {
770
+ throw new Error(`Can't remove the root node`);
771
+ }
772
+ }
773
+ const operations = (0, operation_1.getRemovalOperations)(options.indexPaths);
774
+ return (0, operation_1.applyOperations)(node, operations, options);
775
+ }
776
+ exports2.remove = remove;
777
+ }
778
+ });
779
+
780
+ // ../../node_modules/tree-visit/lib/replace.js
781
+ var require_replace = __commonJS({
782
+ "../../node_modules/tree-visit/lib/replace.js"(exports2) {
783
+ "use strict";
784
+ Object.defineProperty(exports2, "__esModule", { value: true });
785
+ exports2.replace = void 0;
786
+ var operation_1 = require_operation();
787
+ function replace(node, options) {
788
+ if (options.at.length === 0)
789
+ return options.node;
790
+ const operations = (0, operation_1.getReplaceOperations)(options.at, options.node);
791
+ return (0, operation_1.applyOperations)(node, operations, options);
792
+ }
793
+ exports2.replace = replace;
794
+ }
795
+ });
796
+
797
+ // ../../node_modules/tree-visit/lib/defineTree.js
798
+ var require_defineTree = __commonJS({
799
+ "../../node_modules/tree-visit/lib/defineTree.js"(exports2) {
800
+ "use strict";
801
+ Object.defineProperty(exports2, "__esModule", { value: true });
802
+ exports2.defineTree = void 0;
803
+ var access_1 = require_access();
804
+ var diagram_1 = require_diagram();
805
+ var find_1 = require_find();
806
+ var flat_1 = require_flat();
807
+ var flatMap_1 = require_flatMap();
808
+ var insert_1 = require_insert();
809
+ var map_1 = require_map();
810
+ var move_1 = require_move();
811
+ var reduce_1 = require_reduce();
812
+ var remove_1 = require_remove();
813
+ var replace_1 = require_replace();
814
+ var visit_1 = require_visit();
815
+ var Tree = class _Tree {
816
+ constructor(getChildrenOrBaseOptions, appliedOptions) {
817
+ this.appliedOptions = appliedOptions;
818
+ this.getChildren = (node, indexPath, context) => {
819
+ return this._getChildren(node, indexPath, context);
820
+ };
821
+ this.mergeOptions = (options) => Object.assign(Object.assign(Object.assign({}, this.baseOptions), this.appliedOptions), options);
822
+ this.withOptions = (newOptions) => new _Tree(this.baseOptions, Object.assign(Object.assign({}, this.appliedOptions), newOptions));
823
+ this.access = (node, indexPath) => (0, access_1.access)(node, indexPath, this.mergeOptions({}));
824
+ this.accessPath = (node, indexPath) => (0, access_1.accessPath)(node, indexPath, this.mergeOptions({}));
825
+ this.diagram = (node, options) => typeof options === "function" ? (0, diagram_1.diagram)(node, this.mergeOptions({ getLabel: options })) : (0, diagram_1.diagram)(node, this.mergeOptions(options));
826
+ this.find = (node, predicateOrOptions) => typeof predicateOrOptions === "function" ? (0, find_1.find)(node, this.mergeOptions({ predicate: predicateOrOptions })) : (0, find_1.find)(node, this.mergeOptions(Object.assign({}, predicateOrOptions)));
827
+ this.findAll = (node, predicateOrOptions) => typeof predicateOrOptions === "function" ? (0, find_1.findAll)(node, this.mergeOptions({ predicate: predicateOrOptions })) : (0, find_1.findAll)(node, this.mergeOptions(Object.assign({}, predicateOrOptions)));
828
+ this.findIndexPath = (node, predicateOrOptions) => typeof predicateOrOptions === "function" ? (0, find_1.findIndexPath)(node, this.mergeOptions({ predicate: predicateOrOptions })) : (0, find_1.findIndexPath)(node, this.mergeOptions(Object.assign({}, predicateOrOptions)));
829
+ this.findAllIndexPaths = (node, predicateOrOptions) => typeof predicateOrOptions === "function" ? (0, find_1.findAllIndexPaths)(node, this.mergeOptions({ predicate: predicateOrOptions })) : (0, find_1.findAllIndexPaths)(node, this.mergeOptions(Object.assign({}, predicateOrOptions)));
830
+ this.flat = (node) => (0, flat_1.flat)(node, this.mergeOptions({}));
831
+ this.flatMap = (node, transform) => (0, flatMap_1.flatMap)(node, this.mergeOptions({ transform }));
832
+ this.reduce = (node, nextResult, initialResult) => (0, reduce_1.reduce)(node, this.mergeOptions({ nextResult, initialResult }));
833
+ this.map = (node, transform) => (0, map_1.map)(node, this.mergeOptions({ transform }));
834
+ this.visit = (node, onEnterOrOptions) => typeof onEnterOrOptions === "function" ? (0, visit_1.visit)(node, this.mergeOptions({ onEnter: onEnterOrOptions })) : (0, visit_1.visit)(node, this.mergeOptions(Object.assign({}, onEnterOrOptions)));
835
+ this.insert = (node, options) => (0, insert_1.insert)(node, this.mergeOptions(options));
836
+ this.remove = (node, options) => (0, remove_1.remove)(node, this.mergeOptions(options));
837
+ this.move = (node, options) => (0, move_1.move)(node, this.mergeOptions(options));
838
+ this.replace = (node, options) => (0, replace_1.replace)(node, this.mergeOptions(options));
839
+ this.baseOptions = typeof getChildrenOrBaseOptions === "function" ? { getChildren: getChildrenOrBaseOptions } : getChildrenOrBaseOptions;
840
+ this._getChildren = this.baseOptions.getChildren;
841
+ }
842
+ };
843
+ function defineTree2(getChildren) {
844
+ return new Tree(getChildren, {});
845
+ }
846
+ exports2.defineTree = defineTree2;
847
+ }
848
+ });
849
+
850
+ // ../../node_modules/tree-visit/lib/indexPath.js
851
+ var require_indexPath = __commonJS({
852
+ "../../node_modules/tree-visit/lib/indexPath.js"(exports2) {
853
+ "use strict";
854
+ Object.defineProperty(exports2, "__esModule", { value: true });
855
+ }
856
+ });
857
+
858
+ // ../../node_modules/tree-visit/lib/options.js
859
+ var require_options = __commonJS({
860
+ "../../node_modules/tree-visit/lib/options.js"(exports2) {
861
+ "use strict";
862
+ Object.defineProperty(exports2, "__esModule", { value: true });
863
+ }
864
+ });
865
+
866
+ // ../../node_modules/tree-visit/lib/withOptions.js
867
+ var require_withOptions = __commonJS({
868
+ "../../node_modules/tree-visit/lib/withOptions.js"(exports2) {
869
+ "use strict";
870
+ Object.defineProperty(exports2, "__esModule", { value: true });
871
+ exports2.withOptions = void 0;
872
+ var defineTree_1 = require_defineTree();
873
+ exports2.withOptions = defineTree_1.defineTree;
874
+ }
875
+ });
876
+
877
+ // ../../node_modules/tree-visit/lib/index.js
878
+ var require_lib = __commonJS({
879
+ "../../node_modules/tree-visit/lib/index.js"(exports2) {
880
+ "use strict";
881
+ var __createBinding = exports2 && exports2.__createBinding || (Object.create ? function(o, m, k, k2) {
882
+ if (k2 === void 0) k2 = k;
883
+ Object.defineProperty(o, k2, { enumerable: true, get: function() {
884
+ return m[k];
885
+ } });
886
+ } : function(o, m, k, k2) {
887
+ if (k2 === void 0) k2 = k;
888
+ o[k2] = m[k];
889
+ });
890
+ var __exportStar = exports2 && exports2.__exportStar || function(m, exports3) {
891
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports3, p)) __createBinding(exports3, m, p);
892
+ };
893
+ Object.defineProperty(exports2, "__esModule", { value: true });
894
+ __exportStar(require_access(), exports2);
895
+ __exportStar(require_ancestors(), exports2);
896
+ __exportStar(require_defineTree(), exports2);
897
+ __exportStar(require_diagram(), exports2);
898
+ __exportStar(require_find(), exports2);
899
+ __exportStar(require_flat(), exports2);
900
+ __exportStar(require_flatMap(), exports2);
901
+ __exportStar(require_indexPath(), exports2);
902
+ __exportStar(require_insert(), exports2);
903
+ __exportStar(require_map(), exports2);
904
+ __exportStar(require_move(), exports2);
905
+ __exportStar(require_options(), exports2);
906
+ __exportStar(require_reduce(), exports2);
907
+ __exportStar(require_remove(), exports2);
908
+ __exportStar(require_replace(), exports2);
909
+ __exportStar(require_sort(), exports2);
910
+ __exportStar(require_visit(), exports2);
911
+ __exportStar(require_withOptions(), exports2);
912
+ }
913
+ });
914
+
915
+ // src/index.ts
916
+ var src_exports = {};
917
+ __export(src_exports, {
918
+ MediaCollection: () => MediaCollection,
919
+ PLACEHOLDER_ITEM_NAME: () => PLACEHOLDER_ITEM_NAME,
920
+ basenameValidator: () => basenameValidator,
921
+ createMediaAsset: () => createMediaAsset,
922
+ createMediaFile: () => createMediaFile,
923
+ createMediaFolder: () => createMediaFolder,
924
+ createMediaItem: () => createMediaItem,
925
+ createMediaItemTree: () => createMediaItemTree,
926
+ deleteMediaItems: () => deleteMediaItems,
927
+ getDepthMap: () => getDepthMap,
928
+ getParentDirectories: () => getParentDirectories,
929
+ getVisibleItems: () => getVisibleItems,
930
+ moveMediaInsideFolder: () => moveMediaInsideFolder,
931
+ movePathsIntoTarget: () => movePathsIntoTarget,
932
+ moveUpAFolder: () => moveUpAFolder,
933
+ rootMediaItem: () => rootMediaItem,
934
+ rootMediaItemName: () => rootMediaItemName,
935
+ rootMediaItemPath: () => rootMediaItemPath,
936
+ updateExpandedMap: () => updateExpandedMap,
937
+ validateMediaItemRename: () => validateMediaItemRename
938
+ });
939
+ module.exports = __toCommonJS(src_exports);
940
+
941
+ // src/MediaCollection.tsx
942
+ var import_noya_designsystem = require("@noya-app/noya-designsystem");
943
+ var import_noya_icons = require("@noya-app/noya-icons");
944
+ var import_noya_multiplayer_react = require("@noya-app/noya-multiplayer-react");
945
+ var import_noya_utils2 = require("@noya-app/noya-utils");
946
+ var import_react_utils = require("@noya-app/react-utils");
947
+ var import_browser_fs_access = require("browser-fs-access");
948
+ var import_react = require("react");
949
+
950
+ // src/utils/mediaItemTree.ts
951
+ var import_noya_utils = require("@noya-app/noya-utils");
952
+ var import_imfs = require("imfs");
953
+ var import_tree_visit = __toESM(require_lib());
954
+ var createMediaFolder = (folder) => {
955
+ return {
956
+ id: (0, import_noya_utils.uuid)(),
957
+ kind: "folder",
958
+ ...folder
959
+ };
960
+ };
961
+ var createMediaAsset = (asset) => {
962
+ return {
963
+ id: (0, import_noya_utils.uuid)(),
964
+ kind: "asset",
965
+ ...asset
966
+ };
967
+ };
968
+ var createMediaFile = (file) => {
969
+ return {
970
+ id: (0, import_noya_utils.uuid)(),
971
+ kind: "file",
972
+ ...file
973
+ };
974
+ };
975
+ var createMediaItem = (item) => {
976
+ return {
977
+ ...item
978
+ };
979
+ };
980
+ var rootMediaItem = {
981
+ id: "root",
982
+ kind: "folder"
983
+ };
984
+ var rootMediaItemPath = ".";
985
+ var rootMediaItemName = "All Files";
986
+ var PLACEHOLDER_ITEM_NAME = "placeholder";
987
+ var createMediaItemTree = (mediaMap) => {
988
+ const sortedMediaMap = Object.fromEntries(
989
+ Object.entries(mediaMap).sort((a, b) => a[0].localeCompare(b[0]))
990
+ );
991
+ const parentToChildrenMap = /* @__PURE__ */ new Map();
992
+ const idToPathMap = /* @__PURE__ */ new Map();
993
+ idToPathMap.set(rootMediaItem.id, rootMediaItemPath);
994
+ for (const [itemPath, item] of Object.entries(sortedMediaMap)) {
995
+ const parentPath = import_imfs.path.dirname(itemPath);
996
+ const children = parentToChildrenMap.get(parentPath) ?? [];
997
+ children.push(item);
998
+ parentToChildrenMap.set(parentPath, children);
999
+ idToPathMap.set(item.id, itemPath);
1000
+ }
1001
+ const tree = (0, import_tree_visit.defineTree)({
1002
+ getChildren: (item) => {
1003
+ const itemPath = item === rootMediaItem ? rootMediaItemPath : idToPathMap.get(item.id);
1004
+ if (!itemPath) return [];
1005
+ return parentToChildrenMap.get(itemPath) ?? [];
1006
+ },
1007
+ onDetectCycle: "skip",
1008
+ getIdentifier: (item) => item.id
1009
+ });
1010
+ const result = tree.withOptions({
1011
+ getLabel: (item) => idToPathMap.get(item.id) ?? ""
1012
+ });
1013
+ const mediaItemsWithRoot = [...Object.values(sortedMediaMap), rootMediaItem];
1014
+ const getNameForId = (id) => id === rootMediaItem.id ? rootMediaItemName : import_imfs.path.basename(idToPathMap.get(id) ?? "");
1015
+ const getParentIdForId = (id) => {
1016
+ const itemPath = idToPathMap.get(id);
1017
+ if (!itemPath) return;
1018
+ const parentPath = import_imfs.path.dirname(itemPath);
1019
+ return idToPathMap.get(parentPath);
1020
+ };
1021
+ return {
1022
+ ...result,
1023
+ idToPathMap,
1024
+ parentToChildrenMap,
1025
+ mediaItemsWithRoot,
1026
+ getParentIdForId,
1027
+ getNameForId
1028
+ };
1029
+ };
1030
+
1031
+ // src/MediaCollection.tsx
1032
+ var import_imfs3 = require("imfs");
1033
+ var import_react2 = __toESM(require("react"));
1034
+
1035
+ // src/utils/files.ts
1036
+ var import_imfs2 = require("imfs");
1037
+ var import_tree_visit2 = __toESM(require_lib());
1038
+ var getVisibleItems = ({
1039
+ expandedMap,
1040
+ fileKindFilter,
1041
+ rootItemId,
1042
+ tree,
1043
+ showAllDescendants,
1044
+ showRootItem
1045
+ }) => {
1046
+ const filteredItems = [];
1047
+ const relativeRootItem = tree.find(rootMediaItem, (item) => item.id === rootItemId) ?? rootMediaItem;
1048
+ tree.visit(relativeRootItem, (item) => {
1049
+ if (relativeRootItem.id === item.id) {
1050
+ if (showRootItem) {
1051
+ filteredItems.push(item);
1052
+ }
1053
+ return;
1054
+ }
1055
+ if (item.kind === "file" && fileKindFilter === "all") {
1056
+ filteredItems.push(item);
1057
+ }
1058
+ if (item.kind === "asset" && (fileKindFilter === "assets" || fileKindFilter === "all")) {
1059
+ filteredItems.push(item);
1060
+ }
1061
+ if (item.kind === "folder" && (fileKindFilter === "directories" || fileKindFilter === "all")) {
1062
+ filteredItems.push(item);
1063
+ }
1064
+ if (!expandedMap[item.id] || !showAllDescendants) return "skip";
1065
+ });
1066
+ return filteredItems;
1067
+ };
1068
+ var basenameValidator = (basename) => {
1069
+ if (!basename || basename.trim() === "") return false;
1070
+ const invalidCharsRegex = /[/\\<>:"|?*]/;
1071
+ return !invalidCharsRegex.test(basename);
1072
+ };
1073
+ var validateMediaItemRename = ({
1074
+ basename,
1075
+ selectedItemPath,
1076
+ media
1077
+ }) => {
1078
+ if (!basenameValidator(basename)) return false;
1079
+ const newItemPath = import_imfs2.path.join(import_imfs2.path.dirname(selectedItemPath), basename);
1080
+ const newPathExists = media[newItemPath];
1081
+ if (newPathExists) return false;
1082
+ return true;
1083
+ };
1084
+ var movePathsIntoTarget = ({
1085
+ media,
1086
+ sourceItemPaths,
1087
+ targetItemPath,
1088
+ tree
1089
+ }) => {
1090
+ const ancestors = (0, import_tree_visit2.ancestorPaths)(
1091
+ sourceItemPaths.map((path4) => path4.split("/"))
1092
+ );
1093
+ const mediaClone = { ...media };
1094
+ for (const ancestor of ancestors) {
1095
+ const ancestorPath = ancestor.join("/");
1096
+ const ancestorItem = mediaClone[ancestorPath];
1097
+ const newAncestorPath = import_imfs2.path.join(
1098
+ targetItemPath,
1099
+ import_imfs2.path.basename(ancestorPath)
1100
+ );
1101
+ if (!ancestorItem) continue;
1102
+ const descendantPaths = tree.flat(ancestorItem).map((item) => tree.idToPathMap.get(item.id));
1103
+ for (const descendantPath of descendantPaths) {
1104
+ if (!descendantPath) continue;
1105
+ const newDescendantPath = descendantPath.replace(
1106
+ ancestorPath,
1107
+ newAncestorPath
1108
+ );
1109
+ const newPathIsValid = validateMediaItemRename({
1110
+ basename: import_imfs2.path.basename(descendantPath),
1111
+ selectedItemPath: newDescendantPath,
1112
+ media
1113
+ });
1114
+ if (newPathIsValid) {
1115
+ mediaClone[newDescendantPath] = mediaClone[descendantPath];
1116
+ delete mediaClone[descendantPath];
1117
+ }
1118
+ }
1119
+ }
1120
+ return mediaClone;
1121
+ };
1122
+ var moveUpAFolder = ({
1123
+ tree,
1124
+ media,
1125
+ selectedIds
1126
+ }) => {
1127
+ const indexPath = tree.findIndexPath(
1128
+ rootMediaItem,
1129
+ (item) => item.id === selectedIds[0]
1130
+ );
1131
+ if (!indexPath) return;
1132
+ const grandparentFolder = tree.access(
1133
+ rootMediaItem,
1134
+ indexPath.slice(0, indexPath.length - 2)
1135
+ );
1136
+ const grandparentFolderPath = tree.idToPathMap.get(grandparentFolder.id);
1137
+ if (!grandparentFolderPath) return;
1138
+ const sourceItemPaths = selectedIds.map((id) => tree.idToPathMap.get(id)).filter((path4) => Boolean(path4));
1139
+ return movePathsIntoTarget({
1140
+ media,
1141
+ targetItemPath: grandparentFolderPath,
1142
+ sourceItemPaths,
1143
+ tree
1144
+ });
1145
+ };
1146
+ var getDepthMap = (item, tree, showAllDescendants) => {
1147
+ const depthMap = {};
1148
+ tree.visit(item, (item2, indexPath) => {
1149
+ if (showAllDescendants) {
1150
+ depthMap[item2.id] = Math.max(indexPath.length - 1, 0);
1151
+ } else {
1152
+ depthMap[item2.id] = 0;
1153
+ }
1154
+ });
1155
+ return depthMap;
1156
+ };
1157
+ var updateExpandedMap = ({
1158
+ item,
1159
+ expanded,
1160
+ expandable,
1161
+ expandedMap,
1162
+ tree
1163
+ }) => {
1164
+ const newExpandedMap = { ...expandedMap };
1165
+ const inner = (item2, expanded2) => {
1166
+ if (!expandable) return {};
1167
+ if (item2.id === rootMediaItem.id) return {};
1168
+ if (!expanded2) {
1169
+ const children = tree.getChildren(item2, []);
1170
+ children.forEach((child) => inner(child, false));
1171
+ }
1172
+ newExpandedMap[item2.id] = expanded2;
1173
+ };
1174
+ inner(item, expanded);
1175
+ return newExpandedMap;
1176
+ };
1177
+ var deleteMediaItems = ({
1178
+ selectedIds,
1179
+ media,
1180
+ tree
1181
+ }) => {
1182
+ const itemsToDelete = selectedIds.flatMap((mediaItemId) => {
1183
+ const mediaItem = tree.mediaItemsWithRoot.find(
1184
+ (item) => item.id === mediaItemId
1185
+ );
1186
+ if (!mediaItem) return [];
1187
+ return tree.flat(mediaItem);
1188
+ });
1189
+ const itemKeysToDelete = new Set(
1190
+ itemsToDelete.map((item) => tree.idToPathMap.get(item.id))
1191
+ );
1192
+ return Object.fromEntries(
1193
+ Object.entries(media).filter(([key]) => !itemKeysToDelete.has(key))
1194
+ );
1195
+ };
1196
+ var moveMediaInsideFolder = ({
1197
+ sourceItemIds,
1198
+ targetItemId,
1199
+ media,
1200
+ tree
1201
+ }) => {
1202
+ const targetItemPath = tree.idToPathMap.get(targetItemId);
1203
+ if (!targetItemPath) return media;
1204
+ const sourceItemPaths = sourceItemIds.map((id) => tree.idToPathMap.get(id)).filter((path4) => Boolean(path4));
1205
+ return movePathsIntoTarget({
1206
+ media,
1207
+ sourceItemPaths,
1208
+ targetItemPath,
1209
+ tree
1210
+ });
1211
+ };
1212
+ var getParentDirectories = (mediaMap, folderId) => {
1213
+ const tree = createMediaItemTree(mediaMap);
1214
+ const indexPath = tree.findIndexPath(
1215
+ rootMediaItem,
1216
+ (item) => item.id === folderId
1217
+ );
1218
+ if (!indexPath) return [rootMediaItem];
1219
+ return tree.accessPath(rootMediaItem, indexPath);
1220
+ };
1221
+
1222
+ // src/MediaCollection.tsx
1223
+ var MediaThumbnailInternal = (0, import_react_utils.memoGeneric)(
1224
+ ({ item, selected }) => {
1225
+ const asset = (0, import_noya_multiplayer_react.useAsset)(item.kind === "asset" ? item.assetId : void 0);
1226
+ const isRoot = item.id === rootMediaItem.id;
1227
+ const isFolder = item.kind === "folder";
1228
+ return /* @__PURE__ */ import_react2.default.createElement(
1229
+ import_noya_designsystem.MediaThumbnail,
1230
+ {
1231
+ contentType: asset?.contentType,
1232
+ iconName: isRoot ? "HomeIcon" : isFolder ? "FolderIcon" : void 0,
1233
+ url: asset?.url,
1234
+ selected
1235
+ }
1236
+ );
1237
+ }
1238
+ );
1239
+ var MediaCollection = (0, import_react.memo)(
1240
+ (0, import_react.forwardRef)(function MediaCollection2({
1241
+ onSelectionChange,
1242
+ selectedIds: selectedIdsProp,
1243
+ media,
1244
+ setMedia,
1245
+ viewType = "list",
1246
+ fileKindFilter = "all",
1247
+ showRootItem = false,
1248
+ initialExpanded,
1249
+ expandable = true,
1250
+ renamable = true,
1251
+ onDoubleClickItem,
1252
+ rootItemId = rootMediaItem.id,
1253
+ title,
1254
+ size = "medium",
1255
+ right,
1256
+ renderAction: renderActionProp,
1257
+ className,
1258
+ showUploadButton = true,
1259
+ showAllDescendants = true,
1260
+ scrollable = false,
1261
+ sortable = false,
1262
+ renderEmptyState
1263
+ }, ref) {
1264
+ const tree = (0, import_react.useMemo)(() => createMediaItemTree(media), [media]);
1265
+ const [tempItem, setTempItem] = (0, import_react.useState)(
1266
+ void 0
1267
+ );
1268
+ const treeWithTempItem = (0, import_react.useMemo)(
1269
+ () => createMediaItemTree({
1270
+ ...media,
1271
+ ...tempItem ? { [tempItem[0]]: tempItem[1] } : {}
1272
+ }),
1273
+ [media, tempItem]
1274
+ );
1275
+ const [selectedIds, setSelectedIds] = (0, import_react_utils.useControlledOrUncontrolled)(
1276
+ {
1277
+ defaultValue: [],
1278
+ value: selectedIdsProp,
1279
+ onChange: onSelectionChange
1280
+ }
1281
+ );
1282
+ const assetManager = (0, import_noya_multiplayer_react.useAssetManager)();
1283
+ const assets = (0, import_noya_multiplayer_react.useAssets)();
1284
+ const [expandedMap, setExpandedMap] = (0, import_react.useState)({});
1285
+ const visibleItems = (0, import_react.useMemo)(
1286
+ () => getVisibleItems({
1287
+ expandedMap,
1288
+ fileKindFilter,
1289
+ rootItemId,
1290
+ tree: treeWithTempItem,
1291
+ showAllDescendants,
1292
+ showRootItem
1293
+ }),
1294
+ [
1295
+ expandedMap,
1296
+ fileKindFilter,
1297
+ rootItemId,
1298
+ treeWithTempItem,
1299
+ showAllDescendants,
1300
+ showRootItem
1301
+ ]
1302
+ );
1303
+ const depthMap = (0, import_react.useMemo)(
1304
+ () => getDepthMap(rootMediaItem, treeWithTempItem, showAllDescendants),
1305
+ [treeWithTempItem, showAllDescendants]
1306
+ );
1307
+ const collectionRef = (0, import_react.useRef)(null);
1308
+ const selectedMediaItems = (0, import_react.useMemo)(
1309
+ () => treeWithTempItem.mediaItemsWithRoot.filter(
1310
+ (item) => selectedIds.includes(item.id)
1311
+ ),
1312
+ [treeWithTempItem, selectedIds]
1313
+ );
1314
+ const groupedItems = (0, import_noya_utils2.groupBy)(selectedMediaItems, (item) => item.kind);
1315
+ const selectedAssetItems = groupedItems.asset ?? [];
1316
+ const selectedFolderItems = groupedItems.folder ?? [];
1317
+ const singleItemSelected = selectedMediaItems.length === 1;
1318
+ const onlyAssetsSelected = selectedAssetItems.length > 0 && selectedAssetItems.length === selectedMediaItems.length;
1319
+ const onlyFoldersSelected = selectedFolderItems.length > 0 && selectedFolderItems.length === selectedMediaItems.length;
1320
+ const onlySingleFolderSelected = onlyFoldersSelected && selectedFolderItems.length === 1;
1321
+ const onlySingleAssetSelected = onlyAssetsSelected && selectedAssetItems.length === 1;
1322
+ const rootSelected = selectedIds.includes(rootMediaItem.id);
1323
+ const sameParentSelected = selectedMediaItems.every((item) => {
1324
+ const itemPath = tree.idToPathMap.get(item.id);
1325
+ const firstSelectedPath = tree.idToPathMap.get(selectedIds[0]);
1326
+ if (!itemPath || !firstSelectedPath) return false;
1327
+ return itemPath.startsWith(import_imfs3.path.dirname(firstSelectedPath));
1328
+ });
1329
+ const gridSize = (0, import_react.useMemo)(() => {
1330
+ if (viewType === "grid") {
1331
+ return size;
1332
+ }
1333
+ return "medium";
1334
+ }, [viewType, size]);
1335
+ (0, import_react.useEffect)(() => {
1336
+ if (initialExpanded) {
1337
+ setExpandedMap(initialExpanded);
1338
+ }
1339
+ }, [initialExpanded]);
1340
+ const handleExpanded = (0, import_react.useCallback)(
1341
+ (item) => {
1342
+ if (!expandable) return void 0;
1343
+ if (item.kind !== "folder") return void 0;
1344
+ if (item.id === rootMediaItem.id) return void 0;
1345
+ return expandedMap[item.id] ?? false;
1346
+ },
1347
+ [expandedMap, expandable]
1348
+ );
1349
+ const handleDelete = (0, import_react.useCallback)(
1350
+ (selectedIds2) => {
1351
+ const newMedia = deleteMediaItems({
1352
+ selectedIds: selectedIds2,
1353
+ media,
1354
+ tree
1355
+ });
1356
+ setSelectedIds([rootMediaItem.id]);
1357
+ setMedia({ name: "Delete items", timestamp: Date.now() }, newMedia);
1358
+ },
1359
+ [media, setMedia, setSelectedIds, tree]
1360
+ );
1361
+ const onRename = (0, import_react.useCallback)(
1362
+ (selectedItem, newName) => {
1363
+ if (!renamable) return;
1364
+ const selectedItemPath = treeWithTempItem.idToPathMap.get(
1365
+ selectedItem.id
1366
+ );
1367
+ if (!selectedItemPath) return;
1368
+ const mediaWithTempItem = {
1369
+ ...media,
1370
+ ...tempItem ? { [tempItem[0]]: tempItem[1] } : {}
1371
+ };
1372
+ const renameIsValid = validateMediaItemRename({
1373
+ basename: newName,
1374
+ selectedItemPath,
1375
+ media: mediaWithTempItem
1376
+ });
1377
+ if (!renameIsValid) {
1378
+ setTempItem(void 0);
1379
+ return;
1380
+ }
1381
+ const mediaClone = { ...media };
1382
+ delete mediaClone[selectedItemPath];
1383
+ setMedia(
1384
+ { name: "Rename media item", timestamp: Date.now() },
1385
+ {
1386
+ ...mediaClone,
1387
+ [import_imfs3.path.join(import_imfs3.path.dirname(selectedItemPath), newName)]: selectedItem
1388
+ }
1389
+ );
1390
+ setTempItem(void 0);
1391
+ },
1392
+ [media, renamable, setMedia, tempItem, treeWithTempItem.idToPathMap]
1393
+ );
1394
+ const handleAddFolder = (0, import_react.useCallback)(
1395
+ (currentFolderId) => {
1396
+ const newFolder = createMediaFolder();
1397
+ const currentFolderPath = tree.idToPathMap.get(currentFolderId);
1398
+ if (!currentFolderPath) return;
1399
+ setTempItem([
1400
+ import_imfs3.path.join(currentFolderPath, PLACEHOLDER_ITEM_NAME),
1401
+ newFolder
1402
+ ]);
1403
+ setTimeout(() => {
1404
+ collectionRef.current?.editName(newFolder.id);
1405
+ }, 50);
1406
+ },
1407
+ [tree]
1408
+ );
1409
+ const handleAddFile = (0, import_react.useCallback)(
1410
+ (currentFolderId) => {
1411
+ const newFile = createMediaFile({
1412
+ content: "",
1413
+ encoding: "utf-8"
1414
+ });
1415
+ const currentFolderPath = tree.idToPathMap.get(
1416
+ currentFolderId ?? rootMediaItem.id
1417
+ );
1418
+ if (!currentFolderPath) return;
1419
+ setTempItem([
1420
+ import_imfs3.path.join(currentFolderPath, PLACEHOLDER_ITEM_NAME),
1421
+ newFile
1422
+ ]);
1423
+ setTimeout(() => {
1424
+ collectionRef.current?.editName(newFile.id);
1425
+ }, 50);
1426
+ },
1427
+ [tree.idToPathMap]
1428
+ );
1429
+ const handleMoveUpAFolder = (0, import_react.useCallback)(
1430
+ (selectedIds2) => {
1431
+ const newMedia = moveUpAFolder({
1432
+ tree,
1433
+ media,
1434
+ selectedIds: selectedIds2
1435
+ });
1436
+ if (!newMedia) return;
1437
+ setMedia({ name: "Move items", timestamp: Date.now() }, newMedia);
1438
+ },
1439
+ [media, tree, setMedia]
1440
+ );
1441
+ const handleUpload = (0, import_react.useCallback)(
1442
+ async (selectedId) => {
1443
+ try {
1444
+ const files = await (0, import_browser_fs_access.fileOpen)({ multiple: true });
1445
+ if (!files || !Array.isArray(files) || files.length === 0) return;
1446
+ const parentPath = tree.idToPathMap.get(selectedId);
1447
+ if (!parentPath) return;
1448
+ const uploadPromises = files.map(async (file) => {
1449
+ const asset = await assetManager.create(file);
1450
+ const assetPath = import_imfs3.path.join(parentPath, import_imfs3.path.basename(file.name));
1451
+ return {
1452
+ assetPath,
1453
+ asset: createMediaAsset({ assetId: asset.id })
1454
+ };
1455
+ });
1456
+ const newMediaMap = await Promise.all(uploadPromises);
1457
+ setMedia(
1458
+ { name: "Add media items", timestamp: Date.now() },
1459
+ {
1460
+ ...media,
1461
+ ...Object.fromEntries(
1462
+ newMediaMap.map(({ assetPath, asset }) => [assetPath, asset])
1463
+ )
1464
+ }
1465
+ );
1466
+ } catch (error) {
1467
+ console.error("Failed to upload files:", error);
1468
+ }
1469
+ },
1470
+ [tree.idToPathMap, setMedia, media, assetManager]
1471
+ );
1472
+ const handleDownload = (0, import_react.useCallback)(
1473
+ async (selectedItems) => {
1474
+ const downloadPromises = selectedItems.filter((item) => item.kind === "asset").map(async (item) => {
1475
+ const asset = assets.find((a) => a.id === item.assetId);
1476
+ if (!asset?.url) return;
1477
+ return (0, import_react_utils.downloadUrl)(asset.url, tree.getNameForId(item.id));
1478
+ });
1479
+ await Promise.all(downloadPromises);
1480
+ },
1481
+ [assets, tree]
1482
+ );
1483
+ const handlePreview = (0, import_react.useCallback)(
1484
+ async (selectedItems) => {
1485
+ const previewPromises = selectedItems.filter((item) => item.kind === "asset").map(async (item) => {
1486
+ const asset = assets.find((a) => a.id === item.assetId);
1487
+ if (!asset?.url) return;
1488
+ return window?.open(asset.url, "_blank");
1489
+ });
1490
+ await Promise.all(previewPromises);
1491
+ },
1492
+ [assets]
1493
+ );
1494
+ const handleReplace = (0, import_react.useCallback)(
1495
+ async (selectedItem) => {
1496
+ try {
1497
+ const file = await (0, import_browser_fs_access.fileOpen)();
1498
+ if (!file) return;
1499
+ const asset = await assetManager.create(file);
1500
+ const oldFile = selectedItem;
1501
+ const oldFilePath = tree.idToPathMap.get(oldFile.id);
1502
+ if (!oldFilePath || oldFile.kind !== "asset") return;
1503
+ setMedia(
1504
+ { name: "Replace media file", timestamp: Date.now() },
1505
+ {
1506
+ ...media,
1507
+ [oldFilePath]: createMediaAsset({
1508
+ ...oldFile,
1509
+ assetId: asset.id
1510
+ })
1511
+ }
1512
+ );
1513
+ } catch (error) {
1514
+ console.error("Failed to upload file:", error);
1515
+ }
1516
+ },
1517
+ [media, setMedia, assetManager, tree]
1518
+ );
1519
+ const handleRename = (0, import_react.useCallback)(
1520
+ (selectedItemId) => {
1521
+ collectionRef.current?.editName(selectedItemId);
1522
+ },
1523
+ [collectionRef]
1524
+ );
1525
+ const handleMoveMediaInsideFolder = (0, import_react.useCallback)(
1526
+ (sourceItem, targetItem) => {
1527
+ const sourceItemPath = tree.idToPathMap.get(sourceItem.id);
1528
+ const targetItemPath = tree.idToPathMap.get(targetItem.id);
1529
+ if (!sourceItemPath || !targetItemPath) return;
1530
+ const newMedia = moveMediaInsideFolder({
1531
+ sourceItemIds: [sourceItem.id],
1532
+ targetItemId: targetItem.id,
1533
+ media,
1534
+ tree
1535
+ });
1536
+ setMedia(
1537
+ {
1538
+ name: "Move media file inside folder",
1539
+ timestamp: Date.now()
1540
+ },
1541
+ newMedia
1542
+ );
1543
+ },
1544
+ [media, setMedia, tree]
1545
+ );
1546
+ const assetContextMenuItems = (0, import_react.useMemo)(() => {
1547
+ return (0, import_noya_designsystem.createSectionedMenu)(
1548
+ [
1549
+ !rootSelected && singleItemSelected && {
1550
+ title: "Rename",
1551
+ value: "rename",
1552
+ icon: /* @__PURE__ */ import_react2.default.createElement(import_noya_icons.InputIcon, null)
1553
+ },
1554
+ onlySingleAssetSelected && {
1555
+ title: "Replace",
1556
+ value: "replace",
1557
+ icon: /* @__PURE__ */ import_react2.default.createElement(import_noya_icons.UpdateIcon, null)
1558
+ },
1559
+ !rootSelected && {
1560
+ title: "Delete",
1561
+ value: "delete",
1562
+ icon: /* @__PURE__ */ import_react2.default.createElement(import_noya_icons.TrashIcon, null)
1563
+ }
1564
+ ],
1565
+ [
1566
+ onlySingleFolderSelected && {
1567
+ title: "Add media",
1568
+ value: "upload",
1569
+ icon: /* @__PURE__ */ import_react2.default.createElement(import_noya_icons.UploadIcon, null)
1570
+ },
1571
+ onlySingleFolderSelected && {
1572
+ title: "Add a Folder",
1573
+ value: "addFolder",
1574
+ icon: /* @__PURE__ */ import_react2.default.createElement(import_noya_icons.FolderIcon, null)
1575
+ },
1576
+ onlyAssetsSelected && tree.mediaItemsWithRoot.length > 0 && {
1577
+ title: "Download",
1578
+ value: "download",
1579
+ icon: /* @__PURE__ */ import_react2.default.createElement(import_noya_icons.DownloadIcon, null)
1580
+ },
1581
+ onlySingleAssetSelected && {
1582
+ title: "Preview",
1583
+ value: "preview",
1584
+ icon: /* @__PURE__ */ import_react2.default.createElement(import_noya_icons.OpenInNewWindowIcon, null)
1585
+ }
1586
+ ],
1587
+ [
1588
+ !rootSelected && sameParentSelected && {
1589
+ title: "Move up a folder",
1590
+ value: "move",
1591
+ icon: /* @__PURE__ */ import_react2.default.createElement(import_noya_icons.ResetIcon, null)
1592
+ }
1593
+ ]
1594
+ );
1595
+ }, [
1596
+ rootSelected,
1597
+ singleItemSelected,
1598
+ onlySingleAssetSelected,
1599
+ onlySingleFolderSelected,
1600
+ onlyAssetsSelected,
1601
+ tree.mediaItemsWithRoot.length,
1602
+ sameParentSelected
1603
+ ]);
1604
+ const handleMenuAction = (0, import_react.useCallback)(
1605
+ async (action, selectedItems) => {
1606
+ if (selectedItems.length === 0) return;
1607
+ switch (action) {
1608
+ case "rename":
1609
+ handleRename(selectedItems[0].id);
1610
+ return;
1611
+ case "delete":
1612
+ handleDelete(selectedIds);
1613
+ return;
1614
+ case "replace":
1615
+ handleReplace(selectedItems[0]);
1616
+ return;
1617
+ case "upload":
1618
+ handleUpload(selectedItems[0].id);
1619
+ return;
1620
+ case "addFolder":
1621
+ handleAddFolder(selectedItems[0].id);
1622
+ return;
1623
+ case "preview":
1624
+ handlePreview(selectedItems);
1625
+ return;
1626
+ case "download":
1627
+ handleDownload(selectedItems);
1628
+ return;
1629
+ case "move":
1630
+ handleMoveUpAFolder(selectedIds);
1631
+ return;
1632
+ }
1633
+ },
1634
+ [
1635
+ handleRename,
1636
+ handleDelete,
1637
+ selectedIds,
1638
+ handleReplace,
1639
+ handleUpload,
1640
+ handleAddFolder,
1641
+ handlePreview,
1642
+ handleDownload,
1643
+ handleMoveUpAFolder
1644
+ ]
1645
+ );
1646
+ const handleSetExpanded = (0, import_react.useCallback)(
1647
+ (item, expanded) => {
1648
+ setExpandedMap(
1649
+ (prev) => updateExpandedMap({
1650
+ item,
1651
+ expanded,
1652
+ expandable,
1653
+ expandedMap: prev,
1654
+ tree
1655
+ })
1656
+ );
1657
+ },
1658
+ [expandable, tree]
1659
+ );
1660
+ const renderAction = (0, import_react.useMemo)(() => {
1661
+ if (renderActionProp) return renderActionProp;
1662
+ return ({
1663
+ selected,
1664
+ onOpenChange
1665
+ }) => /* @__PURE__ */ import_react2.default.createElement(
1666
+ import_noya_designsystem.ActionMenu,
1667
+ {
1668
+ menuItems: assetContextMenuItems,
1669
+ onSelect: (action) => handleMenuAction(action, selectedMediaItems),
1670
+ selected,
1671
+ onOpenChange,
1672
+ style: {
1673
+ backgroundColor: selected ? import_noya_designsystem.cssVars.colors.primaryPastel : "transparent"
1674
+ }
1675
+ }
1676
+ );
1677
+ }, [
1678
+ assetContextMenuItems,
1679
+ handleMenuAction,
1680
+ renderActionProp,
1681
+ selectedMediaItems
1682
+ ]);
1683
+ (0, import_react.useImperativeHandle)(ref, () => ({
1684
+ upload: (selectedId) => handleUpload(selectedId),
1685
+ delete: handleDelete,
1686
+ download: handleDownload,
1687
+ rename: handleRename,
1688
+ addFolder: handleAddFolder,
1689
+ addFile: handleAddFile,
1690
+ moveUpAFolder: handleMoveUpAFolder,
1691
+ replace: handleReplace,
1692
+ preview: handlePreview,
1693
+ moveMediaInsideFolder: handleMoveMediaInsideFolder
1694
+ }));
1695
+ return /* @__PURE__ */ import_react2.default.createElement(import_react2.default.Fragment, null, /* @__PURE__ */ import_react2.default.createElement(
1696
+ import_noya_designsystem.FileExplorerLayout,
1697
+ {
1698
+ title: title ?? rootMediaItemName,
1699
+ right: /* @__PURE__ */ import_react2.default.createElement(
1700
+ import_noya_designsystem.FileExplorerUploadButton,
1701
+ {
1702
+ showUploadButton,
1703
+ onUpload: () => handleUpload(rootMediaItem.id)
1704
+ },
1705
+ right
1706
+ ),
1707
+ className
1708
+ },
1709
+ /* @__PURE__ */ import_react2.default.createElement(
1710
+ import_noya_designsystem.FileExplorerCollection,
1711
+ {
1712
+ ref: collectionRef,
1713
+ scrollable,
1714
+ items: visibleItems,
1715
+ viewType,
1716
+ size: gridSize,
1717
+ getId: (file) => file.id,
1718
+ getName: (file) => {
1719
+ if (file.id === tempItem?.[1].id) {
1720
+ return "";
1721
+ }
1722
+ return treeWithTempItem.getNameForId(file.id);
1723
+ },
1724
+ expandable,
1725
+ sortable,
1726
+ getPlaceholder: (item) => {
1727
+ switch (item.kind) {
1728
+ case "folder":
1729
+ return "Enter folder name";
1730
+ case "asset":
1731
+ case "file":
1732
+ return "Enter file name";
1733
+ }
1734
+ },
1735
+ getExpanded: handleExpanded,
1736
+ setExpanded: handleSetExpanded,
1737
+ getRenamable: (item) => {
1738
+ if (item.id === rootMediaItem.id) return false;
1739
+ return true;
1740
+ },
1741
+ getDepth: (item) => depthMap[item.id],
1742
+ menuItems: assetContextMenuItems,
1743
+ onSelectMenuItem: handleMenuAction,
1744
+ onSelectionChange: setSelectedIds,
1745
+ onDoubleClickItem,
1746
+ onRename,
1747
+ renamable,
1748
+ selectedIds,
1749
+ renderThumbnail: (props) => /* @__PURE__ */ import_react2.default.createElement(MediaThumbnailInternal, { ...props }),
1750
+ renderAction,
1751
+ renderDetail: (file, selected) => {
1752
+ if (file.kind !== "asset") return null;
1753
+ const asset = assets.find((a) => a.id === file.assetId);
1754
+ if (!asset) return null;
1755
+ return /* @__PURE__ */ import_react2.default.createElement(import_noya_designsystem.FileExplorerDetail, { selected }, (asset.size / 1024).toFixed(1), "KB");
1756
+ },
1757
+ renderEmptyState: () => renderEmptyState?.() ?? /* @__PURE__ */ import_react2.default.createElement(import_noya_designsystem.FileExplorerEmptyState, null),
1758
+ itemRoleDescription: "clickable file item",
1759
+ getDropTargetParentIndex: (overIndex) => {
1760
+ const item = visibleItems[overIndex];
1761
+ const parentIndex = visibleItems.findIndex(
1762
+ (i) => i.id === tree.getParentIdForId(item.id)
1763
+ );
1764
+ return parentIndex === -1 ? void 0 : parentIndex;
1765
+ },
1766
+ acceptsDrop: (sourceIndex, targetIndex, position) => {
1767
+ const sourceItem = visibleItems[sourceIndex];
1768
+ const targetItem = visibleItems[targetIndex];
1769
+ if (position !== "inside" || targetItem.kind === "asset") {
1770
+ return false;
1771
+ }
1772
+ const sourcePath = tree.findIndexPath(
1773
+ rootMediaItem,
1774
+ (item) => item.id === sourceItem.id
1775
+ );
1776
+ const targetPath = tree.findIndexPath(
1777
+ rootMediaItem,
1778
+ (item) => item.id === targetItem.id
1779
+ );
1780
+ if (!sourcePath || !targetPath) return false;
1781
+ if ((0, import_noya_utils2.isDeepEqual)(sourcePath, targetPath.slice(0, sourcePath.length))) {
1782
+ return false;
1783
+ }
1784
+ return true;
1785
+ },
1786
+ onMoveItem: (sourceIndex, targetIndex, position) => {
1787
+ const sourceItem = visibleItems[sourceIndex];
1788
+ const targetItem = visibleItems[targetIndex];
1789
+ if (position === "inside") {
1790
+ handleMoveMediaInsideFolder(sourceItem, targetItem);
1791
+ }
1792
+ },
1793
+ onFilesDrop: async (event) => {
1794
+ event.preventDefault();
1795
+ const files = Array.from(event.dataTransfer.files);
1796
+ if (files.length === 0) return;
1797
+ try {
1798
+ const uploadPromises = files.map(async (file) => {
1799
+ const asset = await assetManager.create(file);
1800
+ return {
1801
+ asset: createMediaAsset({
1802
+ assetId: asset.id
1803
+ }),
1804
+ name: file.name
1805
+ };
1806
+ });
1807
+ const newMediaItems = await Promise.all(uploadPromises);
1808
+ const rootItemPath = tree.idToPathMap.get(rootItemId);
1809
+ if (!rootItemPath) return;
1810
+ setMedia(
1811
+ { name: "Add media files", timestamp: Date.now() },
1812
+ {
1813
+ ...media,
1814
+ ...Object.fromEntries(
1815
+ newMediaItems.map((item) => [
1816
+ import_imfs3.path.join(rootItemPath, item.name),
1817
+ item.asset
1818
+ ])
1819
+ )
1820
+ }
1821
+ );
1822
+ } catch (error) {
1823
+ console.error("Failed to upload dropped files:", error);
1824
+ }
1825
+ }
1826
+ }
1827
+ )
1828
+ ));
1829
+ })
1830
+ );
1831
+ // Annotate the CommonJS export names for ESM import in node:
1832
+ 0 && (module.exports = {
1833
+ MediaCollection,
1834
+ PLACEHOLDER_ITEM_NAME,
1835
+ basenameValidator,
1836
+ createMediaAsset,
1837
+ createMediaFile,
1838
+ createMediaFolder,
1839
+ createMediaItem,
1840
+ createMediaItemTree,
1841
+ deleteMediaItems,
1842
+ getDepthMap,
1843
+ getParentDirectories,
1844
+ getVisibleItems,
1845
+ moveMediaInsideFolder,
1846
+ movePathsIntoTarget,
1847
+ moveUpAFolder,
1848
+ rootMediaItem,
1849
+ rootMediaItemName,
1850
+ rootMediaItemPath,
1851
+ updateExpandedMap,
1852
+ validateMediaItemRename
1853
+ });
1854
+ //# sourceMappingURL=index.js.map