@thebes/cadmea 1.4.0 → 1.6.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.
@@ -128,6 +128,12 @@ interface CollectionEditProps {
128
128
  * consuming route) since `CollectionEdit` has no router access itself.
129
129
  */
130
130
  onDirtyChange?: (dirty: boolean) => void;
131
+ /**
132
+ * Fired with the current editable values on every change — wire this to a
133
+ * side-by-side live preview (e.g. `VisualEditingPane`'s `previewValues`).
134
+ * Fires on mount with the initial values too.
135
+ */
136
+ onValuesChange?: (values: Record<string, unknown>) => void;
131
137
  /**
132
138
  * Per-field custom editor widgets (issue #17), keyed by field name. When a
133
139
  * field has a widget here, it's rendered instead of the generic input for
@@ -223,6 +229,17 @@ interface VisualEditingPaneProps {
223
229
  /** Class for the iframe (size it via the consumer's layout). */
224
230
  class?: string;
225
231
  title?: string;
232
+ /**
233
+ * In-progress form values to push into the preview for as-you-type live
234
+ * updates. Posted to the iframe on every change; the preview page must call
235
+ * `mountPreviewSync` to receive them. Requires `previewTarget`.
236
+ */
237
+ previewValues?: Record<string, unknown>;
238
+ /** Which document `previewValues` belong to (matched by the preview). */
239
+ previewTarget?: {
240
+ collection: string;
241
+ id: number;
242
+ };
226
243
  }
227
244
  declare function VisualEditingPane(props: VisualEditingPaneProps): import("solid-js").JSX.Element;
228
245
  //#endregion
@@ -1,6 +1,6 @@
1
1
  import { className, createComponent, delegateEvents, effect, insert, memo, setAttribute, setStyleProperty, template, use } from "solid-js/web";
2
2
  import { createForm } from "@tanstack/solid-form";
3
- import { VISUAL_EDIT_MESSAGE, validateDocument } from "@thebes/cadmus/cms";
3
+ import { PREVIEW_VALUES_MESSAGE, VISUAL_EDIT_MESSAGE, validateDocument } from "@thebes/cadmus/cms";
4
4
  import { For, Index, Show, Suspense, createEffect, createMemo, createSignal, lazy, onCleanup, onMount } from "solid-js";
5
5
  import { createSolidTable, flexRender, getCoreRowModel } from "@tanstack/solid-table";
6
6
  //#region src/CollectionEdit.tsx
@@ -52,6 +52,7 @@ function CollectionEdit(props) {
52
52
  const isDefaultValue = form.useStore((s) => s.isDefaultValue);
53
53
  createEffect(() => props.onDirtyChange?.(!isDefaultValue()));
54
54
  const formValues = form.useStore((s) => s.values);
55
+ createEffect(() => props.onValuesChange?.(editablePayload(formValues())));
55
56
  function editablePayload(value) {
56
57
  return Object.fromEntries(Object.entries(value).filter(([key]) => props.config.fields[key]?.type !== "date"));
57
58
  }
@@ -1387,6 +1388,8 @@ function originOf(url) {
1387
1388
  }
1388
1389
  }
1389
1390
  function VisualEditingPane(props) {
1391
+ let iframe;
1392
+ const targetOrigin = () => props.allowedOrigin ?? originOf(props.src) ?? "*";
1390
1393
  onMount(() => {
1391
1394
  const expected = props.allowedOrigin ?? originOf(props.src);
1392
1395
  const handler = (event) => {
@@ -1397,8 +1400,24 @@ function VisualEditingPane(props) {
1397
1400
  window.addEventListener("message", handler);
1398
1401
  onCleanup(() => window.removeEventListener("message", handler));
1399
1402
  });
1403
+ createEffect(() => {
1404
+ const values = props.previewValues;
1405
+ const target = props.previewTarget;
1406
+ const win = iframe?.contentWindow;
1407
+ if (!values || !target || !win) return;
1408
+ const message = {
1409
+ type: PREVIEW_VALUES_MESSAGE,
1410
+ collection: target.collection,
1411
+ id: target.id,
1412
+ values
1413
+ };
1414
+ win.postMessage(message, targetOrigin());
1415
+ });
1400
1416
  return (() => {
1401
1417
  var _el$ = _tmpl$();
1418
+ use((el) => {
1419
+ iframe = el;
1420
+ }, _el$);
1402
1421
  effect((_p$) => {
1403
1422
  var _v$ = props.src, _v$2 = props.title ?? "Preview", _v$3 = props.class ?? "h-full w-full border-0";
1404
1423
  _v$ !== _p$.e && setAttribute(_el$, "src", _p$.e = _v$);