@burdenoff/microfe-files 2026.525.3 → 2026.527.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.
Files changed (74) hide show
  1. package/dist/files/components/ActionMenu.js +3 -1
  2. package/dist/files/components/ActionMenu.js.map +1 -1
  3. package/dist/files/components/ContextMenu.js +16 -112
  4. package/dist/files/components/ContextMenu.js.map +1 -1
  5. package/dist/files/components/CopyDialog.js +8 -0
  6. package/dist/files/components/CopyDialog.js.map +1 -1
  7. package/dist/files/components/EmptyState.js +2 -0
  8. package/dist/files/components/EmptyState.js.map +1 -1
  9. package/dist/files/components/FileBrowser.js +192 -171
  10. package/dist/files/components/FileBrowser.js.map +1 -1
  11. package/dist/files/components/FileCard.js +4 -0
  12. package/dist/files/components/FileCard.js.map +1 -1
  13. package/dist/files/components/FileInfoPanel.js +2 -0
  14. package/dist/files/components/FileInfoPanel.js.map +1 -1
  15. package/dist/files/components/FileListItem.js +6 -0
  16. package/dist/files/components/FileListItem.js.map +1 -1
  17. package/dist/files/components/FilePreviewModal.js +9 -3
  18. package/dist/files/components/FilePreviewModal.js.map +1 -1
  19. package/dist/files/components/FileVersionPanel.js +5 -0
  20. package/dist/files/components/FileVersionPanel.js.map +1 -1
  21. package/dist/files/components/FolderCard.js +147 -158
  22. package/dist/files/components/FolderCard.js.map +1 -1
  23. package/dist/files/components/MoveDialog.js +17 -12
  24. package/dist/files/components/MoveDialog.js.map +1 -1
  25. package/dist/files/components/SearchBar.js +4 -0
  26. package/dist/files/components/SearchBar.js.map +1 -1
  27. package/dist/files/components/ShareDialog.js +109 -104
  28. package/dist/files/components/ShareDialog.js.map +1 -1
  29. package/dist/files/components/TabBar.js +1 -0
  30. package/dist/files/components/TabBar.js.map +1 -1
  31. package/dist/files/components/Toast.js +1 -0
  32. package/dist/files/components/Toast.js.map +1 -1
  33. package/dist/files/components/UploadQueue.js +5 -0
  34. package/dist/files/components/UploadQueue.js.map +1 -1
  35. package/dist/files/components/contextMenuItems.js +103 -0
  36. package/dist/files/components/contextMenuItems.js.map +1 -0
  37. package/dist/files/components/viewers/AudioPlayer.js +4 -1
  38. package/dist/files/components/viewers/AudioPlayer.js.map +1 -1
  39. package/dist/files/components/viewers/CodeViewer.js +2 -0
  40. package/dist/files/components/viewers/CodeViewer.js.map +1 -1
  41. package/dist/files/components/viewers/ImageViewer.js +4 -0
  42. package/dist/files/components/viewers/ImageViewer.js.map +1 -1
  43. package/dist/files/components/viewers/PDFViewer.js +2 -0
  44. package/dist/files/components/viewers/PDFViewer.js.map +1 -1
  45. package/dist/files/components/viewers/TextViewer.js +4 -2
  46. package/dist/files/components/viewers/TextViewer.js.map +1 -1
  47. package/dist/files/components/viewers/VideoPlayer.js +5 -1
  48. package/dist/files/components/viewers/VideoPlayer.js.map +1 -1
  49. package/dist/files/hooks/useBatchOperations.js.map +1 -1
  50. package/dist/files/hooks/useCreateFolder.js +15 -7
  51. package/dist/files/hooks/useCreateFolder.js.map +1 -1
  52. package/dist/files/hooks/useFileVersions.js.map +1 -1
  53. package/dist/files/hooks/useMoveFile.js +1 -2
  54. package/dist/files/hooks/useMoveFile.js.map +1 -1
  55. package/dist/files/hooks/useMoveFolder.js +0 -2
  56. package/dist/files/hooks/useMoveFolder.js.map +1 -1
  57. package/dist/files/hooks/useStarredItems.js +4 -3
  58. package/dist/files/hooks/useStarredItems.js.map +1 -1
  59. package/dist/files/hooks/useToggleStar.js +10 -10
  60. package/dist/files/hooks/useToggleStar.js.map +1 -1
  61. package/dist/files/pages/BrowserPage.js +332 -302
  62. package/dist/files/pages/BrowserPage.js.map +1 -1
  63. package/dist/files/pages/ShareAccessPage.js +6 -5
  64. package/dist/files/pages/ShareAccessPage.js.map +1 -1
  65. package/dist/files/utils/index.js +1 -1
  66. package/dist/files/utils/index.js.map +1 -1
  67. package/dist/files/utils/quotaUtils.js +14 -0
  68. package/dist/files/utils/quotaUtils.js.map +1 -0
  69. package/dist/files/utils/thumbnail.js.map +1 -1
  70. package/dist/files.js +2 -1
  71. package/dist/translations/en.js +259 -0
  72. package/dist/translations/en.js.map +1 -0
  73. package/package.json +2 -5
  74. package/dist/files/components/viewers/index.js +0 -6
@@ -1,222 +1,211 @@
1
1
  import { useFilesStore as e } from "../store/filesStore.js";
2
2
  import { formatFileDate as t } from "../utils/index.js";
3
3
  import { tWithFallback as n } from "../utils/i18n.js";
4
- import { ActionMenu as r } from "./ActionMenu.js";
5
- import { canDropOnFolder as i, getDragOperation as a } from "../hooks/useDragDrop.js";
6
- import { useMemo as o, useState as s } from "react";
7
- import { Activity as ee, ChevronRight as c, Copy as l, Edit as u, Folder as d, FolderInput as f, FolderOpen as te, Info as p, RotateCcw as m, Share2 as h, Star as g, Trash2 as _ } from "lucide-react";
8
- import { jsx as v, jsxs as y } from "react/jsx-runtime";
4
+ import { ActionMenu as ee } from "./ActionMenu.js";
5
+ import { canDropOnFolder as r, getDragOperation as i } from "../hooks/useDragDrop.js";
6
+ import { useMemo as te, useState as a } from "react";
7
+ import { Activity as o, ChevronRight as s, Edit as c, Folder as l, FolderInput as u, FolderOpen as d, Info as f, RotateCcw as p, Share2 as m, Star as h, Trash2 as g } from "lucide-react";
8
+ import { Fragment as _, jsx as v, jsxs as y } from "react/jsx-runtime";
9
9
  import { useI18n as b } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
10
10
  //#region src/files/components/FolderCard.tsx
11
- var x = ({ folder: x, isSelected: S = !1, isDragging: C = !1, isDropTarget: w = !1, draggedItem: T = null, onSelect: E, onOpen: D, onShare: O, onDelete: k, onRestore: A, onRename: j, onFavorite: M, onCopy: N, onMove: P, onInfo: F, onActivity: I, onDragStart: L, onDragEnd: R, onDrop: z, onContextMenu: B }) => {
12
- let { t: V } = b(), [H, U] = s(!1), [W, G] = s(!1), [ne, K] = s(!1), { toggleFolderSelection: q } = e(), J = i(T, x), Y = w && J, X = () => {
11
+ var x = ({ folder: x, isSelected: S = !1, isDragging: C = !1, isDropTarget: w = !1, draggedItem: T = null, onSelect: E, onOpen: D, onShare: O, onDelete: k, onRestore: A, onRename: j, onFavorite: M, onCopy: ne, onMove: N, onInfo: P, onActivity: F, onDragStart: I, onDragEnd: L, onDrop: R, onContextMenu: z }) => {
12
+ let { t: B } = b(), [V, H] = a(!1), [U, W] = a(!1), { toggleFolderSelection: G } = e(), K = r(T, x), q = w && K, J = x.filesCount ?? 0, Y = x.subfoldersCount ?? 0, X = J + Y, Z = () => {
13
13
  D && D(x);
14
- }, Z = (e) => {
15
- e.stopPropagation(), E ? E(x.id) : q(x.id);
14
+ }, re = (e) => {
15
+ e.stopPropagation(), E ? E(x.id) : G(x.id);
16
16
  }, Q = (e, t) => {
17
- e.stopPropagation(), t(), U(!1);
18
- }, $ = (e) => {
19
- e.dataTransfer.effectAllowed = "copyMove", e.dataTransfer.setData("application/x-file-id", x.id), e.dataTransfer.setData("application/x-file-type", "folder");
20
- let t = a(e);
21
- e.dataTransfer.setData("application/x-drag-operation", t), L?.(x, t);
22
- }, re = () => {
23
- R?.();
17
+ e.stopPropagation(), t();
24
18
  }, ie = (e) => {
25
- Y && (e.preventDefault(), e.dataTransfer.dropEffect = T?.operation === "copy" ? "copy" : "move");
26
- }, ae = (e) => {
27
- Y && e.preventDefault();
28
- }, oe = () => {}, se = (e) => {
29
- e.preventDefault(), Y && z?.(x);
30
- }, ce = (e) => {
31
- e.preventDefault(), e.stopPropagation(), B?.(x, e.clientX, e.clientY);
32
- }, le = W ? te : d, ue = o(() => [
19
+ e.dataTransfer.effectAllowed = "copyMove", e.dataTransfer.setData("application/x-file-id", x.id), e.dataTransfer.setData("application/x-file-type", "folder");
20
+ let t = i(e);
21
+ e.dataTransfer.setData("application/x-drag-operation", t), I?.(x, t);
22
+ }, ae = () => {
23
+ L?.();
24
+ }, $ = (e) => {
25
+ q && (e.preventDefault(), e.dataTransfer.dropEffect = T?.operation === "copy" ? "copy" : "move");
26
+ }, oe = (e) => {
27
+ q && e.preventDefault();
28
+ }, se = () => {}, ce = (e) => {
29
+ e.preventDefault(), q && R?.(x);
30
+ }, le = (e) => {
31
+ e.preventDefault(), e.stopPropagation(), z?.(x, e.clientX, e.clientY);
32
+ }, ue = V ? d : l, de = te(() => [
33
33
  ...O ? [{
34
- label: n(V, "files.card.share", "Share"),
35
- icon: /* @__PURE__ */ v(h, { className: "size-4" }),
34
+ label: n(B, "files.card.share", "Share"),
35
+ icon: /* @__PURE__ */ v(m, { className: "size-4" }),
36
36
  onClick: () => O(x)
37
37
  }] : [],
38
38
  ...N ? [{
39
- label: n(V, "files.card.makeCopy", "Make a copy"),
40
- icon: /* @__PURE__ */ v(l, { className: "size-4" }),
39
+ label: n(B, "files.card.moveTo", "Move to"),
40
+ icon: /* @__PURE__ */ v(u, { className: "size-4" }),
41
41
  onClick: () => N(x)
42
42
  }] : [],
43
- ...P ? [{
44
- label: n(V, "files.card.moveTo", "Move to"),
45
- icon: /* @__PURE__ */ v(f, { className: "size-4" }),
46
- onClick: () => P(x)
47
- }] : [],
48
43
  ...j ? [{
49
- label: n(V, "files.card.rename", "Rename"),
50
- icon: /* @__PURE__ */ v(u, { className: "size-4" }),
44
+ label: n(B, "files.card.rename", "Rename"),
45
+ icon: /* @__PURE__ */ v(c, { className: "size-4" }),
51
46
  onClick: () => j(x),
52
47
  divider: !0
53
48
  }] : [],
54
49
  ...M ? [{
55
- label: x.starred ? n(V, "files.card.removeFromStarred", "Remove from starred") : n(V, "files.card.addToStarred", "Add to starred"),
56
- icon: /* @__PURE__ */ v(g, { className: "size-4" }),
50
+ label: x.starred ? n(B, "files.card.removeFromStarred", "Remove from starred") : n(B, "files.card.addToStarred", "Add to starred"),
51
+ icon: /* @__PURE__ */ v(h, { className: "size-4" }),
57
52
  onClick: () => M(x)
58
53
  }] : [],
54
+ ...P ? [{
55
+ label: n(B, "files.card.details", "Details"),
56
+ icon: /* @__PURE__ */ v(f, { className: "size-4" }),
57
+ onClick: () => P(x)
58
+ }] : [],
59
59
  ...F ? [{
60
- label: n(V, "files.card.details", "Details"),
61
- icon: /* @__PURE__ */ v(p, { className: "size-4" }),
60
+ label: n(B, "files.card.activity", "Activity"),
61
+ icon: /* @__PURE__ */ v(o, { className: "size-4" }),
62
62
  onClick: () => F(x)
63
63
  }] : [],
64
- ...I ? [{
65
- label: n(V, "files.card.activity", "Activity"),
66
- icon: /* @__PURE__ */ v(ee, { className: "size-4" }),
67
- onClick: () => I(x)
68
- }] : [],
69
64
  ...k ? [{
70
- label: n(V, "files.card.delete", "Delete"),
71
- icon: /* @__PURE__ */ v(_, { className: "size-4" }),
65
+ label: n(B, "files.card.delete", "Delete"),
66
+ icon: /* @__PURE__ */ v(g, { className: "size-4" }),
72
67
  onClick: () => k(x),
73
68
  variant: "danger",
74
69
  divider: !0
75
70
  }] : [],
76
71
  ...A ? [{
77
- label: n(V, "files.card.restore", "Restore"),
78
- icon: /* @__PURE__ */ v(m, { className: "size-4" }),
72
+ label: n(B, "files.card.restore", "Restore"),
73
+ icon: /* @__PURE__ */ v(p, { className: "size-4" }),
79
74
  onClick: () => A(x)
80
75
  }] : []
81
76
  ], [
82
77
  x,
83
78
  O,
84
79
  N,
85
- P,
86
80
  j,
87
81
  M,
82
+ P,
88
83
  F,
89
- I,
90
84
  k,
91
85
  A,
92
- V
86
+ B
93
87
  ]);
94
- return /* @__PURE__ */ y("div", {
95
- className: `@container group relative cursor-pointer overflow-hidden rounded-card border bg-bg-surface shadow-elevation-1 transition-shadow hover:shadow-elevation-2 focus-within:shadow-elevation-2 ${C ? "opacity-50" : ""} ${Y ? "border-action-primary-bg ring-2 ring-action-primary-bg ring-offset-2" : "border-border-subtle"}`,
96
- onClick: X,
97
- onContextMenu: ce,
98
- onMouseEnter: () => {
99
- U(!0), G(!0);
100
- },
88
+ return /* @__PURE__ */ v("div", {
89
+ className: `group relative cursor-pointer rounded-card border bg-bg-surface shadow-elevation-1 transition-all hover:shadow-elevation-2 focus-within:shadow-elevation-2 ${C ? "opacity-50" : ""} ${q ? "border-action-primary-bg ring-2 ring-action-primary-bg ring-offset-2" : S ? "border-action-primary-bg bg-bg-accent" : "border-border-subtle"}`,
90
+ onClick: Z,
91
+ onContextMenu: le,
92
+ onMouseEnter: () => H(!0),
101
93
  onMouseLeave: () => {
102
- U(!1), G(!1);
103
- },
104
- onFocus: () => {
105
- U(!0), G(!0);
94
+ U || H(!1);
106
95
  },
96
+ onFocus: () => H(!0),
107
97
  onBlur: (e) => {
108
- e.currentTarget.contains(e.relatedTarget) || (U(!1), G(!1));
98
+ !e.currentTarget.contains(e.relatedTarget) && !U && H(!1);
109
99
  },
110
100
  onKeyDown: (e) => {
111
- (e.key === "Enter" || e.key === " ") && (e.preventDefault(), X());
101
+ (e.key === "Enter" || e.key === " ") && (e.preventDefault(), Z());
112
102
  },
113
- draggable: !!L,
114
- onDragStart: $,
115
- onDragEnd: re,
116
- onDragOver: ie,
117
- onDragEnter: ae,
118
- onDragLeave: oe,
119
- onDrop: se,
103
+ draggable: !!I,
104
+ onDragStart: ie,
105
+ onDragEnd: ae,
106
+ onDragOver: $,
107
+ onDragEnter: oe,
108
+ onDragLeave: se,
109
+ onDrop: ce,
120
110
  role: "button",
121
111
  tabIndex: 0,
122
- "aria-label": `${n(V, "files.browser.openFolder", "Open folder")} ${x.name}`,
123
- children: [
124
- /* @__PURE__ */ v("div", {
125
- className: `absolute top-2 left-2 z-10 transition-opacity ${S ? "opacity-100" : "opacity-0 group-hover:opacity-100 group-focus-within:opacity-100"}`,
126
- children: /* @__PURE__ */ v("input", {
127
- type: "checkbox",
128
- checked: S,
129
- onChange: Z,
130
- className: "size-4 rounded border-border-default bg-bg-surface text-action-primary-bg focus:ring-2 focus:ring-action-primary-bg focus:ring-offset-2",
131
- "aria-label": `Select ${x.name}`
132
- })
133
- }),
134
- x.starred && /* @__PURE__ */ v("div", {
135
- className: "absolute top-2 right-2 z-10",
136
- children: /* @__PURE__ */ v(g, { className: "size-4 fill-yellow-400 text-yellow-400" })
137
- }),
138
- /* @__PURE__ */ v("div", {
139
- className: "aspect-[4/3] bg-bg-sunken flex items-center justify-center",
140
- children: /* @__PURE__ */ v(le, { className: "size-10 @md:size-14 text-action-primary-bg" })
141
- }),
142
- /* @__PURE__ */ y("div", {
143
- className: "p-3 @md:p-4",
144
- children: [
145
- /* @__PURE__ */ y("div", {
146
- className: "flex items-center justify-between gap-2 mb-1",
147
- children: [/* @__PURE__ */ v("h3", {
148
- className: "font-text-md font-weight-medium text-text-primary truncate flex-1",
112
+ "aria-label": `${n(B, "files.browser.openFolder", "Open folder")} ${x.name}`,
113
+ children: /* @__PURE__ */ y("div", {
114
+ className: "flex items-center gap-3 p-3",
115
+ children: [
116
+ /* @__PURE__ */ v("div", {
117
+ className: `flex-shrink-0 transition-opacity ${S ? "opacity-100" : "opacity-0 group-hover:opacity-100 group-focus-within:opacity-100"}`,
118
+ onClick: (e) => e.stopPropagation(),
119
+ children: /* @__PURE__ */ v("input", {
120
+ type: "checkbox",
121
+ checked: S,
122
+ onChange: re,
123
+ className: "size-4 rounded border-border-default bg-bg-surface text-action-primary-bg focus:ring-2 focus:ring-action-primary-bg focus:ring-offset-2",
124
+ "aria-label": `Select ${x.name}`
125
+ })
126
+ }),
127
+ /* @__PURE__ */ v("div", {
128
+ className: "flex-shrink-0 flex items-center justify-center size-10 rounded-lg bg-action-primary-bg/10",
129
+ children: /* @__PURE__ */ v(ue, { className: "size-5 text-action-primary-bg" })
130
+ }),
131
+ /* @__PURE__ */ y("div", {
132
+ className: "flex-1 min-w-0 pr-1",
133
+ children: [/* @__PURE__ */ y("div", {
134
+ className: "flex items-center gap-1.5",
135
+ children: [/* @__PURE__ */ v("span", {
136
+ className: "text-sm font-medium text-text-primary truncate",
149
137
  children: x.name
150
- }), /* @__PURE__ */ v(c, { className: "size-4 text-text-muted flex-shrink-0" })]
151
- }),
152
- /* @__PURE__ */ y("div", {
153
- className: "flex items-center gap-2 text-text-secondary font-text-sm",
138
+ }), x.starred && /* @__PURE__ */ v(h, { className: "size-3 flex-shrink-0 fill-yellow-400 text-yellow-400" })]
139
+ }), /* @__PURE__ */ y("div", {
140
+ className: "flex items-center gap-1 mt-0.5 text-xs text-text-secondary",
154
141
  children: [
155
- /* @__PURE__ */ y("span", { children: [
156
- x.filesCount ?? 0,
142
+ Y > 0 && /* @__PURE__ */ y(_, { children: [/* @__PURE__ */ y("span", { children: [
143
+ Y,
144
+ " ",
145
+ Y === 1 ? n(B, "files.folder.subfolder", "folder") : n(B, "files.folder.subfolders", "folders")
146
+ ] }), J > 0 && /* @__PURE__ */ v("span", {
147
+ className: "text-border-subtle",
148
+ children: "·"
149
+ })] }),
150
+ J > 0 && /* @__PURE__ */ y("span", { children: [
151
+ J,
157
152
  " ",
158
- (x.filesCount ?? 0) === 1 ? n(V, "files.folder.item", "item") : n(V, "files.browser.items", "items")
153
+ J === 1 ? n(B, "files.folder.file", "file") : n(B, "files.folder.files", "files")
159
154
  ] }),
155
+ X === 0 && /* @__PURE__ */ v("span", { children: n(B, "files.folder.empty", "Empty") }),
160
156
  /* @__PURE__ */ v("span", {
161
- className: "hidden @sm:inline text-border-subtle",
162
- children: "•"
157
+ className: "text-border-subtle",
158
+ children: "·"
163
159
  }),
164
160
  /* @__PURE__ */ v("span", {
165
- className: "hidden @sm:inline",
161
+ className: "truncate",
166
162
  children: t(x.updatedAt)
167
163
  })
168
164
  ]
169
- }),
170
- x.createdBy && /* @__PURE__ */ v("div", {
171
- className: "hidden @md:flex items-center gap-2 mt-2 text-text-muted font-text-xs",
172
- children: /* @__PURE__ */ y("div", {
173
- className: "flex items-center gap-1",
174
- children: [x.createdBy.avatar && /* @__PURE__ */ v("img", {
175
- src: x.createdBy.avatar,
176
- alt: x.createdBy.name,
177
- className: "size-4 rounded-full"
178
- }), /* @__PURE__ */ v("span", { children: x.createdBy.name })]
179
- })
180
- })
181
- ]
182
- }),
183
- H && /* @__PURE__ */ y("div", {
184
- className: "absolute bottom-3 right-3 flex items-center gap-1 bg-bg-elevated border border-border-subtle rounded shadow-elevation-2 p-1",
185
- children: [
186
- O && /* @__PURE__ */ v("button", {
187
- onClick: (e) => Q(e, () => O(x)),
188
- className: "p-1.5 hover:bg-action-ghost-bg-hover rounded transition-colors",
189
- "aria-label": n(V, "files.card.share", "Share"),
190
- title: n(V, "files.card.share", "Share"),
191
- children: /* @__PURE__ */ v(h, { className: "size-4 text-text-primary" })
192
- }),
193
- j && /* @__PURE__ */ v("button", {
194
- onClick: (e) => Q(e, () => j(x)),
195
- className: "p-1.5 hover:bg-action-ghost-bg-hover rounded transition-colors",
196
- "aria-label": n(V, "files.card.rename", "Rename"),
197
- title: n(V, "files.card.rename", "Rename"),
198
- children: /* @__PURE__ */ v(u, { className: "size-4 text-text-primary" })
199
- }),
200
- A && /* @__PURE__ */ v("button", {
201
- onClick: (e) => Q(e, () => A(x)),
202
- className: "p-1.5 hover:bg-status-success-bg-subtle rounded transition-colors",
203
- "aria-label": n(V, "files.card.restore", "Restore"),
204
- title: n(V, "files.card.restore", "Restore"),
205
- children: /* @__PURE__ */ v(m, { className: "size-4 text-status-success-text" })
206
- }),
207
- /* @__PURE__ */ v("div", {
208
- onClick: (e) => e.stopPropagation(),
209
- children: /* @__PURE__ */ v(r, {
210
- items: ue,
211
- align: "right",
212
- triggerClassName: "p-1.5",
213
- isOpen: ne,
214
- onToggle: K
165
+ })]
166
+ }),
167
+ /* @__PURE__ */ y("div", {
168
+ className: "flex-shrink-0 flex items-center gap-1",
169
+ children: [
170
+ V && A && /* @__PURE__ */ v("button", {
171
+ type: "button",
172
+ onClick: (e) => Q(e, () => A(x)),
173
+ className: "p-1.5 hover:bg-status-success-bg-subtle rounded transition-colors",
174
+ "aria-label": n(B, "files.card.restore", "Restore"),
175
+ title: n(B, "files.card.restore", "Restore"),
176
+ children: /* @__PURE__ */ v(p, { className: "size-4 text-status-success-text" })
177
+ }),
178
+ V && O && /* @__PURE__ */ v("button", {
179
+ onClick: (e) => Q(e, () => O(x)),
180
+ className: "p-1.5 hover:bg-action-ghost-bg-hover rounded transition-colors",
181
+ "aria-label": n(B, "files.card.share", "Share"),
182
+ title: n(B, "files.card.share", "Share"),
183
+ children: /* @__PURE__ */ v(m, { className: "size-4 text-text-secondary" })
184
+ }),
185
+ V && j && /* @__PURE__ */ v("button", {
186
+ onClick: (e) => Q(e, () => j(x)),
187
+ className: "p-1.5 hover:bg-action-ghost-bg-hover rounded transition-colors",
188
+ "aria-label": n(B, "files.card.rename", "Rename"),
189
+ title: n(B, "files.card.rename", "Rename"),
190
+ children: /* @__PURE__ */ v(c, { className: "size-4 text-text-secondary" })
191
+ }),
192
+ /* @__PURE__ */ v("div", {
193
+ onClick: (e) => e.stopPropagation(),
194
+ children: /* @__PURE__ */ v(ee, {
195
+ items: de,
196
+ align: "right",
197
+ triggerClassName: !V && !U ? "opacity-0 group-hover:opacity-100" : "",
198
+ isOpen: U,
199
+ onToggle: (e) => {
200
+ W(e), e && H(!0);
201
+ }
202
+ })
215
203
  })
216
- })
217
- ]
218
- })
219
- ]
204
+ ]
205
+ }),
206
+ /* @__PURE__ */ v(s, { className: "flex-shrink-0 size-4 text-text-muted opacity-0 group-hover:opacity-100 transition-opacity" })
207
+ ]
208
+ })
220
209
  });
221
210
  };
222
211
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"FolderCard.js","names":[],"sources":["../../../src/files/components/FolderCard.tsx"],"sourcesContent":["import { type FC, useState, useMemo } from \"react\";\nimport {\n Folder,\n FolderOpen,\n Share2,\n Trash2,\n Edit,\n ChevronRight,\n Copy,\n FolderInput,\n Info,\n Activity,\n Star,\n RotateCcw,\n} from \"lucide-react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport type { FolderItem } from \"../types\";\nimport { formatFileDate } from \"../utils\";\nimport { useFilesStore } from \"../store/filesStore\";\nimport { ActionMenu } from \"./ActionMenu\";\nimport { getDragOperation, canDropOnFolder } from \"../hooks/useDragDrop\";\nimport { tWithFallback } from \"../utils/i18n\";\nimport type { DragData } from \"../hooks/useDragDrop\";\n\ninterface FolderCardProps {\n folder: FolderItem;\n isSelected?: boolean;\n isDragging?: boolean;\n isDropTarget?: boolean;\n draggedItem?: DragData | null;\n onSelect?: (folderId: string) => void;\n onOpen?: (folder: FolderItem) => void;\n onShare?: (folder: FolderItem) => void;\n onDelete?: (folder: FolderItem) => void;\n onRestore?: (folder: FolderItem) => void;\n onRename?: (folder: FolderItem) => void;\n onFavorite?: (folder: FolderItem) => void;\n onCopy?: (folder: FolderItem) => void;\n onMove?: (folder: FolderItem) => void;\n onInfo?: (folder: FolderItem) => void;\n onActivity?: (folder: FolderItem) => void;\n onDragStart?: (folder: FolderItem, operation: \"move\" | \"copy\") => void;\n onDragEnd?: () => void;\n onDrop?: (folder: FolderItem) => void;\n onContextMenu?: (folder: FolderItem, x: number, y: number) => void;\n}\n\ninterface DraggableFolderCardProps extends Omit<\n FolderCardProps,\n \"onDragStart\" | \"onDragEnd\" | \"onDrop\"\n> {\n onDragStart?: (folder: FolderItem, operation: \"move\" | \"copy\") => void;\n onDragEnd?: () => void;\n onDrop?: (folder: FolderItem) => void;\n onContextMenu?: (folder: FolderItem, x: number, y: number) => void;\n}\n\nexport const FolderCard: FC<DraggableFolderCardProps> = ({\n folder,\n isSelected = false,\n isDragging = false,\n isDropTarget = false,\n draggedItem = null,\n onSelect,\n onOpen,\n onShare,\n onDelete,\n onRestore,\n onRename,\n onFavorite,\n onCopy,\n onMove,\n onInfo,\n onActivity,\n onDragStart,\n onDragEnd,\n onDrop,\n onContextMenu,\n}) => {\n const { t } = useI18n();\n const [showActions, setShowActions] = useState(false);\n const [isHovered, setIsHovered] = useState(false);\n const [menuOpen, setMenuOpen] = useState(false);\n const { toggleFolderSelection } = useFilesStore();\n\n const canDrop = canDropOnFolder(draggedItem, folder);\n const isValidDropTarget = isDropTarget && canDrop;\n\n const handleClick = () => {\n if (onOpen) {\n onOpen(folder);\n }\n };\n\n const handleCheckboxChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n e.stopPropagation();\n if (onSelect) {\n onSelect(folder.id);\n } else {\n toggleFolderSelection(folder.id);\n }\n };\n\n const handleActionClick = (e: React.MouseEvent, action: () => void) => {\n e.stopPropagation();\n action();\n setShowActions(false);\n };\n\n const handleDragStart = (e: React.DragEvent<HTMLDivElement>) => {\n e.dataTransfer.effectAllowed = \"copyMove\";\n e.dataTransfer.setData(\"application/x-file-id\", folder.id);\n e.dataTransfer.setData(\"application/x-file-type\", \"folder\");\n const operation = getDragOperation(e);\n e.dataTransfer.setData(\"application/x-drag-operation\", operation);\n onDragStart?.(folder, operation);\n };\n\n const handleDragEnd = () => {\n onDragEnd?.();\n };\n\n const handleDragOver = (e: React.DragEvent<HTMLDivElement>) => {\n if (isValidDropTarget) {\n e.preventDefault();\n e.dataTransfer.dropEffect =\n draggedItem?.operation === \"copy\" ? \"copy\" : \"move\";\n }\n };\n\n const handleDragEnter = (e: React.DragEvent<HTMLDivElement>) => {\n if (isValidDropTarget) {\n e.preventDefault();\n }\n };\n\n const handleDragLeave = () => {};\n\n const handleDrop = (e: React.DragEvent<HTMLDivElement>) => {\n e.preventDefault();\n if (isValidDropTarget) {\n onDrop?.(folder);\n }\n };\n\n const handleContextMenu = (e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n onContextMenu?.(folder, e.clientX, e.clientY);\n };\n\n const FolderIcon = isHovered ? FolderOpen : Folder;\n\n // Memoize menu items to prevent re-renders\n const menuItems = useMemo(\n () => [\n ...(onShare\n ? [\n {\n label: tWithFallback(t, \"files.card.share\", \"Share\"),\n icon: <Share2 className=\"size-4\" />,\n onClick: () => onShare(folder),\n },\n ]\n : []),\n ...(onCopy\n ? [\n {\n label: tWithFallback(t, \"files.card.makeCopy\", \"Make a copy\"),\n icon: <Copy className=\"size-4\" />,\n onClick: () => onCopy(folder),\n },\n ]\n : []),\n ...(onMove\n ? [\n {\n label: tWithFallback(t, \"files.card.moveTo\", \"Move to\"),\n icon: <FolderInput className=\"size-4\" />,\n onClick: () => onMove(folder),\n },\n ]\n : []),\n ...(onRename\n ? [\n {\n label: tWithFallback(t, \"files.card.rename\", \"Rename\"),\n icon: <Edit className=\"size-4\" />,\n onClick: () => onRename(folder),\n divider: true,\n },\n ]\n : []),\n ...(onFavorite\n ? [\n {\n label: folder.starred\n ? tWithFallback(\n t,\n \"files.card.removeFromStarred\",\n \"Remove from starred\",\n )\n : tWithFallback(t, \"files.card.addToStarred\", \"Add to starred\"),\n icon: <Star className=\"size-4\" />,\n onClick: () => onFavorite(folder),\n },\n ]\n : []),\n ...(onInfo\n ? [\n {\n label: tWithFallback(t, \"files.card.details\", \"Details\"),\n icon: <Info className=\"size-4\" />,\n onClick: () => onInfo(folder),\n },\n ]\n : []),\n ...(onActivity\n ? [\n {\n label: tWithFallback(t, \"files.card.activity\", \"Activity\"),\n icon: <Activity className=\"size-4\" />,\n onClick: () => onActivity(folder),\n },\n ]\n : []),\n ...(onDelete\n ? [\n {\n label: tWithFallback(t, \"files.card.delete\", \"Delete\"),\n icon: <Trash2 className=\"size-4\" />,\n onClick: () => onDelete(folder),\n variant: \"danger\" as const,\n divider: true,\n },\n ]\n : []),\n ...(onRestore\n ? [\n {\n label: tWithFallback(t, \"files.card.restore\", \"Restore\"),\n icon: <RotateCcw className=\"size-4\" />,\n onClick: () => onRestore(folder),\n },\n ]\n : []),\n ],\n [\n folder,\n onShare,\n onCopy,\n onMove,\n onRename,\n onFavorite,\n onInfo,\n onActivity,\n onDelete,\n onRestore,\n t,\n ],\n );\n\n return (\n <div\n className={`@container group relative cursor-pointer overflow-hidden rounded-card border bg-bg-surface shadow-elevation-1 transition-shadow hover:shadow-elevation-2 focus-within:shadow-elevation-2 ${isDragging ? \"opacity-50\" : \"\"} ${isValidDropTarget ? \"border-action-primary-bg ring-2 ring-action-primary-bg ring-offset-2\" : \"border-border-subtle\"}`}\n onClick={handleClick}\n onContextMenu={handleContextMenu}\n onMouseEnter={() => {\n setShowActions(true);\n setIsHovered(true);\n }}\n onMouseLeave={() => {\n setShowActions(false);\n setIsHovered(false);\n }}\n onFocus={() => {\n setShowActions(true);\n setIsHovered(true);\n }}\n onBlur={(event) => {\n if (!event.currentTarget.contains(event.relatedTarget)) {\n setShowActions(false);\n setIsHovered(false);\n }\n }}\n onKeyDown={(event) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n handleClick();\n }\n }}\n draggable={Boolean(onDragStart)}\n onDragStart={handleDragStart}\n onDragEnd={handleDragEnd}\n onDragOver={handleDragOver}\n onDragEnter={handleDragEnter}\n onDragLeave={handleDragLeave}\n onDrop={handleDrop}\n role=\"button\"\n tabIndex={0}\n aria-label={`${tWithFallback(t, \"files.browser.openFolder\", \"Open folder\")} ${folder.name}`}\n >\n {/* Selection checkbox */}\n <div\n className={`absolute top-2 left-2 z-10 transition-opacity ${\n isSelected\n ? \"opacity-100\"\n : \"opacity-0 group-hover:opacity-100 group-focus-within:opacity-100\"\n }`}\n >\n <input\n type=\"checkbox\"\n checked={isSelected}\n onChange={handleCheckboxChange}\n className=\"size-4 rounded border-border-default bg-bg-surface text-action-primary-bg focus:ring-2 focus:ring-action-primary-bg focus:ring-offset-2\"\n aria-label={`Select ${folder.name}`}\n />\n </div>\n\n {/* Favorite indicator */}\n {folder.starred && (\n <div className=\"absolute top-2 right-2 z-10\">\n <Star className=\"size-4 fill-yellow-400 text-yellow-400\" />\n </div>\n )}\n\n {/* Folder icon section */}\n <div className=\"aspect-[4/3] bg-bg-sunken flex items-center justify-center\">\n <FolderIcon className=\"size-10 @md:size-14 text-action-primary-bg\" />\n </div>\n\n {/* Folder info */}\n <div className=\"p-3 @md:p-4\">\n <div className=\"flex items-center justify-between gap-2 mb-1\">\n <h3 className=\"font-text-md font-weight-medium text-text-primary truncate flex-1\">\n {folder.name}\n </h3>\n <ChevronRight className=\"size-4 text-text-muted flex-shrink-0\" />\n </div>\n\n <div className=\"flex items-center gap-2 text-text-secondary font-text-sm\">\n <span>\n {folder.filesCount ?? 0}{\" \"}\n {(folder.filesCount ?? 0) === 1\n ? tWithFallback(t, \"files.folder.item\", \"item\")\n : tWithFallback(t, \"files.browser.items\", \"items\")}\n </span>\n <span className=\"hidden @sm:inline text-border-subtle\">•</span>\n <span className=\"hidden @sm:inline\">\n {formatFileDate(folder.updatedAt)}\n </span>\n </div>\n\n {/* Extended metadata on larger containers */}\n {folder.createdBy && (\n <div className=\"hidden @md:flex items-center gap-2 mt-2 text-text-muted font-text-xs\">\n <div className=\"flex items-center gap-1\">\n {folder.createdBy.avatar && (\n <img\n src={folder.createdBy.avatar}\n alt={folder.createdBy.name}\n className=\"size-4 rounded-full\"\n />\n )}\n <span>{folder.createdBy.name}</span>\n </div>\n </div>\n )}\n </div>\n\n {/* Action buttons (on hover) with dropdown menu */}\n {showActions && (\n <div className=\"absolute bottom-3 right-3 flex items-center gap-1 bg-bg-elevated border border-border-subtle rounded shadow-elevation-2 p-1\">\n {onShare && (\n <button\n onClick={(e) => handleActionClick(e, () => onShare(folder))}\n className=\"p-1.5 hover:bg-action-ghost-bg-hover rounded transition-colors\"\n aria-label={tWithFallback(t, \"files.card.share\", \"Share\")}\n title={tWithFallback(t, \"files.card.share\", \"Share\")}\n >\n <Share2 className=\"size-4 text-text-primary\" />\n </button>\n )}\n\n {onRename && (\n <button\n onClick={(e) => handleActionClick(e, () => onRename(folder))}\n className=\"p-1.5 hover:bg-action-ghost-bg-hover rounded transition-colors\"\n aria-label={tWithFallback(t, \"files.card.rename\", \"Rename\")}\n title={tWithFallback(t, \"files.card.rename\", \"Rename\")}\n >\n <Edit className=\"size-4 text-text-primary\" />\n </button>\n )}\n\n {onRestore && (\n <button\n onClick={(e) => handleActionClick(e, () => onRestore(folder))}\n className=\"p-1.5 hover:bg-status-success-bg-subtle rounded transition-colors\"\n aria-label={tWithFallback(t, \"files.card.restore\", \"Restore\")}\n title={tWithFallback(t, \"files.card.restore\", \"Restore\")}\n >\n <RotateCcw className=\"size-4 text-status-success-text\" />\n </button>\n )}\n\n {/* More options dropdown */}\n <div onClick={(e) => e.stopPropagation()}>\n <ActionMenu\n items={menuItems}\n align=\"right\"\n triggerClassName=\"p-1.5\"\n isOpen={menuOpen}\n onToggle={setMenuOpen}\n />\n </div>\n </div>\n )}\n </div>\n );\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"FolderCard.js","names":[],"sources":["../../../src/files/components/FolderCard.tsx"],"sourcesContent":["import { type FC, useState, useMemo } from \"react\";\nimport {\n Folder,\n FolderOpen,\n Share2,\n Trash2,\n Edit,\n ChevronRight,\n FolderInput,\n Info,\n Activity,\n Star,\n RotateCcw,\n} from \"lucide-react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport type { FolderItem } from \"../types\";\nimport { formatFileDate } from \"../utils\";\nimport { useFilesStore } from \"../store/filesStore\";\nimport { ActionMenu } from \"./ActionMenu\";\nimport { getDragOperation, canDropOnFolder } from \"../hooks/useDragDrop\";\nimport { tWithFallback } from \"../utils/i18n\";\nimport type { DragData } from \"../hooks/useDragDrop\";\n\ninterface FolderCardProps {\n folder: FolderItem;\n isSelected?: boolean;\n isDragging?: boolean;\n isDropTarget?: boolean;\n draggedItem?: DragData | null;\n onSelect?: (folderId: string) => void;\n onOpen?: (folder: FolderItem) => void;\n onShare?: (folder: FolderItem) => void;\n onDelete?: (folder: FolderItem) => void;\n onRestore?: (folder: FolderItem) => void;\n onRename?: (folder: FolderItem) => void;\n onFavorite?: (folder: FolderItem) => void;\n onCopy?: (folder: FolderItem) => void;\n onMove?: (folder: FolderItem) => void;\n onInfo?: (folder: FolderItem) => void;\n onActivity?: (folder: FolderItem) => void;\n onDragStart?: (folder: FolderItem, operation: \"move\" | \"copy\") => void;\n onDragEnd?: () => void;\n onDrop?: (folder: FolderItem) => void;\n onContextMenu?: (folder: FolderItem, x: number, y: number) => void;\n}\n\ninterface DraggableFolderCardProps extends Omit<\n FolderCardProps,\n \"onDragStart\" | \"onDragEnd\" | \"onDrop\"\n> {\n onDragStart?: (folder: FolderItem, operation: \"move\" | \"copy\") => void;\n onDragEnd?: () => void;\n onDrop?: (folder: FolderItem) => void;\n onContextMenu?: (folder: FolderItem, x: number, y: number) => void;\n}\n\nexport const FolderCard: FC<DraggableFolderCardProps> = ({\n folder,\n isSelected = false,\n isDragging = false,\n isDropTarget = false,\n draggedItem = null,\n onSelect,\n onOpen,\n onShare,\n onDelete,\n onRestore,\n onRename,\n onFavorite,\n onCopy: _onCopy,\n onMove,\n onInfo,\n onActivity,\n onDragStart,\n onDragEnd,\n onDrop,\n onContextMenu,\n}) => {\n const { t } = useI18n();\n const [isHovered, setIsHovered] = useState(false);\n const [menuOpen, setMenuOpen] = useState(false);\n const { toggleFolderSelection } = useFilesStore();\n\n const canDrop = canDropOnFolder(draggedItem, folder);\n const isValidDropTarget = isDropTarget && canDrop;\n\n const filesCount = folder.filesCount ?? 0;\n const subfoldersCount = folder.subfoldersCount ?? 0;\n const totalItems = filesCount + subfoldersCount;\n\n const handleClick = () => {\n if (onOpen) {\n onOpen(folder);\n }\n };\n\n const handleCheckboxChange = (e: React.ChangeEvent<HTMLInputElement>) => {\n e.stopPropagation();\n if (onSelect) {\n onSelect(folder.id);\n } else {\n toggleFolderSelection(folder.id);\n }\n };\n\n const handleActionClick = (e: React.MouseEvent, action: () => void) => {\n e.stopPropagation();\n action();\n };\n\n const handleDragStart = (e: React.DragEvent<HTMLDivElement>) => {\n e.dataTransfer.effectAllowed = \"copyMove\";\n e.dataTransfer.setData(\"application/x-file-id\", folder.id);\n e.dataTransfer.setData(\"application/x-file-type\", \"folder\");\n const operation = getDragOperation(e);\n e.dataTransfer.setData(\"application/x-drag-operation\", operation);\n onDragStart?.(folder, operation);\n };\n\n const handleDragEnd = () => {\n onDragEnd?.();\n };\n\n const handleDragOver = (e: React.DragEvent<HTMLDivElement>) => {\n if (isValidDropTarget) {\n e.preventDefault();\n e.dataTransfer.dropEffect =\n draggedItem?.operation === \"copy\" ? \"copy\" : \"move\";\n }\n };\n\n const handleDragEnter = (e: React.DragEvent<HTMLDivElement>) => {\n if (isValidDropTarget) {\n e.preventDefault();\n }\n };\n\n const handleDragLeave = () => {};\n\n const handleDrop = (e: React.DragEvent<HTMLDivElement>) => {\n e.preventDefault();\n if (isValidDropTarget) {\n onDrop?.(folder);\n }\n };\n\n const handleContextMenu = (e: React.MouseEvent) => {\n e.preventDefault();\n e.stopPropagation();\n onContextMenu?.(folder, e.clientX, e.clientY);\n };\n\n const FolderIcon = isHovered ? FolderOpen : Folder;\n\n const menuItems = useMemo(\n () => [\n ...(onShare\n ? [\n {\n label: tWithFallback(t, \"files.card.share\", \"Share\"),\n icon: <Share2 className=\"size-4\" />,\n onClick: () => onShare(folder),\n },\n ]\n : []),\n ...(onMove\n ? [\n {\n label: tWithFallback(t, \"files.card.moveTo\", \"Move to\"),\n icon: <FolderInput className=\"size-4\" />,\n onClick: () => onMove(folder),\n },\n ]\n : []),\n ...(onRename\n ? [\n {\n label: tWithFallback(t, \"files.card.rename\", \"Rename\"),\n icon: <Edit className=\"size-4\" />,\n onClick: () => onRename(folder),\n divider: true,\n },\n ]\n : []),\n ...(onFavorite\n ? [\n {\n label: folder.starred\n ? tWithFallback(\n t,\n \"files.card.removeFromStarred\",\n \"Remove from starred\",\n )\n : tWithFallback(t, \"files.card.addToStarred\", \"Add to starred\"),\n icon: <Star className=\"size-4\" />,\n onClick: () => onFavorite(folder),\n },\n ]\n : []),\n ...(onInfo\n ? [\n {\n label: tWithFallback(t, \"files.card.details\", \"Details\"),\n icon: <Info className=\"size-4\" />,\n onClick: () => onInfo(folder),\n },\n ]\n : []),\n ...(onActivity\n ? [\n {\n label: tWithFallback(t, \"files.card.activity\", \"Activity\"),\n icon: <Activity className=\"size-4\" />,\n onClick: () => onActivity(folder),\n },\n ]\n : []),\n ...(onDelete\n ? [\n {\n label: tWithFallback(t, \"files.card.delete\", \"Delete\"),\n icon: <Trash2 className=\"size-4\" />,\n onClick: () => onDelete(folder),\n variant: \"danger\" as const,\n divider: true,\n },\n ]\n : []),\n ...(onRestore\n ? [\n {\n label: tWithFallback(t, \"files.card.restore\", \"Restore\"),\n icon: <RotateCcw className=\"size-4\" />,\n onClick: () => onRestore(folder),\n },\n ]\n : []),\n ],\n [\n folder,\n onShare,\n onMove,\n onRename,\n onFavorite,\n onInfo,\n onActivity,\n onDelete,\n onRestore,\n t,\n ],\n );\n\n return (\n <div\n className={`group relative cursor-pointer rounded-card border bg-bg-surface shadow-elevation-1 transition-all hover:shadow-elevation-2 focus-within:shadow-elevation-2 ${\n isDragging ? \"opacity-50\" : \"\"\n } ${\n isValidDropTarget\n ? \"border-action-primary-bg ring-2 ring-action-primary-bg ring-offset-2\"\n : isSelected\n ? \"border-action-primary-bg bg-bg-accent\"\n : \"border-border-subtle\"\n }`}\n onClick={handleClick}\n onContextMenu={handleContextMenu}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => {\n if (!menuOpen) setIsHovered(false);\n }}\n onFocus={() => setIsHovered(true)}\n onBlur={(event) => {\n if (!event.currentTarget.contains(event.relatedTarget) && !menuOpen) {\n setIsHovered(false);\n }\n }}\n onKeyDown={(event) => {\n if (event.key === \"Enter\" || event.key === \" \") {\n event.preventDefault();\n handleClick();\n }\n }}\n draggable={Boolean(onDragStart)}\n onDragStart={handleDragStart}\n onDragEnd={handleDragEnd}\n onDragOver={handleDragOver}\n onDragEnter={handleDragEnter}\n onDragLeave={handleDragLeave}\n onDrop={handleDrop}\n role=\"button\"\n tabIndex={0}\n aria-label={`${tWithFallback(t, \"files.browser.openFolder\", \"Open folder\")} ${folder.name}`}\n >\n <div className=\"flex items-center gap-3 p-3\">\n {/* Selection checkbox */}\n <div\n className={`flex-shrink-0 transition-opacity ${\n isSelected\n ? \"opacity-100\"\n : \"opacity-0 group-hover:opacity-100 group-focus-within:opacity-100\"\n }`}\n onClick={(e) => e.stopPropagation()}\n >\n <input\n type=\"checkbox\"\n checked={isSelected}\n onChange={handleCheckboxChange}\n className=\"size-4 rounded border-border-default bg-bg-surface text-action-primary-bg focus:ring-2 focus:ring-action-primary-bg focus:ring-offset-2\"\n aria-label={`Select ${folder.name}`}\n />\n </div>\n\n {/* Folder icon */}\n <div className=\"flex-shrink-0 flex items-center justify-center size-10 rounded-lg bg-action-primary-bg/10\">\n <FolderIcon className=\"size-5 text-action-primary-bg\" />\n </div>\n\n {/* Folder info */}\n <div className=\"flex-1 min-w-0 pr-1\">\n <div className=\"flex items-center gap-1.5\">\n <span className=\"text-sm font-medium text-text-primary truncate\">\n {folder.name}\n </span>\n {folder.starred && (\n <Star className=\"size-3 flex-shrink-0 fill-yellow-400 text-yellow-400\" />\n )}\n </div>\n <div className=\"flex items-center gap-1 mt-0.5 text-xs text-text-secondary\">\n {subfoldersCount > 0 && (\n <>\n <span>\n {subfoldersCount}{\" \"}\n {subfoldersCount === 1\n ? tWithFallback(t, \"files.folder.subfolder\", \"folder\")\n : tWithFallback(t, \"files.folder.subfolders\", \"folders\")}\n </span>\n {filesCount > 0 && (\n <span className=\"text-border-subtle\">·</span>\n )}\n </>\n )}\n {filesCount > 0 && (\n <span>\n {filesCount}{\" \"}\n {filesCount === 1\n ? tWithFallback(t, \"files.folder.file\", \"file\")\n : tWithFallback(t, \"files.folder.files\", \"files\")}\n </span>\n )}\n {totalItems === 0 && (\n <span>{tWithFallback(t, \"files.folder.empty\", \"Empty\")}</span>\n )}\n <span className=\"text-border-subtle\">·</span>\n <span className=\"truncate\">{formatFileDate(folder.updatedAt)}</span>\n </div>\n </div>\n\n {/* Right-side actions — always reserve space so layout is stable */}\n <div className=\"flex-shrink-0 flex items-center gap-1\">\n {isHovered && onRestore && (\n <button\n type=\"button\"\n onClick={(e) => handleActionClick(e, () => onRestore(folder))}\n className=\"p-1.5 hover:bg-status-success-bg-subtle rounded transition-colors\"\n aria-label={tWithFallback(t, \"files.card.restore\", \"Restore\")}\n title={tWithFallback(t, \"files.card.restore\", \"Restore\")}\n >\n <RotateCcw className=\"size-4 text-status-success-text\" />\n </button>\n )}\n {isHovered && onShare && (\n <button\n onClick={(e) => handleActionClick(e, () => onShare(folder))}\n className=\"p-1.5 hover:bg-action-ghost-bg-hover rounded transition-colors\"\n aria-label={tWithFallback(t, \"files.card.share\", \"Share\")}\n title={tWithFallback(t, \"files.card.share\", \"Share\")}\n >\n <Share2 className=\"size-4 text-text-secondary\" />\n </button>\n )}\n {isHovered && onRename && (\n <button\n onClick={(e) => handleActionClick(e, () => onRename(folder))}\n className=\"p-1.5 hover:bg-action-ghost-bg-hover rounded transition-colors\"\n aria-label={tWithFallback(t, \"files.card.rename\", \"Rename\")}\n title={tWithFallback(t, \"files.card.rename\", \"Rename\")}\n >\n <Edit className=\"size-4 text-text-secondary\" />\n </button>\n )}\n <div onClick={(e) => e.stopPropagation()}>\n <ActionMenu\n items={menuItems}\n align=\"right\"\n triggerClassName={\n !isHovered && !menuOpen\n ? \"opacity-0 group-hover:opacity-100\"\n : \"\"\n }\n isOpen={menuOpen}\n onToggle={(open) => {\n setMenuOpen(open);\n if (open) setIsHovered(true);\n }}\n />\n </div>\n </div>\n\n {/* Navigate-into arrow */}\n <ChevronRight className=\"flex-shrink-0 size-4 text-text-muted opacity-0 group-hover:opacity-100 transition-opacity\" />\n </div>\n </div>\n );\n};\n"],"mappings":"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"}
@@ -6,19 +6,19 @@ import { jsx as c, jsxs as l } from "react/jsx-runtime";
6
6
  import { useI18n as u } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
7
7
  //#region src/files/components/MoveDialog.tsx
8
8
  var d = ({ item: d, type: f, onClose: p, onMove: m, isLoading: h = !1 }) => {
9
- let { t: g } = u(), [_, v] = n(null), [y, b] = n([]), [x, S] = n(null), { data: C, loading: w } = t(_ || void 0), T = C?.getFolders?.folders || [], E = (e) => {
9
+ let { t: g } = u(), [_, v] = n(null), [y, b] = n([]), [x, S] = n(void 0), { data: C, loading: w } = t(_ || void 0), T = C?.getFolders?.folders || [], E = (e) => {
10
10
  v(e.id), b([...y, {
11
11
  id: e.id,
12
12
  name: e.name
13
- }]);
13
+ }]), S(e.id);
14
14
  }, D = (e) => {
15
- if (e === -1) v(null), b([]);
15
+ if (e === -1) v(null), b([]), S(null);
16
16
  else {
17
17
  let t = y[e];
18
- v(t.id), b(y.slice(0, e + 1));
18
+ v(t.id), b(y.slice(0, e + 1)), S(t.id);
19
19
  }
20
20
  }, O = async () => {
21
- x !== d.id && (await m(x), p());
21
+ x === void 0 || x === d.id || (await m(x), p());
22
22
  }, k = T.filter((e) => !(f === "folder" && e.id === d.id));
23
23
  return /* @__PURE__ */ c("div", {
24
24
  className: "fixed inset-0 backdrop-blur-sm flex items-center justify-center z-[100] animate-in fade-in duration-200",
@@ -37,6 +37,7 @@ var d = ({ item: d, type: f, onClose: p, onMove: m, isLoading: h = !1 }) => {
37
37
  className: "text-lg font-semibold text-text-primary",
38
38
  children: e(g, "files.moveDialog.title", "Move \"{{name}}\"", { name: d.name })
39
39
  }), /* @__PURE__ */ c("button", {
40
+ type: "button",
40
41
  onClick: p,
41
42
  className: "p-1 text-text-tertiary hover:text-text-secondary hover:bg-action-ghost-bg-hover rounded transition-colors duration-200",
42
43
  "aria-label": e(g, "files.moveDialog.actions.close", "Close move dialog"),
@@ -48,12 +49,14 @@ var d = ({ item: d, type: f, onClose: p, onMove: m, isLoading: h = !1 }) => {
48
49
  children: /* @__PURE__ */ l("div", {
49
50
  className: "flex items-center gap-2 text-sm overflow-x-auto",
50
51
  children: [/* @__PURE__ */ l("button", {
52
+ type: "button",
51
53
  onClick: () => D(-1),
52
54
  className: "flex items-center gap-1.5 text-text-primary hover:bg-action-ghost-bg-hover px-2 py-1 rounded transition-colors duration-200 whitespace-nowrap",
53
55
  children: [/* @__PURE__ */ c(a, { className: "size-4" }), /* @__PURE__ */ c("span", { children: e(g, "files.browser.rootLabel", "My Drive") })]
54
56
  }), y.map((e, t) => /* @__PURE__ */ l("div", {
55
57
  className: "flex items-center gap-2 whitespace-nowrap",
56
58
  children: [/* @__PURE__ */ c(r, { className: "size-4 text-text-tertiary" }), /* @__PURE__ */ c("button", {
59
+ type: "button",
57
60
  onClick: () => D(t),
58
61
  className: `hover:bg-action-ghost-bg-hover px-2 py-1 rounded transition-colors duration-200 ${t === y.length - 1 ? "text-text-primary font-medium" : "text-text-secondary"}`,
59
62
  children: e.name
@@ -66,24 +69,23 @@ var d = ({ item: d, type: f, onClose: p, onMove: m, isLoading: h = !1 }) => {
66
69
  children: w ? /* @__PURE__ */ c("div", {
67
70
  className: "flex items-center justify-center py-8",
68
71
  children: /* @__PURE__ */ c(o, { className: "size-6 text-text-tertiary animate-spin" })
69
- }) : k.length === 0 ? /* @__PURE__ */ l("div", {
70
- className: "text-center py-8",
71
- children: [/* @__PURE__ */ c(i, { className: "size-12 text-text-tertiary mx-auto mb-3" }), /* @__PURE__ */ c("p", {
72
- className: "text-sm text-text-secondary",
73
- children: e(g, "files.moveDialog.empty.noFolders", "No folders here")
74
- })]
75
72
  }) : /* @__PURE__ */ l("div", {
76
73
  className: "space-y-1",
77
74
  children: [/* @__PURE__ */ l("button", {
75
+ type: "button",
78
76
  onClick: () => S(_),
79
77
  className: `w-full flex items-center gap-3 px-3 py-2.5 rounded-lg text-left transition-all duration-200 ${x === _ ? "bg-bg-accent border-2 border-action-primary-border" : "hover:bg-action-ghost-bg-hover border-2 border-transparent"}`,
80
78
  children: [/* @__PURE__ */ c(i, { className: "size-5 text-text-link" }), /* @__PURE__ */ c("span", {
81
79
  className: "font-medium text-text-primary",
82
80
  children: e(g, "files.moveDialog.actions.moveHere", "Move here")
83
81
  })]
84
- }), k.map((t) => /* @__PURE__ */ l("div", {
82
+ }), k.length === 0 ? /* @__PURE__ */ c("p", {
83
+ className: "text-sm text-text-secondary text-center py-4",
84
+ children: e(g, "files.moveDialog.empty.noSubfolders", "No subfolders")
85
+ }) : k.map((t) => /* @__PURE__ */ l("div", {
85
86
  className: `flex items-center justify-between gap-3 px-3 py-2.5 rounded-lg transition-all duration-200 ${x === t.id ? "bg-bg-accent border-2 border-action-primary-border" : "hover:bg-action-ghost-bg-hover border-2 border-transparent"}`,
86
87
  children: [/* @__PURE__ */ l("button", {
88
+ type: "button",
87
89
  onClick: () => S(t.id),
88
90
  className: "flex items-center gap-3 flex-1 min-w-0",
89
91
  children: [/* @__PURE__ */ c(i, { className: "size-5 text-text-link flex-shrink-0" }), /* @__PURE__ */ c("span", {
@@ -91,6 +93,7 @@ var d = ({ item: d, type: f, onClose: p, onMove: m, isLoading: h = !1 }) => {
91
93
  children: t.name
92
94
  })]
93
95
  }), /* @__PURE__ */ c("button", {
96
+ type: "button",
94
97
  onClick: () => E(t),
95
98
  className: "p-1.5 text-text-tertiary hover:text-text-secondary hover:bg-action-ghost-bg-hover rounded transition-colors duration-200 flex-shrink-0",
96
99
  title: e(g, "files.moveDialog.actions.openFolder", "Open folder"),
@@ -103,10 +106,12 @@ var d = ({ item: d, type: f, onClose: p, onMove: m, isLoading: h = !1 }) => {
103
106
  /* @__PURE__ */ l("div", {
104
107
  className: "flex items-center justify-end gap-2 px-6 py-4 border-t border-border-default",
105
108
  children: [/* @__PURE__ */ c("button", {
109
+ type: "button",
106
110
  onClick: p,
107
111
  className: "px-4 py-2 text-sm font-medium text-text-primary hover:bg-action-ghost-bg-hover rounded-lg transition-colors duration-200",
108
112
  children: e(g, "files.common.actions.cancel", "Cancel")
109
113
  }), /* @__PURE__ */ l("button", {
114
+ type: "button",
110
115
  onClick: O,
111
116
  disabled: h || x === void 0,
112
117
  className: "px-4 py-2 text-sm font-medium text-text-inverse bg-action-primary-bg rounded-lg hover:bg-action-primary-bg-hover disabled:bg-bg-muted disabled:text-text-tertiary disabled:cursor-not-allowed transition-colors duration-200 flex items-center gap-2",