camox 0.52.3 → 0.54.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 (59) hide show
  1. package/dist/core/editing/createEditableBlock.js +1 -1
  2. package/dist/features/canvas/CamoxCanvas.js +103 -83
  3. package/dist/features/canvas/CanvasPageFrame.js +1 -1
  4. package/dist/features/canvas/CanvasPreviewPageSlot.js +1 -1
  5. package/dist/features/canvas/canvasCamera.js +3 -3
  6. package/dist/features/canvas/sidebar/CanvasInspector.js +4 -159
  7. package/dist/features/canvas/sidebar/CanvasNavigator.js +41 -85
  8. package/dist/features/canvas/sidebar/CanvasSidebar.js +54 -32
  9. package/dist/features/canvas/sidebar/CanvasSidebarFrame.js +4 -3
  10. package/dist/features/canvas/sidebar/CanvasSidebarSkeleton.js +14 -6
  11. package/dist/features/canvas/sidebar/CanvasViewHeader.js +50 -0
  12. package/dist/features/canvas/sidebar/DerivedPageInspector.js +30 -18
  13. package/dist/features/canvas/sidebar/LayoutPageOverview.js +28 -11
  14. package/dist/features/canvas/sidebar/LayoutPageSeo.js +356 -0
  15. package/dist/features/canvas/sidebar/PageInspector.js +118 -80
  16. package/dist/features/canvas/sidebar/PageOverview.js +6 -1
  17. package/dist/features/canvas/sidebar/SingletonPageInspector.js +22 -14
  18. package/dist/features/canvas/useCanvasCamera.js +36 -39
  19. package/dist/features/og/documentFonts.js +49 -0
  20. package/dist/features/og/imageResponse.d.ts +14 -5
  21. package/dist/features/og/imageResponse.js +20 -21
  22. package/dist/features/og/pageImage.js +7 -4
  23. package/dist/features/preview/CamoxPreview.js +1 -1
  24. package/dist/features/preview/components/BlockActionsPopover.js +2 -2
  25. package/dist/features/preview/components/BlockThumbnail.js +1 -1
  26. package/dist/features/preview/components/CanvasPreview.js +1 -1
  27. package/dist/features/preview/components/CreatePageModal.js +1 -1
  28. package/dist/features/preview/components/IconFieldEditor.js +1 -1
  29. package/dist/features/preview/components/ItemFieldsEditor.js +1 -1
  30. package/dist/features/preview/components/LinkFieldEditor.js +1 -1
  31. package/dist/features/preview/components/OverlayTracker.js +1 -1
  32. package/dist/features/preview/components/PageInfo.js +345 -228
  33. package/dist/features/preview/components/PagePicker.js +1 -1
  34. package/dist/features/preview/components/PageTree.js +1 -1
  35. package/dist/features/preview/components/PreviewPanel.js +1 -1
  36. package/dist/features/preview/components/PreviewToolbar.js +2 -2
  37. package/dist/features/preview/components/RepeatableItemsList.js +1 -1
  38. package/dist/features/preview/components/SelectionEditor.js +668 -652
  39. package/dist/features/preview/components/SidebarStack.js +582 -0
  40. package/dist/features/preview/components/StudioEditingFallback.js +2 -2
  41. package/dist/features/renderer/RendererFrames.js +34 -27
  42. package/dist/features/runtime/RuntimeChrome.js +1 -1
  43. package/dist/features/runtime/runtime.d.ts +5 -0
  44. package/dist/features/runtime/runtime.js +99 -30
  45. package/dist/features/studio/components/ChatSidebar.js +76 -86
  46. package/dist/features/studio/components/Navbar.js +1 -1
  47. package/dist/features/studio/components/Squareling.js +114 -0
  48. package/dist/features/studio/components/ThreadMessages.js +128 -126
  49. package/dist/features/studio/components/UserButton.js +1 -1
  50. package/dist/features/vite/bundlerLogs.js +1 -0
  51. package/dist/features/vite/runtimeDev.js +11 -0
  52. package/dist/features/vite/vite.js +3 -1
  53. package/dist/lib/studio-reads.js +18 -0
  54. package/dist/package.js +1 -1
  55. package/dist/studio.css +1 -1
  56. package/package.json +5 -5
  57. package/skills/camox/references/layout-definitions.md +11 -16
  58. package/dist/features/og/defaultFonts.js +0 -31
  59. package/dist/features/og/geist-variable-ttf-base64.js +0 -21
@@ -1,53 +1,33 @@
1
1
  import { previewStore } from "../../preview/previewStore.js";
2
2
  import { canvasPagePath } from "../canvasPages.js";
3
3
  import { c } from "react/compiler-runtime";
4
- import * as React from "react";
5
4
  import { jsx, jsxs } from "react/jsx-runtime";
6
5
  import { Button } from "@camox/ui/button";
7
- import { Plus } from "lucide-react";
8
- import { Command as Command$1, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, commandFilter } from "@camox/ui/command";
6
+ import { CheckIcon, Plus } from "lucide-react";
9
7
 
10
8
  //#region src/features/canvas/sidebar/CanvasNavigator.tsx
11
9
  /**
12
10
  * The Canvas Navigator, shown while nothing is selected: every Page of the Canvas,
13
- * in Canvas order, with its path, and a search that takes focus. Picking a Page
14
- * shows it: the camera goes to it.
11
+ * in Canvas order, with its path. Picking a Page shows it: the camera goes to it. One card
12
+ * groups them, a line across it between each Page.
15
13
  */
16
14
  function CanvasNavigator(t0) {
17
- const $ = c(17);
15
+ const $ = c(7);
18
16
  const { pages, selectedKey, onShowPage } = t0;
19
- const [search, setSearch] = React.useState("");
20
17
  let t1;
21
- if ($[0] !== search) {
22
- t1 = /* @__PURE__ */ jsx(CommandInput, {
23
- placeholder: "Search pages…",
24
- autoFocus: true,
25
- value: search,
26
- onValueChange: setSearch
27
- });
28
- $[0] = search;
29
- $[1] = t1;
30
- } else t1 = $[1];
31
- let t2;
32
- if ($[2] === Symbol.for("react.memo_cache_sentinel")) {
33
- t2 = /* @__PURE__ */ jsx(CommandEmpty, { children: "Nothing found." });
34
- $[2] = t2;
35
- } else t2 = $[2];
36
- const t3 = `Pages (${pages.length})`;
37
- let t4;
38
- if ($[3] !== onShowPage || $[4] !== pages || $[5] !== selectedKey) {
39
- let t5;
40
- if ($[7] !== onShowPage || $[8] !== selectedKey) {
41
- t5 = (page) => {
18
+ if ($[0] !== onShowPage || $[1] !== pages || $[2] !== selectedKey) {
19
+ t1 = pages.length > 0 && /* @__PURE__ */ jsx("ul", {
20
+ className: "bg-background divide-border/50 border-border/70 m-1 flex shrink-0 flex-col divide-y overflow-hidden rounded-lg border",
21
+ children: pages.map((page) => {
42
22
  const selected = page.key === selectedKey;
43
23
  const path = canvasPagePath(page);
44
- return /* @__PURE__ */ jsx(CommandItem, {
45
- value: page.key,
46
- keywords: path ? [page.title, path] : [page.title],
47
- "data-checked": selected,
48
- "aria-current": selected ? "true" : void 0,
49
- onSelect: () => onShowPage(page.key),
50
- children: /* @__PURE__ */ jsxs("div", {
24
+ return /* @__PURE__ */ jsx("li", { children: /* @__PURE__ */ jsxs("button", {
25
+ type: "button",
26
+ "data-canvas-navigator-page": page.key,
27
+ "aria-current": selected ? "page" : void 0,
28
+ className: "hover:bg-accent hover:text-accent-foreground focus-visible:bg-accent focus-visible:text-accent-foreground flex w-full cursor-pointer items-start gap-2 px-3 py-2 text-left text-sm outline-hidden transition-colors",
29
+ onClick: () => onShowPage(page.key),
30
+ children: [/* @__PURE__ */ jsxs("span", {
51
31
  className: "flex min-w-0 flex-col py-0.5",
52
32
  children: [/* @__PURE__ */ jsx("span", {
53
33
  className: "truncate font-medium",
@@ -56,69 +36,45 @@ function CanvasNavigator(t0) {
56
36
  className: "text-muted-foreground truncate font-mono text-xs",
57
37
  children: path
58
38
  })]
59
- })
60
- }, page.key);
61
- };
62
- $[7] = onShowPage;
63
- $[8] = selectedKey;
64
- $[9] = t5;
65
- } else t5 = $[9];
66
- t4 = pages.map(t5);
67
- $[3] = onShowPage;
68
- $[4] = pages;
69
- $[5] = selectedKey;
70
- $[6] = t4;
71
- } else t4 = $[6];
72
- let t5;
73
- if ($[10] === Symbol.for("react.memo_cache_sentinel")) {
74
- t5 = /* @__PURE__ */ jsx("div", {
39
+ }), selected && /* @__PURE__ */ jsx(CheckIcon, { className: "text-muted-foreground mt-[3px] ml-auto size-4 shrink-0" })]
40
+ }) }, page.key);
41
+ })
42
+ });
43
+ $[0] = onShowPage;
44
+ $[1] = pages;
45
+ $[2] = selectedKey;
46
+ $[3] = t1;
47
+ } else t1 = $[3];
48
+ let t2;
49
+ if ($[4] === Symbol.for("react.memo_cache_sentinel")) {
50
+ t2 = /* @__PURE__ */ jsx("div", {
75
51
  className: "p-1",
76
52
  children: /* @__PURE__ */ jsxs(Button, {
77
53
  type: "button",
78
54
  variant: "secondary",
79
55
  className: "w-full",
80
- onClick: _temp2,
56
+ onClick: _temp,
81
57
  children: [/* @__PURE__ */ jsx(Plus, {}), "Create page"]
82
58
  })
83
59
  });
84
- $[10] = t5;
85
- } else t5 = $[10];
86
- let t6;
87
- if ($[11] !== t3 || $[12] !== t4) {
88
- t6 = /* @__PURE__ */ jsxs(CommandList, {
89
- className: "max-h-none flex-1",
90
- children: [t2, /* @__PURE__ */ jsxs(CommandGroup, {
91
- heading: t3,
92
- children: [t4, t5]
93
- })]
94
- });
95
- $[11] = t3;
96
- $[12] = t4;
97
- $[13] = t6;
98
- } else t6 = $[13];
99
- let t7;
100
- if ($[14] !== t1 || $[15] !== t6) {
101
- t7 = /* @__PURE__ */ jsx("div", {
60
+ $[4] = t2;
61
+ } else t2 = $[4];
62
+ let t3;
63
+ if ($[5] !== t1) {
64
+ t3 = /* @__PURE__ */ jsxs("nav", {
102
65
  "data-canvas-navigator": true,
103
- className: "flex min-h-0 flex-1 flex-col",
104
- children: /* @__PURE__ */ jsxs(Command$1, {
105
- className: "rounded-none! bg-transparent",
106
- filter: _temp,
107
- children: [t1, t6]
108
- })
66
+ "aria-label": "Pages",
67
+ className: "flex min-h-0 flex-1 flex-col overflow-y-auto p-1",
68
+ children: [t1, t2]
109
69
  });
110
- $[14] = t1;
111
- $[15] = t6;
112
- $[16] = t7;
113
- } else t7 = $[16];
114
- return t7;
70
+ $[5] = t1;
71
+ $[6] = t3;
72
+ } else t3 = $[6];
73
+ return t3;
115
74
  }
116
- function _temp2() {
75
+ function _temp() {
117
76
  return previewStore.send({ type: "openCreatePageModal" });
118
77
  }
119
- function _temp(_value, search_0, keywords) {
120
- return commandFilter(keywords?.join(" ") ?? "", search_0);
121
- }
122
78
 
123
79
  //#endregion
124
80
  export { CanvasNavigator };
@@ -1,4 +1,6 @@
1
+ import { SidebarStack, SidebarStackView } from "../../preview/components/SidebarStack.js";
1
2
  import { CanvasSidebarFrame } from "./CanvasSidebarFrame.js";
3
+ import { CanvasViewHeader } from "./CanvasViewHeader.js";
2
4
  import { CreatePageModal } from "../../preview/components/CreatePageModal.js";
3
5
  import { CanvasNavigator } from "./CanvasNavigator.js";
4
6
  import { PageInspector } from "./PageInspector.js";
@@ -7,47 +9,67 @@ import { jsx, jsxs } from "react/jsx-runtime";
7
9
 
8
10
  //#region src/features/canvas/sidebar/CanvasSidebar.tsx
9
11
  /**
10
- * The sidebar beside the Canvas. Without a selection, it shows the Canvas Navigator;
11
- * with one, the Canvas Inspector of the selected Page.
12
+ * The sidebar beside the Canvas, a stack of views: the Canvas's own, which shows the Canvas
13
+ * Navigator, then the Canvas Inspector of the selected Page laid over it, if any.
12
14
  */
13
15
  function CanvasSidebar(t0) {
14
- const $ = c(11);
15
- const { page, navigator, onShowWholeCanvas, onRenamePage, owner: t1, pageRecord } = t0;
16
+ const $ = c(16);
17
+ const { page, navigator, onShowWholeCanvas, owner: t1, pageRecord, runtimeBasePath } = t0;
16
18
  const owner = t1 === void 0 ? null : t1;
17
19
  const t2 = page?.title ?? "Canvas navigator";
18
- let t3;
19
- if ($[0] !== navigator || $[1] !== onRenamePage || $[2] !== onShowWholeCanvas || $[3] !== owner || $[4] !== page || $[5] !== pageRecord) {
20
- t3 = page ? /* @__PURE__ */ jsx(PageInspector, {
20
+ const t3 = page != null;
21
+ let t4;
22
+ if ($[0] !== onShowWholeCanvas || $[1] !== t3) {
23
+ t4 = /* @__PURE__ */ jsx(CanvasViewHeader, {
24
+ covered: t3,
25
+ onShowWholeCanvas
26
+ });
27
+ $[0] = onShowWholeCanvas;
28
+ $[1] = t3;
29
+ $[2] = t4;
30
+ } else t4 = $[2];
31
+ let t5;
32
+ if ($[3] !== navigator || $[4] !== owner || $[5] !== page || $[6] !== pageRecord || $[7] !== runtimeBasePath) {
33
+ t5 = page ? /* @__PURE__ */ jsx(PageInspector, {
21
34
  page,
22
35
  owner,
23
36
  pageRecord,
24
- onBack: onShowWholeCanvas,
25
- onRenamePage
26
- }) : /* @__PURE__ */ jsx(CanvasNavigator, { ...navigator });
27
- $[0] = navigator;
28
- $[1] = onRenamePage;
29
- $[2] = onShowWholeCanvas;
30
- $[3] = owner;
31
- $[4] = page;
32
- $[5] = pageRecord;
33
- $[6] = t3;
34
- } else t3 = $[6];
35
- let t4;
36
- if ($[7] === Symbol.for("react.memo_cache_sentinel")) {
37
- t4 = /* @__PURE__ */ jsx(CreatePageModal, {});
38
- $[7] = t4;
39
- } else t4 = $[7];
40
- let t5;
41
- if ($[8] !== t2 || $[9] !== t3) {
42
- t5 = /* @__PURE__ */ jsxs(CanvasSidebarFrame, {
43
- label: t2,
44
- children: [t3, t4]
37
+ runtimeBasePath
38
+ }) : /* @__PURE__ */ jsx(SidebarStackView, {
39
+ depth: 0,
40
+ className: "flex flex-col",
41
+ children: /* @__PURE__ */ jsx(CanvasNavigator, { ...navigator })
45
42
  });
46
- $[8] = t2;
47
- $[9] = t3;
43
+ $[3] = navigator;
44
+ $[4] = owner;
45
+ $[5] = page;
46
+ $[6] = pageRecord;
47
+ $[7] = runtimeBasePath;
48
+ $[8] = t5;
49
+ } else t5 = $[8];
50
+ let t6;
51
+ if ($[9] !== t4 || $[10] !== t5) {
52
+ t6 = /* @__PURE__ */ jsxs(SidebarStack, { children: [t4, t5] });
53
+ $[9] = t4;
48
54
  $[10] = t5;
49
- } else t5 = $[10];
50
- return t5;
55
+ $[11] = t6;
56
+ } else t6 = $[11];
57
+ let t7;
58
+ if ($[12] === Symbol.for("react.memo_cache_sentinel")) {
59
+ t7 = /* @__PURE__ */ jsx(CreatePageModal, {});
60
+ $[12] = t7;
61
+ } else t7 = $[12];
62
+ let t8;
63
+ if ($[13] !== t2 || $[14] !== t6) {
64
+ t8 = /* @__PURE__ */ jsxs(CanvasSidebarFrame, {
65
+ label: t2,
66
+ children: [t6, t7]
67
+ });
68
+ $[13] = t2;
69
+ $[14] = t6;
70
+ $[15] = t8;
71
+ } else t8 = $[15];
72
+ return t8;
51
73
  }
52
74
 
53
75
  //#endregion
@@ -3,8 +3,9 @@ import { jsx } from "react/jsx-runtime";
3
3
 
4
4
  //#region src/features/canvas/sidebar/CanvasSidebarFrame.tsx
5
5
  /**
6
- * The Canvas sidebar's own box, beside the Canvas: the Canvas Navigator or the Canvas
7
- * Inspector, or a stand-in for either, goes in it.
6
+ * The Canvas sidebar's own box, laid over the Canvas's left side: the Canvas Navigator or the
7
+ * Canvas Inspector, or a stand-in for either, goes in it. Only its cards have a background:
8
+ * around them, the Canvas shows through.
8
9
  */
9
10
  function CanvasSidebarFrame(t0) {
10
11
  const $ = c(9);
@@ -31,7 +32,7 @@ function CanvasSidebarFrame(t0) {
31
32
  if ($[5] !== children || $[6] !== label || $[7] !== props) {
32
33
  t2 = /* @__PURE__ */ jsx("aside", {
33
34
  "aria-label": label,
34
- className: "bg-background relative flex shrink-0 flex-col border-r-2",
35
+ className: "absolute inset-y-0 left-0 z-10 flex flex-col py-2",
35
36
  style: t1,
36
37
  ...props,
37
38
  children
@@ -1,15 +1,15 @@
1
+ import { SidebarStack, SidebarStackView } from "../../preview/components/SidebarStack.js";
1
2
  import { CanvasInspectorBody, CanvasInspectorHeaderSkeleton } from "./CanvasInspector.js";
2
3
  import { CanvasSidebarFrame } from "./CanvasSidebarFrame.js";
4
+ import { CanvasViewHeader } from "./CanvasViewHeader.js";
3
5
  import { CuratedPageSkeleton, LayoutPageSkeleton } from "./PageInspectorSkeleton.js";
4
6
  import { c } from "react/compiler-runtime";
5
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
7
+ import { jsx, jsxs } from "react/jsx-runtime";
6
8
 
7
9
  //#region src/features/canvas/sidebar/CanvasSidebarSkeleton.tsx
8
10
  /**
9
- * Stands in for the Canvas sidebar while the Canvas loads, so the page beside it
10
- * doesn't shift once the Canvas shows. For a selected Page, it takes the Canvas
11
- * Inspector's layout. Without one, it is empty but just as wide, so selecting and
12
- * deselecting on the Canvas never resizes the page frame's place under it.
11
+ * Stands in for the Canvas sidebar while the Canvas loads, where the sidebar will show. For a
12
+ * selected Page, it takes the Canvas Inspector's layout. Without one, it is empty.
13
13
  */
14
14
  function CanvasSidebarSkeleton(t0) {
15
15
  const $ = c(5);
@@ -18,7 +18,15 @@ function CanvasSidebarSkeleton(t0) {
18
18
  const layoutPage = t2 === void 0 ? false : t2;
19
19
  let t3;
20
20
  if ($[0] !== layoutPage || $[1] !== page) {
21
- t3 = page && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(CanvasInspectorHeaderSkeleton, {}), /* @__PURE__ */ jsx(CanvasInspectorBody, { children: layoutPage ? /* @__PURE__ */ jsx(LayoutPageSkeleton, {}) : /* @__PURE__ */ jsx(CuratedPageSkeleton, {}) })] });
21
+ t3 = page && /* @__PURE__ */ jsxs(SidebarStack, { children: [
22
+ /* @__PURE__ */ jsx(CanvasViewHeader, { covered: true }),
23
+ /* @__PURE__ */ jsx(CanvasInspectorHeaderSkeleton, {}),
24
+ /* @__PURE__ */ jsx(CanvasInspectorBody, { children: /* @__PURE__ */ jsx(SidebarStackView, {
25
+ depth: 1,
26
+ className: "flex flex-col",
27
+ children: layoutPage ? /* @__PURE__ */ jsx(LayoutPageSkeleton, {}) : /* @__PURE__ */ jsx(CuratedPageSkeleton, {})
28
+ }) })
29
+ ] });
22
30
  $[0] = layoutPage;
23
31
  $[1] = page;
24
32
  $[2] = t3;
@@ -0,0 +1,50 @@
1
+ import { SidebarStackHeader, useSelectionViewCount } from "../../preview/components/SidebarStack.js";
2
+ import { SHOW_WHOLE_CANVAS_SHORTCUT } from "../../preview/previewConstants.js";
3
+ import { formatShortcut } from "../../../lib/shortcuts.js";
4
+ import { c } from "react/compiler-runtime";
5
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
6
+
7
+ //#region src/features/canvas/sidebar/CanvasViewHeader.tsx
8
+ /**
9
+ * The header of the Canvas's own view, the bottom of the sidebar's stack. Under a Page's
10
+ * inspector, it leaves the selection and zooms out to the whole Canvas.
11
+ */
12
+ function CanvasViewHeader(t0) {
13
+ const $ = c(7);
14
+ const { covered, onShowWholeCanvas } = t0;
15
+ const selectionViews = useSelectionViewCount();
16
+ const distance = covered ? 1 + selectionViews : 0;
17
+ let t1;
18
+ if ($[0] === Symbol.for("react.memo_cache_sentinel")) {
19
+ t1 = /* @__PURE__ */ jsxs(Fragment, { children: ["Show entire site ", formatShortcut(SHOW_WHOLE_CANVAS_SHORTCUT)] });
20
+ $[0] = t1;
21
+ } else t1 = $[0];
22
+ let t2;
23
+ if ($[1] !== covered) {
24
+ t2 = covered ? "Site" : /* @__PURE__ */ jsx("h2", {
25
+ className: "truncate text-sm font-medium",
26
+ children: "Site"
27
+ });
28
+ $[1] = covered;
29
+ $[2] = t2;
30
+ } else t2 = $[2];
31
+ let t3;
32
+ if ($[3] !== distance || $[4] !== onShowWholeCanvas || $[5] !== t2) {
33
+ t3 = /* @__PURE__ */ jsx(SidebarStackHeader, {
34
+ first: true,
35
+ depth: 0,
36
+ distance,
37
+ onSelect: onShowWholeCanvas,
38
+ tooltip: t1,
39
+ children: t2
40
+ });
41
+ $[3] = distance;
42
+ $[4] = onShowWholeCanvas;
43
+ $[5] = t2;
44
+ $[6] = t3;
45
+ } else t3 = $[6];
46
+ return t3;
47
+ }
48
+
49
+ //#endregion
50
+ export { CanvasViewHeader };
@@ -8,29 +8,41 @@ import { jsx } from "react/jsx-runtime";
8
8
  * its code generates. A record page's content is its record, edited from the preview.
9
9
  */
10
10
  function DerivedPageInspector(t0) {
11
- const $ = c(5);
12
- const { layoutId, pageRecord } = t0;
13
- const t1 = pageRecord ? "Changes to these blocks apply to every page using this layout. Select this page’s content in the preview to edit its record, shared everywhere it appears." : "Changes apply to every page using this layout. The generated page content is managed outside the studio.";
14
- let t2;
15
- if ($[0] !== t1) {
16
- t2 = {
17
- title: "Shared layout blocks",
18
- description: t1
11
+ const $ = c(9);
12
+ const { layoutId, pageRecord, runtimeBasePath } = t0;
13
+ let t1;
14
+ if ($[0] !== layoutId || $[1] !== runtimeBasePath) {
15
+ t1 = {
16
+ runtimeBasePath,
17
+ derivedLayoutId: layoutId
19
18
  };
20
- $[0] = t1;
21
- $[1] = t2;
22
- } else t2 = $[1];
19
+ $[0] = layoutId;
20
+ $[1] = runtimeBasePath;
21
+ $[2] = t1;
22
+ } else t1 = $[2];
23
+ const t2 = pageRecord ? "Changes to these blocks apply to every page using this layout. Select this page’s content in the preview to edit its record, shared everywhere it appears." : "Changes apply to every page using this layout. The generated page content is managed outside the studio.";
23
24
  let t3;
24
- if ($[2] !== layoutId || $[3] !== t2) {
25
- t3 = /* @__PURE__ */ jsx(LayoutPageOverview, {
26
- layoutId,
27
- notice: t2
28
- });
29
- $[2] = layoutId;
25
+ if ($[3] !== t2) {
26
+ t3 = {
27
+ title: "Shared layout blocks",
28
+ description: t2
29
+ };
30
30
  $[3] = t2;
31
31
  $[4] = t3;
32
32
  } else t3 = $[4];
33
- return t3;
33
+ let t4;
34
+ if ($[5] !== layoutId || $[6] !== t1 || $[7] !== t3) {
35
+ t4 = /* @__PURE__ */ jsx(LayoutPageOverview, {
36
+ layoutId,
37
+ target: t1,
38
+ notice: t3
39
+ });
40
+ $[5] = layoutId;
41
+ $[6] = t1;
42
+ $[7] = t3;
43
+ $[8] = t4;
44
+ } else t4 = $[8];
45
+ return t4;
34
46
  }
35
47
 
36
48
  //#endregion
@@ -2,6 +2,7 @@ import { useProjectUuid } from "../../../lib/auth.js";
2
2
  import { reads, useRead } from "../../../lib/studio-reads.js";
3
3
  import { PageOverview } from "./PageOverview.js";
4
4
  import { LayoutPageBlocks } from "./LayoutPageBlocks.js";
5
+ import { LayoutPageSeo } from "./LayoutPageSeo.js";
5
6
  import { c } from "react/compiler-runtime";
6
7
  import { jsx, jsxs } from "react/jsx-runtime";
7
8
  import { Alert, AlertDescription, AlertTitle } from "@camox/ui/alert";
@@ -9,11 +10,11 @@ import { Alert, AlertDescription, AlertTitle } from "@camox/ui/alert";
9
10
  //#region src/features/canvas/sidebar/LayoutPageOverview.tsx
10
11
  /**
11
12
  * A layout page's overview: its layout's blocks, then a notice, which a singleton and a
12
- * derived page word for themselves.
13
+ * derived page word for themselves, then its SEO and Markdown, which its code builds.
13
14
  */
14
15
  function LayoutPageOverview(t0) {
15
- const $ = c(15);
16
- const { layoutId, notice } = t0;
16
+ const $ = c(20);
17
+ const { layoutId, notice, target } = t0;
17
18
  const projectUuid = useProjectUuid();
18
19
  let t1;
19
20
  if ($[0] !== layoutId || $[1] !== projectUuid) {
@@ -53,18 +54,34 @@ function LayoutPageOverview(t0) {
53
54
  } else t5 = $[11];
54
55
  let t6;
55
56
  if ($[12] !== t2 || $[13] !== t5) {
56
- t6 = /* @__PURE__ */ jsx(PageOverview, { children: /* @__PURE__ */ jsx("div", {
57
- className: "flex min-h-0 flex-1 flex-col overflow-auto",
58
- children: /* @__PURE__ */ jsxs("div", {
59
- className: "flex flex-col gap-4 px-2 pt-5",
60
- children: [t2, t5]
61
- })
62
- }) });
57
+ t6 = /* @__PURE__ */ jsxs("div", {
58
+ className: "flex flex-col gap-4 px-2 pt-5",
59
+ children: [t2, t5]
60
+ });
63
61
  $[12] = t2;
64
62
  $[13] = t5;
65
63
  $[14] = t6;
66
64
  } else t6 = $[14];
67
- return t6;
65
+ let t7;
66
+ if ($[15] !== target) {
67
+ t7 = /* @__PURE__ */ jsx("div", {
68
+ className: "space-y-4 p-2 pt-4",
69
+ children: /* @__PURE__ */ jsx(LayoutPageSeo, { target })
70
+ });
71
+ $[15] = target;
72
+ $[16] = t7;
73
+ } else t7 = $[16];
74
+ let t8;
75
+ if ($[17] !== t6 || $[18] !== t7) {
76
+ t8 = /* @__PURE__ */ jsx(PageOverview, { children: /* @__PURE__ */ jsxs("div", {
77
+ className: "flex min-h-0 flex-1 flex-col overflow-auto",
78
+ children: [t6, t7]
79
+ }) });
80
+ $[17] = t6;
81
+ $[18] = t7;
82
+ $[19] = t8;
83
+ } else t8 = $[19];
84
+ return t8;
68
85
  }
69
86
 
70
87
  //#endregion