@noya-app/noya-file-explorer 0.0.15 → 0.0.16

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 CHANGED
@@ -44,10 +44,10 @@ var require_access = __commonJS({
44
44
  const accessed = _getPath(node, indexPath, options);
45
45
  return accessed[accessed.length - 1];
46
46
  }
47
- let path4 = indexPath.slice();
48
- while (path4.length > 0) {
49
- let index = path4.shift();
50
- const children = options.getChildren(node, path4);
47
+ let path5 = indexPath.slice();
48
+ while (path5.length > 0) {
49
+ let index = path5.shift();
50
+ const children = options.getChildren(node, path5);
51
51
  const child = children[index];
52
52
  if (!child) {
53
53
  return void 0;
@@ -60,12 +60,12 @@ var require_access = __commonJS({
60
60
  return _getPath(node, indexPath, options).slice(0, -1);
61
61
  }
62
62
  function _getPath(node, indexPath, options) {
63
- let path4 = indexPath.slice();
63
+ let path5 = indexPath.slice();
64
64
  let result = [node];
65
- while (path4.length > 0) {
66
- let index = path4.shift();
65
+ while (path5.length > 0) {
66
+ let index = path5.shift();
67
67
  const context = options.includeTraversalContext ? makeTraversalContext(result) : void 0;
68
- const children = options.getChildren(node, path4, context);
68
+ const children = options.getChildren(node, path5, context);
69
69
  const child = children[index];
70
70
  if (!child) {
71
71
  return result;
@@ -80,20 +80,20 @@ var require_access = __commonJS({
80
80
  const accessed = accessPath(node, indexPath, options);
81
81
  return accessed[accessed.length - 1];
82
82
  }
83
- let path4 = indexPath.slice();
84
- while (path4.length > 0) {
85
- let index = path4.shift();
86
- node = options.getChildren(node, path4)[index];
83
+ let path5 = indexPath.slice();
84
+ while (path5.length > 0) {
85
+ let index = path5.shift();
86
+ node = options.getChildren(node, path5)[index];
87
87
  }
88
88
  return node;
89
89
  }
90
90
  function accessPath(node, indexPath, options) {
91
- let path4 = indexPath.slice();
91
+ let path5 = indexPath.slice();
92
92
  let result = [node];
93
- while (path4.length > 0) {
94
- let index = path4.shift();
93
+ while (path5.length > 0) {
94
+ let index = path5.shift();
95
95
  const context = options.includeTraversalContext ? makeTraversalContext(result) : void 0;
96
- node = options.getChildren(node, path4, context)[index];
96
+ node = options.getChildren(node, path5, context)[index];
97
97
  result.push(node);
98
98
  }
99
99
  return result;
@@ -607,40 +607,40 @@ var require_transformPath = __commonJS({
607
607
  Object.defineProperty(exports2, "__esModule", { value: true });
608
608
  exports2.transformPath = transformPath;
609
609
  var sort_1 = require_sort();
610
- function commonAncestor(path4, otherPath) {
611
- const length = Math.min(path4.length, otherPath.length);
610
+ function commonAncestor(path5, otherPath) {
611
+ const length = Math.min(path5.length, otherPath.length);
612
612
  for (let i = 0; i < length; i++) {
613
- if (path4[i] !== otherPath[i]) {
614
- return path4.slice(0, i);
613
+ if (path5[i] !== otherPath[i]) {
614
+ return path5.slice(0, i);
615
615
  }
616
616
  }
617
- return path4.slice(0, length);
617
+ return path5.slice(0, length);
618
618
  }
619
- function transformPath(path4, operation, otherPath, count = 1) {
620
- if (otherPath.length > path4.length || (0, sort_1.comparePathsByComponent)(otherPath, path4) > 0) {
621
- return path4;
619
+ function transformPath(path5, operation, otherPath, count = 1) {
620
+ if (otherPath.length > path5.length || (0, sort_1.comparePathsByComponent)(otherPath, path5) > 0) {
621
+ return path5;
622
622
  }
623
623
  if (otherPath.length === 0 && operation === "remove") {
624
624
  return void 0;
625
625
  }
626
- const common = commonAncestor(path4, otherPath);
627
- const adjustmentIndex = common.length === path4.length || common.length === otherPath.length ? common.length - 1 : common.length;
628
- const pathValue = path4[adjustmentIndex];
626
+ const common = commonAncestor(path5, otherPath);
627
+ const adjustmentIndex = common.length === path5.length || common.length === otherPath.length ? common.length - 1 : common.length;
628
+ const pathValue = path5[adjustmentIndex];
629
629
  const otherPathValue = otherPath[adjustmentIndex];
630
630
  if (operation === "insert" && otherPathValue <= pathValue) {
631
- const newPath = [...path4];
631
+ const newPath = [...path5];
632
632
  newPath[adjustmentIndex] += count;
633
633
  return newPath;
634
634
  } else if (operation === "remove") {
635
635
  if (otherPathValue === pathValue) {
636
636
  return void 0;
637
637
  } else if (otherPathValue < pathValue) {
638
- const newPath = [...path4];
638
+ const newPath = [...path5];
639
639
  newPath[adjustmentIndex] -= count;
640
640
  return newPath;
641
641
  }
642
642
  }
643
- return path4;
643
+ return path5;
644
644
  }
645
645
  }
646
646
  });
@@ -806,15 +806,15 @@ var require_operation = __commonJS({
806
806
  switch (operation.type) {
807
807
  case "insert": {
808
808
  const otherPath = parentPath.concat(operation.index);
809
- return transformedPaths.map((path4) => path4 ? (0, transformPath_1.transformPath)(path4, "insert", otherPath, operation.nodes.length) : void 0);
809
+ return transformedPaths.map((path5) => path5 ? (0, transformPath_1.transformPath)(path5, "insert", otherPath, operation.nodes.length) : void 0);
810
810
  }
811
811
  case "remove": {
812
812
  const otherPaths = [...operation.indexes].reverse().map((index) => parentPath.concat(index));
813
- return transformedPaths.map((path4) => {
813
+ return transformedPaths.map((path5) => {
814
814
  for (const otherPath of otherPaths) {
815
- path4 = path4 ? (0, transformPath_1.transformPath)(path4, "remove", otherPath) : void 0;
815
+ path5 = path5 ? (0, transformPath_1.transformPath)(path5, "remove", otherPath) : void 0;
816
816
  }
817
- return path4;
817
+ return path5;
818
818
  });
819
819
  }
820
820
  case "removeThenInsert": {
@@ -951,22 +951,22 @@ var require_splice = __commonJS({
951
951
  return _spliceWithPathTracking(node, options);
952
952
  }
953
953
  function _spliceWithPathTracking(node, options) {
954
- const { path: path4, deleteCount = 0, nodes, track } = options;
955
- if (path4.length === 0) {
954
+ const { path: path5, deleteCount = 0, nodes, track } = options;
955
+ if (path5.length === 0) {
956
956
  throw new Error(`Can't splice at the root`);
957
957
  }
958
- const pathsToRemove = getPathsToRemove(path4, deleteCount);
959
- const operations = (0, operation_1.getInsertionOperations)(path4, nodes, (0, operation_1.getRemovalOperations)(pathsToRemove));
958
+ const pathsToRemove = getPathsToRemove(path5, deleteCount);
959
+ const operations = (0, operation_1.getInsertionOperations)(path5, nodes, (0, operation_1.getRemovalOperations)(pathsToRemove));
960
960
  const transformedPaths = track ? (0, operation_1.transformPathsByOperations)(track, operations) : [];
961
961
  return {
962
962
  node: (0, operation_1.applyOperations)(node, operations, options),
963
963
  paths: transformedPaths
964
964
  };
965
965
  }
966
- function getPathsToRemove(path4, deleteCount) {
966
+ function getPathsToRemove(path5, deleteCount) {
967
967
  let pathsToRemove = [];
968
- let parentPath = path4.slice(0, -1);
969
- let index = path4[path4.length - 1];
968
+ let parentPath = path5.slice(0, -1);
969
+ let index = path5[path5.length - 1];
970
970
  for (let i = 0; i < deleteCount; i++) {
971
971
  pathsToRemove.push(parentPath.concat(index + i));
972
972
  }
@@ -1111,6 +1111,7 @@ var src_exports = {};
1111
1111
  __export(src_exports, {
1112
1112
  MediaCollection: () => MediaCollection,
1113
1113
  PLACEHOLDER_ITEM_NAME: () => PLACEHOLDER_ITEM_NAME,
1114
+ acceptsMediaItemDrop: () => acceptsMediaItemDrop,
1114
1115
  basenameValidator: () => basenameValidator,
1115
1116
  createMediaAsset: () => createMediaAsset,
1116
1117
  createMediaFile: () => createMediaFile,
@@ -1118,7 +1119,6 @@ __export(src_exports, {
1118
1119
  createMediaItem: () => createMediaItem,
1119
1120
  createMediaItemTree: () => createMediaItemTree,
1120
1121
  deleteMediaItems: () => deleteMediaItems,
1121
- formatByteSize: () => formatByteSize,
1122
1122
  getDepthMap: () => getDepthMap,
1123
1123
  getParentDirectories: () => getParentDirectories,
1124
1124
  getVisibleItems: () => getVisibleItems,
@@ -1134,15 +1134,6 @@ __export(src_exports, {
1134
1134
  });
1135
1135
  module.exports = __toCommonJS(src_exports);
1136
1136
 
1137
- // src/formatByteSize.ts
1138
- var byteSizeUnits = ["B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
1139
- function formatByteSize(size) {
1140
- const unitIndex = Math.floor(Math.log(size) / Math.log(1024));
1141
- const unit = byteSizeUnits[unitIndex];
1142
- const value = size / Math.pow(1024, unitIndex);
1143
- return `${value.toFixed(1)} ${unit}`;
1144
- }
1145
-
1146
1137
  // src/MediaCollection.tsx
1147
1138
  var import_noya_designsystem = require("@noya-app/noya-designsystem");
1148
1139
  var import_noya_icons = require("@noya-app/noya-icons");
@@ -1234,7 +1225,7 @@ var createMediaItemTree = (mediaMap) => {
1234
1225
  };
1235
1226
 
1236
1227
  // src/MediaCollection.tsx
1237
- var import_imfs3 = require("imfs");
1228
+ var import_imfs4 = require("imfs");
1238
1229
  var import_react2 = __toESM(require("react"));
1239
1230
 
1240
1231
  // src/utils/files.ts
@@ -1257,6 +1248,9 @@ var getVisibleItems = ({
1257
1248
  }
1258
1249
  return;
1259
1250
  }
1251
+ if (item.kind === "noyaFile" && fileKindFilter === "all") {
1252
+ filteredItems.push(item);
1253
+ }
1260
1254
  if (item.kind === "file" && fileKindFilter === "all") {
1261
1255
  filteredItems.push(item);
1262
1256
  }
@@ -1293,7 +1287,7 @@ var movePathsIntoTarget = ({
1293
1287
  tree
1294
1288
  }) => {
1295
1289
  const ancestors = (0, import_tree_visit2.ancestorPaths)(
1296
- sourceItemPaths.map((path4) => path4.split("/"))
1290
+ sourceItemPaths.map((path5) => path5.split("/"))
1297
1291
  );
1298
1292
  const mediaClone = { ...media };
1299
1293
  for (const ancestor of ancestors) {
@@ -1340,7 +1334,7 @@ var moveUpAFolder = ({
1340
1334
  );
1341
1335
  const grandparentFolderPath = tree.idToPathMap.get(grandparentFolder.id);
1342
1336
  if (!grandparentFolderPath) return;
1343
- const sourceItemPaths = selectedIds.map((id) => tree.idToPathMap.get(id)).filter((path4) => Boolean(path4));
1337
+ const sourceItemPaths = selectedIds.map((id) => tree.idToPathMap.get(id)).filter((path5) => Boolean(path5));
1344
1338
  return movePathsIntoTarget({
1345
1339
  media,
1346
1340
  targetItemPath: grandparentFolderPath,
@@ -1406,7 +1400,7 @@ var moveMediaInsideFolder = ({
1406
1400
  }) => {
1407
1401
  const targetItemPath = tree.idToPathMap.get(targetItemId);
1408
1402
  if (!targetItemPath) return media;
1409
- const sourceItemPaths = sourceItemIds.map((id) => tree.idToPathMap.get(id)).filter((path4) => Boolean(path4));
1403
+ const sourceItemPaths = sourceItemIds.map((id) => tree.idToPathMap.get(id)).filter((path5) => Boolean(path5));
1410
1404
  return movePathsIntoTarget({
1411
1405
  media,
1412
1406
  sourceItemPaths,
@@ -1447,6 +1441,115 @@ var renameMediaItemAndDescendantPaths = ({
1447
1441
  return mediaClone;
1448
1442
  };
1449
1443
 
1444
+ // src/utils/handleFileDrop.ts
1445
+ var import_imfs3 = require("imfs");
1446
+ function isDirectoryEntry(entry) {
1447
+ return entry.isDirectory;
1448
+ }
1449
+ function isFileEntry(entry) {
1450
+ return entry.isFile;
1451
+ }
1452
+ async function handleDataTransfer({
1453
+ dataTransfer,
1454
+ rootItemPath,
1455
+ media,
1456
+ uploadAsset
1457
+ }) {
1458
+ try {
1459
+ const dataTransferItems = Array.from(dataTransfer.items ?? []);
1460
+ const supportsEntries = dataTransferItems.some(
1461
+ (item) => typeof item?.webkitGetAsEntry === "function"
1462
+ );
1463
+ const collectFromEntry = async (entry, basePath) => {
1464
+ if (!entry) return [];
1465
+ if (isFileEntry(entry)) {
1466
+ const file = await new Promise(
1467
+ (resolve) => entry.file((f) => resolve(f))
1468
+ );
1469
+ return [
1470
+ {
1471
+ file,
1472
+ relativePath: import_imfs3.path.join(basePath, file.name)
1473
+ }
1474
+ ];
1475
+ }
1476
+ if (isDirectoryEntry(entry)) {
1477
+ const reader = entry.createReader();
1478
+ const readAll = async () => {
1479
+ const all = [];
1480
+ while (true) {
1481
+ const entries = await new Promise(
1482
+ (resolve) => reader.readEntries((ents) => resolve(ents))
1483
+ );
1484
+ if (!entries.length) break;
1485
+ all.push(...entries);
1486
+ }
1487
+ return all;
1488
+ };
1489
+ const children = await readAll();
1490
+ const results = await Promise.all(
1491
+ children.map(
1492
+ (child) => collectFromEntry(child, import_imfs3.path.join(basePath, entry.name))
1493
+ )
1494
+ );
1495
+ return results.flat();
1496
+ }
1497
+ return [];
1498
+ };
1499
+ let dropped = [];
1500
+ if (supportsEntries) {
1501
+ const topLevelEntries = dataTransferItems.flatMap((item) => {
1502
+ const entry = item.webkitGetAsEntry?.();
1503
+ if (!entry) return [];
1504
+ return [entry];
1505
+ });
1506
+ const nested = await Promise.all(
1507
+ topLevelEntries.map((entry) => collectFromEntry(entry, ""))
1508
+ );
1509
+ dropped = nested.flat();
1510
+ } else {
1511
+ const files = Array.from(dataTransfer.files);
1512
+ if (files.length === 0) return;
1513
+ dropped = files.map((file) => ({
1514
+ file,
1515
+ // Best effort: try webkitRelativePath; fall back to name
1516
+ relativePath: file.webkitRelativePath && file.webkitRelativePath.length > 0 ? file.webkitRelativePath : file.name
1517
+ }));
1518
+ }
1519
+ if (dropped.length === 0) return;
1520
+ const folderRelativePaths = /* @__PURE__ */ new Set();
1521
+ for (const { relativePath } of dropped) {
1522
+ const dir = import_imfs3.path.dirname(relativePath);
1523
+ if (dir && dir !== ".") {
1524
+ const parts = dir.split("/").filter(Boolean);
1525
+ let acc = "";
1526
+ for (const part of parts) {
1527
+ acc = acc ? import_imfs3.path.join(acc, part) : part;
1528
+ folderRelativePaths.add(acc);
1529
+ }
1530
+ }
1531
+ }
1532
+ const folderEntries = Array.from(folderRelativePaths).map((rel) => import_imfs3.path.join(rootItemPath, rel)).filter((full) => !media[full]).map((full) => [full, createMediaFolder()]);
1533
+ const uploadResults = await Promise.all(
1534
+ dropped.map(
1535
+ async ({ file, relativePath }) => {
1536
+ const asset = await uploadAsset(file);
1537
+ return [
1538
+ import_imfs3.path.join(rootItemPath, relativePath),
1539
+ createMediaAsset({ assetId: asset.id })
1540
+ ];
1541
+ }
1542
+ )
1543
+ );
1544
+ return {
1545
+ ...media,
1546
+ ...Object.fromEntries([...folderEntries, ...uploadResults])
1547
+ };
1548
+ } catch (error) {
1549
+ console.error("Failed to upload dropped files:", error);
1550
+ }
1551
+ }
1552
+
1450
1553
  // src/MediaCollection.tsx
1451
1554
  var extensionToContentType = {
1452
1555
  svg: "image/svg+xml",
@@ -1454,7 +1557,7 @@ var extensionToContentType = {
1454
1557
  jpeg: "image/jpeg"
1455
1558
  };
1456
1559
  function encodeFileContentForThumbnail(pathProp, item) {
1457
- const extension = import_imfs3.path.extname(pathProp).slice(1);
1560
+ const extension = import_imfs4.path.extname(pathProp).slice(1);
1458
1561
  const contentType = extensionToContentType[extension];
1459
1562
  if (contentType) {
1460
1563
  if (item.encoding === "base64") {
@@ -1481,7 +1584,8 @@ var MediaThumbnailInternal = (0, import_react_utils.memoGeneric)(
1481
1584
  item,
1482
1585
  selected,
1483
1586
  size,
1484
- path: pathProp
1587
+ path: pathProp,
1588
+ renderThumbnailIcon
1485
1589
  }) => {
1486
1590
  const asset = (0, import_noya_multiplayer_react.useAsset)(item.kind === "asset" ? item.assetId : void 0);
1487
1591
  const isRoot = item.id === rootMediaItem.id;
@@ -1499,7 +1603,7 @@ var MediaThumbnailInternal = (0, import_react_utils.memoGeneric)(
1499
1603
  url = encoded.url;
1500
1604
  }
1501
1605
  }
1502
- const fileName = pathProp ? import_imfs3.path.basename(pathProp) : void 0;
1606
+ const fileName = pathProp ? import_imfs4.path.basename(pathProp) : void 0;
1503
1607
  return /* @__PURE__ */ import_react2.default.createElement(
1504
1608
  import_noya_designsystem.MediaThumbnail,
1505
1609
  {
@@ -1508,7 +1612,8 @@ var MediaThumbnailInternal = (0, import_react_utils.memoGeneric)(
1508
1612
  url,
1509
1613
  selected,
1510
1614
  size,
1511
- fileName
1615
+ fileName,
1616
+ renderThumbnailIcon
1512
1617
  }
1513
1618
  );
1514
1619
  }
@@ -1540,7 +1645,9 @@ var MediaCollection = (0, import_react.memo)(
1540
1645
  sortable = false,
1541
1646
  renderEmptyState,
1542
1647
  sharedDragProps,
1543
- onClickItem
1648
+ onClickItem,
1649
+ renderThumbnailIcon,
1650
+ onDidDeleteItems
1544
1651
  }, ref) {
1545
1652
  const setMedia = (0, import_react.useCallback)(
1546
1653
  (...args) => {
@@ -1622,7 +1729,7 @@ var MediaCollection = (0, import_react.memo)(
1622
1729
  const itemPath = tree.idToPathMap.get(item.id);
1623
1730
  const firstSelectedPath = tree.idToPathMap.get(selectedIds[0]);
1624
1731
  if (!itemPath || !firstSelectedPath) return false;
1625
- return itemPath.startsWith(import_imfs3.path.dirname(firstSelectedPath));
1732
+ return itemPath.startsWith(import_imfs4.path.dirname(firstSelectedPath));
1626
1733
  });
1627
1734
  (0, import_react.useEffect)(() => {
1628
1735
  if (initialExpanded) {
@@ -1640,6 +1747,14 @@ var MediaCollection = (0, import_react.memo)(
1640
1747
  );
1641
1748
  const handleDelete = (0, import_react.useCallback)(
1642
1749
  (selectedIds2) => {
1750
+ const deletedItems = Object.entries(media).flatMap(
1751
+ ([path5, item]) => {
1752
+ if (selectedIds2.includes(item.id)) {
1753
+ return [[path5, item]];
1754
+ }
1755
+ return [];
1756
+ }
1757
+ );
1643
1758
  const newMedia = deleteMediaItems({
1644
1759
  selectedIds: selectedIds2,
1645
1760
  media,
@@ -1647,8 +1762,9 @@ var MediaCollection = (0, import_react.memo)(
1647
1762
  });
1648
1763
  setSelectedIds([rootMediaItem.id]);
1649
1764
  setMedia({ name: "Delete items", timestamp: Date.now() }, newMedia);
1765
+ onDidDeleteItems?.(deletedItems);
1650
1766
  },
1651
- [media, setMedia, setSelectedIds, tree]
1767
+ [media, setMedia, setSelectedIds, tree, onDidDeleteItems]
1652
1768
  );
1653
1769
  const onRename = (0, import_react.useCallback)(
1654
1770
  (selectedItem, newName) => {
@@ -1686,7 +1802,7 @@ var MediaCollection = (0, import_react.memo)(
1686
1802
  const currentFolderPath = tree.idToPathMap.get(currentFolderId);
1687
1803
  if (!currentFolderPath) return;
1688
1804
  setTempItem([
1689
- import_imfs3.path.join(currentFolderPath, PLACEHOLDER_ITEM_NAME),
1805
+ import_imfs4.path.join(currentFolderPath, PLACEHOLDER_ITEM_NAME),
1690
1806
  newFolder
1691
1807
  ]);
1692
1808
  setTimeout(() => {
@@ -1706,7 +1822,7 @@ var MediaCollection = (0, import_react.memo)(
1706
1822
  );
1707
1823
  if (!currentFolderPath) return;
1708
1824
  setTempItem([
1709
- import_imfs3.path.join(currentFolderPath, PLACEHOLDER_ITEM_NAME),
1825
+ import_imfs4.path.join(currentFolderPath, PLACEHOLDER_ITEM_NAME),
1710
1826
  newFile
1711
1827
  ]);
1712
1828
  setTimeout(() => {
@@ -1737,7 +1853,7 @@ var MediaCollection = (0, import_react.memo)(
1737
1853
  if (!parentPath) return;
1738
1854
  const uploadPromises = files.map(async (file) => {
1739
1855
  const asset = await assetManager.create(file);
1740
- const assetPath = import_imfs3.path.join(parentPath, import_imfs3.path.basename(file.name));
1856
+ const assetPath = import_imfs4.path.join(parentPath, import_imfs4.path.basename(file.name));
1741
1857
  return {
1742
1858
  assetPath,
1743
1859
  asset: createMediaAsset({ assetId: asset.id })
@@ -1817,9 +1933,6 @@ var MediaCollection = (0, import_react.memo)(
1817
1933
  );
1818
1934
  const handleMoveMediaInsideFolder = (0, import_react.useCallback)(
1819
1935
  (sourceItem, targetItem) => {
1820
- const sourceItemPath = tree.idToPathMap.get(sourceItem.id);
1821
- const targetItemPath = tree.idToPathMap.get(targetItem.id);
1822
- if (!sourceItemPath || !targetItemPath) return;
1823
1936
  const newMedia = moveMediaInsideFolder({
1824
1937
  sourceItemIds: [sourceItem.id],
1825
1938
  targetItemId: targetItem.id,
@@ -1857,12 +1970,12 @@ var MediaCollection = (0, import_react.memo)(
1857
1970
  ],
1858
1971
  [
1859
1972
  onlySingleFolderSelected && {
1860
- title: "Add media",
1973
+ title: "Upload Files",
1861
1974
  value: "upload",
1862
1975
  icon: /* @__PURE__ */ import_react2.default.createElement(import_noya_icons.UploadIcon, null)
1863
1976
  },
1864
1977
  onlySingleFolderSelected && {
1865
- title: "Add a Folder",
1978
+ title: "Add Folder",
1866
1979
  value: "addFolder",
1867
1980
  icon: /* @__PURE__ */ import_react2.default.createElement(import_noya_icons.FolderIcon, null)
1868
1981
  },
@@ -1986,7 +2099,8 @@ var MediaCollection = (0, import_react.memo)(
1986
2099
  moveUpAFolder: handleMoveUpAFolder,
1987
2100
  replace: handleReplace,
1988
2101
  preview: handlePreview,
1989
- moveMediaInsideFolder: handleMoveMediaInsideFolder
2102
+ moveMediaInsideFolder: handleMoveMediaInsideFolder,
2103
+ getItemAtIndex: (index) => visibleItems[index]
1990
2104
  }));
1991
2105
  return /* @__PURE__ */ import_react2.default.createElement(import_react2.default.Fragment, null, /* @__PURE__ */ import_react2.default.createElement(
1992
2106
  import_noya_designsystem.FileExplorerLayout,
@@ -2028,6 +2142,7 @@ var MediaCollection = (0, import_react.memo)(
2028
2142
  return "Enter folder name";
2029
2143
  case "asset":
2030
2144
  case "file":
2145
+ case "noyaFile":
2031
2146
  return "Enter file name";
2032
2147
  }
2033
2148
  },
@@ -2050,7 +2165,8 @@ var MediaCollection = (0, import_react.memo)(
2050
2165
  MediaThumbnailInternal,
2051
2166
  {
2052
2167
  ...props,
2053
- path: tree.idToPathMap.get(props.item.id)
2168
+ path: tree.idToPathMap.get(props.item.id),
2169
+ renderThumbnailIcon
2054
2170
  }
2055
2171
  ),
2056
2172
  renderAction,
@@ -2058,7 +2174,7 @@ var MediaCollection = (0, import_react.memo)(
2058
2174
  if (file.kind !== "asset") return null;
2059
2175
  const asset = assets.find((a) => a.id === file.assetId);
2060
2176
  if (!asset) return null;
2061
- return /* @__PURE__ */ import_react2.default.createElement(import_noya_designsystem.FileExplorerDetail, { selected, size }, formatByteSize(asset.size));
2177
+ return /* @__PURE__ */ import_react2.default.createElement(import_noya_designsystem.FileExplorerDetail, { selected, size }, (0, import_noya_designsystem.formatByteSize)(asset.size));
2062
2178
  },
2063
2179
  renderEmptyState: () => renderEmptyState?.() ?? /* @__PURE__ */ import_react2.default.createElement(import_noya_designsystem.FileExplorerEmptyState, null),
2064
2180
  itemRoleDescription: "clickable file item",
@@ -2079,26 +2195,28 @@ var MediaCollection = (0, import_react.memo)(
2079
2195
  if (sourceListId !== targetListId) {
2080
2196
  return false;
2081
2197
  }
2082
- const sourceItem = visibleItems[sourceIndex];
2083
- const targetItem = visibleItems[targetIndex];
2084
- if (position !== "inside" || targetItem.kind === "asset") {
2085
- return false;
2086
- }
2087
- const sourcePath = tree.findPath(
2088
- rootMediaItem,
2089
- (item) => item.id === sourceItem.id
2090
- );
2091
- const targetPath = tree.findPath(
2092
- rootMediaItem,
2093
- (item) => item.id === targetItem.id
2094
- );
2095
- if (!sourcePath || !targetPath) return false;
2096
- if ((0, import_noya_utils2.isDeepEqual)(sourcePath, targetPath.slice(0, sourcePath.length))) {
2198
+ if (sourceListId !== sortableId || targetListId !== sortableId) {
2097
2199
  return false;
2098
2200
  }
2099
- return true;
2201
+ const sourceItem = visibleItems[sourceIndex];
2202
+ const targetItem = visibleItems[targetIndex];
2203
+ return acceptsMediaItemDrop({
2204
+ position,
2205
+ sourceItem,
2206
+ targetItem,
2207
+ tree
2208
+ });
2100
2209
  },
2101
- onMoveItem: ({ sourceIndex, targetIndex, position }) => {
2210
+ onMoveItem: ({
2211
+ sourceListId,
2212
+ sourceIndex,
2213
+ targetListId,
2214
+ targetIndex,
2215
+ position
2216
+ }) => {
2217
+ if (sourceListId !== sortableId || targetListId !== sortableId) {
2218
+ return;
2219
+ }
2102
2220
  const sourceItem = visibleItems[sourceIndex];
2103
2221
  const targetItem = visibleItems[targetIndex];
2104
2222
  if (position === "inside") {
@@ -2107,46 +2225,49 @@ var MediaCollection = (0, import_react.memo)(
2107
2225
  },
2108
2226
  onFilesDrop: async (event) => {
2109
2227
  event.preventDefault();
2110
- const files = Array.from(event.dataTransfer.files);
2111
- if (files.length === 0) return;
2112
- try {
2113
- const uploadPromises = files.map(async (file) => {
2114
- const asset = await assetManager.create(file);
2115
- return {
2116
- asset: createMediaAsset({
2117
- assetId: asset.id
2118
- }),
2119
- name: file.name
2120
- };
2121
- });
2122
- const newMediaItems = await Promise.all(uploadPromises);
2123
- const rootItemPath = tree.idToPathMap.get(rootItemId);
2124
- if (!rootItemPath) return;
2125
- setMedia(
2126
- { name: "Add media files", timestamp: Date.now() },
2127
- {
2128
- ...media,
2129
- ...Object.fromEntries(
2130
- newMediaItems.map((item) => [
2131
- import_imfs3.path.join(rootItemPath, item.name),
2132
- item.asset
2133
- ])
2134
- )
2135
- }
2136
- );
2137
- } catch (error) {
2138
- console.error("Failed to upload dropped files:", error);
2139
- }
2228
+ const rootItemPath = tree.idToPathMap.get(rootItemId);
2229
+ if (!rootItemPath) return;
2230
+ const newMedia = await handleDataTransfer({
2231
+ dataTransfer: event.dataTransfer,
2232
+ rootItemPath,
2233
+ media,
2234
+ uploadAsset: (file) => assetManager.create(file)
2235
+ });
2236
+ if (!newMedia) return;
2237
+ setMedia(
2238
+ { name: "Add media files", timestamp: Date.now() },
2239
+ newMedia
2240
+ );
2140
2241
  }
2141
2242
  }
2142
2243
  )
2143
2244
  ));
2144
2245
  })
2145
2246
  );
2247
+ function acceptsMediaItemDrop(parameters) {
2248
+ const { position, sourceItem, targetItem, tree } = parameters;
2249
+ if (position !== "inside" || targetItem.kind === "asset") {
2250
+ return false;
2251
+ }
2252
+ const sourcePath = tree.findPath(
2253
+ rootMediaItem,
2254
+ (item) => item.id === sourceItem.id
2255
+ );
2256
+ const targetPath = tree.findPath(
2257
+ rootMediaItem,
2258
+ (item) => item.id === targetItem.id
2259
+ );
2260
+ if (!sourcePath || !targetPath) return false;
2261
+ if ((0, import_noya_utils2.isDeepEqual)(sourcePath, targetPath.slice(0, sourcePath.length))) {
2262
+ return false;
2263
+ }
2264
+ return true;
2265
+ }
2146
2266
  // Annotate the CommonJS export names for ESM import in node:
2147
2267
  0 && (module.exports = {
2148
2268
  MediaCollection,
2149
2269
  PLACEHOLDER_ITEM_NAME,
2270
+ acceptsMediaItemDrop,
2150
2271
  basenameValidator,
2151
2272
  createMediaAsset,
2152
2273
  createMediaFile,
@@ -2154,7 +2275,6 @@ var MediaCollection = (0, import_react.memo)(
2154
2275
  createMediaItem,
2155
2276
  createMediaItemTree,
2156
2277
  deleteMediaItems,
2157
- formatByteSize,
2158
2278
  getDepthMap,
2159
2279
  getParentDirectories,
2160
2280
  getVisibleItems,