@drawnagency/primitives 0.1.62 → 0.1.64

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,6 +1,6 @@
1
1
  import {
2
2
  EditablePlainText
3
- } from "./chunk-QWDOJUUO.js";
3
+ } from "./chunk-VMDKWUMT.js";
4
4
  import {
5
5
  usePages
6
6
  } from "./chunk-4E66N6UV.js";
@@ -9,7 +9,7 @@ import {
9
9
  MediaBlock,
10
10
  containerGridClass,
11
11
  useEditableCollection
12
- } from "./chunk-QWDOJUUO.js";
12
+ } from "./chunk-VMDKWUMT.js";
13
13
  import {
14
14
  AddIcon,
15
15
  DeleteIcon,
@@ -264,10 +264,14 @@ function MediaBlock({ refValue, options, link, isEditMode, onRefChange }) {
264
264
  const showBorder = refValue.border ?? options.border;
265
265
  const captionStr = refValue.caption ? Array.isArray(refValue.caption) ? refValue.caption.join("\n") : refValue.caption : "";
266
266
  const replace = onRefChange ? (imageId) => onRefChange({ ...refValue, imageId }) : void 0;
267
+ const baked = refValue;
267
268
  const resolved = /* @__PURE__ */ jsx3(
268
269
  ResolvedMedia,
269
270
  {
270
271
  imageId: refValue.imageId || void 0,
272
+ src: baked.src,
273
+ srcset: baked.srcset,
274
+ alt: baked.alt,
271
275
  className: "h-full w-full",
272
276
  imgClassName: fitClass,
273
277
  invertFrom: refValue.invertFrom
@@ -2,7 +2,7 @@ import {
2
2
  EditableRichText,
3
3
  LinkPopover,
4
4
  defineHeadingSection
5
- } from "../../chunk-FJBDGYHE.js";
5
+ } from "../../chunk-FECCYOPJ.js";
6
6
  import {
7
7
  EditableGrid,
8
8
  EditablePlainText,
@@ -10,7 +10,7 @@ import {
10
10
  MediaBlock,
11
11
  ResolvedMedia,
12
12
  useEditableCollection
13
- } from "../../chunk-QWDOJUUO.js";
13
+ } from "../../chunk-VMDKWUMT.js";
14
14
  import "../../chunk-4E66N6UV.js";
15
15
  import {
16
16
  DeleteIcon,
@@ -1 +1 @@
1
- {"version":3,"file":"MediaBlock.d.ts","sourceRoot":"","sources":["../../../../src/components/sections/Media/MediaBlock.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAOvD,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,OAAO,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAC;QAAC,WAAW,CAAC,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAC;QAAC,SAAS,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;KAAE,CAAC;IACxG,4EAA4E;IAC5E,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,oBAAoB,KAAK,IAAI,CAAC;CACnD;AAED,wBAAgB,UAAU,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,EAAE,eAAe,2CA2E/F"}
1
+ {"version":3,"file":"MediaBlock.d.ts","sourceRoot":"","sources":["../../../../src/components/sections/Media/MediaBlock.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAOvD,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,OAAO,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAC;QAAC,WAAW,CAAC,EAAE,OAAO,CAAC;QAAC,MAAM,CAAC,EAAE,OAAO,CAAC;QAAC,SAAS,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;KAAE,CAAC;IACxG,4EAA4E;IAC5E,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,UAAU,EAAE,OAAO,CAAC;IACpB,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,oBAAoB,KAAK,IAAI,CAAC;CACnD;AAED,wBAAgB,UAAU,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,EAAE,eAAe,2CAoF/F"}
@@ -2,9 +2,9 @@ import {
2
2
  ColorItemSchema,
3
3
  ColorSpaceSchema,
4
4
  brandGuideSectionDefs
5
- } from "../../chunk-JRT4KWHU.js";
5
+ } from "../../chunk-QYQ3DQHI.js";
6
6
  import "../../chunk-5THS4K5D.js";
7
- import "../../chunk-QWDOJUUO.js";
7
+ import "../../chunk-VMDKWUMT.js";
8
8
  import "../../chunk-I5737FJY.js";
9
9
  import "../../chunk-CBWK3KPV.js";
10
10
  import "../../chunk-3DCG4DNU.js";
@@ -3,7 +3,7 @@ import {
3
3
  pluralize,
4
4
  stripHtmlToPlainText,
5
5
  truncate
6
- } from "../../chunk-JRT4KWHU.js";
6
+ } from "../../chunk-QYQ3DQHI.js";
7
7
  import {
8
8
  DeleteButton,
9
9
  DragHandle,
@@ -20,7 +20,7 @@ import "../../chunk-5THS4K5D.js";
20
20
  import {
21
21
  EditableRichText,
22
22
  defineHeadingSection
23
- } from "../../chunk-FJBDGYHE.js";
23
+ } from "../../chunk-FECCYOPJ.js";
24
24
  import {
25
25
  EditablePlainText,
26
26
  MAX_CONTAINER_COLUMNS,
@@ -28,7 +28,7 @@ import {
28
28
  colSpanClass,
29
29
  containerGridClass,
30
30
  spacerHiddenClass
31
- } from "../../chunk-QWDOJUUO.js";
31
+ } from "../../chunk-VMDKWUMT.js";
32
32
  import "../../chunk-4E66N6UV.js";
33
33
  import "../../chunk-I5737FJY.js";
34
34
  import "../../chunk-CBWK3KPV.js";
@@ -1 +1 @@
1
- {"version":3,"file":"EditorShell.d.ts","sourceRoot":"","sources":["../../../src/components/shell/EditorShell.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAqEjD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAQxD,UAAU,KAAK;IACb,OAAO,EAAE,MAAM,CAAC;IAIhB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,YAAY,EAAE;QACZ,KAAK,EAAE,OAAO,CAAC;QACf,aAAa,EAAE,OAAO,CAAC;QACvB,YAAY,EAAE,OAAO,CAAC;QACtB,cAAc,EAAE,OAAO,CAAC;QACxB,kBAAkB,EAAE,OAAO,CAAC;QAC5B,cAAc,EAAE,OAAO,CAAC;KACzB,CAAC;IACF,WAAW,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAA;KAAE,GAAG,IAAI,CAAC;CACjE;AAED,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,EAClC,OAAO,EACP,YAAY,EACZ,MAAM,EACN,SAAS,EAAE,gBAAgB,EAC3B,YAAY,EACZ,WAAW,GACZ,EAAE,KAAK,2CAo6BP"}
1
+ {"version":3,"file":"EditorShell.d.ts","sourceRoot":"","sources":["../../../src/components/shell/EditorShell.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAsEjD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAQxD,UAAU,KAAK;IACb,OAAO,EAAE,MAAM,CAAC;IAIhB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,QAAQ,EAAE,CAAC;IACtB,YAAY,EAAE;QACZ,KAAK,EAAE,OAAO,CAAC;QACf,aAAa,EAAE,OAAO,CAAC;QACvB,YAAY,EAAE,OAAO,CAAC;QACtB,cAAc,EAAE,OAAO,CAAC;QACxB,kBAAkB,EAAE,OAAO,CAAC;QAC5B,cAAc,EAAE,OAAO,CAAC;KACzB,CAAC;IACF,WAAW,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,GAAG,QAAQ,CAAA;KAAE,GAAG,IAAI,CAAC;CACjE;AAED,MAAM,CAAC,OAAO,UAAU,WAAW,CAAC,EAClC,OAAO,EACP,YAAY,EACZ,MAAM,EACN,SAAS,EAAE,gBAAgB,EAC3B,YAAY,EACZ,WAAW,GACZ,EAAE,KAAK,2CAo6BP"}
@@ -0,0 +1,38 @@
1
+ export type ViewBranch = "saved" | "live";
2
+ /**
3
+ * Section visibility for the editor's view-mode toggle.
4
+ *
5
+ * - `"live"` ("Published"): mirrors what an anonymous visitor sees on the
6
+ * deployed site — only `status === "live"` (the same predicate the real viewer
7
+ * applies in `viewer-page.ts`).
8
+ * - `"saved"` ("Unpublished"): all in-progress edits — every status EXCEPT
9
+ * `archived` — so edits to live content show alongside drafts.
10
+ */
11
+ export declare function isSectionVisibleInViewBranch(status: string, viewBranch: ViewBranch): boolean;
12
+ /**
13
+ * Which sections to render in the editor's view mode.
14
+ *
15
+ * - Edit mode: the in-memory sections as-is (edit chrome handles them).
16
+ * - "Unpublished" (saved): the editor's CURRENT in-memory content — all edits
17
+ * minus archived. It must NOT depend on a re-fetched branch: after a publish
18
+ * the `saved` branch is deleted and `/api/content?branch=saved` falls back to
19
+ * `main`, which would clobber unsaved edits (they'd flash then vanish).
20
+ * - "Published" (live): the deployed site — the fetched `main` branch filtered to
21
+ * `status === "live"`, in page order. Renders nothing until the fetch resolves
22
+ * so in-memory edits never flash as if they were published.
23
+ */
24
+ export declare function computeDisplaySections<T extends {
25
+ section: {
26
+ id: string;
27
+ };
28
+ meta: {
29
+ status: string;
30
+ };
31
+ }>(args: {
32
+ isEditMode: boolean;
33
+ viewBranch: ViewBranch;
34
+ sections: T[];
35
+ viewSections: T[] | null;
36
+ activePageSectionIds: string[];
37
+ }): T[];
38
+ //# sourceMappingURL=view-branch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"view-branch.d.ts","sourceRoot":"","sources":["../../../src/components/shell/view-branch.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,UAAU,GAAG,OAAO,GAAG,MAAM,CAAC;AAE1C;;;;;;;;GAQG;AACH,wBAAgB,4BAA4B,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,UAAU,GAAG,OAAO,CAE5F;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CAAC,CAAC,SAAS;IAAE,OAAO,EAAE;QAAE,EAAE,EAAE,MAAM,CAAA;KAAE,CAAC;IAAC,IAAI,EAAE;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAA;CAAE,EAAE,IAAI,EAAE;IAC5G,UAAU,EAAE,OAAO,CAAC;IACpB,UAAU,EAAE,UAAU,CAAC;IACvB,QAAQ,EAAE,CAAC,EAAE,CAAC;IACd,YAAY,EAAE,CAAC,EAAE,GAAG,IAAI,CAAC;IACzB,oBAAoB,EAAE,MAAM,EAAE,CAAC;CAChC,GAAG,CAAC,EAAE,CAaN"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@drawnagency/primitives",
3
- "version": "0.1.62",
3
+ "version": "0.1.64",
4
4
  "type": "module",
5
5
  "exports": {
6
6
  "./package.json": "./package.json",
@@ -27,9 +27,18 @@ export function MediaBlock({ refValue, options, link, isEditMode, onRefChange }:
27
27
 
28
28
  const replace = onRefChange ? (imageId: string) => onRefChange({ ...refValue, imageId }) : undefined;
29
29
 
30
+ // The zero-JS viewer has no MediaLibraryContext, so useResolvedMedia() can't
31
+ // resolve the URL. The SSR pass (resolveManifestReferences) bakes src/srcset/alt
32
+ // onto the ref instead — forward them so a real <img> renders rather than the
33
+ // placeholder. In edit mode these are absent and ResolvedMedia falls back to the
34
+ // live manifest via context. (Mirrors a3e8913, which did this for MediaGrid/SplitContent.)
35
+ const baked = refValue as Record<string, unknown>;
30
36
  const resolved = (
31
37
  <ResolvedMedia
32
38
  imageId={refValue.imageId || undefined}
39
+ src={baked.src as string | undefined}
40
+ srcset={baked.srcset as string | undefined}
41
+ alt={baked.alt as string | undefined}
33
42
  className="h-full w-full"
34
43
  imgClassName={fitClass}
35
44
  invertFrom={refValue.invertFrom}
@@ -69,6 +69,7 @@ import { Button } from "../shared/Button";
69
69
  import { SplitButton } from "../shared/SplitButton";
70
70
  import { IconButton } from "../shared/IconButton";
71
71
  import { SegmentedControl } from "../shared/SegmentedControl";
72
+ import { computeDisplaySections } from "./view-branch";
72
73
  import { SettingsIcon } from "../shared/icons";
73
74
  import { ImageIcon, ListOrderedIcon, FilesIcon, X } from "lucide-react";
74
75
  import { ErrorBoundary } from "../shared/ErrorBoundary";
@@ -1052,14 +1053,16 @@ function ViewBranchWatcher({
1052
1053
  const { isEditMode, viewBranch } = useEditorContext();
1053
1054
 
1054
1055
  useEffect(() => {
1055
- if (isEditMode) {
1056
+ // Only "Published" (live) needs a fetch — it previews the deployed main
1057
+ // branch. "Unpublished" (saved) renders the editor's in-memory edits, so no
1058
+ // fetch (fetching `saved` would 404 after a publish and fall back to main,
1059
+ // clobbering unsaved edits). Null viewSections routes to the in-memory path.
1060
+ if (isEditMode || viewBranch !== "live") {
1056
1061
  setViewSections(null);
1057
1062
  return;
1058
1063
  }
1059
1064
 
1060
- const branch = viewBranch === "live" ? "main" : "saved";
1061
-
1062
- fetch(`/api/content?branch=${branch}`)
1065
+ fetch(`/api/content?branch=main`)
1063
1066
  .then((res) => res.json())
1064
1067
  .then((data) => {
1065
1068
  setViewSections(data.sections);
@@ -1215,14 +1218,16 @@ function EditorContent({
1215
1218
 
1216
1219
  const editingEnabled = isEditMode && !isPublishing;
1217
1220
 
1218
- // View mode: render the active page's sections from the fetched branch, in page
1219
- // order (Live additionally filters to status === "live"). Edit mode: the active
1220
- // page's in-memory sections (the `sections` prop is already `activeSections`).
1221
- const displaySections = !isEditMode && viewSections !== null
1222
- ? activePageSectionIds
1223
- .map((id) => viewSections.find((s) => s.section.id === id))
1224
- .filter((s): s is LoadedSection => !!s && (viewBranch !== "live" || s.meta.status === "live"))
1225
- : sections;
1221
+ // "Published" (live) previews the deployed main branch (status === "live");
1222
+ // "Unpublished" (saved) previews the editor's current in-memory edits (all
1223
+ // statuses except archived) — see computeDisplaySections in view-branch.ts.
1224
+ const displaySections = computeDisplaySections({
1225
+ isEditMode,
1226
+ viewBranch,
1227
+ sections,
1228
+ viewSections,
1229
+ activePageSectionIds,
1230
+ });
1226
1231
 
1227
1232
  useEffect(() => {
1228
1233
  return combine(
@@ -1642,8 +1647,8 @@ function EditorToolbar({
1642
1647
  <div className="mx-auto max-w-screen-xl flex items-center justify-center px-4 py-2">
1643
1648
  <SegmentedControl
1644
1649
  options={[
1645
- { value: "saved", label: "Draft" },
1646
- { value: "live", label: "Live" },
1650
+ { value: "live", label: "Published" },
1651
+ { value: "saved", label: "Unpublished" },
1647
1652
  ]}
1648
1653
  value={viewBranch}
1649
1654
  onChange={(v) => setViewBranch(v as "saved" | "live")}
@@ -0,0 +1,47 @@
1
+ export type ViewBranch = "saved" | "live";
2
+
3
+ /**
4
+ * Section visibility for the editor's view-mode toggle.
5
+ *
6
+ * - `"live"` ("Published"): mirrors what an anonymous visitor sees on the
7
+ * deployed site — only `status === "live"` (the same predicate the real viewer
8
+ * applies in `viewer-page.ts`).
9
+ * - `"saved"` ("Unpublished"): all in-progress edits — every status EXCEPT
10
+ * `archived` — so edits to live content show alongside drafts.
11
+ */
12
+ export function isSectionVisibleInViewBranch(status: string, viewBranch: ViewBranch): boolean {
13
+ return viewBranch === "live" ? status === "live" : status !== "archived";
14
+ }
15
+
16
+ /**
17
+ * Which sections to render in the editor's view mode.
18
+ *
19
+ * - Edit mode: the in-memory sections as-is (edit chrome handles them).
20
+ * - "Unpublished" (saved): the editor's CURRENT in-memory content — all edits
21
+ * minus archived. It must NOT depend on a re-fetched branch: after a publish
22
+ * the `saved` branch is deleted and `/api/content?branch=saved` falls back to
23
+ * `main`, which would clobber unsaved edits (they'd flash then vanish).
24
+ * - "Published" (live): the deployed site — the fetched `main` branch filtered to
25
+ * `status === "live"`, in page order. Renders nothing until the fetch resolves
26
+ * so in-memory edits never flash as if they were published.
27
+ */
28
+ export function computeDisplaySections<T extends { section: { id: string }; meta: { status: string } }>(args: {
29
+ isEditMode: boolean;
30
+ viewBranch: ViewBranch;
31
+ sections: T[];
32
+ viewSections: T[] | null;
33
+ activePageSectionIds: string[];
34
+ }): T[] {
35
+ const { isEditMode, viewBranch, sections, viewSections, activePageSectionIds } = args;
36
+
37
+ if (isEditMode) return sections;
38
+
39
+ if (viewBranch === "saved") {
40
+ return sections.filter((s) => isSectionVisibleInViewBranch(s.meta.status, "saved"));
41
+ }
42
+
43
+ if (viewSections === null) return [];
44
+ return activePageSectionIds
45
+ .map((id) => viewSections.find((s) => s.section.id === id))
46
+ .filter((s): s is T => !!s && isSectionVisibleInViewBranch(s.meta.status, "live"));
47
+ }