rita-workspace 0.5.33 → 0.5.34

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.d.mts CHANGED
@@ -6,6 +6,8 @@ interface Drawing {
6
6
  id: string;
7
7
  name: string;
8
8
  folderId?: string | null;
9
+ /** Manual sort position. Lower = earlier in list. Falls back to createdAt when unset. */
10
+ position?: number;
9
11
  elements: unknown[];
10
12
  appState: Record<string, unknown>;
11
13
  files: Record<string, unknown>;
@@ -64,6 +66,12 @@ declare function updateDrawing(id: string, updates: Partial<Omit<Drawing, 'id' |
64
66
  declare function deleteDrawing(id: string): Promise<boolean>;
65
67
  declare function duplicateDrawing(id: string, newName?: string): Promise<Drawing | undefined>;
66
68
  declare function moveDrawingToFolder(drawingId: string, folderId: string | null): Promise<Drawing | undefined>;
69
+ /**
70
+ * Re-number `position` for the given drawing IDs in the order provided (0..N-1).
71
+ * Drawings not in `orderedIds` are left untouched (caller should pass the full
72
+ * sorted slice that the user reordered, e.g. all root drawings or all in a folder).
73
+ */
74
+ declare function reorderDrawings(orderedIds: string[]): Promise<void>;
67
75
 
68
76
  declare function createFolder(name: string): Promise<Folder>;
69
77
  declare function getFolder(id: string): Promise<Folder | undefined>;
@@ -147,6 +155,9 @@ interface WorkspaceContextValue {
147
155
  renameFolder: (id: string, name: string) => Promise<void>;
148
156
  deleteFolder: (id: string) => Promise<void>;
149
157
  moveDrawingToFolder: (drawingId: string, folderId: string | null) => Promise<void>;
158
+ /** Re-numbers `position` for the given drawing IDs in order. Use the full ordered slice
159
+ * the user reordered (e.g. all root drawings, or all drawings in a folder). */
160
+ reorderDrawings: (orderedIds: string[]) => Promise<void>;
150
161
  saveCurrentDrawing: (elements: unknown[], appState: Record<string, unknown>, files?: Record<string, unknown>) => Promise<void>;
151
162
  saveDrawingById: (id: string, elements: unknown[], appState: Record<string, unknown>, files?: Record<string, unknown>) => Promise<void>;
152
163
  refreshDrawings: () => Promise<void>;
@@ -388,4 +399,4 @@ interface WorkspacePluginProps {
388
399
  */
389
400
  declare function WorkspacePlugin(props: WorkspacePluginProps): react_jsx_runtime.JSX.Element;
390
401
 
391
- export { type Drawing, DrawingList, DrawingListItem, type DrawingMeta, DrawingsDialog, type DrawingsDialogProps, type ExcalidrawImperativeAPI, type Folder, Sidebar, type SupportedLanguage, type Translations, type Workspace, WorkspaceBridge, type WorkspaceBridgeProps, type WorkspaceContextValue, WorkspaceMenuItems, type WorkspaceMenuItemsProps, WorkspacePlugin, WorkspaceProvider, addDrawingToWorkspace, closeDB, createDrawing, createFolder, deleteDrawing, deleteFolder, duplicateDrawing, getAllDrawings, getAllDrawingsMeta, getAllFolders, getDB, getDrawing, getFolder, getOrCreateDefaultWorkspace, getTranslations, getWorkspace, isDrawingOpenedEarlierInOtherTab, isLanguageSupported, moveDrawingToFolder, removeDrawingFromWorkspace, renameFolder, setActiveDrawing, updateDrawing, updateWorkspace, useExcalidrawBridge, useWorkspace, useWorkspaceLang, warmDB };
402
+ export { type Drawing, DrawingList, DrawingListItem, type DrawingMeta, DrawingsDialog, type DrawingsDialogProps, type ExcalidrawImperativeAPI, type Folder, Sidebar, type SupportedLanguage, type Translations, type Workspace, WorkspaceBridge, type WorkspaceBridgeProps, type WorkspaceContextValue, WorkspaceMenuItems, type WorkspaceMenuItemsProps, WorkspacePlugin, WorkspaceProvider, addDrawingToWorkspace, closeDB, createDrawing, createFolder, deleteDrawing, deleteFolder, duplicateDrawing, getAllDrawings, getAllDrawingsMeta, getAllFolders, getDB, getDrawing, getFolder, getOrCreateDefaultWorkspace, getTranslations, getWorkspace, isDrawingOpenedEarlierInOtherTab, isLanguageSupported, moveDrawingToFolder, removeDrawingFromWorkspace, renameFolder, reorderDrawings, setActiveDrawing, updateDrawing, updateWorkspace, useExcalidrawBridge, useWorkspace, useWorkspaceLang, warmDB };
package/dist/index.d.ts CHANGED
@@ -6,6 +6,8 @@ interface Drawing {
6
6
  id: string;
7
7
  name: string;
8
8
  folderId?: string | null;
9
+ /** Manual sort position. Lower = earlier in list. Falls back to createdAt when unset. */
10
+ position?: number;
9
11
  elements: unknown[];
10
12
  appState: Record<string, unknown>;
11
13
  files: Record<string, unknown>;
@@ -64,6 +66,12 @@ declare function updateDrawing(id: string, updates: Partial<Omit<Drawing, 'id' |
64
66
  declare function deleteDrawing(id: string): Promise<boolean>;
65
67
  declare function duplicateDrawing(id: string, newName?: string): Promise<Drawing | undefined>;
66
68
  declare function moveDrawingToFolder(drawingId: string, folderId: string | null): Promise<Drawing | undefined>;
69
+ /**
70
+ * Re-number `position` for the given drawing IDs in the order provided (0..N-1).
71
+ * Drawings not in `orderedIds` are left untouched (caller should pass the full
72
+ * sorted slice that the user reordered, e.g. all root drawings or all in a folder).
73
+ */
74
+ declare function reorderDrawings(orderedIds: string[]): Promise<void>;
67
75
 
68
76
  declare function createFolder(name: string): Promise<Folder>;
69
77
  declare function getFolder(id: string): Promise<Folder | undefined>;
@@ -147,6 +155,9 @@ interface WorkspaceContextValue {
147
155
  renameFolder: (id: string, name: string) => Promise<void>;
148
156
  deleteFolder: (id: string) => Promise<void>;
149
157
  moveDrawingToFolder: (drawingId: string, folderId: string | null) => Promise<void>;
158
+ /** Re-numbers `position` for the given drawing IDs in order. Use the full ordered slice
159
+ * the user reordered (e.g. all root drawings, or all drawings in a folder). */
160
+ reorderDrawings: (orderedIds: string[]) => Promise<void>;
150
161
  saveCurrentDrawing: (elements: unknown[], appState: Record<string, unknown>, files?: Record<string, unknown>) => Promise<void>;
151
162
  saveDrawingById: (id: string, elements: unknown[], appState: Record<string, unknown>, files?: Record<string, unknown>) => Promise<void>;
152
163
  refreshDrawings: () => Promise<void>;
@@ -388,4 +399,4 @@ interface WorkspacePluginProps {
388
399
  */
389
400
  declare function WorkspacePlugin(props: WorkspacePluginProps): react_jsx_runtime.JSX.Element;
390
401
 
391
- export { type Drawing, DrawingList, DrawingListItem, type DrawingMeta, DrawingsDialog, type DrawingsDialogProps, type ExcalidrawImperativeAPI, type Folder, Sidebar, type SupportedLanguage, type Translations, type Workspace, WorkspaceBridge, type WorkspaceBridgeProps, type WorkspaceContextValue, WorkspaceMenuItems, type WorkspaceMenuItemsProps, WorkspacePlugin, WorkspaceProvider, addDrawingToWorkspace, closeDB, createDrawing, createFolder, deleteDrawing, deleteFolder, duplicateDrawing, getAllDrawings, getAllDrawingsMeta, getAllFolders, getDB, getDrawing, getFolder, getOrCreateDefaultWorkspace, getTranslations, getWorkspace, isDrawingOpenedEarlierInOtherTab, isLanguageSupported, moveDrawingToFolder, removeDrawingFromWorkspace, renameFolder, setActiveDrawing, updateDrawing, updateWorkspace, useExcalidrawBridge, useWorkspace, useWorkspaceLang, warmDB };
402
+ export { type Drawing, DrawingList, DrawingListItem, type DrawingMeta, DrawingsDialog, type DrawingsDialogProps, type ExcalidrawImperativeAPI, type Folder, Sidebar, type SupportedLanguage, type Translations, type Workspace, WorkspaceBridge, type WorkspaceBridgeProps, type WorkspaceContextValue, WorkspaceMenuItems, type WorkspaceMenuItemsProps, WorkspacePlugin, WorkspaceProvider, addDrawingToWorkspace, closeDB, createDrawing, createFolder, deleteDrawing, deleteFolder, duplicateDrawing, getAllDrawings, getAllDrawingsMeta, getAllFolders, getDB, getDrawing, getFolder, getOrCreateDefaultWorkspace, getTranslations, getWorkspace, isDrawingOpenedEarlierInOtherTab, isLanguageSupported, moveDrawingToFolder, removeDrawingFromWorkspace, renameFolder, reorderDrawings, setActiveDrawing, updateDrawing, updateWorkspace, useExcalidrawBridge, useWorkspace, useWorkspaceLang, warmDB };
package/dist/index.js CHANGED
@@ -59,6 +59,7 @@ __export(index_exports, {
59
59
  moveDrawingToFolder: () => moveDrawingToFolder,
60
60
  removeDrawingFromWorkspace: () => removeDrawingFromWorkspace,
61
61
  renameFolder: () => renameFolder,
62
+ reorderDrawings: () => reorderDrawings,
62
63
  setActiveDrawing: () => setActiveDrawing,
63
64
  updateDrawing: () => updateDrawing,
64
65
  updateWorkspace: () => updateWorkspace,
@@ -177,6 +178,17 @@ async function duplicateDrawing(id, newName) {
177
178
  async function moveDrawingToFolder(drawingId, folderId) {
178
179
  return updateDrawing(drawingId, { folderId });
179
180
  }
181
+ async function reorderDrawings(orderedIds) {
182
+ const db = await getDB();
183
+ const tx = db.transaction("drawings", "readwrite");
184
+ const store = tx.objectStore("drawings");
185
+ for (let i = 0; i < orderedIds.length; i++) {
186
+ const existing = await store.get(orderedIds[i]);
187
+ if (!existing) continue;
188
+ await store.put({ ...existing, position: i });
189
+ }
190
+ await tx.done;
191
+ }
180
192
 
181
193
  // src/storage/folderStore.ts
182
194
  var import_nanoid2 = require("nanoid");
@@ -315,8 +327,8 @@ var sv = {
315
327
  // Actions with descriptions
316
328
  createNewDrawing: "Skapa ny ritning",
317
329
  createNewDrawingDesc: "Skapar en tom ritning i din arbetsyta",
318
- openFromFile: "\xD6ppna ritning fr\xE5n fil",
319
- openFromFileDesc: "\xD6ppnar en sparad ritning fr\xE5n din dator",
330
+ openFromFile: "Importera ritning fr\xE5n fil",
331
+ openFromFileDesc: "Importerar en sparad ritning fr\xE5n din dator",
320
332
  saveAllBackup: "Spara alla ritningar (backup)",
321
333
  saveAllBackupDesc: "Ladda ner hela din arbetsyta som backup",
322
334
  loadBackup: "L\xE4s in sparad arbetsyta",
@@ -365,8 +377,8 @@ var en = {
365
377
  // Actions with descriptions
366
378
  createNewDrawing: "Create new drawing",
367
379
  createNewDrawingDesc: "Creates an empty drawing in your workspace",
368
- openFromFile: "Open drawing from file",
369
- openFromFileDesc: "Opens a saved drawing from your computer",
380
+ openFromFile: "Import drawing from file",
381
+ openFromFileDesc: "Imports a saved drawing from your computer",
370
382
  saveAllBackup: "Save all drawings (backup)",
371
383
  saveAllBackupDesc: "Download your entire workspace as a backup",
372
384
  loadBackup: "Load saved workspace",
@@ -1251,6 +1263,19 @@ function WorkspaceProvider({ children, lang = "en" }) {
1251
1263
  setError(err instanceof Error ? err.message : "Failed to move drawing");
1252
1264
  }
1253
1265
  }, []);
1266
+ const reorderDrawings2 = (0, import_react.useCallback)(async (orderedIds) => {
1267
+ const positionMap = new Map(orderedIds.map((id, idx) => [id, idx]));
1268
+ setDrawings((prev) => prev.map(
1269
+ (d) => positionMap.has(d.id) ? { ...d, position: positionMap.get(d.id) } : d
1270
+ ));
1271
+ try {
1272
+ await reorderDrawings(orderedIds);
1273
+ broadcastWorkspaceChange();
1274
+ } catch (err) {
1275
+ setError(err instanceof Error ? err.message : "Failed to reorder drawings");
1276
+ refreshDrawingsRef.current();
1277
+ }
1278
+ }, []);
1254
1279
  const value = {
1255
1280
  workspace,
1256
1281
  drawings,
@@ -1270,6 +1295,7 @@ function WorkspaceProvider({ children, lang = "en" }) {
1270
1295
  renameFolder: renameFolder2,
1271
1296
  deleteFolder: deleteFolder2,
1272
1297
  moveDrawingToFolder: moveDrawingToFolder2,
1298
+ reorderDrawings: reorderDrawings2,
1273
1299
  saveCurrentDrawing,
1274
1300
  saveDrawingById,
1275
1301
  refreshDrawings,
@@ -1638,6 +1664,7 @@ var DrawingsDialog = ({
1638
1664
  renameFolder: renameFolder2,
1639
1665
  deleteFolder: deleteFolder2,
1640
1666
  moveDrawingToFolder: moveDrawingToFolder2,
1667
+ reorderDrawings: reorderDrawings2,
1641
1668
  exportWorkspace,
1642
1669
  importWorkspace,
1643
1670
  exportDrawingAsExcalidraw,
@@ -1666,6 +1693,8 @@ var DrawingsDialog = ({
1666
1693
  const [isRefreshing, setIsRefreshing] = (0, import_react5.useState)(false);
1667
1694
  const [draggingDrawingId, setDraggingDrawingId] = (0, import_react5.useState)(null);
1668
1695
  const [dropTargetFolderId, setDropTargetFolderId] = (0, import_react5.useState)(null);
1696
+ const [dropTargetDrawingId, setDropTargetDrawingId] = (0, import_react5.useState)(null);
1697
+ const [dropTargetPosition, setDropTargetPosition] = (0, import_react5.useState)(null);
1669
1698
  const [position, setPosition] = (0, import_react5.useState)(null);
1670
1699
  const dragRef = (0, import_react5.useRef)(null);
1671
1700
  const dialogRef = (0, import_react5.useRef)(null);
@@ -1773,6 +1802,28 @@ var DrawingsDialog = ({
1773
1802
  setSelectedId(null);
1774
1803
  moveDrawingToFolder2(drawingId, folderId);
1775
1804
  }, [moveDrawingToFolder2]);
1805
+ const handleReorderDrop = (0, import_react5.useCallback)((draggedId, targetId, pos) => {
1806
+ if (draggedId === targetId) return;
1807
+ const target = drawings.find((d) => d.id === targetId);
1808
+ if (!target) return;
1809
+ const scopeFolderId = target.folderId ?? null;
1810
+ const scope = drawings.filter((d) => (d.folderId ?? null) === scopeFolderId).sort((a, b) => (a.position ?? a.createdAt) - (b.position ?? b.createdAt));
1811
+ const withoutDragged = scope.filter((d) => d.id !== draggedId);
1812
+ const targetIdx = withoutDragged.findIndex((d) => d.id === targetId);
1813
+ if (targetIdx === -1) return;
1814
+ const insertIdx = pos === "before" ? targetIdx : targetIdx + 1;
1815
+ const dragged = drawings.find((d) => d.id === draggedId);
1816
+ if (!dragged) return;
1817
+ if ((dragged.folderId ?? null) !== scopeFolderId) {
1818
+ moveDrawingToFolder2(draggedId, scopeFolderId);
1819
+ }
1820
+ const ordered = [
1821
+ ...withoutDragged.slice(0, insertIdx),
1822
+ dragged,
1823
+ ...withoutDragged.slice(insertIdx)
1824
+ ].map((d) => d.id);
1825
+ reorderDrawings2(ordered);
1826
+ }, [drawings, reorderDrawings2, moveDrawingToFolder2]);
1776
1827
  const toggleFolder = (0, import_react5.useCallback)((folderId) => {
1777
1828
  setExpandedFolders((prev) => {
1778
1829
  const next = new Set(prev);
@@ -1805,7 +1856,9 @@ var DrawingsDialog = ({
1805
1856
  const { rootDrawings, drawingsByFolder, filteredFolders } = (0, import_react5.useMemo)(() => {
1806
1857
  const query = searchQuery.toLowerCase().trim();
1807
1858
  const filtered = query ? drawings.filter((d) => d.name.toLowerCase().includes(query)) : drawings;
1808
- const sorted = [...filtered].sort((a, b) => a.createdAt - b.createdAt);
1859
+ const sorted = [...filtered].sort(
1860
+ (a, b) => (a.position ?? a.createdAt) - (b.position ?? b.createdAt)
1861
+ );
1809
1862
  const root = sorted.filter((d) => !d.folderId);
1810
1863
  const byFolder = {};
1811
1864
  for (const folder of folders) {
@@ -1860,6 +1913,34 @@ var DrawingsDialog = ({
1860
1913
  onDragEnd: () => {
1861
1914
  setDraggingDrawingId(null);
1862
1915
  setDropTargetFolderId(null);
1916
+ setDropTargetDrawingId(null);
1917
+ setDropTargetPosition(null);
1918
+ },
1919
+ onDragOver: (e) => {
1920
+ if (!draggingDrawingId || draggingDrawingId === drawing.id) return;
1921
+ e.preventDefault();
1922
+ e.dataTransfer.dropEffect = "move";
1923
+ const rect = e.currentTarget.getBoundingClientRect();
1924
+ const isBefore = e.clientY < rect.top + rect.height / 2;
1925
+ setDropTargetDrawingId(drawing.id);
1926
+ setDropTargetPosition(isBefore ? "before" : "after");
1927
+ },
1928
+ onDragLeave: (e) => {
1929
+ if (e.currentTarget.contains(e.relatedTarget)) return;
1930
+ if (dropTargetDrawingId === drawing.id) {
1931
+ setDropTargetDrawingId(null);
1932
+ setDropTargetPosition(null);
1933
+ }
1934
+ },
1935
+ onDrop: (e) => {
1936
+ if (!draggingDrawingId || !dropTargetPosition || draggingDrawingId === drawing.id) return;
1937
+ e.preventDefault();
1938
+ e.stopPropagation();
1939
+ handleReorderDrop(draggingDrawingId, drawing.id, dropTargetPosition);
1940
+ setDraggingDrawingId(null);
1941
+ setDropTargetDrawingId(null);
1942
+ setDropTargetPosition(null);
1943
+ setDropTargetFolderId(null);
1863
1944
  },
1864
1945
  onMouseEnter: () => setHoveredId(drawing.id),
1865
1946
  onMouseLeave: () => setHoveredId(null),
@@ -1875,6 +1956,7 @@ var DrawingsDialog = ({
1875
1956
  handleSelect(drawing);
1876
1957
  },
1877
1958
  style: {
1959
+ position: "relative",
1878
1960
  padding: "10px 12px",
1879
1961
  display: "flex",
1880
1962
  alignItems: "center",
@@ -1889,6 +1971,16 @@ var DrawingsDialog = ({
1889
1971
  opacity: draggingDrawingId === drawing.id ? 0.4 : switchingId && switchingId !== drawing.id ? 0.5 : 1
1890
1972
  },
1891
1973
  children: [
1974
+ dropTargetDrawingId === drawing.id && dropTargetPosition && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: {
1975
+ position: "absolute",
1976
+ left: 4,
1977
+ right: 4,
1978
+ [dropTargetPosition === "before" ? "top" : "bottom"]: -2,
1979
+ height: "3px",
1980
+ backgroundColor: "var(--color-primary, #6c63ff)",
1981
+ borderRadius: "2px",
1982
+ pointerEvents: "none"
1983
+ } }),
1892
1984
  renderThumbnail && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("div", { style: {
1893
1985
  width: "64px",
1894
1986
  height: "48px",
@@ -2815,6 +2907,7 @@ function WorkspacePlugin(props) {
2815
2907
  moveDrawingToFolder,
2816
2908
  removeDrawingFromWorkspace,
2817
2909
  renameFolder,
2910
+ reorderDrawings,
2818
2911
  setActiveDrawing,
2819
2912
  updateDrawing,
2820
2913
  updateWorkspace,
package/dist/index.mjs CHANGED
@@ -106,6 +106,17 @@ async function duplicateDrawing(id, newName) {
106
106
  async function moveDrawingToFolder(drawingId, folderId) {
107
107
  return updateDrawing(drawingId, { folderId });
108
108
  }
109
+ async function reorderDrawings(orderedIds) {
110
+ const db = await getDB();
111
+ const tx = db.transaction("drawings", "readwrite");
112
+ const store = tx.objectStore("drawings");
113
+ for (let i = 0; i < orderedIds.length; i++) {
114
+ const existing = await store.get(orderedIds[i]);
115
+ if (!existing) continue;
116
+ await store.put({ ...existing, position: i });
117
+ }
118
+ await tx.done;
119
+ }
109
120
 
110
121
  // src/storage/folderStore.ts
111
122
  import { nanoid as nanoid2 } from "nanoid";
@@ -244,8 +255,8 @@ var sv = {
244
255
  // Actions with descriptions
245
256
  createNewDrawing: "Skapa ny ritning",
246
257
  createNewDrawingDesc: "Skapar en tom ritning i din arbetsyta",
247
- openFromFile: "\xD6ppna ritning fr\xE5n fil",
248
- openFromFileDesc: "\xD6ppnar en sparad ritning fr\xE5n din dator",
258
+ openFromFile: "Importera ritning fr\xE5n fil",
259
+ openFromFileDesc: "Importerar en sparad ritning fr\xE5n din dator",
249
260
  saveAllBackup: "Spara alla ritningar (backup)",
250
261
  saveAllBackupDesc: "Ladda ner hela din arbetsyta som backup",
251
262
  loadBackup: "L\xE4s in sparad arbetsyta",
@@ -294,8 +305,8 @@ var en = {
294
305
  // Actions with descriptions
295
306
  createNewDrawing: "Create new drawing",
296
307
  createNewDrawingDesc: "Creates an empty drawing in your workspace",
297
- openFromFile: "Open drawing from file",
298
- openFromFileDesc: "Opens a saved drawing from your computer",
308
+ openFromFile: "Import drawing from file",
309
+ openFromFileDesc: "Imports a saved drawing from your computer",
299
310
  saveAllBackup: "Save all drawings (backup)",
300
311
  saveAllBackupDesc: "Download your entire workspace as a backup",
301
312
  loadBackup: "Load saved workspace",
@@ -1180,6 +1191,19 @@ function WorkspaceProvider({ children, lang = "en" }) {
1180
1191
  setError(err instanceof Error ? err.message : "Failed to move drawing");
1181
1192
  }
1182
1193
  }, []);
1194
+ const reorderDrawings2 = useCallback(async (orderedIds) => {
1195
+ const positionMap = new Map(orderedIds.map((id, idx) => [id, idx]));
1196
+ setDrawings((prev) => prev.map(
1197
+ (d) => positionMap.has(d.id) ? { ...d, position: positionMap.get(d.id) } : d
1198
+ ));
1199
+ try {
1200
+ await reorderDrawings(orderedIds);
1201
+ broadcastWorkspaceChange();
1202
+ } catch (err) {
1203
+ setError(err instanceof Error ? err.message : "Failed to reorder drawings");
1204
+ refreshDrawingsRef.current();
1205
+ }
1206
+ }, []);
1183
1207
  const value = {
1184
1208
  workspace,
1185
1209
  drawings,
@@ -1199,6 +1223,7 @@ function WorkspaceProvider({ children, lang = "en" }) {
1199
1223
  renameFolder: renameFolder2,
1200
1224
  deleteFolder: deleteFolder2,
1201
1225
  moveDrawingToFolder: moveDrawingToFolder2,
1226
+ reorderDrawings: reorderDrawings2,
1202
1227
  saveCurrentDrawing,
1203
1228
  saveDrawingById,
1204
1229
  refreshDrawings,
@@ -1567,6 +1592,7 @@ var DrawingsDialog = ({
1567
1592
  renameFolder: renameFolder2,
1568
1593
  deleteFolder: deleteFolder2,
1569
1594
  moveDrawingToFolder: moveDrawingToFolder2,
1595
+ reorderDrawings: reorderDrawings2,
1570
1596
  exportWorkspace,
1571
1597
  importWorkspace,
1572
1598
  exportDrawingAsExcalidraw,
@@ -1595,6 +1621,8 @@ var DrawingsDialog = ({
1595
1621
  const [isRefreshing, setIsRefreshing] = useState4(false);
1596
1622
  const [draggingDrawingId, setDraggingDrawingId] = useState4(null);
1597
1623
  const [dropTargetFolderId, setDropTargetFolderId] = useState4(null);
1624
+ const [dropTargetDrawingId, setDropTargetDrawingId] = useState4(null);
1625
+ const [dropTargetPosition, setDropTargetPosition] = useState4(null);
1598
1626
  const [position, setPosition] = useState4(null);
1599
1627
  const dragRef = useRef3(null);
1600
1628
  const dialogRef = useRef3(null);
@@ -1702,6 +1730,28 @@ var DrawingsDialog = ({
1702
1730
  setSelectedId(null);
1703
1731
  moveDrawingToFolder2(drawingId, folderId);
1704
1732
  }, [moveDrawingToFolder2]);
1733
+ const handleReorderDrop = useCallback2((draggedId, targetId, pos) => {
1734
+ if (draggedId === targetId) return;
1735
+ const target = drawings.find((d) => d.id === targetId);
1736
+ if (!target) return;
1737
+ const scopeFolderId = target.folderId ?? null;
1738
+ const scope = drawings.filter((d) => (d.folderId ?? null) === scopeFolderId).sort((a, b) => (a.position ?? a.createdAt) - (b.position ?? b.createdAt));
1739
+ const withoutDragged = scope.filter((d) => d.id !== draggedId);
1740
+ const targetIdx = withoutDragged.findIndex((d) => d.id === targetId);
1741
+ if (targetIdx === -1) return;
1742
+ const insertIdx = pos === "before" ? targetIdx : targetIdx + 1;
1743
+ const dragged = drawings.find((d) => d.id === draggedId);
1744
+ if (!dragged) return;
1745
+ if ((dragged.folderId ?? null) !== scopeFolderId) {
1746
+ moveDrawingToFolder2(draggedId, scopeFolderId);
1747
+ }
1748
+ const ordered = [
1749
+ ...withoutDragged.slice(0, insertIdx),
1750
+ dragged,
1751
+ ...withoutDragged.slice(insertIdx)
1752
+ ].map((d) => d.id);
1753
+ reorderDrawings2(ordered);
1754
+ }, [drawings, reorderDrawings2, moveDrawingToFolder2]);
1705
1755
  const toggleFolder = useCallback2((folderId) => {
1706
1756
  setExpandedFolders((prev) => {
1707
1757
  const next = new Set(prev);
@@ -1734,7 +1784,9 @@ var DrawingsDialog = ({
1734
1784
  const { rootDrawings, drawingsByFolder, filteredFolders } = useMemo(() => {
1735
1785
  const query = searchQuery.toLowerCase().trim();
1736
1786
  const filtered = query ? drawings.filter((d) => d.name.toLowerCase().includes(query)) : drawings;
1737
- const sorted = [...filtered].sort((a, b) => a.createdAt - b.createdAt);
1787
+ const sorted = [...filtered].sort(
1788
+ (a, b) => (a.position ?? a.createdAt) - (b.position ?? b.createdAt)
1789
+ );
1738
1790
  const root = sorted.filter((d) => !d.folderId);
1739
1791
  const byFolder = {};
1740
1792
  for (const folder of folders) {
@@ -1789,6 +1841,34 @@ var DrawingsDialog = ({
1789
1841
  onDragEnd: () => {
1790
1842
  setDraggingDrawingId(null);
1791
1843
  setDropTargetFolderId(null);
1844
+ setDropTargetDrawingId(null);
1845
+ setDropTargetPosition(null);
1846
+ },
1847
+ onDragOver: (e) => {
1848
+ if (!draggingDrawingId || draggingDrawingId === drawing.id) return;
1849
+ e.preventDefault();
1850
+ e.dataTransfer.dropEffect = "move";
1851
+ const rect = e.currentTarget.getBoundingClientRect();
1852
+ const isBefore = e.clientY < rect.top + rect.height / 2;
1853
+ setDropTargetDrawingId(drawing.id);
1854
+ setDropTargetPosition(isBefore ? "before" : "after");
1855
+ },
1856
+ onDragLeave: (e) => {
1857
+ if (e.currentTarget.contains(e.relatedTarget)) return;
1858
+ if (dropTargetDrawingId === drawing.id) {
1859
+ setDropTargetDrawingId(null);
1860
+ setDropTargetPosition(null);
1861
+ }
1862
+ },
1863
+ onDrop: (e) => {
1864
+ if (!draggingDrawingId || !dropTargetPosition || draggingDrawingId === drawing.id) return;
1865
+ e.preventDefault();
1866
+ e.stopPropagation();
1867
+ handleReorderDrop(draggingDrawingId, drawing.id, dropTargetPosition);
1868
+ setDraggingDrawingId(null);
1869
+ setDropTargetDrawingId(null);
1870
+ setDropTargetPosition(null);
1871
+ setDropTargetFolderId(null);
1792
1872
  },
1793
1873
  onMouseEnter: () => setHoveredId(drawing.id),
1794
1874
  onMouseLeave: () => setHoveredId(null),
@@ -1804,6 +1884,7 @@ var DrawingsDialog = ({
1804
1884
  handleSelect(drawing);
1805
1885
  },
1806
1886
  style: {
1887
+ position: "relative",
1807
1888
  padding: "10px 12px",
1808
1889
  display: "flex",
1809
1890
  alignItems: "center",
@@ -1818,6 +1899,16 @@ var DrawingsDialog = ({
1818
1899
  opacity: draggingDrawingId === drawing.id ? 0.4 : switchingId && switchingId !== drawing.id ? 0.5 : 1
1819
1900
  },
1820
1901
  children: [
1902
+ dropTargetDrawingId === drawing.id && dropTargetPosition && /* @__PURE__ */ jsx6("div", { style: {
1903
+ position: "absolute",
1904
+ left: 4,
1905
+ right: 4,
1906
+ [dropTargetPosition === "before" ? "top" : "bottom"]: -2,
1907
+ height: "3px",
1908
+ backgroundColor: "var(--color-primary, #6c63ff)",
1909
+ borderRadius: "2px",
1910
+ pointerEvents: "none"
1911
+ } }),
1821
1912
  renderThumbnail && /* @__PURE__ */ jsx6("div", { style: {
1822
1913
  width: "64px",
1823
1914
  height: "48px",
@@ -2743,6 +2834,7 @@ export {
2743
2834
  moveDrawingToFolder,
2744
2835
  removeDrawingFromWorkspace,
2745
2836
  renameFolder,
2837
+ reorderDrawings,
2746
2838
  setActiveDrawing,
2747
2839
  updateDrawing,
2748
2840
  updateWorkspace,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "rita-workspace",
3
- "version": "0.5.33",
3
+ "version": "0.5.34",
4
4
  "description": "Multi-drawing workspace feature for Rita (Excalidraw fork)",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",