@thebes/cadmea 1.5.0 → 1.7.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.
@@ -1,12 +1,12 @@
1
- import { className, createComponent, delegateEvents, effect, insert, memo, setAttribute, template } from "solid-js/web";
1
+ import { className, createComponent, delegateEvents, effect, insert, memo, setAttribute, template, use } from "solid-js/web";
2
2
  import { createMutation, createQuery, useQueryClient } from "@tanstack/solid-query";
3
- import { For, Index, Show, Suspense, createEffect, createSignal, lazy, onCleanup } from "solid-js";
3
+ import { For, Index, Show, Suspense, createEffect, createSignal, lazy, onCleanup, onMount } from "solid-js";
4
4
  import { createForm } from "@tanstack/solid-form";
5
- import { validateDocument } from "@thebes/cadmus/cms";
5
+ import { PREVIEW_VALUES_MESSAGE, VISUAL_EDIT_MESSAGE, validateDocument } from "@thebes/cadmus/cms";
6
6
  import { Link, useBlocker } from "@tanstack/solid-router";
7
7
  import { createSolidTable, flexRender, getCoreRowModel } from "@tanstack/solid-table";
8
8
  //#region src/CollectionEdit.tsx
9
- var _tmpl$$4 = /*#__PURE__*/ template(`<p class="text-sm text-error"role=alert>`), _tmpl$2$3 = /*#__PURE__*/ template(`<span class="loading loading-spinner loading-sm">`), _tmpl$3$1 = /*#__PURE__*/ template(`<button type=button class="btn flex-1">`), _tmpl$4$1 = /*#__PURE__*/ template(`<button type=button class="btn btn-primary flex-1">`), _tmpl$5$1 = /*#__PURE__*/ template(`<button type=button class="btn btn-outline flex-1">`), _tmpl$6$1 = /*#__PURE__*/ template(`<span class="text-base-content/60 self-center px-1 text-xs"aria-live=polite>`), _tmpl$7$1 = /*#__PURE__*/ template(`<form class="flex flex-col gap-4"><div class="bg-base-100 sticky bottom-0 flex gap-2 border-t py-3">`), _tmpl$8$1 = /*#__PURE__*/ template(`<fieldset class="border-base-300 rounded-box border p-4"><legend class="px-2 text-sm font-semibold">`), _tmpl$9$1 = /*#__PURE__*/ template(`<div class="grid grid-cols-1 gap-4 md:grid-cols-2">`), _tmpl$0$1 = /*#__PURE__*/ template(`<span class=text-error> *`), _tmpl$1$1 = /*#__PURE__*/ template(`<p class="text-base-content/60 mb-1 text-xs">`), _tmpl$10$1 = /*#__PURE__*/ template(`<p class="text-error mt-1 text-sm"role=alert>`), _tmpl$11$1 = /*#__PURE__*/ template(`<div><label class=label>`), _tmpl$12$1 = /*#__PURE__*/ template(`<input class=input type=text>`), _tmpl$13$1 = /*#__PURE__*/ template(`<select class=select>`), _tmpl$14 = /*#__PURE__*/ template(`<option>`), _tmpl$15 = /*#__PURE__*/ template(`<input class=input type=number>`), _tmpl$16 = /*#__PURE__*/ template(`<input class=input type=text readonly>`), _tmpl$17 = /*#__PURE__*/ template(`<input class=checkbox type=checkbox>`), _tmpl$18 = /*#__PURE__*/ template(`<p class="text-sm opacity-70 break-all">`), _tmpl$19 = /*#__PURE__*/ template(`<p class="text-sm text-error">`), _tmpl$20 = /*#__PURE__*/ template(`<div class="flex flex-col gap-2"><input class=file-input type=file>`), _tmpl$21 = /*#__PURE__*/ template(`<div class="mb-1 flex flex-wrap gap-1">`), _tmpl$22 = /*#__PURE__*/ template(`<button type=button aria-label=Clear class="absolute top-2 right-2 cursor-pointer opacity-60">×`), _tmpl$23 = /*#__PURE__*/ template(`<div role=listbox class="bg-base-100 border-base-300 rounded-box absolute z-10 mt-1 flex max-h-56 w-full flex-col overflow-auto border p-1 shadow">`), _tmpl$24 = /*#__PURE__*/ template(`<div class=relative><input type=text role=combobox autocomplete=off class=input>`), _tmpl$25 = /*#__PURE__*/ template(`<span class="badge badge-primary gap-1"><button type=button class=cursor-pointer>×`), _tmpl$26 = /*#__PURE__*/ template(`<button type=button role=option class="rounded px-3 py-2 text-left">`), _tmpl$27 = /*#__PURE__*/ template(`<div role=menu class="bg-base-100 border-base-300 rounded-box absolute z-10 mt-1 flex flex-col border p-1 shadow">`), _tmpl$28 = /*#__PURE__*/ template(`<div class="relative self-start"><button type=button class="btn btn-outline btn-sm"aria-haspopup=menu>Add block`), _tmpl$29 = /*#__PURE__*/ template(`<div class="form-control md:col-span-2"><div class="label font-medium"></div><div class="flex flex-col gap-3">`), _tmpl$30 = /*#__PURE__*/ template(`<span class="text-base-content/60 truncate text-sm">`), _tmpl$31 = /*#__PURE__*/ template(`<div class="flex flex-col gap-2">`), _tmpl$32 = /*#__PURE__*/ template(`<div class="card bg-base-200 flex flex-col gap-2 p-3"><div class="flex items-center gap-2"><button type=button class="btn btn-ghost btn-sm gap-2"><span aria-hidden=true></span><span class=font-semibold></span></button><div class="ml-auto flex gap-1"><button type=button class="btn btn-ghost btn-xs"aria-label="Move up">↑</button><button type=button class="btn btn-ghost btn-xs"aria-label="Move down">↓</button><button type=button class="btn btn-ghost btn-xs"aria-label=Duplicate>⧉</button><button type=button class="btn btn-ghost btn-xs text-error"aria-label=Remove>Remove`), _tmpl$33 = /*#__PURE__*/ template(`<button type=button class="btn btn-outline btn-sm self-start">Add `), _tmpl$34 = /*#__PURE__*/ template(`<i aria-hidden=true>`), _tmpl$35 = /*#__PURE__*/ template(`<button type=button role=menuitem class="flex items-center gap-2 rounded px-3 py-2 text-left">`);
9
+ var _tmpl$$5 = /*#__PURE__*/ template(`<p class="text-sm text-error"role=alert>`), _tmpl$2$3 = /*#__PURE__*/ template(`<span class="loading loading-spinner loading-sm">`), _tmpl$3$3 = /*#__PURE__*/ template(`<button type=button class="btn flex-1">`), _tmpl$4$2 = /*#__PURE__*/ template(`<button type=button class="btn btn-primary flex-1">`), _tmpl$5$1 = /*#__PURE__*/ template(`<button type=button class="btn btn-outline flex-1">`), _tmpl$6$1 = /*#__PURE__*/ template(`<span class="text-base-content/60 self-center px-1 text-xs"aria-live=polite>`), _tmpl$7$1 = /*#__PURE__*/ template(`<div class="modal modal-open"role=dialog aria-modal=true><div class=modal-box><h3 class="text-lg font-semibold">Publish changes?</h3><p class="text-base-content/70 py-2 text-sm">Your latest saved draft will go live on the site.</p><div class=modal-action><button type=button class="btn btn-ghost">Cancel</button><button type=button class="btn btn-primary">Publish</button></div></div><button type=button class=modal-backdrop aria-label=Cancel>`), _tmpl$8$1 = /*#__PURE__*/ template(`<form class="flex flex-col gap-4"><div class="bg-base-100 sticky bottom-0 flex gap-2 border-t py-3">`), _tmpl$9$1 = /*#__PURE__*/ template(`<fieldset class="border-base-300 rounded-box border p-4"><legend class="px-2 text-sm font-semibold">`), _tmpl$0$1 = /*#__PURE__*/ template(`<div class="grid grid-cols-1 gap-4 md:grid-cols-2">`), _tmpl$1$1 = /*#__PURE__*/ template(`<span class=text-error> *`), _tmpl$10$1 = /*#__PURE__*/ template(`<p class="text-base-content/60 mb-1 text-xs">`), _tmpl$11$1 = /*#__PURE__*/ template(`<p class="text-error mt-1 text-sm"role=alert>`), _tmpl$12$1 = /*#__PURE__*/ template(`<div><label class=label>`), _tmpl$13$1 = /*#__PURE__*/ template(`<input class=input type=text>`), _tmpl$14 = /*#__PURE__*/ template(`<select class=select>`), _tmpl$15 = /*#__PURE__*/ template(`<option>`), _tmpl$16 = /*#__PURE__*/ template(`<input class=input type=number>`), _tmpl$17 = /*#__PURE__*/ template(`<input class=input type=text readonly>`), _tmpl$18 = /*#__PURE__*/ template(`<input class=checkbox type=checkbox>`), _tmpl$19 = /*#__PURE__*/ template(`<p class="text-sm opacity-70 break-all">`), _tmpl$20 = /*#__PURE__*/ template(`<p class="text-sm text-error">`), _tmpl$21 = /*#__PURE__*/ template(`<div class="flex flex-col gap-2"><input class=file-input type=file>`), _tmpl$22 = /*#__PURE__*/ template(`<div class="mb-1 flex flex-wrap gap-1">`), _tmpl$23 = /*#__PURE__*/ template(`<button type=button aria-label=Clear class="absolute top-2 right-2 cursor-pointer opacity-60">×`), _tmpl$24 = /*#__PURE__*/ template(`<div role=listbox class="bg-base-100 border-base-300 rounded-box absolute z-10 mt-1 flex max-h-56 w-full flex-col overflow-auto border p-1 shadow">`), _tmpl$25 = /*#__PURE__*/ template(`<div class=relative><input type=text role=combobox autocomplete=off class=input>`), _tmpl$26 = /*#__PURE__*/ template(`<span class="badge badge-primary gap-1"><button type=button class=cursor-pointer>×`), _tmpl$27 = /*#__PURE__*/ template(`<button type=button role=option class="rounded px-3 py-2 text-left">`), _tmpl$28 = /*#__PURE__*/ template(`<div role=menu class="bg-base-100 border-base-300 rounded-box absolute z-10 mt-1 flex flex-col border p-1 shadow">`), _tmpl$29 = /*#__PURE__*/ template(`<div class="relative self-start"><button type=button class="btn btn-outline btn-sm"aria-haspopup=menu>Add block`), _tmpl$30 = /*#__PURE__*/ template(`<div class="form-control md:col-span-2"><div class="label font-medium"></div><div class="flex flex-col gap-3">`), _tmpl$31 = /*#__PURE__*/ template(`<span class="text-base-content/60 truncate text-sm">`), _tmpl$32 = /*#__PURE__*/ template(`<div class="flex flex-col gap-2">`), _tmpl$33 = /*#__PURE__*/ template(`<div class="card bg-base-200 flex flex-col gap-2 p-3"><div class="flex items-center gap-2"><button type=button class="btn btn-ghost btn-sm gap-2"><span aria-hidden=true></span><span class=font-semibold></span></button><div class="ml-auto flex gap-1"><button type=button class="btn btn-ghost btn-xs"aria-label="Move up">↑</button><button type=button class="btn btn-ghost btn-xs"aria-label="Move down">↓</button><button type=button class="btn btn-ghost btn-xs"aria-label=Duplicate>⧉</button><button type=button class="btn btn-ghost btn-xs text-error"aria-label=Remove>Remove`), _tmpl$34 = /*#__PURE__*/ template(`<button type=button class="btn btn-outline btn-sm self-start">Add `), _tmpl$35 = /*#__PURE__*/ template(`<i aria-hidden=true>`), _tmpl$36 = /*#__PURE__*/ template(`<button type=button role=menuitem class="flex items-center gap-2 rounded px-3 py-2 text-left">`);
10
10
  const RichTextEditor = lazy(() => import("../RichTextEditor-ComcBFfl.js").then((mod) => ({ default: mod.RichTextEditor })));
11
11
  function editableFields(config) {
12
12
  return Object.entries(config.fields).filter(([key]) => key !== "id");
@@ -72,6 +72,11 @@ function CollectionEdit(props) {
72
72
  const fieldGroups = groupFields(editableFields(props.config));
73
73
  const versioned = () => props.config.versions?.drafts && props.draftActions;
74
74
  const [autosaveStatus, setAutosaveStatus] = createSignal("idle");
75
+ const [confirmingPublish, setConfirmingPublish] = createSignal(false);
76
+ function requestPublish() {
77
+ if (props.draftActions?.confirmPublish) setConfirmingPublish(true);
78
+ else props.draftActions?.onPublish?.();
79
+ }
75
80
  let autosaveTimer;
76
81
  createEffect(() => {
77
82
  const dirty = !isDefaultValue();
@@ -94,7 +99,7 @@ function CollectionEdit(props) {
94
99
  });
95
100
  onCleanup(() => clearTimeout(autosaveTimer));
96
101
  return (() => {
97
- var _el$ = _tmpl$7$1(), _el$3 = _el$.firstChild;
102
+ var _el$ = _tmpl$8$1(), _el$3 = _el$.firstChild;
98
103
  _el$.addEventListener("submit", (event) => {
99
104
  event.preventDefault();
100
105
  form.handleSubmit();
@@ -104,7 +109,7 @@ function CollectionEdit(props) {
104
109
  return props.error;
105
110
  },
106
111
  get children() {
107
- var _el$2 = _tmpl$$4();
112
+ var _el$2 = _tmpl$$5();
108
113
  insert(_el$2, () => props.error);
109
114
  return _el$2;
110
115
  }
@@ -126,9 +131,9 @@ function CollectionEdit(props) {
126
131
  });
127
132
  },
128
133
  get children() {
129
- var _el$1 = _tmpl$8$1(), _el$10 = _el$1.firstChild;
130
- insert(_el$10, () => group.name);
131
- insert(_el$1, createComponent(FieldsGrid, {
134
+ var _el$17 = _tmpl$9$1(), _el$18 = _el$17.firstChild;
135
+ insert(_el$18, () => group.name);
136
+ insert(_el$17, createComponent(FieldsGrid, {
132
137
  form,
133
138
  ctx,
134
139
  get fields() {
@@ -136,7 +141,7 @@ function CollectionEdit(props) {
136
141
  },
137
142
  values: formValues
138
143
  }), null);
139
- return _el$1;
144
+ return _el$17;
140
145
  }
141
146
  })
142
147
  }), _el$3);
@@ -150,9 +155,9 @@ function CollectionEdit(props) {
150
155
  return props.capabilities?.canUpdate !== false;
151
156
  },
152
157
  get children() {
153
- var _el$11 = _tmpl$4$1();
154
- _el$11.$$click = () => void form.handleSubmit();
155
- insert(_el$11, createComponent(Show, {
158
+ var _el$19 = _tmpl$4$2();
159
+ _el$19.$$click = () => void form.handleSubmit();
160
+ insert(_el$19, createComponent(Show, {
156
161
  get when() {
157
162
  return props.saving;
158
163
  },
@@ -163,15 +168,15 @@ function CollectionEdit(props) {
163
168
  return _tmpl$2$3();
164
169
  }
165
170
  }));
166
- effect(() => _el$11.disabled = props.saving);
167
- return _el$11;
171
+ effect(() => _el$19.disabled = props.saving);
172
+ return _el$19;
168
173
  }
169
174
  });
170
175
  },
171
176
  get children() {
172
177
  return [
173
178
  (() => {
174
- var _el$4 = _tmpl$3$1();
179
+ var _el$4 = _tmpl$3$3();
175
180
  _el$4.$$click = () => void props.draftActions?.onSaveDraft(editablePayload(formValues()));
176
181
  insert(_el$4, createComponent(Show, {
177
182
  get when() {
@@ -188,8 +193,8 @@ function CollectionEdit(props) {
188
193
  return _el$4;
189
194
  })(),
190
195
  (() => {
191
- var _el$6 = _tmpl$4$1();
192
- _el$6.$$click = () => void props.draftActions?.onPublish?.();
196
+ var _el$6 = _tmpl$4$2();
197
+ _el$6.$$click = requestPublish;
193
198
  insert(_el$6, createComponent(Show, {
194
199
  get when() {
195
200
  return props.draftActions?.publishing;
@@ -250,13 +255,28 @@ function CollectionEdit(props) {
250
255
  ];
251
256
  }
252
257
  }));
258
+ insert(_el$, createComponent(Show, {
259
+ get when() {
260
+ return confirmingPublish();
261
+ },
262
+ get children() {
263
+ var _el$1 = _tmpl$7$1(), _el$10 = _el$1.firstChild, _el$14 = _el$10.firstChild.nextSibling.nextSibling.firstChild, _el$15 = _el$14.nextSibling, _el$16 = _el$10.nextSibling;
264
+ _el$14.$$click = () => setConfirmingPublish(false);
265
+ _el$15.$$click = () => {
266
+ setConfirmingPublish(false);
267
+ props.draftActions?.onPublish?.();
268
+ };
269
+ _el$16.$$click = () => setConfirmingPublish(false);
270
+ return _el$1;
271
+ }
272
+ }), null);
253
273
  return _el$;
254
274
  })();
255
275
  }
256
276
  function FieldsGrid(props) {
257
277
  return (() => {
258
- var _el$13 = _tmpl$9$1();
259
- insert(_el$13, createComponent(For, {
278
+ var _el$21 = _tmpl$0$1();
279
+ insert(_el$21, createComponent(For, {
260
280
  get each() {
261
281
  return props.fields;
262
282
  },
@@ -269,7 +289,7 @@ function FieldsGrid(props) {
269
289
  }
270
290
  })
271
291
  }));
272
- return _el$13;
292
+ return _el$21;
273
293
  })();
274
294
  }
275
295
  function renderField(form, ctx, name, field, label) {
@@ -278,40 +298,40 @@ function renderField(form, ctx, name, field, label) {
278
298
  return createComponent(form.Field, {
279
299
  name,
280
300
  children: (fieldApi) => (() => {
281
- var _el$14 = _tmpl$11$1(), _el$15 = _el$14.firstChild;
282
- className(_el$14, `form-control ${spanClass}`);
283
- setAttribute(_el$15, "for", name);
284
- insert(_el$15, label, null);
285
- insert(_el$15, createComponent(Show, {
301
+ var _el$22 = _tmpl$12$1(), _el$23 = _el$22.firstChild;
302
+ className(_el$22, `form-control ${spanClass}`);
303
+ setAttribute(_el$23, "for", name);
304
+ insert(_el$23, label, null);
305
+ insert(_el$23, createComponent(Show, {
286
306
  get when() {
287
307
  return field.required;
288
308
  },
289
309
  get children() {
290
- return _tmpl$0$1();
310
+ return _tmpl$1$1();
291
311
  }
292
312
  }), null);
293
- insert(_el$14, createComponent(Show, {
313
+ insert(_el$22, createComponent(Show, {
294
314
  get when() {
295
315
  return field.admin?.description;
296
316
  },
297
317
  get children() {
298
- var _el$17 = _tmpl$1$1();
299
- insert(_el$17, () => field.admin?.description);
300
- return _el$17;
318
+ var _el$25 = _tmpl$10$1();
319
+ insert(_el$25, () => field.admin?.description);
320
+ return _el$25;
301
321
  }
302
322
  }), null);
303
- insert(_el$14, () => renderControl(ctx, name, field, fieldApi), null);
304
- insert(_el$14, createComponent(Show, {
323
+ insert(_el$22, () => renderControl(ctx, name, field, fieldApi), null);
324
+ insert(_el$22, createComponent(Show, {
305
325
  get when() {
306
326
  return (fieldApi().state.meta.errors?.length ?? 0) > 0;
307
327
  },
308
328
  get children() {
309
- var _el$18 = _tmpl$10$1();
310
- insert(_el$18, () => fieldApi().state.meta.errors.filter(Boolean).join(", "));
311
- return _el$18;
329
+ var _el$26 = _tmpl$11$1();
330
+ insert(_el$26, () => fieldApi().state.meta.errors.filter(Boolean).join(", "));
331
+ return _el$26;
312
332
  }
313
333
  }), null);
314
- return _el$14;
334
+ return _el$22;
315
335
  })()
316
336
  });
317
337
  }
@@ -331,75 +351,75 @@ function renderControl(ctx, name, field, fieldApi) {
331
351
  const change = (v) => fieldApi().handleChange(v);
332
352
  switch (field.type) {
333
353
  case "text": return (() => {
334
- var _el$19 = _tmpl$12$1();
335
- _el$19.addEventListener("blur", () => fieldApi().handleBlur());
336
- _el$19.$$input = (e) => change(e.currentTarget.value);
337
- setAttribute(_el$19, "id", name);
338
- _el$19.readOnly = readOnly;
354
+ var _el$27 = _tmpl$13$1();
355
+ _el$27.addEventListener("blur", () => fieldApi().handleBlur());
356
+ _el$27.$$input = (e) => change(e.currentTarget.value);
357
+ setAttribute(_el$27, "id", name);
358
+ _el$27.readOnly = readOnly;
339
359
  effect((_p$) => {
340
360
  var _v$ = field.admin?.placeholder, _v$2 = field.required;
341
- _v$ !== _p$.e && setAttribute(_el$19, "placeholder", _p$.e = _v$);
342
- _v$2 !== _p$.t && (_el$19.required = _p$.t = _v$2);
361
+ _v$ !== _p$.e && setAttribute(_el$27, "placeholder", _p$.e = _v$);
362
+ _v$2 !== _p$.t && (_el$27.required = _p$.t = _v$2);
343
363
  return _p$;
344
364
  }, {
345
365
  e: void 0,
346
366
  t: void 0
347
367
  });
348
- effect(() => _el$19.value = fieldApi().state.value ?? "");
349
- return _el$19;
368
+ effect(() => _el$27.value = fieldApi().state.value ?? "");
369
+ return _el$27;
350
370
  })();
351
371
  case "select": return (() => {
352
- var _el$20 = _tmpl$13$1();
353
- _el$20.addEventListener("blur", () => fieldApi().handleBlur());
354
- _el$20.addEventListener("change", (e) => change(e.currentTarget.value));
355
- setAttribute(_el$20, "id", name);
356
- _el$20.disabled = readOnly;
357
- insert(_el$20, createComponent(For, {
372
+ var _el$28 = _tmpl$14();
373
+ _el$28.addEventListener("blur", () => fieldApi().handleBlur());
374
+ _el$28.addEventListener("change", (e) => change(e.currentTarget.value));
375
+ setAttribute(_el$28, "id", name);
376
+ _el$28.disabled = readOnly;
377
+ insert(_el$28, createComponent(For, {
358
378
  get each() {
359
379
  return field.options;
360
380
  },
361
381
  children: (option) => (() => {
362
- var _el$21 = _tmpl$14();
363
- _el$21.value = option;
364
- insert(_el$21, option);
365
- return _el$21;
382
+ var _el$29 = _tmpl$15();
383
+ _el$29.value = option;
384
+ insert(_el$29, option);
385
+ return _el$29;
366
386
  })()
367
387
  }));
368
- effect(() => _el$20.required = field.required);
369
- effect(() => _el$20.value = fieldApi().state.value ?? "");
370
- return _el$20;
388
+ effect(() => _el$28.required = field.required);
389
+ effect(() => _el$28.value = fieldApi().state.value ?? "");
390
+ return _el$28;
371
391
  })();
372
392
  case "number": return (() => {
373
- var _el$22 = _tmpl$15();
374
- _el$22.addEventListener("blur", () => fieldApi().handleBlur());
375
- _el$22.$$input = (e) => change(e.currentTarget.valueAsNumber);
376
- setAttribute(_el$22, "id", name);
377
- _el$22.readOnly = readOnly;
393
+ var _el$30 = _tmpl$16();
394
+ _el$30.addEventListener("blur", () => fieldApi().handleBlur());
395
+ _el$30.$$input = (e) => change(e.currentTarget.valueAsNumber);
396
+ setAttribute(_el$30, "id", name);
397
+ _el$30.readOnly = readOnly;
378
398
  effect((_p$) => {
379
399
  var _v$3 = field.admin?.placeholder, _v$4 = field.required;
380
- _v$3 !== _p$.e && setAttribute(_el$22, "placeholder", _p$.e = _v$3);
381
- _v$4 !== _p$.t && (_el$22.required = _p$.t = _v$4);
400
+ _v$3 !== _p$.e && setAttribute(_el$30, "placeholder", _p$.e = _v$3);
401
+ _v$4 !== _p$.t && (_el$30.required = _p$.t = _v$4);
382
402
  return _p$;
383
403
  }, {
384
404
  e: void 0,
385
405
  t: void 0
386
406
  });
387
- effect(() => _el$22.value = fieldApi().state.value ?? "");
388
- return _el$22;
407
+ effect(() => _el$30.value = fieldApi().state.value ?? "");
408
+ return _el$30;
389
409
  })();
390
410
  case "date": return (() => {
391
- var _el$23 = _tmpl$16();
392
- setAttribute(_el$23, "id", name);
393
- effect(() => _el$23.value = formatDateValue(fieldApi().state.value));
394
- return _el$23;
411
+ var _el$31 = _tmpl$17();
412
+ setAttribute(_el$31, "id", name);
413
+ effect(() => _el$31.value = formatDateValue(fieldApi().state.value));
414
+ return _el$31;
395
415
  })();
396
416
  case "checkbox": return (() => {
397
- var _el$24 = _tmpl$17();
398
- _el$24.addEventListener("change", (e) => change(e.currentTarget.checked));
399
- setAttribute(_el$24, "id", name);
400
- _el$24.disabled = readOnly;
401
- effect(() => _el$24.checked = fieldApi().state.value ?? false);
402
- return _el$24;
417
+ var _el$32 = _tmpl$18();
418
+ _el$32.addEventListener("change", (e) => change(e.currentTarget.checked));
419
+ setAttribute(_el$32, "id", name);
420
+ _el$32.disabled = readOnly;
421
+ effect(() => _el$32.checked = fieldApi().state.value ?? false);
422
+ return _el$32;
403
423
  })();
404
424
  case "upload": return createComponent(UploadControl, {
405
425
  name,
@@ -458,19 +478,19 @@ function UploadControl(props) {
458
478
  }
459
479
  }
460
480
  return (() => {
461
- var _el$26 = _tmpl$20(), _el$28 = _el$26.firstChild;
462
- insert(_el$26, createComponent(Show, {
481
+ var _el$34 = _tmpl$21(), _el$36 = _el$34.firstChild;
482
+ insert(_el$34, createComponent(Show, {
463
483
  get when() {
464
484
  return value();
465
485
  },
466
486
  get children() {
467
- var _el$27 = _tmpl$18();
468
- insert(_el$27, value);
469
- return _el$27;
487
+ var _el$35 = _tmpl$19();
488
+ insert(_el$35, value);
489
+ return _el$35;
470
490
  }
471
- }), _el$28);
472
- _el$28.addEventListener("change", handleFileChange);
473
- insert(_el$26, createComponent(Show, {
491
+ }), _el$36);
492
+ _el$36.addEventListener("change", handleFileChange);
493
+ insert(_el$34, createComponent(Show, {
474
494
  get when() {
475
495
  return uploading();
476
496
  },
@@ -478,28 +498,28 @@ function UploadControl(props) {
478
498
  return _tmpl$2$3();
479
499
  }
480
500
  }), null);
481
- insert(_el$26, createComponent(Show, {
501
+ insert(_el$34, createComponent(Show, {
482
502
  get when() {
483
503
  return uploadError();
484
504
  },
485
505
  get children() {
486
- var _el$30 = _tmpl$19();
487
- insert(_el$30, uploadError);
488
- return _el$30;
506
+ var _el$38 = _tmpl$20();
507
+ insert(_el$38, uploadError);
508
+ return _el$38;
489
509
  }
490
510
  }), null);
491
511
  effect((_p$) => {
492
512
  var _v$5 = props.name, _v$6 = props.field.required && !value(), _v$7 = uploading() || props.field.admin?.readOnly;
493
- _v$5 !== _p$.e && setAttribute(_el$28, "id", _p$.e = _v$5);
494
- _v$6 !== _p$.t && (_el$28.required = _p$.t = _v$6);
495
- _v$7 !== _p$.a && (_el$28.disabled = _p$.a = _v$7);
513
+ _v$5 !== _p$.e && setAttribute(_el$36, "id", _p$.e = _v$5);
514
+ _v$6 !== _p$.t && (_el$36.required = _p$.t = _v$6);
515
+ _v$7 !== _p$.a && (_el$36.disabled = _p$.a = _v$7);
496
516
  return _p$;
497
517
  }, {
498
518
  e: void 0,
499
519
  t: void 0,
500
520
  a: void 0
501
521
  });
502
- return _el$26;
522
+ return _el$34;
503
523
  })();
504
524
  }
505
525
  function RelationshipField(props) {
@@ -554,86 +574,86 @@ function RelationshipField(props) {
554
574
  }
555
575
  }
556
576
  return (() => {
557
- var _el$31 = _tmpl$24(), _el$33 = _el$31.firstChild;
558
- insert(_el$31, createComponent(Show, {
577
+ var _el$39 = _tmpl$25(), _el$41 = _el$39.firstChild;
578
+ insert(_el$39, createComponent(Show, {
559
579
  get when() {
560
580
  return memo(() => !!isMulti())() && selectedOptions().length > 0;
561
581
  },
562
582
  get children() {
563
- var _el$32 = _tmpl$21();
564
- insert(_el$32, createComponent(For, {
583
+ var _el$40 = _tmpl$22();
584
+ insert(_el$40, createComponent(For, {
565
585
  get each() {
566
586
  return selectedOptions();
567
587
  },
568
588
  children: (option) => (() => {
569
- var _el$36 = _tmpl$25(), _el$37 = _el$36.firstChild;
570
- insert(_el$36, () => option.label, _el$37);
571
- _el$37.$$click = () => removeId(option.id);
572
- effect(() => setAttribute(_el$37, "aria-label", `Remove ${option.label}`));
573
- return _el$36;
589
+ var _el$44 = _tmpl$26(), _el$45 = _el$44.firstChild;
590
+ insert(_el$44, () => option.label, _el$45);
591
+ _el$45.$$click = () => removeId(option.id);
592
+ effect(() => setAttribute(_el$45, "aria-label", `Remove ${option.label}`));
593
+ return _el$44;
574
594
  })()
575
595
  }));
576
- return _el$32;
596
+ return _el$40;
577
597
  }
578
- }), _el$33);
579
- _el$33.$$keydown = onKeyDown;
580
- _el$33.addEventListener("blur", () => setTimeout(() => setOpen(false), 120));
581
- _el$33.addEventListener("focus", () => setOpen(true));
582
- _el$33.$$input = (e) => {
598
+ }), _el$41);
599
+ _el$41.$$keydown = onKeyDown;
600
+ _el$41.addEventListener("blur", () => setTimeout(() => setOpen(false), 120));
601
+ _el$41.addEventListener("focus", () => setOpen(true));
602
+ _el$41.$$input = (e) => {
583
603
  setQuery(e.currentTarget.value);
584
604
  setOpen(true);
585
605
  setActive(0);
586
606
  };
587
- setAttribute(_el$33, "aria-controls", listId);
588
- insert(_el$31, createComponent(Show, {
607
+ setAttribute(_el$41, "aria-controls", listId);
608
+ insert(_el$39, createComponent(Show, {
589
609
  get when() {
590
610
  return memo(() => !!(!isMulti() && value() != null))() && !props.field.required;
591
611
  },
592
612
  get children() {
593
- var _el$34 = _tmpl$22();
594
- _el$34.$$click = () => removeId(value());
595
- _el$34.$$mousedown = (e) => e.preventDefault();
596
- return _el$34;
613
+ var _el$42 = _tmpl$23();
614
+ _el$42.$$click = () => removeId(value());
615
+ _el$42.$$mousedown = (e) => e.preventDefault();
616
+ return _el$42;
597
617
  }
598
618
  }), null);
599
- insert(_el$31, createComponent(Show, {
619
+ insert(_el$39, createComponent(Show, {
600
620
  get when() {
601
621
  return memo(() => !!open())() && filtered().length > 0;
602
622
  },
603
623
  get children() {
604
- var _el$35 = _tmpl$23();
605
- setAttribute(_el$35, "id", listId);
606
- insert(_el$35, createComponent(For, {
624
+ var _el$43 = _tmpl$24();
625
+ setAttribute(_el$43, "id", listId);
626
+ insert(_el$43, createComponent(For, {
607
627
  get each() {
608
628
  return filtered();
609
629
  },
610
630
  children: (option, i) => (() => {
611
- var _el$38 = _tmpl$26();
612
- _el$38.$$click = () => choose(option);
613
- _el$38.$$mousedown = (e) => e.preventDefault();
614
- insert(_el$38, () => option.label);
631
+ var _el$46 = _tmpl$27();
632
+ _el$46.$$click = () => choose(option);
633
+ _el$46.$$mousedown = (e) => e.preventDefault();
634
+ insert(_el$46, () => option.label);
615
635
  effect((_p$) => {
616
636
  var _v$11 = selectedIds().includes(option.id), _v$12 = !!(i() === active());
617
- _v$11 !== _p$.e && setAttribute(_el$38, "aria-selected", _p$.e = _v$11);
618
- _v$12 !== _p$.t && _el$38.classList.toggle("bg-base-200", _p$.t = _v$12);
637
+ _v$11 !== _p$.e && setAttribute(_el$46, "aria-selected", _p$.e = _v$11);
638
+ _v$12 !== _p$.t && _el$46.classList.toggle("bg-base-200", _p$.t = _v$12);
619
639
  return _p$;
620
640
  }, {
621
641
  e: void 0,
622
642
  t: void 0
623
643
  });
624
- return _el$38;
644
+ return _el$46;
625
645
  })()
626
646
  }));
627
- return _el$35;
647
+ return _el$43;
628
648
  }
629
649
  }), null);
630
650
  effect((_p$) => {
631
651
  var _v$8 = props.name, _v$9 = open(), _v$0 = props.field.required && selectedIds().length === 0, _v$1 = props.field.admin?.readOnly, _v$10 = props.field.admin?.placeholder ?? "Search…";
632
- _v$8 !== _p$.e && setAttribute(_el$33, "id", _p$.e = _v$8);
633
- _v$9 !== _p$.t && setAttribute(_el$33, "aria-expanded", _p$.t = _v$9);
634
- _v$0 !== _p$.a && (_el$33.required = _p$.a = _v$0);
635
- _v$1 !== _p$.o && (_el$33.disabled = _p$.o = _v$1);
636
- _v$10 !== _p$.i && setAttribute(_el$33, "placeholder", _p$.i = _v$10);
652
+ _v$8 !== _p$.e && setAttribute(_el$41, "id", _p$.e = _v$8);
653
+ _v$9 !== _p$.t && setAttribute(_el$41, "aria-expanded", _p$.t = _v$9);
654
+ _v$0 !== _p$.a && (_el$41.required = _p$.a = _v$0);
655
+ _v$1 !== _p$.o && (_el$41.disabled = _p$.o = _v$1);
656
+ _v$10 !== _p$.i && setAttribute(_el$41, "placeholder", _p$.i = _v$10);
637
657
  return _p$;
638
658
  }, {
639
659
  e: void 0,
@@ -642,8 +662,8 @@ function RelationshipField(props) {
642
662
  o: void 0,
643
663
  i: void 0
644
664
  });
645
- effect(() => _el$33.value = open() || isMulti() ? query() : singleLabel());
646
- return _el$31;
665
+ effect(() => _el$41.value = open() || isMulti() ? query() : singleLabel());
666
+ return _el$39;
647
667
  })();
648
668
  }
649
669
  function renderArray(form, ctx, name, field, label) {
@@ -704,129 +724,129 @@ function BlockEditor(props) {
704
724
  return "";
705
725
  }
706
726
  return (() => {
707
- var _el$39 = _tmpl$29(), _el$40 = _el$39.firstChild, _el$43 = _el$40.nextSibling;
708
- insert(_el$40, () => props.label, null);
709
- insert(_el$40, createComponent(Show, {
727
+ var _el$47 = _tmpl$30(), _el$48 = _el$47.firstChild, _el$51 = _el$48.nextSibling;
728
+ insert(_el$48, () => props.label, null);
729
+ insert(_el$48, createComponent(Show, {
710
730
  get when() {
711
731
  return props.field.required;
712
732
  },
713
733
  get children() {
714
- return _tmpl$0$1();
734
+ return _tmpl$1$1();
715
735
  }
716
736
  }), null);
717
- insert(_el$39, createComponent(Show, {
737
+ insert(_el$47, createComponent(Show, {
718
738
  get when() {
719
739
  return props.field.admin?.description;
720
740
  },
721
741
  get children() {
722
- var _el$42 = _tmpl$1$1();
723
- insert(_el$42, () => props.field.admin?.description);
724
- return _el$42;
742
+ var _el$50 = _tmpl$10$1();
743
+ insert(_el$50, () => props.field.admin?.description);
744
+ return _el$50;
725
745
  }
726
- }), _el$43);
727
- insert(_el$43, createComponent(Index, {
746
+ }), _el$51);
747
+ insert(_el$51, createComponent(Index, {
728
748
  get each() {
729
749
  return items();
730
750
  },
731
751
  children: (item, index) => {
732
752
  const isCollapsed = () => collapsed().has(index);
733
753
  return (() => {
734
- var _el$47 = _tmpl$32(), _el$48 = _el$47.firstChild, _el$49 = _el$48.firstChild, _el$50 = _el$49.firstChild, _el$51 = _el$50.nextSibling, _el$53 = _el$49.nextSibling, _el$54 = _el$53.firstChild, _el$55 = _el$54.nextSibling, _el$56 = _el$55.nextSibling, _el$57 = _el$56.nextSibling;
735
- _el$49.$$click = () => toggleCollapse(index);
736
- insert(_el$50, () => isCollapsed() ? "▸" : "▾");
737
- insert(_el$51, () => blockTitle(item()));
738
- insert(_el$48, createComponent(Show, {
754
+ var _el$55 = _tmpl$33(), _el$56 = _el$55.firstChild, _el$57 = _el$56.firstChild, _el$58 = _el$57.firstChild, _el$59 = _el$58.nextSibling, _el$61 = _el$57.nextSibling, _el$62 = _el$61.firstChild, _el$63 = _el$62.nextSibling, _el$64 = _el$63.nextSibling, _el$65 = _el$64.nextSibling;
755
+ _el$57.$$click = () => toggleCollapse(index);
756
+ insert(_el$58, () => isCollapsed() ? "▸" : "▾");
757
+ insert(_el$59, () => blockTitle(item()));
758
+ insert(_el$56, createComponent(Show, {
739
759
  get when() {
740
760
  return memo(() => !!isCollapsed())() && blockSummary(item());
741
761
  },
742
762
  get children() {
743
- var _el$52 = _tmpl$30();
744
- insert(_el$52, () => blockSummary(item()));
745
- return _el$52;
763
+ var _el$60 = _tmpl$31();
764
+ insert(_el$60, () => blockSummary(item()));
765
+ return _el$60;
746
766
  }
747
- }), _el$53);
748
- _el$54.$$click = () => move(index, index - 1);
749
- _el$54.disabled = index === 0;
750
- _el$55.$$click = () => move(index, index + 1);
751
- _el$56.$$click = () => duplicate(index);
752
- _el$57.$$click = () => props.fieldApi().removeValue(index);
753
- insert(_el$47, createComponent(Show, {
767
+ }), _el$61);
768
+ _el$62.$$click = () => move(index, index - 1);
769
+ _el$62.disabled = index === 0;
770
+ _el$63.$$click = () => move(index, index + 1);
771
+ _el$64.$$click = () => duplicate(index);
772
+ _el$65.$$click = () => props.fieldApi().removeValue(index);
773
+ insert(_el$55, createComponent(Show, {
754
774
  get when() {
755
775
  return !isCollapsed();
756
776
  },
757
777
  get children() {
758
- var _el$58 = _tmpl$31();
759
- insert(_el$58, createComponent(For, {
778
+ var _el$66 = _tmpl$32();
779
+ insert(_el$66, createComponent(For, {
760
780
  get each() {
761
781
  return fieldsForItem(props.field, item());
762
782
  },
763
783
  children: ([itemKey, itemField]) => renderField(props.form, props.ctx, `${props.name}[${index}].${itemKey}`, itemField, labelFor(itemKey, itemField))
764
784
  }));
765
- return _el$58;
785
+ return _el$66;
766
786
  }
767
787
  }), null);
768
788
  effect((_p$) => {
769
789
  var _v$13 = !isCollapsed(), _v$14 = index === items().length - 1;
770
- _v$13 !== _p$.e && setAttribute(_el$49, "aria-expanded", _p$.e = _v$13);
771
- _v$14 !== _p$.t && (_el$55.disabled = _p$.t = _v$14);
790
+ _v$13 !== _p$.e && setAttribute(_el$57, "aria-expanded", _p$.e = _v$13);
791
+ _v$14 !== _p$.t && (_el$63.disabled = _p$.t = _v$14);
772
792
  return _p$;
773
793
  }, {
774
794
  e: void 0,
775
795
  t: void 0
776
796
  });
777
- return _el$47;
797
+ return _el$55;
778
798
  })();
779
799
  }
780
800
  }), null);
781
- insert(_el$43, createComponent(Show, {
801
+ insert(_el$51, createComponent(Show, {
782
802
  get when() {
783
803
  return disc && variants.length > 0;
784
804
  },
785
805
  get fallback() {
786
806
  return (() => {
787
- var _el$59 = _tmpl$33();
788
- _el$59.firstChild;
789
- _el$59.$$click = () => addBlock();
790
- insert(_el$59, () => props.label, null);
791
- return _el$59;
807
+ var _el$67 = _tmpl$34();
808
+ _el$67.firstChild;
809
+ _el$67.$$click = () => addBlock();
810
+ insert(_el$67, () => props.label, null);
811
+ return _el$67;
792
812
  })();
793
813
  },
794
814
  get children() {
795
- var _el$44 = _tmpl$28(), _el$45 = _el$44.firstChild;
796
- _el$45.$$click = () => setMenuOpen((o) => !o);
797
- insert(_el$44, createComponent(Show, {
815
+ var _el$52 = _tmpl$29(), _el$53 = _el$52.firstChild;
816
+ _el$53.$$click = () => setMenuOpen((o) => !o);
817
+ insert(_el$52, createComponent(Show, {
798
818
  get when() {
799
819
  return menuOpen();
800
820
  },
801
821
  get children() {
802
- var _el$46 = _tmpl$27();
803
- insert(_el$46, createComponent(For, {
822
+ var _el$54 = _tmpl$28();
823
+ insert(_el$54, createComponent(For, {
804
824
  each: variants,
805
825
  children: (variant) => (() => {
806
- var _el$61 = _tmpl$35();
807
- _el$61.$$click = () => addBlock(variant);
808
- insert(_el$61, createComponent(Show, {
826
+ var _el$69 = _tmpl$36();
827
+ _el$69.$$click = () => addBlock(variant);
828
+ insert(_el$69, createComponent(Show, {
809
829
  get when() {
810
830
  return disc?.variantsAdmin?.[variant]?.icon;
811
831
  },
812
832
  get children() {
813
- var _el$62 = _tmpl$34();
814
- effect(() => className(_el$62, disc?.variantsAdmin?.[variant]?.icon));
815
- return _el$62;
833
+ var _el$70 = _tmpl$35();
834
+ effect(() => className(_el$70, disc?.variantsAdmin?.[variant]?.icon));
835
+ return _el$70;
816
836
  }
817
837
  }), null);
818
- insert(_el$61, () => variantLabel(disc, variant), null);
819
- return _el$61;
838
+ insert(_el$69, () => variantLabel(disc, variant), null);
839
+ return _el$69;
820
840
  })()
821
841
  }));
822
- return _el$46;
842
+ return _el$54;
823
843
  }
824
844
  }), null);
825
- effect(() => setAttribute(_el$45, "aria-expanded", menuOpen()));
826
- return _el$44;
845
+ effect(() => setAttribute(_el$53, "aria-expanded", menuOpen()));
846
+ return _el$52;
827
847
  }
828
848
  }), null);
829
- return _el$39;
849
+ return _el$47;
830
850
  })();
831
851
  }
832
852
  function fieldsForItem(field, item) {
@@ -850,7 +870,7 @@ delegateEvents([
850
870
  ]);
851
871
  //#endregion
852
872
  //#region src/tanstack-start/create.tsx
853
- var _tmpl$$3 = /*#__PURE__*/ template(`<div class="flex flex-col gap-4"><h1 class="text-xl font-semibold">`);
873
+ var _tmpl$$4 = /*#__PURE__*/ template(`<div class="flex flex-col gap-4"><h1 class="text-xl font-semibold">`);
854
874
  /**
855
875
  * Builds a create-page component for a collection. See
856
876
  * `createCollectionListPage`'s doc comment for the same rationale on
@@ -869,7 +889,7 @@ function createCollectionCreatePage(options) {
869
889
  onError: (e) => setError(e.message)
870
890
  }));
871
891
  return (() => {
872
- var _el$ = _tmpl$$3(), _el$2 = _el$.firstChild;
892
+ var _el$ = _tmpl$$4(), _el$2 = _el$.firstChild;
873
893
  insert(_el$2, () => options.label ?? `New ${options.collection.slug}`);
874
894
  insert(_el$, createComponent(CollectionEdit, {
875
895
  get config() {
@@ -894,8 +914,63 @@ function createCollectionCreatePage(options) {
894
914
  };
895
915
  }
896
916
  //#endregion
917
+ //#region src/VisualEditingPane.tsx
918
+ var _tmpl$$3 = /*#__PURE__*/ template(`<iframe>`);
919
+ function originOf(url) {
920
+ try {
921
+ return new URL(url).origin;
922
+ } catch {
923
+ return;
924
+ }
925
+ }
926
+ function VisualEditingPane(props) {
927
+ let iframe;
928
+ const targetOrigin = () => props.allowedOrigin ?? originOf(props.src) ?? "*";
929
+ onMount(() => {
930
+ const expected = props.allowedOrigin ?? originOf(props.src);
931
+ const handler = (event) => {
932
+ if (expected && event.origin !== expected) return;
933
+ const data = event.data;
934
+ if (data?.type === VISUAL_EDIT_MESSAGE && data.ref) props.onEdit?.(data.ref);
935
+ };
936
+ window.addEventListener("message", handler);
937
+ onCleanup(() => window.removeEventListener("message", handler));
938
+ });
939
+ createEffect(() => {
940
+ const values = props.previewValues;
941
+ const target = props.previewTarget;
942
+ const win = iframe?.contentWindow;
943
+ if (!values || !target || !win) return;
944
+ const message = {
945
+ type: PREVIEW_VALUES_MESSAGE,
946
+ collection: target.collection,
947
+ id: target.id,
948
+ values
949
+ };
950
+ win.postMessage(message, targetOrigin());
951
+ });
952
+ return (() => {
953
+ var _el$ = _tmpl$$3();
954
+ use((el) => {
955
+ iframe = el;
956
+ }, _el$);
957
+ effect((_p$) => {
958
+ var _v$ = props.src, _v$2 = props.title ?? "Preview", _v$3 = props.class ?? "h-full w-full border-0";
959
+ _v$ !== _p$.e && setAttribute(_el$, "src", _p$.e = _v$);
960
+ _v$2 !== _p$.t && setAttribute(_el$, "title", _p$.t = _v$2);
961
+ _v$3 !== _p$.a && className(_el$, _p$.a = _v$3);
962
+ return _p$;
963
+ }, {
964
+ e: void 0,
965
+ t: void 0,
966
+ a: void 0
967
+ });
968
+ return _el$;
969
+ })();
970
+ }
971
+ //#endregion
897
972
  //#region src/tanstack-start/edit.tsx
898
- var _tmpl$$2 = /*#__PURE__*/ template(`<button type=button class="btn btn-error btn-outline btn-sm self-start">`), _tmpl$2$2 = /*#__PURE__*/ template(`<div class="flex flex-col gap-4"><h1 class="text-xl font-semibold">`);
973
+ var _tmpl$$2 = /*#__PURE__*/ template(`<button type=button class="btn btn-error btn-outline btn-sm self-start">`), _tmpl$2$2 = /*#__PURE__*/ template(`<div class="flex flex-col gap-4"><h1 class="text-xl font-semibold">`), _tmpl$3$2 = /*#__PURE__*/ template(`<div class="grid grid-cols-1 gap-4 lg:grid-cols-2">`), _tmpl$4$1 = /*#__PURE__*/ template(`<div class="lg:sticky lg:top-4 lg:h-[calc(100vh-2rem)]">`);
899
974
  /**
900
975
  * Builds an edit-page component for a collection — fetch, update, and
901
976
  * delete, all wired together, plus a router-level unsaved-changes guard
@@ -909,6 +984,7 @@ function createCollectionEditPage(options) {
909
984
  const [error, setError] = createSignal();
910
985
  const [dirty, setDirty] = createSignal(false);
911
986
  const [latestDraftId, setLatestDraftId] = createSignal();
987
+ const [previewValues, setPreviewValues] = createSignal({});
912
988
  useBlocker({
913
989
  shouldBlockFn: () => dirty(),
914
990
  enableBeforeUnload: () => dirty()
@@ -965,7 +1041,7 @@ function createCollectionEditPage(options) {
965
1041
  },
966
1042
  onError: (e) => setError(e.message)
967
1043
  }));
968
- return (() => {
1044
+ const EditorPane = () => (() => {
969
1045
  var _el$ = _tmpl$2$2(), _el$2 = _el$.firstChild;
970
1046
  insert(_el$2, () => options.label ?? `Edit ${options.collection.slug}`);
971
1047
  insert(_el$, createComponent(Show, {
@@ -997,6 +1073,7 @@ function createCollectionEditPage(options) {
997
1073
  return options.fieldWidgets;
998
1074
  },
999
1075
  onDirtyChange: setDirty,
1076
+ onValuesChange: setPreviewValues,
1000
1077
  get capabilities() {
1001
1078
  return options.capabilities?.();
1002
1079
  },
@@ -1012,7 +1089,8 @@ function createCollectionEditPage(options) {
1012
1089
  canPreview: latestDraftId() !== void 0,
1013
1090
  saveDraftLabel: options.draftActions.saveDraftLabel,
1014
1091
  publishLabel: options.draftActions.publishLabel,
1015
- previewLabel: options.draftActions.previewLabel
1092
+ previewLabel: options.draftActions.previewLabel,
1093
+ autosave: options.draftActions.autosave
1016
1094
  };
1017
1095
  }
1018
1096
  });
@@ -1031,12 +1109,53 @@ function createCollectionEditPage(options) {
1031
1109
  }), null);
1032
1110
  return _el$;
1033
1111
  })();
1112
+ return createComponent(Show, {
1113
+ get when() {
1114
+ return options.preview;
1115
+ },
1116
+ get fallback() {
1117
+ return createComponent(EditorPane, {});
1118
+ },
1119
+ get children() {
1120
+ var _el$4 = _tmpl$3$2();
1121
+ insert(_el$4, createComponent(EditorPane, {}), null);
1122
+ insert(_el$4, createComponent(Show, {
1123
+ get when() {
1124
+ return options.preview?.url();
1125
+ },
1126
+ children: (url) => (() => {
1127
+ var _el$5 = _tmpl$4$1();
1128
+ insert(_el$5, createComponent(VisualEditingPane, {
1129
+ get src() {
1130
+ return url();
1131
+ },
1132
+ get allowedOrigin() {
1133
+ return options.preview?.allowedOrigin?.();
1134
+ },
1135
+ get previewValues() {
1136
+ return previewValues();
1137
+ },
1138
+ get previewTarget() {
1139
+ return {
1140
+ collection: options.collection.slug,
1141
+ id: Number(row.data?.id)
1142
+ };
1143
+ },
1144
+ "class": "border-base-300 rounded-box h-full w-full border",
1145
+ title: "Live preview"
1146
+ }));
1147
+ return _el$5;
1148
+ })()
1149
+ }), null);
1150
+ return _el$4;
1151
+ }
1152
+ });
1034
1153
  };
1035
1154
  }
1036
1155
  delegateEvents(["click"]);
1037
1156
  //#endregion
1038
1157
  //#region src/CollectionList.tsx
1039
- var _tmpl$$1 = /*#__PURE__*/ template(`<button type=button class="btn btn-outline btn-sm">`), _tmpl$2$1 = /*#__PURE__*/ template(`<div class=join><select aria-label="Sort by"class="select select-sm join-item"></select><select aria-label="Sort direction"class="select select-sm join-item"><option value=asc>Ascending</option><option value=desc>Descending`), _tmpl$3 = /*#__PURE__*/ template(`<table class="table hidden md:table"><thead></thead><tbody>`), _tmpl$4 = /*#__PURE__*/ template(`<div class="flex flex-col gap-2 md:hidden">`), _tmpl$5 = /*#__PURE__*/ template(`<div class="bg-base-100 sticky bottom-0 flex items-center justify-between gap-2 border-t py-2"><button type=button class="btn btn-sm">Prev</button><span class="text-sm opacity-70">Page </span><button type=button class="btn btn-sm">Next`), _tmpl$6 = /*#__PURE__*/ template(`<div class="flex flex-col gap-3"><div class="flex flex-wrap items-center justify-between gap-2">`), _tmpl$7 = /*#__PURE__*/ template(`<option>`), _tmpl$8 = /*#__PURE__*/ template(`<p class="text-sm opacity-70">No <!> yet.`), _tmpl$9 = /*#__PURE__*/ template(`<th>`), _tmpl$0 = /*#__PURE__*/ template(`<tr>`), _tmpl$1 = /*#__PURE__*/ template(`<td><input type=checkbox class="checkbox checkbox-sm">`), _tmpl$10 = /*#__PURE__*/ template(`<td>`), _tmpl$11 = /*#__PURE__*/ template(`<input type=checkbox class="checkbox checkbox-sm mt-1">`), _tmpl$12 = /*#__PURE__*/ template(`<div class="card bg-base-200 cursor-pointer p-3"role=button tabindex=0><div class="flex items-start gap-3"><div class="flex flex-1 flex-col gap-1">`), _tmpl$13 = /*#__PURE__*/ template(`<div class="flex justify-between gap-2 text-sm"><span class=opacity-60></span><span class=text-right>`);
1158
+ var _tmpl$$1 = /*#__PURE__*/ template(`<button type=button class="btn btn-outline btn-sm">`), _tmpl$2$1 = /*#__PURE__*/ template(`<div class=join><select aria-label="Sort by"class="select select-sm join-item"></select><select aria-label="Sort direction"class="select select-sm join-item"><option value=asc>Ascending</option><option value=desc>Descending`), _tmpl$3$1 = /*#__PURE__*/ template(`<table class="table hidden md:table"><thead></thead><tbody>`), _tmpl$4 = /*#__PURE__*/ template(`<div class="flex flex-col gap-2 md:hidden">`), _tmpl$5 = /*#__PURE__*/ template(`<div class="bg-base-100 sticky bottom-0 flex items-center justify-between gap-2 border-t py-2"><button type=button class="btn btn-sm">Prev</button><span class="text-sm opacity-70">Page </span><button type=button class="btn btn-sm">Next`), _tmpl$6 = /*#__PURE__*/ template(`<div class="flex flex-col gap-3"><div class="flex flex-wrap items-center justify-between gap-2">`), _tmpl$7 = /*#__PURE__*/ template(`<option>`), _tmpl$8 = /*#__PURE__*/ template(`<div class="border-base-300 rounded-box flex flex-col items-center gap-1 border border-dashed py-12 text-center"><p class="text-base-content/70 m-0">No <!> yet.`), _tmpl$9 = /*#__PURE__*/ template(`<th>`), _tmpl$0 = /*#__PURE__*/ template(`<tr>`), _tmpl$1 = /*#__PURE__*/ template(`<td><input type=checkbox class="checkbox checkbox-sm">`), _tmpl$10 = /*#__PURE__*/ template(`<td>`), _tmpl$11 = /*#__PURE__*/ template(`<input type=checkbox class="checkbox checkbox-sm mt-1">`), _tmpl$12 = /*#__PURE__*/ template(`<div class="card bg-base-200 cursor-pointer p-3"role=button tabindex=0><div class="flex items-start gap-3"><div class="flex flex-1 flex-col gap-1">`), _tmpl$13 = /*#__PURE__*/ template(`<div class="flex justify-between gap-2 text-sm"><span class=opacity-60></span><span class=text-right>`);
1040
1159
  function listableFields(config) {
1041
1160
  const excluded = new Set([
1042
1161
  "richText",
@@ -1126,23 +1245,23 @@ function CollectionList(props) {
1126
1245
  return props.rows.length > 0;
1127
1246
  },
1128
1247
  get fallback() {
1129
- return (() => {
1130
- var _el$15 = _tmpl$8(), _el$18 = _el$15.firstChild.nextSibling;
1131
- _el$18.nextSibling;
1132
- insert(_el$15, () => props.config.slug, _el$18);
1248
+ return props.emptyState ?? (() => {
1249
+ var _el$15 = _tmpl$8(), _el$16 = _el$15.firstChild, _el$19 = _el$16.firstChild.nextSibling;
1250
+ _el$19.nextSibling;
1251
+ insert(_el$16, () => props.config.slug, _el$19);
1133
1252
  return _el$15;
1134
1253
  })();
1135
1254
  },
1136
1255
  get children() {
1137
1256
  return [(() => {
1138
- var _el$7 = _tmpl$3(), _el$8 = _el$7.firstChild, _el$9 = _el$8.nextSibling;
1257
+ var _el$7 = _tmpl$3$1(), _el$8 = _el$7.firstChild, _el$9 = _el$8.nextSibling;
1139
1258
  insert(_el$8, createComponent(For, {
1140
1259
  get each() {
1141
1260
  return table.getHeaderGroups();
1142
1261
  },
1143
1262
  children: (headerGroup) => (() => {
1144
- var _el$19 = _tmpl$0();
1145
- insert(_el$19, createComponent(Show, {
1263
+ var _el$20 = _tmpl$0();
1264
+ insert(_el$20, createComponent(Show, {
1146
1265
  get when() {
1147
1266
  return selectMode();
1148
1267
  },
@@ -1150,17 +1269,17 @@ function CollectionList(props) {
1150
1269
  return _tmpl$9();
1151
1270
  }
1152
1271
  }), null);
1153
- insert(_el$19, createComponent(For, {
1272
+ insert(_el$20, createComponent(For, {
1154
1273
  get each() {
1155
1274
  return headerGroup.headers;
1156
1275
  },
1157
1276
  children: (header) => (() => {
1158
- var _el$21 = _tmpl$9();
1159
- insert(_el$21, () => flexRender(header.column.columnDef.header, header.getContext()));
1160
- return _el$21;
1277
+ var _el$22 = _tmpl$9();
1278
+ insert(_el$22, () => flexRender(header.column.columnDef.header, header.getContext()));
1279
+ return _el$22;
1161
1280
  })()
1162
1281
  }), null);
1163
- return _el$19;
1282
+ return _el$20;
1164
1283
  })()
1165
1284
  }));
1166
1285
  insert(_el$9, createComponent(For, {
@@ -1168,35 +1287,35 @@ function CollectionList(props) {
1168
1287
  return table.getRowModel().rows;
1169
1288
  },
1170
1289
  children: (row) => (() => {
1171
- var _el$22 = _tmpl$0();
1172
- _el$22.$$click = () => handleRowActivate(row.original);
1173
- insert(_el$22, createComponent(Show, {
1290
+ var _el$23 = _tmpl$0();
1291
+ _el$23.$$click = () => handleRowActivate(row.original);
1292
+ insert(_el$23, createComponent(Show, {
1174
1293
  get when() {
1175
1294
  return selectMode();
1176
1295
  },
1177
1296
  get children() {
1178
- var _el$23 = _tmpl$1(), _el$24 = _el$23.firstChild;
1179
- _el$24.addEventListener("change", () => {
1297
+ var _el$24 = _tmpl$1(), _el$25 = _el$24.firstChild;
1298
+ _el$25.addEventListener("change", () => {
1180
1299
  const id = rowId(row.original);
1181
1300
  if (id !== void 0) toggleSelected(id);
1182
1301
  });
1183
- _el$24.$$click = (e) => e.stopPropagation();
1184
- effect(() => _el$24.checked = rowId(row.original) !== void 0 && (props.selectedIds?.has(rowId(row.original)) ?? false));
1185
- return _el$23;
1302
+ _el$25.$$click = (e) => e.stopPropagation();
1303
+ effect(() => _el$25.checked = rowId(row.original) !== void 0 && (props.selectedIds?.has(rowId(row.original)) ?? false));
1304
+ return _el$24;
1186
1305
  }
1187
1306
  }), null);
1188
- insert(_el$22, createComponent(For, {
1307
+ insert(_el$23, createComponent(For, {
1189
1308
  get each() {
1190
1309
  return row.getVisibleCells();
1191
1310
  },
1192
1311
  children: (cell) => (() => {
1193
- var _el$25 = _tmpl$10();
1194
- insert(_el$25, () => flexRender(cell.column.columnDef.cell, cell.getContext()));
1195
- return _el$25;
1312
+ var _el$26 = _tmpl$10();
1313
+ insert(_el$26, () => flexRender(cell.column.columnDef.cell, cell.getContext()));
1314
+ return _el$26;
1196
1315
  })()
1197
1316
  }), null);
1198
- effect(() => className(_el$22, props.onRowClick || selectMode() ? "cursor-pointer hover" : void 0));
1199
- return _el$22;
1317
+ effect(() => className(_el$23, props.onRowClick || selectMode() ? "cursor-pointer hover" : void 0));
1318
+ return _el$23;
1200
1319
  })()
1201
1320
  }));
1202
1321
  return _el$7;
@@ -1207,41 +1326,41 @@ function CollectionList(props) {
1207
1326
  return table.getRowModel().rows;
1208
1327
  },
1209
1328
  children: (row) => (() => {
1210
- var _el$26 = _tmpl$12(), _el$27 = _el$26.firstChild, _el$29 = _el$27.firstChild;
1211
- _el$26.$$keydown = (e) => {
1329
+ var _el$27 = _tmpl$12(), _el$28 = _el$27.firstChild, _el$30 = _el$28.firstChild;
1330
+ _el$27.$$keydown = (e) => {
1212
1331
  if (e.key === "Enter" || e.key === " ") {
1213
1332
  e.preventDefault();
1214
1333
  handleRowActivate(row.original);
1215
1334
  }
1216
1335
  };
1217
- _el$26.$$click = () => handleRowActivate(row.original);
1218
- insert(_el$27, createComponent(Show, {
1336
+ _el$27.$$click = () => handleRowActivate(row.original);
1337
+ insert(_el$28, createComponent(Show, {
1219
1338
  get when() {
1220
1339
  return selectMode();
1221
1340
  },
1222
1341
  get children() {
1223
- var _el$28 = _tmpl$11();
1224
- _el$28.addEventListener("change", () => {
1342
+ var _el$29 = _tmpl$11();
1343
+ _el$29.addEventListener("change", () => {
1225
1344
  const id = rowId(row.original);
1226
1345
  if (id !== void 0) toggleSelected(id);
1227
1346
  });
1228
- _el$28.$$click = (e) => e.stopPropagation();
1229
- effect(() => _el$28.checked = rowId(row.original) !== void 0 && (props.selectedIds?.has(rowId(row.original)) ?? false));
1230
- return _el$28;
1347
+ _el$29.$$click = (e) => e.stopPropagation();
1348
+ effect(() => _el$29.checked = rowId(row.original) !== void 0 && (props.selectedIds?.has(rowId(row.original)) ?? false));
1349
+ return _el$29;
1231
1350
  }
1232
- }), _el$29);
1233
- insert(_el$29, createComponent(For, {
1351
+ }), _el$30);
1352
+ insert(_el$30, createComponent(For, {
1234
1353
  get each() {
1235
1354
  return row.getVisibleCells();
1236
1355
  },
1237
1356
  children: (cell) => (() => {
1238
- var _el$30 = _tmpl$13(), _el$31 = _el$30.firstChild, _el$32 = _el$31.nextSibling;
1239
- insert(_el$31, () => cell.column.id);
1240
- insert(_el$32, () => flexRender(cell.column.columnDef.cell, cell.getContext()));
1241
- return _el$30;
1357
+ var _el$31 = _tmpl$13(), _el$32 = _el$31.firstChild, _el$33 = _el$32.nextSibling;
1358
+ insert(_el$32, () => cell.column.id);
1359
+ insert(_el$33, () => flexRender(cell.column.columnDef.cell, cell.getContext()));
1360
+ return _el$31;
1242
1361
  })()
1243
1362
  }));
1244
- return _el$26;
1363
+ return _el$27;
1245
1364
  })()
1246
1365
  }));
1247
1366
  return _el$0;
@@ -1277,7 +1396,7 @@ function CollectionList(props) {
1277
1396
  delegateEvents(["click", "keydown"]);
1278
1397
  //#endregion
1279
1398
  //#region src/tanstack-start/list.tsx
1280
- var _tmpl$ = /*#__PURE__*/ template(`<div class="flex flex-col gap-4"><div class="flex items-center justify-between"><h1 class="text-xl font-semibold">`), _tmpl$2 = /*#__PURE__*/ template(`<div class="loading loading-spinner">`);
1399
+ var _tmpl$ = /*#__PURE__*/ template(`<div class="flex flex-col gap-4"><div class="flex items-center justify-between"><h1 class="text-xl font-semibold">`), _tmpl$2 = /*#__PURE__*/ template(`<div class="loading loading-spinner">`), _tmpl$3 = /*#__PURE__*/ template(`<div class="border-base-300 rounded-box flex flex-col items-center gap-3 border border-dashed py-12 text-center"><p class="text-base-content/70 m-0">No <!> yet.`);
1281
1400
  /**
1282
1401
  * Builds a list-view page component for a collection — paginated/sortable
1283
1402
  * query, loading state, and the generic table/card list, wired together.
@@ -1363,6 +1482,30 @@ function createCollectionListPage(options) {
1363
1482
  get rows() {
1364
1483
  return result.data?.rows ?? [];
1365
1484
  },
1485
+ get emptyState() {
1486
+ return (() => {
1487
+ var _el$5 = _tmpl$3(), _el$6 = _el$5.firstChild, _el$9 = _el$6.firstChild.nextSibling;
1488
+ _el$9.nextSibling;
1489
+ insert(_el$6, () => options.label ?? options.collection.slug, _el$9);
1490
+ insert(_el$5, createComponent(Show, {
1491
+ get when() {
1492
+ return memo(() => !!options.newHref)() && options.capabilities?.()?.canCreate !== false;
1493
+ },
1494
+ get children() {
1495
+ return createComponent(Link, {
1496
+ get to() {
1497
+ return options.newHref;
1498
+ },
1499
+ "class": "btn btn-primary btn-sm",
1500
+ get children() {
1501
+ return options.newLabel ?? `New ${options.collection.slug}`;
1502
+ }
1503
+ });
1504
+ }
1505
+ }), null);
1506
+ return _el$5;
1507
+ })();
1508
+ },
1366
1509
  get onRowClick() {
1367
1510
  return options.onRowClick;
1368
1511
  },