@openrails/contentkit-ui 0.103.1 → 0.103.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 (48) hide show
  1. package/dist/components/admin/content-manager.d.ts +1 -1
  2. package/dist/components/admin/content-manager.js +346 -304
  3. package/dist/components/admin/content-manager.js.map +1 -1
  4. package/dist/components/admin/page-review.js +106 -97
  5. package/dist/components/admin/page-review.js.map +1 -1
  6. package/dist/components/admin/reader-content-editor.d.ts +6 -0
  7. package/dist/components/admin/reader-content-editor.js +709 -0
  8. package/dist/components/admin/reader-content-editor.js.map +1 -0
  9. package/dist/components/admin/reader-manifest.js +120 -105
  10. package/dist/components/admin/reader-manifest.js.map +1 -1
  11. package/dist/components/content/editor-save.d.ts +32 -0
  12. package/dist/components/content/editor-save.js +51 -0
  13. package/dist/components/content/editor-save.js.map +1 -0
  14. package/dist/components/content/editors.d.ts +17 -2
  15. package/dist/components/content/editors.js +359 -328
  16. package/dist/components/content/editors.js.map +1 -1
  17. package/dist/components/content/offer-fields.d.ts +1 -1
  18. package/dist/components/content/offer-fields.js +86 -64
  19. package/dist/components/content/offer-fields.js.map +1 -1
  20. package/dist/components/groups/memberships.d.ts +11 -1
  21. package/dist/components/groups/memberships.js +1 -1
  22. package/dist/components/groups/memberships.js.map +1 -1
  23. package/dist/components/media-folder-editor.d.ts +4 -0
  24. package/dist/components/media-folder-editor.js +177 -167
  25. package/dist/components/media-folder-editor.js.map +1 -1
  26. package/dist/index.js +1 -1
  27. package/dist/locales/admin/de.js +25 -0
  28. package/dist/locales/admin/de.js.map +1 -1
  29. package/dist/locales/admin/en.d.ts +25 -0
  30. package/dist/locales/admin/en.js +25 -0
  31. package/dist/locales/admin/en.js.map +1 -1
  32. package/dist/locales/admin/es.js +25 -0
  33. package/dist/locales/admin/es.js.map +1 -1
  34. package/dist/locales/admin/ja.js +25 -0
  35. package/dist/locales/admin/ja.js.map +1 -1
  36. package/dist/locales/admin/ko.js +25 -0
  37. package/dist/locales/admin/ko.js.map +1 -1
  38. package/dist/locales/admin/zh.js +25 -0
  39. package/dist/locales/admin/zh.js.map +1 -1
  40. package/dist/locales/en.d.ts +25 -0
  41. package/dist/react/page-review.d.ts +1 -1
  42. package/dist/react/page-review.js +6 -5
  43. package/dist/react/page-review.js.map +1 -1
  44. package/dist/react/use-draft.d.ts +8 -0
  45. package/dist/react/use-draft.js +35 -0
  46. package/dist/react/use-draft.js.map +1 -0
  47. package/dist/styles.css +1 -1
  48. package/package.json +1 -1
@@ -11,12 +11,12 @@ import { isProcessing as u } from "../client/media/windows.js";
11
11
  import { Alert as d, AlertDescription as f, AlertTitle as p } from "../ui/alert.js";
12
12
  import { Button as m } from "../ui/button.js";
13
13
  import { progressLabel as h, progressValue as g } from "./progress.js";
14
- import { ImageCropDialog as _ } from "./image-crop-dialog.js";
15
- import { isAudioType as v, isImageType as y, isSubtitleType as b, isVideoType as x } from "../client/gallery.js";
16
- import { useEditorCrop as S } from "../react/crop.js";
17
- import { nameIn as C, thumbnailOf as w, useMediaFolder as T } from "../react/folder.js";
18
- import { SortableList as E } from "./sortable-list.js";
19
- import { useEffect as D, useImperativeHandle as ee, useMemo as O, useRef as te, useState as k } from "react";
14
+ import { ImageCropDialog as ee } from "./image-crop-dialog.js";
15
+ import { isAudioType as _, isImageType as v, isSubtitleType as y, isVideoType as b } from "../client/gallery.js";
16
+ import { useEditorCrop as x } from "../react/crop.js";
17
+ import { nameIn as S, thumbnailOf as C, useMediaFolder as w } from "../react/folder.js";
18
+ import { SortableList as T } from "./sortable-list.js";
19
+ import { useEffect as E, useImperativeHandle as D, useMemo as O, useRef as te, useState as k } from "react";
20
20
  import { Fragment as A, jsx as j, jsxs as M } from "react/jsx-runtime";
21
21
  import { cn as N } from "cn";
22
22
  import { Alert02Icon as P, CropIcon as F, Delete02Icon as I, Edit02Icon as L, File01Icon as R, Image01Icon as z, ImageAdd01Icon as ne, Loading03Icon as re, MusicNote01Icon as B, Refresh01Icon as V, RepeatIcon as H, Video01Icon as U } from "@hugeicons/core-free-icons";
@@ -29,7 +29,7 @@ var ie = [
29
29
  "16:9"
30
30
  ];
31
31
  function G(e) {
32
- return y(e) ? "image" : x(e) ? "video" : v(e) ? "audio" : b(e) ? "subtitle" : "file";
32
+ return v(e) ? "image" : b(e) ? "video" : _(e) ? "audio" : y(e) ? "subtitle" : "file";
33
33
  }
34
34
  var K = {
35
35
  image: z,
@@ -57,67 +57,69 @@ function ae(e, t) {
57
57
  }
58
58
  return n.join(" · ");
59
59
  }
60
- function oe(e) {
60
+ function J(e) {
61
61
  if (e.folder) {
62
62
  let { folder: n, ...r } = e;
63
- return /* @__PURE__ */ j(J, {
63
+ return /* @__PURE__ */ j(X, {
64
64
  folder: n,
65
65
  ...r
66
66
  }, n.ref ? t(n.ref) : "");
67
67
  }
68
- return /* @__PURE__ */ j(se, { ...e }, t(e.item));
68
+ return /* @__PURE__ */ j(Y, { ...e }, t(e.item));
69
69
  }
70
- function se(e) {
71
- let { item: t, ref: n, label: r, toolbar: i, rowActions: a, footer: o, aspects: s, confirmRemove: c, disabled: l, className: u, appearance: d, ...f } = e, p = T(t, f);
72
- return /* @__PURE__ */ j(J, {
73
- folder: p,
70
+ function Y(e) {
71
+ let { item: t, ref: n, label: r, layout: i, inputLabel: a, toolbar: o, rowActions: s, footer: c, aspects: l, confirmRemove: u, disabled: d, className: f, appearance: p, ...m } = e, h = w(t, m);
72
+ return /* @__PURE__ */ j(X, {
73
+ folder: h,
74
74
  ref: n,
75
75
  label: r,
76
- toolbar: i,
77
- rowActions: a,
78
- footer: o,
79
- aspects: s,
80
- confirmRemove: c,
81
- disabled: l,
82
- className: u,
83
- appearance: d
76
+ layout: i,
77
+ inputLabel: a,
78
+ toolbar: o,
79
+ rowActions: s,
80
+ footer: c,
81
+ aspects: l,
82
+ confirmRemove: u,
83
+ disabled: d,
84
+ className: f,
85
+ appearance: p
84
86
  });
85
87
  }
86
- var ce = {
88
+ var oe = {
87
89
  kind: "",
88
90
  id: ""
89
91
  };
90
- function J(e) {
91
- let { folder: t, ref: n, label: i, toolbar: a, rowActions: c, footer: l, aspects: u = ie, confirmRemove: h, disabled: g, className: v, appearance: y } = e, { t: b, error: x } = o(), { groups: C, queue: w, read: T, options: O } = t;
92
- ee(n, () => ({
92
+ function X(e) {
93
+ let { folder: t, ref: n, label: i, layout: a, inputLabel: c, toolbar: l, rowActions: u, footer: h, aspects: g = ie, confirmRemove: _, disabled: v, className: y, appearance: b } = e, { t: S, error: C } = o(), { groups: w, queue: O, read: A, options: F } = t;
94
+ D(n, () => ({
93
95
  discard: t.discard,
94
96
  commit: t.commit,
95
97
  folder: t
96
98
  }), [t]);
97
- let A = O.commit === "auto", F = C.flatMap((e) => e.rule ? [e.rule] : []), L = r(F), R = t.uploads.length + w.items.length + t.waiting.length + t.pending.length === 0, z = !!g, [B, V] = k(/* @__PURE__ */ new Set());
98
- D(() => {
99
+ let L = F.commit === "auto", R = w.flatMap((e) => e.rule ? [e.rule] : []), z = r(R), B = t.uploads.length + O.items.length + t.waiting.length + t.pending.length === 0, V = !!v, [H, U] = k(/* @__PURE__ */ new Set());
100
+ E(() => {
99
101
  let e = new Set(t.uploads.map((e) => e.path));
100
- V((t) => [...t].every((t) => e.has(t)) ? t : new Set([...t].filter((t) => e.has(t))));
102
+ U((t) => [...t].every((t) => e.has(t)) ? t : new Set([...t].filter((t) => e.has(t))));
101
103
  }, [t.uploads]);
102
- let [H, U] = k(null), K = S(t.ref ?? ce, H, {
103
- client: O.client,
104
- onError: O.onError,
105
- onSaved: () => U(null)
106
- }), q = H ? C.find((e) => e.files.some((e) => e.path === H))?.rule : void 0, [oe, se] = k(null), J = te(null), [X, Z] = k(null), [Q, $] = k(!1), fe = {
104
+ let [K, q] = k(null), J = x(t.ref ?? oe, K, {
105
+ client: F.client,
106
+ onError: F.onError,
107
+ onSaved: () => q(null)
108
+ }), Y = K ? w.find((e) => e.files.some((e) => e.path === K))?.rule : void 0, [X, ce] = k(null), Q = te(null), [$, de] = k(null), [fe, pe] = k(!1), me = {
107
109
  onDragOver: (e) => {
108
- !z && e.dataTransfer.types.includes("Files") && (e.preventDefault(), $(!0));
110
+ !V && e.dataTransfer.types.includes("Files") && (e.preventDefault(), pe(!0));
109
111
  },
110
112
  onDragLeave: (e) => {
111
- e.currentTarget.contains(e.relatedTarget) || $(!1);
113
+ e.currentTarget.contains(e.relatedTarget) || pe(!1);
112
114
  },
113
115
  onDrop: (e) => {
114
- !z && e.dataTransfer.files.length && (e.preventDefault(), $(!1), t.add(e.dataTransfer.files));
116
+ !V && e.dataTransfer.files.length && (e.preventDefault(), pe(!1), t.add(e.dataTransfer.files));
115
117
  }
116
- }, pe = async () => {
117
- let e = [...B];
118
- (h === !1 || (h ? await h(e.length) : globalThis.confirm?.(b("folder.confirmRemove", { count: e.length })) ?? !0)) && await t.remove(e).then(() => V(/* @__PURE__ */ new Set()), () => {});
119
- }, me = w.items.filter((e) => e.status === "uploaded").length + t.pending.length, he = (e) => /* @__PURE__ */ M("label", {
120
- className: N(e ? "flex cursor-pointer flex-col items-center justify-center gap-2 rounded-lg border border-dashed border-border px-4 py-8 text-center text-sm text-muted-foreground transition-colors hover:border-primary hover:bg-primary/5" : "inline-flex h-8 cursor-pointer items-center gap-1.5 rounded-md border border-border bg-background px-2.5 text-sm font-medium transition-colors hover:bg-muted focus-within:ring-3 focus-within:ring-ring/50", e && Q && "border-primary bg-primary/5", z && "pointer-events-none opacity-50"),
118
+ }, he = async () => {
119
+ let e = [...H];
120
+ (_ === !1 || (_ ? await _(e.length) : globalThis.confirm?.(S("folder.confirmRemove", { count: e.length })) ?? !0)) && await t.remove(e).then(() => U(/* @__PURE__ */ new Set()), () => {});
121
+ }, ge = O.items.filter((e) => e.status === "uploaded").length + t.pending.length, _e = (e) => /* @__PURE__ */ M("label", {
122
+ className: N(e ? "flex cursor-pointer flex-col items-center justify-center gap-2 rounded-lg border border-dashed border-border px-4 py-8 text-center text-sm text-muted-foreground transition-colors hover:border-primary hover:bg-primary/5" : "inline-flex h-8 cursor-pointer items-center gap-1.5 rounded-md border border-border bg-background px-2.5 text-sm font-medium transition-colors hover:bg-muted focus-within:ring-3 focus-within:ring-ring/50", e && fe && "border-primary bg-primary/5", V && "pointer-events-none opacity-50"),
121
123
  "data-ckui": e ? "folder-drop" : "folder-add",
122
124
  children: [
123
125
  /* @__PURE__ */ j(W, {
@@ -127,19 +129,20 @@ function J(e) {
127
129
  }),
128
130
  e ? /* @__PURE__ */ j("strong", {
129
131
  className: "font-medium text-foreground",
130
- children: b("folder.drop")
131
- }) : b("folder.add"),
132
- e && F.length > 0 && /* @__PURE__ */ j("span", {
132
+ children: S("folder.drop")
133
+ }) : S("folder.add"),
134
+ e && R.length > 0 && /* @__PURE__ */ j("span", {
133
135
  className: "text-xs",
134
- children: ae(b, F)
136
+ children: ae(S, R)
135
137
  }),
136
138
  /* @__PURE__ */ j("input", {
137
139
  type: "file",
138
140
  multiple: !0,
139
- accept: L,
141
+ accept: z,
140
142
  className: "sr-only",
141
- disabled: z,
143
+ disabled: V,
142
144
  "data-ckui": "file",
145
+ "aria-label": c,
143
146
  onChange: (e) => {
144
147
  t.add([...e.target.files ?? []]), e.target.value = "";
145
148
  }
@@ -147,25 +150,25 @@ function J(e) {
147
150
  ]
148
151
  });
149
152
  return /* @__PURE__ */ M(s, {
150
- appearance: y,
151
- className: N("grid gap-3", v),
153
+ appearance: b,
154
+ className: N("grid gap-3", y),
152
155
  "data-ckui": "media-folder",
153
- "data-over": Q ? "" : void 0,
154
- ...fe,
156
+ "data-over": fe ? "" : void 0,
157
+ ...me,
155
158
  children: [
156
159
  /* @__PURE__ */ M("div", {
157
160
  className: "flex flex-wrap items-center justify-between gap-2",
158
161
  "data-ckui": "folder-header",
159
162
  children: [/* @__PURE__ */ j("h3", {
160
163
  className: "text-sm font-semibold",
161
- children: i ?? b("folder.label")
164
+ children: i ?? S("folder.label")
162
165
  }), /* @__PURE__ */ M("div", {
163
166
  className: "flex flex-wrap items-center gap-2",
164
- children: [a, !R && he(!1)]
167
+ children: [l, !B && _e(!1)]
165
168
  })]
166
169
  }),
167
- R && (T.read || !t.ref) && he(!0),
168
- R && !T.read && T.loading && /* @__PURE__ */ j("div", {
170
+ B && (A.read || !t.ref) && _e(!0),
171
+ B && !A.read && A.loading && /* @__PURE__ */ j("div", {
169
172
  className: "flex justify-center py-6 text-muted-foreground",
170
173
  "data-ckui": "folder-loading",
171
174
  children: /* @__PURE__ */ j(W, {
@@ -189,17 +192,17 @@ function J(e) {
189
192
  children: e.file.name
190
193
  }),
191
194
  ": ",
192
- x(e.error)
195
+ C(e.error)
193
196
  ] }, t))
194
197
  }), /* @__PURE__ */ j(m, {
195
198
  variant: "outline",
196
199
  size: "xs",
197
200
  className: "mt-1 w-fit",
198
201
  onClick: t.dismiss,
199
- children: b("folder.dismiss")
202
+ children: S("folder.dismiss")
200
203
  })] })]
201
204
  }),
202
- w.blocked && /* @__PURE__ */ M(d, {
205
+ O.blocked && /* @__PURE__ */ M(d, {
203
206
  variant: "destructive",
204
207
  role: "alert",
205
208
  "data-ckui": "folder-paused",
@@ -208,13 +211,13 @@ function J(e) {
208
211
  icon: P,
209
212
  strokeWidth: 2
210
213
  }),
211
- /* @__PURE__ */ j(p, { children: b("folder.paused") }),
212
- /* @__PURE__ */ M(f, { children: [x(w.blocked), /* @__PURE__ */ j(m, {
214
+ /* @__PURE__ */ j(p, { children: S("folder.paused") }),
215
+ /* @__PURE__ */ M(f, { children: [C(O.blocked), /* @__PURE__ */ j(m, {
213
216
  variant: "outline",
214
217
  size: "xs",
215
218
  className: "mt-1 w-fit",
216
- onClick: () => w.start(),
217
- children: b("folder.resume")
219
+ onClick: () => O.start(),
220
+ children: S("folder.resume")
218
221
  })] })
219
222
  ]
220
223
  }),
@@ -225,57 +228,58 @@ function J(e) {
225
228
  children: [/* @__PURE__ */ j(W, {
226
229
  icon: P,
227
230
  strokeWidth: 2
228
- }), /* @__PURE__ */ j(f, { children: x(t.error) })]
231
+ }), /* @__PURE__ */ j(f, { children: C(t.error) })]
229
232
  }),
230
- B.size > 0 && /* @__PURE__ */ M("div", {
233
+ H.size > 0 && /* @__PURE__ */ M("div", {
231
234
  className: "flex flex-wrap items-center gap-2 rounded-md bg-muted px-3 py-1.5 text-sm",
232
235
  "data-ckui": "folder-selection",
233
236
  children: [
234
237
  /* @__PURE__ */ j("span", {
235
238
  className: "tabular-nums",
236
- children: b("folder.selected", { count: B.size })
239
+ children: S("folder.selected", { count: H.size })
237
240
  }),
238
241
  /* @__PURE__ */ M(m, {
239
242
  variant: "destructive",
240
243
  size: "xs",
241
- disabled: z || t.updating,
242
- onClick: () => void pe(),
244
+ disabled: V || t.updating,
245
+ onClick: () => void he(),
243
246
  children: [/* @__PURE__ */ j(W, {
244
247
  icon: I,
245
248
  strokeWidth: 2
246
- }), b("folder.removeSelected")]
249
+ }), S("folder.removeSelected")]
247
250
  }),
248
251
  /* @__PURE__ */ j(m, {
249
252
  variant: "ghost",
250
253
  size: "xs",
251
- onClick: () => V(/* @__PURE__ */ new Set()),
252
- children: b("folder.clearSelection")
254
+ onClick: () => U(/* @__PURE__ */ new Set()),
255
+ children: S("folder.clearSelection")
253
256
  })
254
257
  ]
255
258
  }),
256
- C.map((e) => e.files.length ? /* @__PURE__ */ j(le, {
259
+ w.map((e) => e.files.length ? /* @__PURE__ */ j(se, {
257
260
  group: e,
258
- titled: C.length > 1,
261
+ layout: a === "grid" && e.rule?.page ? "grid" : "list",
262
+ titled: w.length > 1,
259
263
  folder: t,
260
- disabled: z,
261
- selected: B,
262
- onSelect: (e, t) => V((n) => t ? /* @__PURE__ */ new Set([...n, e]) : new Set([...n].filter((t) => t !== e))),
263
- renaming: oe,
264
- onRename: se,
265
- onCrop: U,
264
+ disabled: V,
265
+ selected: H,
266
+ onSelect: (e, t) => U((n) => t ? /* @__PURE__ */ new Set([...n, e]) : new Set([...n].filter((t) => t !== e))),
267
+ renaming: X,
268
+ onRename: ce,
269
+ onCrop: q,
266
270
  onReplace: (e) => {
267
- Z(e), J.current?.click();
271
+ de(e), Q.current?.click();
268
272
  },
269
- rowActions: c
273
+ rowActions: u
270
274
  }, e.path) : null),
271
275
  t.waiting.length > 0 && /* @__PURE__ */ j("ul", {
272
276
  className: "grid",
273
- "aria-label": b("folder.label"),
277
+ "aria-label": S("folder.label"),
274
278
  children: t.waiting.map((e, t) => /* @__PURE__ */ M("li", {
275
279
  className: "flex min-h-11 items-center gap-2 px-1",
276
280
  "data-ckui": "queue-row",
277
281
  "data-status": "waiting",
278
- children: [/* @__PURE__ */ j(Y, { kind: G(e.type) }), /* @__PURE__ */ M("div", {
282
+ children: [/* @__PURE__ */ j(Z, { kind: G(e.type) }), /* @__PURE__ */ M("div", {
279
283
  className: "grid min-w-0 flex-1 gap-1",
280
284
  children: [/* @__PURE__ */ j("span", {
281
285
  className: "truncate text-sm",
@@ -283,126 +287,130 @@ function J(e) {
283
287
  }), /* @__PURE__ */ j("span", {
284
288
  className: "text-xs text-muted-foreground",
285
289
  "data-ckui": "queue-status",
286
- children: b("folder.queued")
290
+ children: S("folder.queued")
287
291
  })]
288
292
  })]
289
293
  }, t))
290
294
  }),
291
295
  t.pending.length > 0 && /* @__PURE__ */ j("ul", {
292
296
  className: "grid",
293
- "aria-label": b("folder.label"),
297
+ "aria-label": S("folder.label"),
294
298
  "data-ckui": "folder-pending",
295
- children: t.pending.map((e) => /* @__PURE__ */ j(ue, {
299
+ children: t.pending.map((e) => /* @__PURE__ */ j(le, {
296
300
  file: e,
297
301
  folder: t,
298
- auto: A,
299
- disabled: z
302
+ auto: L,
303
+ disabled: V
300
304
  }, e.path))
301
305
  }),
302
- w.items.length > 0 && /* @__PURE__ */ j(E, {
303
- items: w.items,
306
+ O.items.length > 0 && /* @__PURE__ */ j(T, {
307
+ items: O.items,
304
308
  id: (e) => e.id,
305
309
  name: (e) => e.file.name,
306
- disabled: A || z,
307
- label: b("folder.label"),
308
- onMove: (e, t) => w.move(w.items[e].id, t),
310
+ disabled: L || V,
311
+ label: S("folder.label"),
312
+ onMove: (e, t) => O.move(O.items[e].id, t),
309
313
  row: (e) => ({
310
314
  className: "flex min-h-11 items-center gap-2 px-1",
311
315
  "data-ckui": "queue-row",
312
316
  "data-status": e.status
313
317
  }),
314
- children: (e, n) => /* @__PURE__ */ j(de, {
318
+ children: (e, n) => /* @__PURE__ */ j(ue, {
315
319
  item: e,
316
- handle: A ? null : n,
317
- auto: A,
320
+ handle: L ? null : n,
321
+ auto: L,
318
322
  folder: t
319
323
  })
320
324
  }),
321
- (!A && me > 0 || A && t.error && me > 0) && /* @__PURE__ */ M(m, {
325
+ (!L && ge > 0 || L && t.error && ge > 0) && /* @__PURE__ */ M(m, {
322
326
  className: "w-fit",
323
- disabled: z || w.items.length > 0 && !w.ready || t.committing,
327
+ disabled: V || O.items.length > 0 && !O.ready || t.committing,
324
328
  onClick: () => void t.commit().catch(() => {}),
325
329
  "data-ckui": "folder-commit",
326
330
  children: [t.committing && /* @__PURE__ */ j(W, {
327
331
  icon: re,
328
332
  strokeWidth: 2,
329
333
  className: "motion-safe:animate-spin"
330
- }), A ? b("folder.commitAgain") : b("folder.commit", { count: w.items.filter((e) => e.status !== "committed").length + t.pending.length })]
334
+ }), L ? S("folder.commitAgain") : S("folder.commit", { count: O.items.filter((e) => e.status !== "committed").length + t.pending.length })]
331
335
  }),
332
- l,
336
+ h,
333
337
  /* @__PURE__ */ j("input", {
334
- ref: J,
338
+ ref: Q,
335
339
  type: "file",
336
- accept: L,
340
+ accept: z,
337
341
  className: "sr-only",
338
342
  tabIndex: -1,
339
343
  "aria-hidden": !0,
340
344
  onChange: (e) => {
341
345
  let n = e.target.files?.[0];
342
- e.target.value = "", n && X && t.replace(X, n).catch(() => {}), Z(null);
346
+ e.target.value = "", n && $ && t.replace($, n).catch(() => {}), de(null);
343
347
  }
344
348
  }),
345
- /* @__PURE__ */ j(_, {
346
- open: !!H,
347
- onOpenChange: (e) => !e && K.status !== "saving" && U(null),
348
- source: "source" in K ? K.source ?? null : null,
349
- aspect: q?.aspect ?? "",
350
- aspects: q?.aspect ? void 0 : u,
351
- initialEdit: "edit" in K ? K.edit : null,
352
- minWidth: q?.min_width,
353
- title: b("folder.crop"),
354
- busy: K.status === "saving",
355
- error: K.status === "error" ? x(K.error) : void 0,
356
- onConfirm: (e) => void K.save(e)
349
+ /* @__PURE__ */ j(ee, {
350
+ open: !!K,
351
+ onOpenChange: (e) => !e && J.status !== "saving" && q(null),
352
+ source: "source" in J ? J.source ?? null : null,
353
+ aspect: Y?.aspect ?? "",
354
+ aspects: Y?.aspect ? void 0 : g,
355
+ initialEdit: "edit" in J ? J.edit : null,
356
+ minWidth: Y?.min_width,
357
+ title: S("folder.crop"),
358
+ busy: J.status === "saving",
359
+ error: J.status === "error" ? C(J.error) : void 0,
360
+ onConfirm: (e) => void J.save(e)
357
361
  })
358
362
  ]
359
363
  });
360
364
  }
361
- function le({ group: e, titled: t, folder: n, disabled: r, selected: i, onSelect: a, renaming: s, onRename: c, onCrop: l, onReplace: u, rowActions: d }) {
362
- let { t: f } = o(), p = f(`folder.kinds.${q(e.rule)}`), m = e.rule?.max;
365
+ function se({ group: e, layout: t, titled: n, folder: r, disabled: i, selected: a, onSelect: s, renaming: c, onRename: l, onCrop: u, onReplace: d, rowActions: f }) {
366
+ let { t: p } = o(), m = p(`folder.kinds.${q(e.rule)}`), h = e.rule?.max;
363
367
  return /* @__PURE__ */ M("section", {
364
368
  className: "grid gap-1",
365
369
  "data-ckui": "folder-group",
366
370
  "data-path": e.path,
367
- children: [t && /* @__PURE__ */ M("h4", {
371
+ children: [n && /* @__PURE__ */ M("h4", {
368
372
  className: "px-1 text-xs font-medium text-muted-foreground tabular-nums",
369
373
  children: [
370
- p,
374
+ m,
371
375
  " · ",
372
- m ? `${e.files.length} / ${m}` : e.files.length
376
+ h ? `${e.files.length} / ${h}` : e.files.length
373
377
  ]
374
- }), /* @__PURE__ */ j(E, {
378
+ }), /* @__PURE__ */ j(T, {
379
+ layout: t,
380
+ className: t === "grid" ? "grid-cols-[repeat(auto-fill,minmax(12rem,1fr))]" : void 0,
375
381
  items: e.files,
376
382
  id: (e) => e.path,
377
- name: (t) => C(e, t.path),
378
- disabled: r || n.updating,
379
- label: p,
380
- onMove: (t, r) => void n.move(e.files[t].path, r).catch(() => {}),
383
+ name: (t) => S(e, t.path),
384
+ disabled: i || r.updating,
385
+ label: m,
386
+ onMove: (t, n) => void r.move(e.files[t].path, n).catch(() => {}),
381
387
  row: (e) => ({
382
- className: "flex min-h-12 items-center gap-2 px-1",
388
+ className: t === "grid" ? "grid min-w-0 grid-cols-[auto_minmax(0,1fr)] items-start gap-2 rounded-lg border border-border bg-background p-2" : "flex min-h-12 items-center gap-2 px-1",
383
389
  "data-ckui": "upload-row",
384
390
  "data-path": e.path
385
391
  }),
386
- children: (t, o) => /* @__PURE__ */ j(X, {
387
- file: t,
392
+ children: (n, o) => /* @__PURE__ */ j(ce, {
393
+ file: n,
394
+ grid: t === "grid",
388
395
  group: e,
389
396
  handle: o,
390
- folder: n,
391
- disabled: r,
392
- selected: i.has(t.path),
393
- onSelect: (e) => a(t.path, e),
394
- renaming: s === t.path,
395
- onRename: c,
396
- onCrop: l,
397
- onReplace: u,
398
- actions: d?.(t)
397
+ folder: r,
398
+ disabled: i,
399
+ selected: a.has(n.path),
400
+ onSelect: (e) => s(n.path, e),
401
+ renaming: c === n.path,
402
+ onRename: l,
403
+ onCrop: u,
404
+ onReplace: d,
405
+ actions: f?.(n)
399
406
  })
400
407
  })]
401
408
  });
402
409
  }
403
- function Y({ kind: e, url: t, busy: n }) {
410
+ function Z({ kind: e, url: t, busy: n, grid: r, aspect: i }) {
404
411
  return /* @__PURE__ */ M("span", {
405
- className: "relative flex size-10 shrink-0 items-center justify-center overflow-hidden rounded-md bg-muted text-muted-foreground",
412
+ className: N("relative flex shrink-0 items-center justify-center overflow-hidden rounded-md bg-muted text-muted-foreground", r ? "col-span-2 w-full" : "size-10"),
413
+ style: r ? { aspectRatio: i ?? .75 } : void 0,
406
414
  "data-ckui": "thumb",
407
415
  children: [t ? /* @__PURE__ */ j("img", {
408
416
  src: t,
@@ -420,33 +428,35 @@ function Y({ kind: e, url: t, busy: n }) {
420
428
  })]
421
429
  });
422
430
  }
423
- function X({ file: t, group: r, handle: i, folder: a, disabled: s, selected: c, onSelect: d, renaming: f, onRename: p, onCrop: h, onReplace: g, actions: _ }) {
424
- let { t: v, error: y } = o(), b = G(t.type), x = C(r, t.path), S = u(t), T = O(() => w(a.read.read, t), [a.read.read, t]), E = s || a.updating, D = t.failed ? y(e(t.failed)) : void 0;
431
+ function ce({ file: t, grid: r, group: i, handle: a, folder: s, disabled: c, selected: d, onSelect: f, renaming: p, onRename: h, onCrop: g, onReplace: ee, actions: _ }) {
432
+ let { t: v, error: y } = o(), b = G(t.type), x = S(i, t.path), w = u(t), T = O(() => C(s.read.read, t), [s.read.read, t]), E = c || s.updating, D = t.failed ? y(e(t.failed)) : void 0;
425
433
  return /* @__PURE__ */ M(A, { children: [
426
- i,
434
+ a,
427
435
  /* @__PURE__ */ j("input", {
428
436
  type: "checkbox",
429
437
  className: "size-4 shrink-0 accent-primary",
430
- checked: c,
431
- disabled: s,
438
+ checked: d,
439
+ disabled: c,
432
440
  "aria-label": v("folder.select", { name: x }),
433
- onChange: (e) => d(e.target.checked)
441
+ onChange: (e) => f(e.target.checked)
434
442
  }),
435
- /* @__PURE__ */ j(Y, {
443
+ /* @__PURE__ */ j(Z, {
436
444
  kind: b,
437
445
  url: T?.url,
438
- busy: S
446
+ busy: w,
447
+ grid: r,
448
+ aspect: T?.w && T.h ? T.w / T.h : void 0
439
449
  }),
440
450
  /* @__PURE__ */ M("div", {
441
- className: "grid min-w-0 flex-1 gap-1",
451
+ className: N("grid min-w-0 flex-1 gap-1", r && "col-span-2"),
442
452
  children: [
443
453
  /* @__PURE__ */ M("div", {
444
454
  className: "flex min-w-0 flex-wrap items-center gap-x-2 gap-y-0.5",
445
455
  children: [
446
- f ? /* @__PURE__ */ j(Z, {
456
+ p ? /* @__PURE__ */ j(Q, {
447
457
  name: n(x),
448
458
  label: v("folder.renameLabel", { name: x }),
449
- onDone: (e) => e === null ? p(null) : a.rename(t.path, e).then(() => p(null))
459
+ onDone: (e) => e === null ? h(null) : s.rename(t.path, e).then(() => h(null))
450
460
  }) : /* @__PURE__ */ j("span", {
451
461
  className: "max-w-full truncate text-sm",
452
462
  title: t.path,
@@ -470,18 +480,18 @@ function X({ file: t, group: r, handle: i, folder: a, disabled: s, selected: c,
470
480
  className: "text-xs text-destructive",
471
481
  children: D
472
482
  }),
473
- S && b === "video" && /* @__PURE__ */ j(l, {
483
+ w && b === "video" && /* @__PURE__ */ j(l, {
474
484
  progress: t.progress,
475
485
  className: "max-w-sm text-xs"
476
486
  }),
477
- S && b !== "video" && /* @__PURE__ */ j("span", {
487
+ w && b !== "video" && /* @__PURE__ */ j("span", {
478
488
  className: "text-xs text-muted-foreground",
479
489
  children: v("folder.processing")
480
490
  })
481
491
  ]
482
492
  }),
483
493
  /* @__PURE__ */ M("span", {
484
- className: "flex shrink-0 items-center gap-0.5",
494
+ className: N("flex shrink-0 flex-wrap items-center gap-0.5", r && "col-span-2 justify-end"),
485
495
  "data-ckui": "upload-actions",
486
496
  children: [
487
497
  _,
@@ -491,19 +501,19 @@ function X({ file: t, group: r, handle: i, folder: a, disabled: s, selected: c,
491
501
  "aria-label": v("folder.crop"),
492
502
  title: v("folder.crop"),
493
503
  disabled: E || !!t.staged || !t.size,
494
- onClick: () => h(t.path),
504
+ onClick: () => g(t.path),
495
505
  children: /* @__PURE__ */ j(W, {
496
506
  icon: F,
497
507
  strokeWidth: 2
498
508
  })
499
509
  }),
500
- !r.rule?.named && /* @__PURE__ */ j(m, {
510
+ !i.rule?.named && /* @__PURE__ */ j(m, {
501
511
  variant: "ghost",
502
512
  size: "icon-sm",
503
513
  "aria-label": v("common.rename"),
504
514
  title: v("common.rename"),
505
515
  disabled: E,
506
- onClick: () => p(t.path),
516
+ onClick: () => h(t.path),
507
517
  children: /* @__PURE__ */ j(W, {
508
518
  icon: L,
509
519
  strokeWidth: 2
@@ -515,7 +525,7 @@ function X({ file: t, group: r, handle: i, folder: a, disabled: s, selected: c,
515
525
  "aria-label": v("common.replace"),
516
526
  title: v("common.replace"),
517
527
  disabled: E,
518
- onClick: () => g(t.path),
528
+ onClick: () => ee(t.path),
519
529
  children: /* @__PURE__ */ j(W, {
520
530
  icon: H,
521
531
  strokeWidth: 2
@@ -527,7 +537,7 @@ function X({ file: t, group: r, handle: i, folder: a, disabled: s, selected: c,
527
537
  "aria-label": v("common.remove"),
528
538
  title: v("common.remove"),
529
539
  disabled: E,
530
- onClick: () => void a.remove([t.path]).catch(() => {}),
540
+ onClick: () => void s.remove([t.path]).catch(() => {}),
531
541
  children: /* @__PURE__ */ j(W, {
532
542
  icon: I,
533
543
  strokeWidth: 2
@@ -537,7 +547,7 @@ function X({ file: t, group: r, handle: i, folder: a, disabled: s, selected: c,
537
547
  })
538
548
  ] });
539
549
  }
540
- function Z({ name: e, label: t, onDone: n }) {
550
+ function Q({ name: e, label: t, onDone: n }) {
541
551
  let [r, i] = k(e), a = te(!1), o = (t) => {
542
552
  a.current || (a.current = !0, Promise.resolve(n(t && t.trim() && t.trim() !== e ? t.trim() : null)).catch(() => a.current = !1));
543
553
  };
@@ -554,14 +564,14 @@ function Z({ name: e, label: t, onDone: n }) {
554
564
  "data-ckui": "rename"
555
565
  });
556
566
  }
557
- function ue({ file: t, folder: n, auto: r, disabled: i }) {
558
- let { t: a, error: s } = o(), c = G(t.type), l = u(t), d = O(() => w(n.read.read, t), [n.read.read, t]), f = t.failed ? s(e(t.failed)) : l ? t.progress && t.progress.phase !== "queued" ? a("folder.processingPercent", { percent: Math.round(t.progress.percent) }) : a("folder.processing") : a(r ? "folder.adding" : "folder.notAdded");
567
+ function le({ file: t, folder: n, auto: r, disabled: i }) {
568
+ let { t: a, error: s } = o(), c = G(t.type), l = u(t), d = O(() => C(n.read.read, t), [n.read.read, t]), f = t.failed ? s(e(t.failed)) : l ? t.progress && t.progress.phase !== "queued" ? a("folder.processingPercent", { percent: Math.round(t.progress.percent) }) : a("folder.processing") : a(r ? "folder.adding" : "folder.notAdded");
559
569
  return /* @__PURE__ */ M("li", {
560
570
  className: "flex min-h-11 items-center gap-2 px-1",
561
571
  "data-ckui": "pending-row",
562
572
  "data-path": t.path,
563
573
  children: [
564
- /* @__PURE__ */ j(Y, {
574
+ /* @__PURE__ */ j(Z, {
565
575
  kind: c,
566
576
  url: d?.url,
567
577
  busy: l
@@ -593,7 +603,7 @@ function ue({ file: t, folder: n, auto: r, disabled: i }) {
593
603
  ]
594
604
  });
595
605
  }
596
- function Q(t, n, r, i) {
606
+ function $(t, n, r, i) {
597
607
  if (r.status === "failed") return n(r.error);
598
608
  if (r.status === "uploading") return h(t, r.progress);
599
609
  if (r.status === "uploaded") {
@@ -602,11 +612,11 @@ function Q(t, n, r, i) {
602
612
  }
603
613
  return r.status === "committed" ? t("folder.adding") : t("folder.queued");
604
614
  }
605
- function de({ item: e, handle: t, auto: n, folder: r }) {
606
- let { t: i, error: a } = o(), { queue: s } = r, l = G(e.file.type), u = Q(i, a, e, n), d = e.status === "uploading" ? g(e.progress) : e.unattached && !e.processed && e.processing?.progress ? e.processing.progress.percent : null;
615
+ function ue({ item: e, handle: t, auto: n, folder: r }) {
616
+ let { t: i, error: a } = o(), { queue: s } = r, l = G(e.file.type), u = $(i, a, e, n), d = e.status === "uploading" ? g(e.progress) : e.unattached && !e.processed && e.processing?.progress ? e.processing.progress.percent : null;
607
617
  return /* @__PURE__ */ M(A, { children: [
608
618
  t,
609
- /* @__PURE__ */ j(Y, {
619
+ /* @__PURE__ */ j(Z, {
610
620
  kind: l,
611
621
  busy: e.status === "uploading" || !!e.unattached && !e.processed
612
622
  }),
@@ -657,6 +667,6 @@ function de({ item: e, handle: t, auto: n, folder: r }) {
657
667
  ] });
658
668
  }
659
669
  //#endregion
660
- export { oe as MediaFolderEditor, ae as describeRules };
670
+ export { J as MediaFolderEditor, ae as describeRules };
661
671
 
662
672
  //# sourceMappingURL=media-folder-editor.js.map