@declarion/react 0.66.0 → 0.80.0

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 (66) hide show
  1. package/README.md +1 -1
  2. package/dist-lib/api/auth.js +24 -14
  3. package/dist-lib/app.js +28 -23
  4. package/dist-lib/components/chrome/AssociationTabs.js +35 -38
  5. package/dist-lib/components/chrome/HighlightsStrip.js +2 -1
  6. package/dist-lib/components/chrome/RecordHeader.js +33 -38
  7. package/dist-lib/components/detail-layout/AssociatedBlock.js +10 -21
  8. package/dist-lib/components/detail-layout/ChildrenBlock.js +1 -8
  9. package/dist-lib/components/detail-layout/ChildrenCards.js +1 -8
  10. package/dist-lib/components/detail-layout/ChildrenList.js +1 -8
  11. package/dist-lib/components/detail-layout/ChildrenTable.js +1 -8
  12. package/dist-lib/components/detail-layout/ChildrenTimeline.js +1 -8
  13. package/dist-lib/components/detail-layout/DetailAuditStrip.js +33 -29
  14. package/dist-lib/components/detail-layout/DetailHighlights.js +7 -2
  15. package/dist-lib/components/detail-layout/FieldsBlock.js +12 -9
  16. package/dist-lib/components/detail-layout/LayoutRenderer.js +10 -10
  17. package/dist-lib/components/detail-layout/LayoutTabs.js +49 -48
  18. package/dist-lib/components/detail-layout/SectionBlock.js +20 -28
  19. package/dist-lib/components/detail-layout/visibility.js +28 -0
  20. package/dist-lib/components/fields/IntArrayField.js +37 -33
  21. package/dist-lib/components/fields/NumberField.js +28 -55
  22. package/dist-lib/components/fields/RichTextField.js +1 -1
  23. package/dist-lib/components/fields/TimestampField.js +50 -89
  24. package/dist-lib/components/fields/cells/factories/date.js +13 -14
  25. package/dist-lib/components/fields/cells/factories/money.js +1 -1
  26. package/dist-lib/components/fields/cells/factories/number.js +4 -4
  27. package/dist-lib/components/file-widgets/DocumentCard.js +1 -1
  28. package/dist-lib/components/file-widgets/Grid.js +153 -152
  29. package/dist-lib/components/file-widgets/ImageWidget.js +90 -91
  30. package/dist-lib/components/file-widgets/LabeledSlots.js +1 -0
  31. package/dist-lib/components/file-widgets/helpers.js +15 -19
  32. package/dist-lib/components/file-widgets/host.js +33 -32
  33. package/dist-lib/components/file-widgets/upload.js +10 -6
  34. package/dist-lib/components/layout/Layout.js +125 -123
  35. package/dist-lib/components/pages/NoScreensPage.impl.js +14 -0
  36. package/dist-lib/components/pages/NoScreensPage.js +12 -0
  37. package/dist-lib/components/pages/SmartDetailPage.impl.js +451 -451
  38. package/dist-lib/components/pages/auth/AuthShell.js +62 -61
  39. package/dist-lib/components/pages/auth/CodeInput.js +63 -0
  40. package/dist-lib/components/pages/auth/SignIn.js +12 -4
  41. package/dist-lib/components/pages/auth/SignUp.impl.js +80 -103
  42. package/dist-lib/components/pages/auth/SignUpCode.js +122 -0
  43. package/dist-lib/components/pages/auth/TwoFA.impl.js +9 -55
  44. package/dist-lib/components/pages/list/cardProjection.js +135 -122
  45. package/dist-lib/components/pages/list/columns.js +58 -43
  46. package/dist-lib/components/pages/profile/Profile.impl.js +87 -104
  47. package/dist-lib/components/pages/tenant-params/TenantParamsPage.impl.js +1 -1
  48. package/dist-lib/components/params/ParamsBlock.js +6 -17
  49. package/dist-lib/components/params/param-editors.js +14 -10
  50. package/dist-lib/components/primitives/Fields.js +314 -236
  51. package/dist-lib/components/shared/MarkdownRenderer.js +44 -43
  52. package/dist-lib/declarion-react.css +1 -1
  53. package/dist-lib/hooks/useActiveTabFollowsRoute.js +49 -0
  54. package/dist-lib/hooks/useAuth.js +44 -37
  55. package/dist-lib/hooks/useDocumentTitle.js +20 -0
  56. package/dist-lib/hooks/useFollowAgentOpen.js +1 -0
  57. package/dist-lib/hooks/useTabTitle.js +1 -1
  58. package/dist-lib/index.d.ts +21 -7
  59. package/dist-lib/lib/date-text.js +57 -0
  60. package/dist-lib/lib/number-text.js +9 -0
  61. package/dist-lib/lib/timestamp.js +29 -29
  62. package/dist-lib/stores/tabs.js +7 -5
  63. package/dist-lib/testing.d.ts +1 -1
  64. package/dist-lib/testing.js +1 -0
  65. package/dist-lib/{useResponsiveMode-DmrpMbZX.d.ts → useResponsiveMode-D3SKz5z4.d.ts} +20 -9
  66. package/package.json +11 -11
@@ -2,38 +2,35 @@ import { pluralText as e } from "../../lib/language.js";
2
2
  import { useText as t } from "../../hooks/useText.js";
3
3
  import { UploadError as n, discardFile as r, formatBytes as i, uploadCheckFailure as a, uploadFailure as o, uploadFile as s, validateClientSide as c } from "./upload.js";
4
4
  import { UploadFailureText as l } from "./UploadFailureText.js";
5
- import { preferredListThumbnailURL as u, preferredThumbnailVariant as d } from "./helpers.js";
6
- import { useDraftRegistration as f } from "./draft-scope.js";
7
- import { useEmbedFileSrc as p } from "./useEmbedFileSrc.js";
8
- import { fileArrayFromValue as m } from "./value.js";
9
- import { useCallback as h, useEffect as g, useMemo as _, useRef as v, useState as y } from "react";
10
- import { Fragment as b, jsx as x, jsxs as S } from "react/jsx-runtime";
11
- import { DndContext as C, PointerSensor as w, closestCenter as ee, useSensor as te, useSensors as ne } from "@dnd-kit/core";
5
+ import { fileFieldLabel as u, preferredListThumbnail as d, previewFileURL as f } from "./helpers.js";
6
+ import { useDraftRegistration as p } from "./draft-scope.js";
7
+ import { useEmbedFileSrc as m } from "./useEmbedFileSrc.js";
8
+ import { fileArrayFromValue as h } from "./value.js";
9
+ import { useCallback as g, useEffect as _, useMemo as v, useRef as y, useState as b } from "react";
10
+ import { Fragment as x, jsx as S, jsxs as C } from "react/jsx-runtime";
11
+ import { DndContext as w, PointerSensor as ee, closestCenter as te, useSensor as ne, useSensors as re } from "@dnd-kit/core";
12
12
  import { SortableContext as T, arrayMove as E, rectSortingStrategy as D, useSortable as O } from "@dnd-kit/sortable";
13
13
  import { CSS as k } from "@dnd-kit/utilities";
14
14
  //#region src/components/file-widgets/Grid.tsx
15
- function A(e, t) {
16
- return u(e, t);
17
- }
18
- function j(i) {
19
- let { field: l, fieldName: u, value: d, onChange: p, mode: b, disabled: O } = i, k = m(d), [A, j] = y([]), [M, N] = y(/* @__PURE__ */ new Set()), [P, F] = y(null), { register: I, unregister: L, isDraft: R } = f(), z = t(), B = t("errors"), V = v(/* @__PURE__ */ new Set()), H = v([]);
20
- H.current = A;
21
- let U = v(k);
22
- U.current = k, g(() => () => {
23
- H.current.forEach((e) => e.abort());
15
+ function A(i) {
16
+ let { field: l, fieldName: d, value: f, onChange: m, mode: x, disabled: O } = i, k = h(f), [A, M] = b([]), [N, P] = b(/* @__PURE__ */ new Set()), [F, I] = b(null), { register: L, unregister: R, isDraft: z } = p(), B = t(), V = t("errors"), H = y(/* @__PURE__ */ new Set()), U = y([]);
17
+ U.current = A;
18
+ let W = y(k);
19
+ W.current = k, _(() => () => {
20
+ U.current.forEach((e) => e.abort());
24
21
  }, []);
25
- let W = ne(te(w, { activationConstraint: { distance: 5 } })), oe = (l.accepts ?? ["image/*"]).join(","), se = l.display?.reorderable !== !1, ce = l.display?.listable_thumbnail, G = h(async (e) => {
26
- let t = c(e, l.accepts, l.max_size_bytes), d = `tile-${Math.random().toString(36).slice(2)}-${Date.now()}`, f = new AbortController();
27
- if (t) j((n) => [...n, {
28
- localId: d,
22
+ let oe = re(ne(ee, { activationConstraint: { distance: 5 } })), se = (l.accepts ?? ["image/*"]).join(","), ce = l.display?.reorderable !== !1, le = l.display?.listable_thumbnail, G = g(async (e) => {
23
+ let t = c(e, l.accepts, l.max_size_bytes), u = `tile-${Math.random().toString(36).slice(2)}-${Date.now()}`, f = new AbortController();
24
+ if (t) M((n) => [...n, {
25
+ localId: u,
29
26
  filename: e.name,
30
27
  progress: null,
31
- error: a(z, B, t),
28
+ error: a(B, V, t),
32
29
  abort: () => {}
33
30
  }]);
34
31
  else {
35
- j((t) => [...t, {
36
- localId: d,
32
+ M((t) => [...t, {
33
+ localId: u,
37
34
  filename: e.name,
38
35
  progress: {
39
36
  loaded: 0,
@@ -47,18 +44,18 @@ function j(i) {
47
44
  let t = await s({
48
45
  file: e,
49
46
  entityCode: i.entityCode,
50
- fieldCode: u,
47
+ fieldCode: d,
51
48
  signal: f.signal,
52
- onProgress: (e) => j((t) => t.map((t) => t.localId === d ? {
49
+ onProgress: (e) => M((t) => t.map((t) => t.localId === u ? {
53
50
  ...t,
54
51
  progress: e
55
52
  } : t))
56
53
  });
57
- if (V.current.delete(d)) {
58
- r(t.id).catch(() => {}), L(t.id);
54
+ if (H.current.delete(u)) {
55
+ r(t.id).catch(() => {}), R(t.id);
59
56
  return;
60
57
  }
61
- I(t.id, () => r(t.id));
58
+ L(t.id, () => r(t.id));
62
59
  let n = {
63
60
  id: t.id,
64
61
  filename: t.filename,
@@ -69,15 +66,15 @@ function j(i) {
69
66
  height: t.height,
70
67
  url: t.url,
71
68
  metadata: t.metadata
72
- }, a = [...U.current, n];
73
- U.current = a, p?.(a), j((e) => e.filter((e) => e.localId !== d));
69
+ }, a = [...W.current, n];
70
+ W.current = a, m?.(a), M((e) => e.filter((e) => e.localId !== u));
74
71
  } catch (e) {
75
72
  if (e instanceof n && e.code === "ABORTED") {
76
- j((e) => e.filter((e) => e.localId !== d));
73
+ M((e) => e.filter((e) => e.localId !== u));
77
74
  return;
78
75
  }
79
- let t = o(z, B, e);
80
- j((e) => e.map((e) => e.localId === d ? {
76
+ let t = o(B, V, e);
77
+ M((e) => e.map((e) => e.localId === u ? {
81
78
  ...e,
82
79
  error: t,
83
80
  progress: null,
@@ -86,169 +83,173 @@ function j(i) {
86
83
  }
87
84
  }
88
85
  }, [
86
+ V,
89
87
  B,
90
- z,
91
88
  l.accepts,
92
89
  l.max_size_bytes,
93
- u,
94
- p,
90
+ d,
91
+ m,
95
92
  i.entityCode,
96
- I,
97
- L
98
- ]), K = h((e) => {
93
+ L,
94
+ R
95
+ ]), K = g((e) => {
99
96
  Array.from(e).forEach((e) => void G(e));
100
- }, [G]), q = v(null), J = h(() => {
97
+ }, [G]), q = y(null), J = g(() => {
101
98
  O || q.current?.click();
102
- }, [O]), le = h((e) => {
99
+ }, [O]), ue = g((e) => {
103
100
  O || (e.preventDefault(), e.dataTransfer.dropEffect = "copy");
104
- }, [O]), ue = h((e) => {
101
+ }, [O]), de = g((e) => {
105
102
  if (O) return;
106
103
  e.preventDefault();
107
104
  let t = e.dataTransfer.files;
108
105
  t && t.length > 0 && K(t);
109
- }, [O, K]), de = h((e) => {
106
+ }, [O, K]), fe = g((e) => {
110
107
  let t = e.target.files;
111
108
  e.target.value = "", t && t.length > 0 && K(t);
112
- }, [K]), fe = h((e) => {
113
- R(e) && (r(e).catch(() => {}), L(e));
109
+ }, [K]), pe = g((e) => {
110
+ z(e) && (r(e).catch(() => {}), R(e));
114
111
  let t = k.filter((t) => t.id !== e);
115
- p?.(t), N((t) => {
112
+ m?.(t), P((t) => {
116
113
  let n = new Set(t);
117
114
  return n.delete(e), n;
118
115
  });
119
116
  }, [
120
- R,
117
+ z,
121
118
  k,
122
- p,
123
- L
124
- ]), pe = h(() => {
125
- M.size !== 0 && (Array.from(M).forEach((e) => {
126
- R(e) && (r(e).catch(() => {}), L(e));
127
- }), p?.(k.filter((e) => !M.has(e.id))), N(/* @__PURE__ */ new Set()));
119
+ m,
120
+ R
121
+ ]), me = g(() => {
122
+ N.size !== 0 && (Array.from(N).forEach((e) => {
123
+ z(e) && (r(e).catch(() => {}), R(e));
124
+ }), m?.(k.filter((e) => !N.has(e.id))), P(/* @__PURE__ */ new Set()));
128
125
  }, [
129
- R,
126
+ z,
130
127
  k,
131
- M,
132
- p,
133
- L
134
- ]), me = h((e) => {
128
+ N,
129
+ m,
130
+ R
131
+ ]), he = g((e) => {
135
132
  let { active: t, over: n } = e;
136
133
  if (!n || t.id === n.id) return;
137
134
  let r = k.findIndex((e) => e.id === t.id), i = k.findIndex((e) => e.id === n.id);
138
- r < 0 || i < 0 || p?.(E(k, r, i));
139
- }, [k, p]), he = h((e) => {
140
- N((t) => {
135
+ r < 0 || i < 0 || m?.(E(k, r, i));
136
+ }, [k, m]), ge = g((e) => {
137
+ P((t) => {
141
138
  let n = new Set(t);
142
139
  return n.has(e) ? n.delete(e) : n.add(e), n;
143
140
  });
144
- }, []), Y = P == null ? null : k[P], X = h(() => {
145
- F((e) => e == null ? e : Math.min(k.length - 1, e + 1));
146
- }, [k.length]), Z = h(() => {
147
- F((e) => e == null ? e : Math.max(0, e - 1));
148
- }, []), Q = h(() => F(null), []);
149
- g(() => {
150
- if (P == null) return;
141
+ }, []), Y = F == null ? null : k[F], X = g(() => {
142
+ I((e) => e == null ? e : Math.min(k.length - 1, e + 1));
143
+ }, [k.length]), Z = g(() => {
144
+ I((e) => e == null ? e : Math.max(0, e - 1));
145
+ }, []), Q = g(() => I(null), []);
146
+ _(() => {
147
+ if (F == null) return;
151
148
  let e = (e) => {
152
149
  e.key === "Escape" ? Q() : e.key === "ArrowRight" ? X() : e.key === "ArrowLeft" && Z();
153
150
  };
154
151
  return window.addEventListener("keydown", e), () => window.removeEventListener("keydown", e);
155
152
  }, [
156
- P,
153
+ F,
157
154
  Q,
158
155
  X,
159
156
  Z
160
157
  ]);
161
- let ge = h((e) => {
158
+ let _e = g((e) => {
162
159
  O || (e.key === "Enter" || e.key === " ") && e.target === e.currentTarget && (e.preventDefault(), J());
163
- }, [O, J]), $ = b === "display", _e = _(() => k.map((e) => e.id), [k]);
164
- return /* @__PURE__ */ S("div", {
165
- "data-testid": `file-widget-${u}`,
160
+ }, [O, J]), $ = x === "display", ve = v(() => k.map((e) => e.id), [k]);
161
+ return /* @__PURE__ */ C("div", {
162
+ "data-testid": `file-widget-${d}`,
166
163
  className: "flex flex-col gap-2",
167
164
  children: [
168
- !$ && M.size > 0 && /* @__PURE__ */ S("div", {
165
+ !$ && N.size > 0 && /* @__PURE__ */ C("div", {
169
166
  className: "flex items-center gap-2 rounded-md border border-border bg-surface-2 p-2 text-sm",
170
167
  role: "toolbar",
171
- "aria-label": z("file.grid.bulk_actions", "Bulk actions"),
168
+ "aria-label": B("file.grid.bulk_actions", "Bulk actions"),
172
169
  children: [
173
- /* @__PURE__ */ x("span", {
170
+ /* @__PURE__ */ S("span", {
174
171
  className: "text-foreground",
175
- children: e(z, "file.grid.selected", M.size, {
172
+ children: e(B, "file.grid.selected", N.size, {
176
173
  one: "{count} selected",
177
174
  other: "{count} selected"
178
175
  })
179
176
  }),
180
- /* @__PURE__ */ x("button", {
177
+ /* @__PURE__ */ S("button", {
181
178
  type: "button",
182
179
  className: "rounded-sm border border-border bg-card px-2 py-1 text-xs text-destructive hover:bg-surface-2",
183
- onClick: pe,
180
+ onClick: me,
184
181
  "data-testid": "bulk-delete",
185
- children: z("file.delete", "Delete")
182
+ children: B("file.delete", "Delete")
186
183
  }),
187
- /* @__PURE__ */ x("button", {
184
+ /* @__PURE__ */ S("button", {
188
185
  type: "button",
189
186
  className: "rounded-sm border border-border bg-card px-2 py-1 text-xs text-foreground hover:bg-surface-2",
190
- onClick: () => N(/* @__PURE__ */ new Set()),
191
- children: z("file.grid.clear_selection", "Clear")
187
+ onClick: () => P(/* @__PURE__ */ new Set()),
188
+ children: B("file.grid.clear_selection", "Clear")
192
189
  })
193
190
  ]
194
191
  }),
195
- /* @__PURE__ */ x(C, {
196
- sensors: W,
197
- collisionDetection: ee,
198
- onDragEnd: me,
199
- children: /* @__PURE__ */ x(T, {
200
- items: _e,
192
+ /* @__PURE__ */ S(w, {
193
+ sensors: oe,
194
+ collisionDetection: te,
195
+ onDragEnd: he,
196
+ children: /* @__PURE__ */ S(T, {
197
+ items: ve,
201
198
  strategy: D,
202
- children: /* @__PURE__ */ S("div", {
203
- className: "grid grid-cols-[repeat(auto-fill,minmax(140px,1fr))] gap-3 rounded-md border border-dashed border-border bg-surface p-3 outline-none focus-visible:outline-2 focus-visible:outline-accent",
199
+ children: /* @__PURE__ */ C("div", {
200
+ className: $ ? "grid grid-cols-[repeat(auto-fill,minmax(140px,1fr))] gap-3" : "grid grid-cols-[repeat(auto-fill,minmax(140px,1fr))] gap-3 rounded-md border border-dashed border-border bg-surface p-3 outline-none focus-visible:outline-2 focus-visible:outline-accent",
204
201
  role: "grid",
205
- "aria-label": u,
202
+ "aria-label": u(B, l, d),
206
203
  tabIndex: $ || O ? -1 : 0,
207
- onDragOver: le,
208
- onDrop: ue,
209
- onKeyDown: ge,
204
+ onDragOver: ue,
205
+ onDrop: de,
206
+ onKeyDown: _e,
210
207
  "data-testid": "grid-container",
211
208
  children: [
212
- k.map((e, t) => /* @__PURE__ */ x(re, {
209
+ k.map((e, t) => /* @__PURE__ */ S(j, {
213
210
  file: e,
214
- selected: M.has(e.id),
211
+ selected: N.has(e.id),
215
212
  disabled: O || $,
216
- reorderable: se && !$,
217
- preferredThumbnail: ce,
218
- onSelect: () => he(e.id),
219
- onRemove: () => fe(e.id),
220
- onPreview: () => F(t)
213
+ reorderable: ce && !$,
214
+ preferredThumbnail: le,
215
+ onSelect: () => ge(e.id),
216
+ onRemove: () => pe(e.id),
217
+ onPreview: () => I(t)
221
218
  }, e.id)),
222
- A.map((e) => /* @__PURE__ */ x(ie, {
219
+ A.map((e) => /* @__PURE__ */ S(ie, {
223
220
  tile: e,
224
221
  onCancel: () => {
225
- e.abort(), V.current.add(e.localId), j((t) => t.filter((t) => t.localId !== e.localId));
222
+ e.abort(), H.current.add(e.localId), M((t) => t.filter((t) => t.localId !== e.localId));
226
223
  },
227
- onDismiss: () => j((t) => t.filter((t) => t.localId !== e.localId))
224
+ onDismiss: () => M((t) => t.filter((t) => t.localId !== e.localId))
228
225
  }, e.localId)),
229
- k.length === 0 && A.length === 0 && /* @__PURE__ */ x("div", {
226
+ k.length === 0 && A.length === 0 && ($ ? /* @__PURE__ */ S("div", {
227
+ className: "col-span-full text-sm text-muted-foreground",
228
+ "data-testid": "grid-empty",
229
+ children: B(l.display?.placeholder) || B("file.list.empty", "No files")
230
+ }) : /* @__PURE__ */ S("div", {
230
231
  className: "col-span-full flex h-24 cursor-pointer items-center justify-center text-sm text-muted-foreground",
231
232
  onClick: J,
232
233
  "data-testid": "grid-empty",
233
- children: z(l.display?.placeholder) || z("file.grid.empty", "Drop files here or click to browse")
234
- })
234
+ children: B(l.display?.placeholder) || B("file.grid.empty", "Drop files here or click to browse")
235
+ }))
235
236
  ]
236
237
  })
237
238
  })
238
239
  }),
239
- !$ && /* @__PURE__ */ x("input", {
240
+ !$ && /* @__PURE__ */ S("input", {
240
241
  ref: q,
241
242
  type: "file",
242
- accept: oe,
243
+ accept: se,
243
244
  multiple: !0,
244
- onChange: de,
245
+ onChange: fe,
245
246
  style: { display: "none" },
246
- "data-testid": `file-input-${u}`
247
+ "data-testid": `file-input-${d}`
247
248
  }),
248
- Y && /* @__PURE__ */ x(ae, {
249
+ Y && /* @__PURE__ */ S(ae, {
249
250
  file: Y,
250
- hasPrev: P > 0,
251
- hasNext: P < k.length - 1,
251
+ hasPrev: F > 0,
252
+ hasNext: F < k.length - 1,
252
253
  onPrev: Z,
253
254
  onNext: X,
254
255
  onClose: Q
@@ -256,63 +257,63 @@ function j(i) {
256
257
  ]
257
258
  });
258
259
  }
259
- function re({ file: e, selected: n, disabled: r, reorderable: i, preferredThumbnail: a, onSelect: o, onRemove: s, onPreview: c }) {
260
- let { attributes: l, listeners: u, setNodeRef: f, transform: m, transition: h, isDragging: g } = O({
260
+ function j({ file: e, selected: n, disabled: r, reorderable: i, preferredThumbnail: a, onSelect: o, onRemove: s, onPreview: c }) {
261
+ let { attributes: l, listeners: u, setNodeRef: p, transform: h, transition: g, isDragging: _ } = O({
261
262
  id: e.id,
262
263
  disabled: !i
263
- }), _ = t(), v = {
264
- transform: k.Transform.toString(m),
265
- transition: h,
266
- opacity: g ? .5 : 1
267
- }, y = p(e.id, d(e, a), A(e, a));
268
- return /* @__PURE__ */ S("div", {
269
- ref: f,
270
- style: v,
264
+ }), v = t(), y = {
265
+ transform: k.Transform.toString(h),
266
+ transition: g,
267
+ opacity: _ ? .5 : 1
268
+ }, b = d(e, a), w = m(b?.id, "preview", b && f(b));
269
+ return /* @__PURE__ */ C("div", {
270
+ ref: p,
271
+ style: y,
271
272
  className: `group relative aspect-square overflow-hidden rounded-md border ${n ? "border-accent" : "border-border"} bg-surface-2`,
272
273
  "data-testid": `grid-tile-${e.id}`,
273
274
  "data-selected": n || void 0,
274
- children: [y ? /* @__PURE__ */ x("img", {
275
- src: y,
275
+ children: [w ? /* @__PURE__ */ S("img", {
276
+ src: w,
276
277
  alt: e.filename,
277
278
  className: "h-full w-full cursor-pointer object-cover",
278
279
  loading: "lazy",
279
280
  onClick: c
280
- }) : /* @__PURE__ */ x("div", {
281
+ }) : /* @__PURE__ */ S("div", {
281
282
  className: "flex h-full w-full cursor-pointer items-center justify-center bg-surface-3 text-xs text-muted-foreground",
282
283
  onClick: c,
283
284
  children: e.filename
284
- }), !r && /* @__PURE__ */ S(b, { children: [
285
- /* @__PURE__ */ x("input", {
285
+ }), !r && /* @__PURE__ */ C(x, { children: [
286
+ /* @__PURE__ */ S("input", {
286
287
  type: "checkbox",
287
288
  className: "absolute left-1 top-1 h-4 w-4 cursor-pointer",
288
289
  checked: n,
289
290
  onChange: o,
290
- "aria-label": _("file.grid.select", "Select {filename}", { filename: e.filename }),
291
+ "aria-label": v("file.grid.select", "Select {filename}", { filename: e.filename }),
291
292
  "data-testid": `select-${e.id}`,
292
293
  onClick: (e) => e.stopPropagation()
293
294
  }),
294
- i && /* @__PURE__ */ x("button", {
295
+ i && /* @__PURE__ */ S("button", {
295
296
  type: "button",
296
297
  className: "absolute right-1 top-1 cursor-grab rounded-sm border border-border bg-card px-1 text-xs",
297
- "aria-label": _("file.grid.reorder", "Drag to reorder {filename}", { filename: e.filename }),
298
+ "aria-label": v("file.grid.reorder", "Drag to reorder {filename}", { filename: e.filename }),
298
299
  "data-testid": `drag-${e.id}`,
299
300
  ...l,
300
301
  ...u,
301
302
  children: "⋮⋮"
302
303
  }),
303
- /* @__PURE__ */ S("div", {
304
+ /* @__PURE__ */ C("div", {
304
305
  className: "absolute inset-x-0 bottom-0 flex items-center justify-end gap-1 bg-black/50 p-1 opacity-0 transition-opacity group-hover:opacity-100 group-focus-within:opacity-100",
305
- children: [/* @__PURE__ */ x("button", {
306
+ children: [/* @__PURE__ */ S("button", {
306
307
  type: "button",
307
308
  className: "rounded-sm border border-border bg-card px-2 py-0.5 text-xs",
308
309
  onClick: c,
309
- children: _("file.view", "View")
310
- }), /* @__PURE__ */ x("button", {
310
+ children: v("file.view", "View")
311
+ }), /* @__PURE__ */ S("button", {
311
312
  type: "button",
312
313
  className: "rounded-sm border border-border bg-card px-2 py-0.5 text-xs text-destructive",
313
314
  onClick: s,
314
315
  "data-testid": `remove-${e.id}`,
315
- children: _("file.delete", "Delete")
316
+ children: v("file.delete", "Delete")
316
317
  })]
317
318
  })
318
319
  ] })]
@@ -320,16 +321,16 @@ function re({ file: e, selected: n, disabled: r, reorderable: i, preferredThumbn
320
321
  }
321
322
  function ie({ tile: e, onCancel: n, onDismiss: r }) {
322
323
  let i = t();
323
- return /* @__PURE__ */ S("div", {
324
+ return /* @__PURE__ */ C("div", {
324
325
  className: `relative flex aspect-square flex-col items-center justify-center rounded-md border ${e.error ? "border-destructive" : "border-border"} bg-surface-2 p-2 text-center text-xs`,
325
326
  "data-testid": `pending-tile-${e.localId}`,
326
327
  children: [
327
- /* @__PURE__ */ x("span", {
328
+ /* @__PURE__ */ S("span", {
328
329
  className: "truncate",
329
330
  title: e.filename,
330
331
  children: e.filename
331
332
  }),
332
- e.progress && !e.error && /* @__PURE__ */ S("span", {
333
+ e.progress && !e.error && /* @__PURE__ */ C("span", {
333
334
  className: "mt-1 text-muted-foreground",
334
335
  role: "progressbar",
335
336
  "aria-valuenow": e.progress.pct,
@@ -337,12 +338,12 @@ function ie({ tile: e, onCancel: n, onDismiss: r }) {
337
338
  "aria-valuemax": 100,
338
339
  children: [e.progress.pct, "%"]
339
340
  }),
340
- e.error && /* @__PURE__ */ x("div", {
341
+ e.error && /* @__PURE__ */ S("div", {
341
342
  role: "alert",
342
343
  className: "mt-1 text-destructive",
343
- children: /* @__PURE__ */ x(l, { failure: e.error })
344
+ children: /* @__PURE__ */ S(l, { failure: e.error })
344
345
  }),
345
- /* @__PURE__ */ x("button", {
346
+ /* @__PURE__ */ S("button", {
346
347
  type: "button",
347
348
  className: "mt-1 rounded-sm border border-border bg-card px-2 py-0.5",
348
349
  onClick: e.error ? r : n,
@@ -352,8 +353,8 @@ function ie({ tile: e, onCancel: n, onDismiss: r }) {
352
353
  });
353
354
  }
354
355
  function ae({ file: e, hasPrev: n, hasNext: r, onPrev: a, onNext: o, onClose: s }) {
355
- let c = t(), l = p(e.id, "preview", e.presigned_url ?? e.url ?? A(e));
356
- return /* @__PURE__ */ S("div", {
356
+ let c = t(), l = m(e.id, "preview", f(e));
357
+ return /* @__PURE__ */ C("div", {
357
358
  className: "fixed inset-0 z-50 flex items-center justify-center bg-black/80",
358
359
  role: "dialog",
359
360
  "aria-modal": "true",
@@ -361,7 +362,7 @@ function ae({ file: e, hasPrev: n, hasNext: r, onPrev: a, onNext: o, onClose: s
361
362
  "data-testid": "lightbox",
362
363
  onClick: s,
363
364
  children: [
364
- /* @__PURE__ */ x("button", {
365
+ /* @__PURE__ */ S("button", {
365
366
  type: "button",
366
367
  className: "absolute right-4 top-4 rounded-sm border border-border bg-card px-3 py-1 text-foreground",
367
368
  onClick: (e) => {
@@ -370,7 +371,7 @@ function ae({ file: e, hasPrev: n, hasNext: r, onPrev: a, onNext: o, onClose: s
370
371
  "data-testid": "lightbox-close",
371
372
  children: c("file.lightbox.close", "Close")
372
373
  }),
373
- n && /* @__PURE__ */ x("button", {
374
+ n && /* @__PURE__ */ S("button", {
374
375
  type: "button",
375
376
  className: "absolute left-4 rounded-sm border border-border bg-card px-3 py-2 text-foreground",
376
377
  onClick: (e) => {
@@ -379,7 +380,7 @@ function ae({ file: e, hasPrev: n, hasNext: r, onPrev: a, onNext: o, onClose: s
379
380
  "data-testid": "lightbox-prev",
380
381
  children: "‹"
381
382
  }),
382
- r && /* @__PURE__ */ x("button", {
383
+ r && /* @__PURE__ */ S("button", {
383
384
  type: "button",
384
385
  className: "absolute right-4 bottom-4 rounded-sm border border-border bg-card px-3 py-2 text-foreground",
385
386
  onClick: (e) => {
@@ -388,12 +389,12 @@ function ae({ file: e, hasPrev: n, hasNext: r, onPrev: a, onNext: o, onClose: s
388
389
  "data-testid": "lightbox-next",
389
390
  children: "›"
390
391
  }),
391
- l ? /* @__PURE__ */ x("img", {
392
+ l ? /* @__PURE__ */ S("img", {
392
393
  src: l,
393
394
  alt: e.filename,
394
395
  className: "max-h-[90vh] max-w-[90vw] object-contain",
395
396
  onClick: (e) => e.stopPropagation()
396
- }) : /* @__PURE__ */ S("div", {
397
+ }) : /* @__PURE__ */ C("div", {
397
398
  className: "rounded-md bg-card p-4 text-foreground",
398
399
  children: [
399
400
  e.filename,
@@ -406,4 +407,4 @@ function ae({ file: e, hasPrev: n, hasNext: r, onPrev: a, onNext: o, onClose: s
406
407
  });
407
408
  }
408
409
  //#endregion
409
- export { j as Grid };
410
+ export { A as Grid };