camox 0.40.0 → 0.41.1

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 (108) hide show
  1. package/dist/components/PlatformLabel.js +62 -0
  2. package/dist/core/components/lexical/GradientNode.js +126 -0
  3. package/dist/core/components/lexical/InlineLexicalEditor.js +37 -56
  4. package/dist/core/components/lexical/InlineStylesPlugin.js +183 -0
  5. package/dist/core/components/lexical/SelectionBroadcaster.js +49 -46
  6. package/dist/core/components/lexical/SidebarLexicalEditor.js +197 -151
  7. package/dist/core/components/lexical/editorConfig.js +25 -7
  8. package/dist/core/components/lexical/selectTextLink.js +21 -0
  9. package/dist/core/createApp.d.ts +30 -17
  10. package/dist/core/createApp.js +14 -3
  11. package/dist/core/createBlock.d.ts +2 -2
  12. package/dist/core/createBlock.js +17 -28
  13. package/dist/core/createLayout.d.ts +48 -4
  14. package/dist/core/createLayout.js +51 -23
  15. package/dist/core/derivedRoutes.js +36 -0
  16. package/dist/core/editing/BlockEditingRuntime.js +4 -4
  17. package/dist/core/editing/CompleteBlockEditingRuntime.js +5 -5
  18. package/dist/core/editing/createEditableBlock.d.ts +9 -8
  19. package/dist/core/editing/createEditableBlock.js +265 -403
  20. package/dist/core/hooks/useIsEditable.js +4 -7
  21. package/dist/core/hooks/useRequireDraftSource.js +7 -11
  22. package/dist/core/lib/lexicalReact.d.ts +1 -26
  23. package/dist/core/lib/lexicalReact.js +46 -60
  24. package/dist/core/lib/lexicalState.js +164 -81
  25. package/dist/core/lib/modifierFormats.js +4 -15
  26. package/dist/core/lib/textStyles.d.ts +27 -0
  27. package/dist/core/lib/textStyles.js +47 -0
  28. package/dist/features/navigation/navigation.d.ts +2 -0
  29. package/dist/features/navigation/navigation.js +51 -46
  30. package/dist/features/page/DerivedPageContent.js +61 -0
  31. package/dist/features/page/PublishedPageContent.js +52 -83
  32. package/dist/features/page/SharedLayoutContent.js +66 -0
  33. package/dist/features/preview/CamoxPreview.d.ts +16 -1
  34. package/dist/features/preview/CamoxPreview.js +246 -290
  35. package/dist/features/preview/DerivedPreview.js +134 -0
  36. package/dist/features/preview/EditablePageExperience.js +25 -8
  37. package/dist/features/preview/components/AddBlockSidebar.js +43 -33
  38. package/dist/features/preview/components/AssetLightbox.js +1 -1
  39. package/dist/features/preview/components/BlockActionsPopover.js +8 -8
  40. package/dist/features/preview/components/BlockThumbnail.js +192 -0
  41. package/dist/features/preview/components/CreatePageModal.js +123 -115
  42. package/dist/features/preview/components/DerivedLayoutDialog.js +100 -0
  43. package/dist/features/preview/components/DerivedLayoutSidebar.d.ts +5 -0
  44. package/dist/features/preview/components/DerivedLayoutSidebar.js +160 -0
  45. package/dist/features/preview/components/DerivedPageInfoSidebar.js +57 -0
  46. package/dist/features/preview/components/FieldToolbar.js +42 -20
  47. package/dist/features/preview/components/Frame.js +133 -140
  48. package/dist/features/preview/components/LeftSidebar.js +42 -38
  49. package/dist/features/preview/components/LinkFieldEditor.js +3 -4
  50. package/dist/features/preview/components/MobilePreviewDrawer.js +4 -4
  51. package/dist/features/preview/components/Overlays.js +59 -47
  52. package/dist/features/preview/components/PageEditorSidebar.js +194 -203
  53. package/dist/features/preview/components/PageInfoSidebar.js +63 -55
  54. package/dist/features/preview/components/PageNavigatorSidebar.js +34 -483
  55. package/dist/features/preview/components/PagePicker.js +205 -153
  56. package/dist/features/preview/components/PageTree.js +366 -340
  57. package/dist/features/preview/components/PreviewActivation.js +78 -0
  58. package/dist/features/preview/components/PreviewPanel.js +98 -68
  59. package/dist/features/preview/components/PreviewToolbar.js +224 -241
  60. package/dist/features/preview/components/PreviewToolbarSpacer.js +43 -0
  61. package/dist/features/preview/components/PublicationRow.js +425 -0
  62. package/dist/features/preview/components/PublishDialog.js +180 -97
  63. package/dist/features/preview/components/RightSidebar.js +19 -34
  64. package/dist/features/preview/components/previewStyles.js +8 -0
  65. package/dist/features/preview/components/useUpdateBlockPosition.js +7 -13
  66. package/dist/features/preview/previewConstants.js +8 -0
  67. package/dist/features/preview/previewStore.js +18 -39
  68. package/dist/features/preview/publication.js +71 -0
  69. package/dist/features/provider/AuthenticatedCamoxProvider.js +2 -1
  70. package/dist/features/provider/CoreCamoxProvider.js +11 -2
  71. package/dist/features/provider/LocalhostPreviewProvider.js +6 -7
  72. package/dist/features/provider/useAdminShortcuts.js +5 -4
  73. package/dist/features/routes/pageRuntime.d.ts +10 -0
  74. package/dist/features/routes/pageRuntime.js +7 -9
  75. package/dist/features/runtime/PreviewDocumentContext.js +7 -0
  76. package/dist/features/runtime/RuntimeChrome.js +149 -0
  77. package/dist/features/runtime/SharedChromeContext.js +7 -0
  78. package/dist/features/runtime/navigationRequest.js +21 -0
  79. package/dist/features/runtime/navigationTarget.js +23 -0
  80. package/dist/features/runtime/pageApp.js +196 -121
  81. package/dist/features/runtime/pageNavigation.js +79 -130
  82. package/dist/features/runtime/runtime.d.ts +11 -0
  83. package/dist/features/runtime/runtime.js +183 -47
  84. package/dist/features/runtime/studioApp.d.ts +2 -11
  85. package/dist/features/runtime/studioApp.js +14 -177
  86. package/dist/features/studio/CamoxStudio.js +27 -13
  87. package/dist/features/studio/components/Navbar.js +80 -74
  88. package/dist/features/studio/components/UserButton.js +4 -4
  89. package/dist/features/studio/studioTheme.js +25 -0
  90. package/dist/features/studio/useTheme.js +94 -109
  91. package/dist/features/vite/appGeneration.js +12 -3
  92. package/dist/features/vite/definitionsSync.js +4 -2
  93. package/dist/features/vite/layoutGeneration.js +38 -0
  94. package/dist/features/vite/runtimeDev.js +3 -1
  95. package/dist/lib/auth.js +15 -13
  96. package/dist/lib/normalized-data.js +4 -4
  97. package/dist/lib/platform.js +13 -0
  98. package/dist/lib/utils.js +90 -38
  99. package/dist/studio-overlays.css +5 -40
  100. package/dist/studio.css +1 -1
  101. package/package.json +8 -4
  102. package/skills/camox/SKILL.md +2 -0
  103. package/skills/camox/references/block-definitions.md +31 -12
  104. package/skills/camox/references/layout-definitions.md +2 -0
  105. package/dist/core/lib/modifiers.js +0 -24
  106. package/dist/features/preview/components/DraftSwitchDialog.js +0 -66
  107. package/dist/features/preview/previewQueryFns.js +0 -23
  108. package/dist/features/runtime/studioNavigation.js +0 -120
@@ -1,7 +1,7 @@
1
+ import { FORMAT_FLAGS } from "../../../core/lib/modifierFormats.js";
1
2
  import { cn } from "../../../lib/utils.js";
2
3
  import { previewStore } from "../previewStore.js";
3
4
  import { TextLinkPopover } from "../../../core/components/lexical/TextLinkPopover.js";
4
- import { FORMAT_FLAGS } from "../../../core/lib/modifierFormats.js";
5
5
  import { isOverlayMessage } from "../overlayMessages.js";
6
6
  import { c } from "react/compiler-runtime";
7
7
  import * as React from "react";
@@ -9,31 +9,48 @@ import { jsx, jsxs } from "react/jsx-runtime";
9
9
  import { useSelector } from "@xstate/store-react";
10
10
  import { Kbd } from "@camox/ui/kbd";
11
11
  import { Button } from "@camox/ui/button";
12
- import { Bold, Italic } from "lucide-react";
13
- import { ButtonGroup } from "@camox/ui/button-group";
12
+ import { Blend, Bold, Italic, Underline } from "lucide-react";
14
13
  import * as Tooltip$1 from "@camox/ui/tooltip";
14
+ import { ButtonGroup } from "@camox/ui/button-group";
15
15
  import { FloatingToolbar } from "@camox/ui/floating-toolbar";
16
16
  import { Toggle } from "@camox/ui/toggle";
17
17
 
18
18
  //#region src/features/preview/components/FieldToolbar.tsx
19
- const FORMAT_BUTTONS = [{
20
- key: "bold",
21
- flag: FORMAT_FLAGS.bold,
22
- icon: Bold,
23
- label: "Bold",
24
- shortcut: "⌘ B"
25
- }, {
26
- key: "italic",
27
- flag: FORMAT_FLAGS.italic,
28
- icon: Italic,
29
- label: "Italic",
30
- shortcut: "⌘ I"
31
- }];
19
+ const FORMAT_BUTTONS = [
20
+ {
21
+ key: "bold",
22
+ flag: FORMAT_FLAGS.bold,
23
+ icon: Bold,
24
+ label: "Bold",
25
+ shortcut: "⌘ B"
26
+ },
27
+ {
28
+ key: "italic",
29
+ flag: FORMAT_FLAGS.italic,
30
+ icon: Italic,
31
+ label: "Italic",
32
+ shortcut: "⌘ I"
33
+ },
34
+ {
35
+ key: "underline",
36
+ flag: FORMAT_FLAGS.underline,
37
+ icon: Underline,
38
+ label: "Underline",
39
+ shortcut: "⌘ U"
40
+ },
41
+ {
42
+ key: "gradient",
43
+ flag: FORMAT_FLAGS.gradient,
44
+ icon: Blend,
45
+ label: "Gradient",
46
+ shortcut: null
47
+ }
48
+ ];
32
49
  const FieldToolbar = () => {
33
50
  const $ = c(28);
34
- if ($[0] !== "bee72c888eb7fec22d667ab73801a7ed4c0292a3149ebb46febb13e2bf2d9bc3") {
51
+ if ($[0] !== "62fc88dbf76bce176e1b9d35a550f78886d467e61d1692885683da9874bf34dd") {
35
52
  for (let $i = 0; $i < 28; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
36
- $[0] = "bee72c888eb7fec22d667ab73801a7ed4c0292a3149ebb46febb13e2bf2d9bc3";
53
+ $[0] = "62fc88dbf76bce176e1b9d35a550f78886d467e61d1692885683da9874bf34dd";
37
54
  }
38
55
  const iframeElement = useSelector(previewStore, _temp);
39
56
  const [hasSelection, setHasSelection] = React.useState(false);
@@ -41,6 +58,7 @@ const FieldToolbar = () => {
41
58
  const [linkTarget, setLinkTarget] = React.useState(null);
42
59
  const [selectedText, setSelectedText] = React.useState("");
43
60
  const [linkPopoverOpen, setLinkPopoverOpen] = React.useState(false);
61
+ const linkPopoverOpenRef = React.useRef(false);
44
62
  let t0;
45
63
  let t1;
46
64
  if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
@@ -51,11 +69,13 @@ const FieldToolbar = () => {
51
69
  if (data.type === "CAMOX_TEXT_SELECTION_STATE") {
52
70
  setHasSelection(data.hasSelection);
53
71
  setActiveFormats(data.activeFormats);
72
+ if (linkPopoverOpenRef.current) return;
54
73
  setLinkTarget(data.linkTarget);
55
74
  setSelectedText(data.selectedText);
56
75
  return;
57
76
  }
58
77
  if (data.type === "CAMOX_OPEN_TEXT_LINK_POPOVER") {
78
+ linkPopoverOpenRef.current = true;
59
79
  setHasSelection(true);
60
80
  setLinkTarget(data.target);
61
81
  setSelectedText(data.text);
@@ -88,6 +108,7 @@ const FieldToolbar = () => {
88
108
  let t3;
89
109
  if ($[5] === Symbol.for("react.memo_cache_sentinel")) {
90
110
  t3 = (open) => {
111
+ linkPopoverOpenRef.current = open;
91
112
  setLinkPopoverOpen(open);
92
113
  };
93
114
  $[5] = t3;
@@ -101,7 +122,7 @@ const FieldToolbar = () => {
101
122
  target,
102
123
  text
103
124
  }, "*");
104
- setLinkPopoverOpen(false);
125
+ handleLinkPopoverOpenChange(false);
105
126
  };
106
127
  $[6] = iframeElement?.contentWindow;
107
128
  $[7] = t4;
@@ -135,13 +156,14 @@ const FieldToolbar = () => {
135
156
  "data-state": isActive ? "on" : "off",
136
157
  pressed: isActive,
137
158
  variant: "outline",
159
+ "aria-label": label,
138
160
  onPressedChange: () => sendFormat(key)
139
161
  }),
140
162
  children: /* @__PURE__ */ jsx(Icon, {})
141
163
  }), /* @__PURE__ */ jsxs(Tooltip$1.TooltipContent, { children: [
142
164
  label,
143
165
  " ",
144
- /* @__PURE__ */ jsx(Kbd, { children: shortcut })
166
+ shortcut && /* @__PURE__ */ jsx(Kbd, { children: shortcut })
145
167
  ] })] }, key);
146
168
  });
147
169
  $[12] = activeFormats;
@@ -1,7 +1,11 @@
1
+ import { useLocation, useNavigate } from "../../navigation/navigation.js";
1
2
  import { cn } from "../../../lib/utils.js";
3
+ import { PreviewDocumentContext } from "../../runtime/PreviewDocumentContext.js";
4
+ import { PreviewActivationContext } from "./PreviewActivation.js";
5
+ import { EMPTY_PREVIEW_DOCUMENT, isSiteStyle } from "./previewStyles.js";
2
6
  import { c } from "react/compiler-runtime";
3
7
  import * as React from "react";
4
- import { jsx, jsxs } from "react/jsx-runtime";
8
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
5
9
  import { createPortal } from "react-dom";
6
10
 
7
11
  //#region src/features/preview/components/Frame.tsx
@@ -14,155 +18,144 @@ function useFrame() {
14
18
  if (!context) throw new Error("useFrame must be used within a Frame");
15
19
  return context;
16
20
  }
17
- const Frame = (t0) => {
18
- const $ = c(26);
19
- if ($[0] !== "d86eac45c10b92a7f69f3cd224c85551755f967726be09bb5f6e2728732531a8") {
20
- for (let $i = 0; $i < 26; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
21
- $[0] = "d86eac45c10b92a7f69f3cd224c85551755f967726be09bb5f6e2728732531a8";
21
+ function ClearServerMarkup(t0) {
22
+ const $ = c(5);
23
+ if ($[0] !== "46ee340e26c292b1d34ac0ef6952dfd17e06dacaf64fa1db1faae4faca07737a") {
24
+ for (let $i = 0; $i < 5; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
25
+ $[0] = "46ee340e26c292b1d34ac0ef6952dfd17e06dacaf64fa1db1faae4faca07737a";
22
26
  }
23
- const { children, className, style, copyStyles: t1, onIframeReady } = t0;
24
- const copyStyles = t1 === void 0 ? true : t1;
27
+ const { nodes } = t0;
28
+ const activate = React.useContext(PreviewActivationContext);
29
+ let t1;
30
+ let t2;
31
+ if ($[1] !== activate || $[2] !== nodes) {
32
+ t1 = () => {
33
+ nodes.forEach(_temp);
34
+ activate?.();
35
+ };
36
+ t2 = [nodes, activate];
37
+ $[1] = activate;
38
+ $[2] = nodes;
39
+ $[3] = t1;
40
+ $[4] = t2;
41
+ } else {
42
+ t1 = $[3];
43
+ t2 = $[4];
44
+ }
45
+ React.useLayoutEffect(t1, t2);
46
+ return null;
47
+ }
48
+ function _temp(node) {
49
+ return node.remove();
50
+ }
51
+ const Frame = ({ children, className, style, copyStyles = true, serverOnly = false, onIframeReady }) => {
52
+ const navigate = useNavigate();
53
+ const { pathname, hash, href } = useLocation();
54
+ const previewDocument = React.useContext(PreviewDocumentContext);
55
+ const [srcDoc] = React.useState(previewDocument ?? "<!doctype html><html><head></head><body><div id=\"root\" data-camox-preview-root></div></body></html>");
56
+ const [serverNodes, setServerNodes] = React.useState([]);
57
+ const initializedDocument = React.useRef(null);
58
+ const navigateRef = React.useRef(navigate);
59
+ navigateRef.current = navigate;
25
60
  const iframeRef = React.useRef(null);
26
61
  const [iframeWindow, setIframeWindow] = React.useState(null);
27
62
  const [iframeElement, setIframeElement] = React.useState(null);
28
63
  const [mountNode, setMountNode] = React.useState(null);
29
64
  const [hasOpenPopup, setHasOpenPopup] = React.useState(false);
30
- let t2;
31
- let t3;
32
- if ($[1] !== copyStyles || $[2] !== onIframeReady) {
33
- t2 = () => {
34
- const iframe = iframeRef.current;
35
- if (!iframe) return;
36
- const handleLoad = () => {
37
- const iframeDoc = iframe.contentDocument;
38
- const iframeWin = iframe.contentWindow;
39
- if (!iframeDoc || !iframeWin) return;
40
- iframeDoc.open();
41
- iframeDoc.write("<!DOCTYPE html><html><head></head><body style='background: transparent;'></body></html>");
42
- iframeDoc.close();
43
- iframeWin.addEventListener("click", _temp);
44
- if (copyStyles) Array.from(document.head.querySelectorAll("style, link[rel=\"stylesheet\"]")).forEach((style_0) => {
45
- const clonedStyle = style_0.cloneNode(true);
46
- iframeDoc.head.appendChild(clonedStyle);
47
- });
48
- setMountNode(iframeDoc.body);
49
- setIframeWindow(iframeWin);
50
- setIframeElement(iframe);
51
- onIframeReady?.(iframe);
52
- };
53
- iframe.addEventListener("load", handleLoad);
54
- if (iframe.contentDocument?.readyState === "complete") handleLoad();
55
- return () => {
56
- iframe.removeEventListener("load", handleLoad);
57
- };
58
- };
59
- t3 = [copyStyles, onIframeReady];
60
- $[1] = copyStyles;
61
- $[2] = onIframeReady;
62
- $[3] = t2;
63
- $[4] = t3;
64
- } else {
65
- t2 = $[3];
66
- t3 = $[4];
67
- }
68
- React.useEffect(t2, t3);
69
- let t4;
70
- let t5;
71
- if ($[5] === Symbol.for("react.memo_cache_sentinel")) {
72
- t4 = () => {
73
- const checkForOpenPopup = () => {
74
- setHasOpenPopup(document.body.querySelector("[data-base-ui-portal] [data-open]") !== null);
75
- };
76
- checkForOpenPopup();
77
- const observer = new MutationObserver(checkForOpenPopup);
78
- observer.observe(document.body, {
79
- childList: true,
80
- subtree: true,
81
- attributes: true,
82
- attributeFilter: ["data-open", "data-closed"]
65
+ React.useEffect(() => {
66
+ const iframe = iframeRef.current;
67
+ if (!iframe) return;
68
+ const handleLoad = () => {
69
+ const iframeDoc = iframe.contentDocument;
70
+ const iframeWin = iframe.contentWindow;
71
+ const root = iframeDoc?.querySelector("[data-camox-preview-root]");
72
+ if (!iframeDoc || !iframeWin || !root || initializedDocument.current === iframeDoc) return;
73
+ initializedDocument.current = iframeDoc;
74
+ iframeWin.addEventListener("click", (e) => {
75
+ if (e.defaultPrevented || e.button !== 0 || e.metaKey || e.ctrlKey || e.altKey || e.shiftKey) return;
76
+ const anchor = e.target.closest("a");
77
+ if (!anchor?.href || anchor.hasAttribute("download")) return;
78
+ if (anchor.target && anchor.target !== "_self") return;
79
+ e.preventDefault();
80
+ navigateRef.current({ to: new URL(anchor.getAttribute("href"), window.location.href).href });
81
+ });
82
+ if (copyStyles && srcDoc === "<!doctype html><html><head></head><body><div id=\"root\" data-camox-preview-root></div></body></html>") Array.from(document.head.querySelectorAll("style, link[rel=\"stylesheet\"]")).filter(isSiteStyle).forEach((style_0) => {
83
+ const clonedStyle = style_0.cloneNode(true);
84
+ iframeDoc.head.appendChild(clonedStyle);
83
85
  });
84
- return () => {
85
- observer.disconnect();
86
- };
86
+ if (serverOnly) return;
87
+ setServerNodes(Array.from(root.childNodes));
88
+ setMountNode(root);
89
+ setIframeWindow(iframeWin);
90
+ setIframeElement(iframe);
91
+ onIframeReady?.(iframe);
87
92
  };
88
- t5 = [];
89
- $[5] = t4;
90
- $[6] = t5;
91
- } else {
92
- t4 = $[5];
93
- t5 = $[6];
94
- }
95
- React.useEffect(t4, t5);
96
- let t6;
97
- if ($[7] !== className) {
98
- t6 = cn("relative w-full h-full", className);
99
- $[7] = className;
100
- $[8] = t6;
101
- } else t6 = $[8];
102
- let t7;
103
- if ($[9] !== hasOpenPopup) {
104
- t7 = hasOpenPopup && /* @__PURE__ */ jsx("div", { className: "absolute top-0 left-0 h-full w-full" });
105
- $[9] = hasOpenPopup;
106
- $[10] = t7;
107
- } else t7 = $[10];
108
- let t8;
109
- if ($[11] !== iframeElement || $[12] !== iframeWindow) {
110
- t8 = {
111
- window: iframeWindow,
112
- iframeElement
93
+ iframe.addEventListener("load", handleLoad);
94
+ if (iframe.contentDocument?.readyState === "complete") handleLoad();
95
+ return () => {
96
+ iframe.removeEventListener("load", handleLoad);
113
97
  };
114
- $[11] = iframeElement;
115
- $[12] = iframeWindow;
116
- $[13] = t8;
117
- } else t8 = $[13];
118
- let t9;
119
- if ($[14] === Symbol.for("react.memo_cache_sentinel")) {
120
- t9 = /* @__PURE__ */ jsx("iframe", {
121
- ref: iframeRef,
122
- className: cn("w-full h-full")
123
- });
124
- $[14] = t9;
125
- } else t9 = $[14];
126
- let t10;
127
- if ($[15] !== children || $[16] !== mountNode) {
128
- t10 = mountNode && createPortal(children, mountNode);
129
- $[15] = children;
130
- $[16] = mountNode;
131
- $[17] = t10;
132
- } else t10 = $[17];
133
- let t11;
134
- if ($[18] !== t10 || $[19] !== t8) {
135
- t11 = /* @__PURE__ */ jsxs(FrameContext.Provider, {
136
- value: t8,
137
- children: [t9, t10]
138
- });
139
- $[18] = t10;
140
- $[19] = t8;
141
- $[20] = t11;
142
- } else t11 = $[20];
143
- let t12;
144
- if ($[21] !== style || $[22] !== t11 || $[23] !== t6 || $[24] !== t7) {
145
- t12 = /* @__PURE__ */ jsxs("div", {
146
- className: t6,
147
- style,
148
- children: [t7, t11]
98
+ }, [
99
+ copyStyles,
100
+ onIframeReady,
101
+ srcDoc,
102
+ serverOnly
103
+ ]);
104
+ React.useEffect(() => {
105
+ if (!iframeWindow || !mountNode) return;
106
+ let base = iframeWindow.document.querySelector("base");
107
+ if (!base) {
108
+ base = iframeWindow.document.createElement("base");
109
+ iframeWindow.document.head.insertBefore(base, iframeWindow.document.head.firstChild);
110
+ }
111
+ base.href = href;
112
+ if (!hash) {
113
+ iframeWindow.scrollTo({ top: 0 });
114
+ return;
115
+ }
116
+ try {
117
+ iframeWindow.document.getElementById(decodeURIComponent(hash.slice(1)))?.scrollIntoView();
118
+ } catch {}
119
+ }, [
120
+ pathname,
121
+ hash,
122
+ href,
123
+ iframeWindow,
124
+ mountNode
125
+ ]);
126
+ React.useEffect(() => {
127
+ const checkForOpenPopup = () => {
128
+ setHasOpenPopup(document.body.querySelector("[data-base-ui-portal] [data-open]") !== null);
129
+ };
130
+ checkForOpenPopup();
131
+ const observer = new MutationObserver(checkForOpenPopup);
132
+ observer.observe(document.body, {
133
+ childList: true,
134
+ subtree: true,
135
+ attributes: true,
136
+ attributeFilter: ["data-open", "data-closed"]
149
137
  });
150
- $[21] = style;
151
- $[22] = t11;
152
- $[23] = t6;
153
- $[24] = t7;
154
- $[25] = t12;
155
- } else t12 = $[25];
156
- return t12;
138
+ return () => {
139
+ observer.disconnect();
140
+ };
141
+ }, []);
142
+ return /* @__PURE__ */ jsxs("div", {
143
+ className: cn("relative w-full h-full", className),
144
+ style,
145
+ children: [hasOpenPopup && /* @__PURE__ */ jsx("div", { className: "absolute top-0 left-0 h-full w-full" }), /* @__PURE__ */ jsxs(FrameContext.Provider, {
146
+ value: {
147
+ window: iframeWindow,
148
+ iframeElement
149
+ },
150
+ children: [/* @__PURE__ */ jsx("iframe", {
151
+ ref: iframeRef,
152
+ title: "Page preview",
153
+ srcDoc,
154
+ className: cn("w-full h-full")
155
+ }), mountNode && createPortal(/* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(ClearServerMarkup, { nodes: serverNodes }), children] }), mountNode)]
156
+ })]
157
+ });
157
158
  };
158
- function _temp(e) {
159
- if (e.defaultPrevented) return;
160
- const anchor = e.target.closest("a");
161
- if (!anchor?.href) return;
162
- if (anchor.target === "_blank") return;
163
- e.preventDefault();
164
- window.top?.location.assign(anchor.href);
165
- }
166
159
 
167
160
  //#endregion
168
- export { Frame, useFrame };
161
+ export { Frame, FrameContext, useFrame };
@@ -1,59 +1,63 @@
1
1
  import { previewStore } from "../previewStore.js";
2
- import { AddBlockSidebar } from "./AddBlockSidebar.js";
2
+ import { DerivedLayoutSidebar } from "./DerivedLayoutSidebar.js";
3
3
  import { PageNavigatorSidebar } from "./PageNavigatorSidebar.js";
4
4
  import { c } from "react/compiler-runtime";
5
5
  import { jsx, jsxs } from "react/jsx-runtime";
6
6
  import { useSelector } from "@xstate/store-react";
7
7
 
8
8
  //#region src/features/preview/components/LeftSidebar.tsx
9
- const getLeftSidebarRoute = ({ isAddBlockSidebarOpen }) => {
10
- if (isAddBlockSidebarOpen) return { type: "add-block" };
11
- return { type: "page-navigator" };
12
- };
13
9
  const LeftSidebar = (t0) => {
14
- const $ = c(12);
15
- if ($[0] !== "f683caf1e19043e2a8ec108ed89c22771f4e771637dbf0249087f015011f6726") {
16
- for (let $i = 0; $i < 12; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
17
- $[0] = "f683caf1e19043e2a8ec108ed89c22771f4e771637dbf0249087f015011f6726";
10
+ const $ = c(13);
11
+ if ($[0] !== "c0b8051f9d03df681e369c0b2954359f21e672e526188e45d0de7a395154e9cc") {
12
+ for (let $i = 0; $i < 13; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
13
+ $[0] = "c0b8051f9d03df681e369c0b2954359f21e672e526188e45d0de7a395154e9cc";
18
14
  }
19
- const { page } = t0;
15
+ const { page, derivedLayout } = t0;
20
16
  const isAddBlockSidebarOpen = useSelector(previewStore, _temp);
21
17
  let t1;
22
- if ($[1] !== isAddBlockSidebarOpen) {
23
- t1 = getLeftSidebarRoute({ isAddBlockSidebarOpen });
24
- $[1] = isAddBlockSidebarOpen;
25
- $[2] = t1;
26
- } else t1 = $[2];
27
- const route = t1;
18
+ if ($[1] === Symbol.for("react.memo_cache_sentinel")) {
19
+ t1 = { width: 250 };
20
+ $[1] = t1;
21
+ } else t1 = $[1];
28
22
  let t2;
29
- if ($[3] === Symbol.for("react.memo_cache_sentinel")) {
30
- t2 = { width: 250 };
31
- $[3] = t2;
32
- } else t2 = $[3];
23
+ if ($[2] !== derivedLayout || $[3] !== page) {
24
+ t2 = derivedLayout ? /* @__PURE__ */ jsx(DerivedLayoutSidebar, { layout: derivedLayout }) : /* @__PURE__ */ jsx(PageNavigatorSidebar, { page });
25
+ $[2] = derivedLayout;
26
+ $[3] = page;
27
+ $[4] = t2;
28
+ } else t2 = $[4];
33
29
  let t3;
34
- if ($[4] !== route.type) {
35
- t3 = route.type === "add-block" && /* @__PURE__ */ jsx(AddBlockSidebar, {});
36
- $[4] = route.type;
37
- $[5] = t3;
38
- } else t3 = $[5];
30
+ if ($[5] !== isAddBlockSidebarOpen || $[6] !== t2) {
31
+ t3 = /* @__PURE__ */ jsx("div", {
32
+ className: "contents",
33
+ inert: isAddBlockSidebarOpen,
34
+ children: t2
35
+ });
36
+ $[5] = isAddBlockSidebarOpen;
37
+ $[6] = t2;
38
+ $[7] = t3;
39
+ } else t3 = $[7];
39
40
  let t4;
40
- if ($[6] !== page || $[7] !== route.type) {
41
- t4 = route.type === "page-navigator" && /* @__PURE__ */ jsx(PageNavigatorSidebar, { page });
42
- $[6] = page;
43
- $[7] = route.type;
44
- $[8] = t4;
45
- } else t4 = $[8];
41
+ if ($[8] !== isAddBlockSidebarOpen) {
42
+ t4 = isAddBlockSidebarOpen && /* @__PURE__ */ jsx("div", {
43
+ className: "absolute inset-0 z-20 cursor-not-allowed",
44
+ style: { background: "rgba(0, 0, 0, 0.5)" },
45
+ "aria-hidden": "true"
46
+ });
47
+ $[8] = isAddBlockSidebarOpen;
48
+ $[9] = t4;
49
+ } else t4 = $[9];
46
50
  let t5;
47
- if ($[9] !== t3 || $[10] !== t4) {
51
+ if ($[10] !== t3 || $[11] !== t4) {
48
52
  t5 = /* @__PURE__ */ jsxs("aside", {
49
- className: "flex shrink-0 flex-col border-r-2",
50
- style: t2,
53
+ className: "relative flex shrink-0 flex-col border-r-2",
54
+ style: t1,
51
55
  children: [t3, t4]
52
56
  });
53
- $[9] = t3;
54
- $[10] = t4;
55
- $[11] = t5;
56
- } else t5 = $[11];
57
+ $[10] = t3;
58
+ $[11] = t4;
59
+ $[12] = t5;
60
+ } else t5 = $[12];
57
61
  return t5;
58
62
  };
59
63
  function _temp(state) {
@@ -26,9 +26,9 @@ const normalizeLinkValue = (value) => {
26
26
  };
27
27
  const LinkFieldEditor = (t0) => {
28
28
  const $ = c(74);
29
- if ($[0] !== "d6e76ca161ece5e3c3ab2fca39477fdbca4669ce2a59cab1e307374e6d56bc57") {
29
+ if ($[0] !== "cdb2f56fb4805e0de235a068b1342c61e1eade64737868f8170208f1ecf497ab") {
30
30
  for (let $i = 0; $i < 74; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
31
- $[0] = "d6e76ca161ece5e3c3ab2fca39477fdbca4669ce2a59cab1e307374e6d56bc57";
31
+ $[0] = "cdb2f56fb4805e0de235a068b1342c61e1eade64737868f8170208f1ecf497ab";
32
32
  }
33
33
  const { fieldName, linkValue: rawLinkValue, onSave } = t0;
34
34
  let t1;
@@ -173,8 +173,7 @@ const LinkFieldEditor = (t0) => {
173
173
  value: textField.value,
174
174
  onChange: t16,
175
175
  onFocus: textField.onFocus,
176
- onBlur: textField.onBlur,
177
- autoFocus: true
176
+ onBlur: textField.onBlur
178
177
  });
179
178
  $[33] = t15;
180
179
  $[34] = t16;
@@ -3,9 +3,9 @@ import { projectQueries } from "../../../lib/queries.js";
3
3
  import { cn } from "../../../lib/utils.js";
4
4
  import { previewStore, selectionBlockId } from "../previewStore.js";
5
5
  import { UserButton } from "../../studio/components/UserButton.js";
6
- import { AddBlockSidebar } from "./AddBlockSidebar.js";
7
6
  import { PageTree } from "./PageTree.js";
8
7
  import { PageNavigatorHeader } from "./PageNavigatorSidebar.js";
8
+ import { AddBlockSidebar } from "./AddBlockSidebar.js";
9
9
  import { PageEditorSidebar } from "./PageEditorSidebar.js";
10
10
  import { PageInfoSidebar, PageMarkdownContent, PageSeoContent } from "./PageInfoSidebar.js";
11
11
  import { c } from "react/compiler-runtime";
@@ -184,7 +184,7 @@ function MobilePreviewDrawer({ page, projectName }) {
184
184
  className: "w-full",
185
185
  disabled: page.status === "published" || page.livePublishedCheckpointId == null,
186
186
  onClick: () => previewStore.send({ type: "viewLivePage" }),
187
- children: "View live site"
187
+ children: "View live page"
188
188
  })
189
189
  }),
190
190
  /* @__PURE__ */ jsxs("div", {
@@ -251,9 +251,9 @@ function MobilePreviewDrawer({ page, projectName }) {
251
251
  }
252
252
  function DrawerTile(t0) {
253
253
  const $ = c(13);
254
- if ($[0] !== "a15836a2c406a6e26e3450f2952542d7c3ef6e1f52eed0eca720954850f751a5") {
254
+ if ($[0] !== "621776a19ae594038e7ff74376eaee55067cbd45ac5f2b72eb73e9a66d3c4ae0") {
255
255
  for (let $i = 0; $i < 13; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
256
- $[0] = "a15836a2c406a6e26e3450f2952542d7c3ef6e1f52eed0eca720954850f751a5";
256
+ $[0] = "621776a19ae594038e7ff74376eaee55067cbd45ac5f2b72eb73e9a66d3c4ae0";
257
257
  }
258
258
  const { title, icon: Icon, onClick, fullWidth: t1, disabled: t2 } = t0;
259
259
  const fullWidth = t1 === void 0 ? false : t1;