camox 0.53.1 → 0.56.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 (52) hide show
  1. package/dist/features/canvas/CamoxCanvas.js +14 -11
  2. package/dist/features/canvas/CanvasLoadingScreen.js +1 -1
  3. package/dist/features/canvas/sidebar/CanvasViewHeader.js +1 -1
  4. package/dist/features/canvas/sidebar/{CanvasSidebar.js → ContentSidebar.js} +5 -5
  5. package/dist/features/canvas/sidebar/{CanvasSidebarFrame.js → ContentSidebarFrame.js} +4 -4
  6. package/dist/features/canvas/sidebar/{CanvasSidebarSkeleton.js → ContentSidebarSkeleton.js} +7 -7
  7. package/dist/features/og/documentFonts.js +49 -0
  8. package/dist/features/og/imageResponse.d.ts +14 -5
  9. package/dist/features/og/imageResponse.js +20 -21
  10. package/dist/features/og/pageImage.js +7 -4
  11. package/dist/features/preview/CamoxPreview.js +2 -2
  12. package/dist/features/preview/components/BlockActionsPopover.js +1 -1
  13. package/dist/features/preview/components/IconFieldEditor.js +1 -1
  14. package/dist/features/preview/components/LinkFieldEditor.js +1 -1
  15. package/dist/features/preview/components/PagePicker.js +1 -1
  16. package/dist/features/preview/components/PreviewToolbar.js +1 -1
  17. package/dist/features/preview/components/SelectionEditor.js +136 -110
  18. package/dist/features/preview/components/SidebarStack.js +110 -83
  19. package/dist/features/preview/components/StudioEditingFallback.js +3 -3
  20. package/dist/features/routes/pageRuntime.d.ts +1 -1
  21. package/dist/features/runtime/RuntimeChrome.js +4 -4
  22. package/dist/features/runtime/runtime.d.ts +5 -0
  23. package/dist/features/runtime/runtime.js +15 -4
  24. package/dist/features/studio/components/AgentSidebar.js +56 -0
  25. package/dist/features/studio/components/ChatWidget.js +237 -0
  26. package/dist/features/studio/components/DraftsControl.js +17 -17
  27. package/dist/features/studio/components/ReviewDraftSheet.js +38 -38
  28. package/dist/features/studio/components/Squareling.js +116 -0
  29. package/dist/features/studio/components/ThreadMessages.js +190 -165
  30. package/dist/features/studio/components/WorkersWidget.js +52 -0
  31. package/dist/features/studio/studioStore.js +5 -5
  32. package/dist/features/vite/bundlerLogs.js +1 -0
  33. package/dist/features/vite/runtimeDev.js +11 -0
  34. package/dist/features/vite/vite.js +3 -1
  35. package/dist/lib/queries.js +1 -1
  36. package/dist/package.js +1 -1
  37. package/dist/studio.css +1 -1
  38. package/package.json +5 -5
  39. package/skills/camox/SKILL.md +3 -10
  40. package/skills/camox/references/artifacts.md +2 -2
  41. package/skills/camox/references/block-definitions.md +1 -1
  42. package/skills/camox/references/layout-definitions.md +12 -17
  43. package/skills/camox/references/routed-layouts.md +2 -2
  44. package/skills/camox-cli/SKILL.md +15 -0
  45. package/skills/{camox → camox-cli}/references/cli-common.md +1 -1
  46. package/skills/{camox → camox-cli}/references/cli-content.md +2 -2
  47. package/skills/{camox → camox-cli}/references/cli-publishing.md +4 -4
  48. package/skills/camox-expand/SKILL.md +1 -1
  49. package/skills/camoxify/SKILL.md +1 -1
  50. package/dist/features/og/defaultFonts.js +0 -31
  51. package/dist/features/og/geist-variable-ttf-base64.js +0 -21
  52. package/dist/features/studio/components/ChatSidebar.js +0 -364
@@ -29,7 +29,7 @@ import { CanvasPageHeader } from "./CanvasPageHeader.js";
29
29
  import { CanvasPreviewPageSlot } from "./CanvasPreviewPageSlot.js";
30
30
  import { CANVAS_WORLD_TRANSFORM, canvasScreenAbove, canvasScreenLength, canvasScreenX } from "./canvasScreenSpace.js";
31
31
  import { selectedCanvasPage } from "./canvasSelection.js";
32
- import { CanvasSidebar } from "./sidebar/CanvasSidebar.js";
32
+ import { ContentSidebar } from "./sidebar/ContentSidebar.js";
33
33
  import { useCanvasCamera } from "./useCanvasCamera.js";
34
34
  import { useCanvasNearness } from "./useCanvasNearness.js";
35
35
  import { useDiscoveredPreviewPaths } from "./useDiscoveredPreviewPaths.js";
@@ -42,7 +42,7 @@ import { createStore as createStore$1 } from "@xstate/store";
42
42
 
43
43
  //#region src/features/canvas/CamoxCanvas.tsx
44
44
  /**
45
- * The Canvas spans the studio under its sidebars, the Canvas sidebar on its left and the chat on
45
+ * The Canvas spans the studio under its sidebars, the Content Sidebar on its left and the Agent Sidebar on
46
46
  * its right: the camera frames and snaps Pages between them, and above the studio's bottom edge.
47
47
  */
48
48
  const CANVAS_INSETS = {
@@ -459,10 +459,10 @@ function CanvasPageFrameLoader(t0) {
459
459
  return t2;
460
460
  }
461
461
  /**
462
- * How far a sidebar's scrim fades, in px: from this far inside the sidebar, to the edge of a
463
- * snapped Page, past it by the page fit's padding.
462
+ * Where a sidebar's scrim starts fading, in px from the studio's edge: past the sidebar's outer
463
+ * gutter (`SIDEBAR_GUTTER`), so it fades across the whole of the sidebar's contents.
464
464
  */
465
- const SCRIM_FADE_INSIDE = 48;
465
+ const SCRIM_FADE_START = 8;
466
466
  /** How opaque the scrim gets at most: what's under it always shows through, faintly. */
467
467
  const SCRIM_MAX_OPACITY = .8;
468
468
  /** Opacity along the fade, relative to the most, eased so it leaves no visible edge where it ends. */
@@ -477,11 +477,14 @@ const SCRIM_EASING = [
477
477
  .05,
478
478
  0
479
479
  ];
480
- /** Fades what the Canvas shows around a sidebar into the Canvas's background, toward the sidebar. */
480
+ /**
481
+ * Fades what the Canvas shows around a sidebar into the Canvas's background, toward the sidebar:
482
+ * from nothing past a snapped Page's edge, to the most only at the sidebar's outer gutter.
483
+ */
481
484
  function scrimGradient(towards, inset) {
482
- const from = inset - SCRIM_FADE_INSIDE;
483
- const length = SCRIM_FADE_INSIDE + 16;
484
- const stops = SCRIM_EASING.map((alpha, index) => `color-mix(in oklab, var(--color-muted) ${alpha * SCRIM_MAX_OPACITY * 100}%, transparent) ${from + length * index / (SCRIM_EASING.length - 1)}px`);
485
+ const from = SCRIM_FADE_START;
486
+ const length = inset + 16 - SCRIM_FADE_START;
487
+ const stops = SCRIM_EASING.map((alpha, index) => `color-mix(in oklab, var(--color-canvas) ${alpha * SCRIM_MAX_OPACITY * 100}%, transparent) ${from + length * index / (SCRIM_EASING.length - 1)}px`);
485
488
  return `linear-gradient(to ${towards === "left" ? "right" : "left"}, ${stops.join(", ")})`;
486
489
  }
487
490
  /** A frame header above an item's slot, at a constant on-screen height. */
@@ -1049,7 +1052,7 @@ function CanvasWorkspace(t0) {
1049
1052
  "aria-describedby": instructionsId,
1050
1053
  tabIndex: 0,
1051
1054
  "data-camox-canvas": true,
1052
- className: "bg-muted relative min-h-0 min-w-0 flex-1 touch-none overflow-clip outline-none *:*:[--canvas-x:initial] *:*:[--canvas-y:initial] data-[canvas-pan]:cursor-grab data-[canvas-pan]:**:cursor-[inherit]! data-[canvas-pan=dragging]:cursor-grabbing data-[canvas-pan]:[&_iframe]:pointer-events-none",
1055
+ className: "bg-canvas relative min-h-0 min-w-0 flex-1 touch-none overflow-clip outline-none *:*:[--canvas-x:initial] *:*:[--canvas-y:initial] data-[canvas-pan]:cursor-grab data-[canvas-pan]:**:cursor-[inherit]! data-[canvas-pan=dragging]:cursor-grabbing data-[canvas-pan]:[&_iframe]:pointer-events-none",
1053
1056
  style: t13,
1054
1057
  children: [
1055
1058
  /* @__PURE__ */ jsx(CanvasWorkspaceContext, {
@@ -1305,7 +1308,7 @@ function CamoxCanvas(t0) {
1305
1308
  } else t17 = $[37];
1306
1309
  let t18;
1307
1310
  if ($[38] !== editingOwner || $[39] !== intendedPage || $[40] !== pageRecord || $[41] !== runtimeBasePath || $[42] !== t16) {
1308
- t18 = /* @__PURE__ */ jsx(CanvasSidebar, {
1311
+ t18 = /* @__PURE__ */ jsx(ContentSidebar, {
1309
1312
  page: intendedPage,
1310
1313
  navigator: t16,
1311
1314
  onShowWholeCanvas: t17,
@@ -26,7 +26,7 @@ function CanvasLoadingScreen(t0) {
26
26
  if ($[3] !== t2) {
27
27
  t3 = /* @__PURE__ */ jsx("div", {
28
28
  "data-canvas-loading": true,
29
- className: "bg-muted absolute inset-0 grid place-items-center",
29
+ className: "bg-canvas absolute inset-0 grid place-items-center",
30
30
  children: t2
31
31
  });
32
32
  $[3] = t2;
@@ -1,6 +1,6 @@
1
1
  import { SidebarStackHeader, useSelectionViewCount } from "../../preview/components/SidebarStack.js";
2
- import { SHOW_WHOLE_CANVAS_SHORTCUT } from "../../preview/previewConstants.js";
3
2
  import { formatShortcut } from "../../../lib/shortcuts.js";
3
+ import { SHOW_WHOLE_CANVAS_SHORTCUT } from "../../preview/previewConstants.js";
4
4
  import { c } from "react/compiler-runtime";
5
5
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
6
6
 
@@ -1,18 +1,18 @@
1
1
  import { SidebarStack, SidebarStackView } from "../../preview/components/SidebarStack.js";
2
- import { CanvasSidebarFrame } from "./CanvasSidebarFrame.js";
3
2
  import { CanvasViewHeader } from "./CanvasViewHeader.js";
3
+ import { ContentSidebarFrame } from "./ContentSidebarFrame.js";
4
4
  import { CreatePageModal } from "../../preview/components/CreatePageModal.js";
5
5
  import { CanvasNavigator } from "./CanvasNavigator.js";
6
6
  import { PageInspector } from "./PageInspector.js";
7
7
  import { c } from "react/compiler-runtime";
8
8
  import { jsx, jsxs } from "react/jsx-runtime";
9
9
 
10
- //#region src/features/canvas/sidebar/CanvasSidebar.tsx
10
+ //#region src/features/canvas/sidebar/ContentSidebar.tsx
11
11
  /**
12
12
  * The sidebar beside the Canvas, a stack of views: the Canvas's own, which shows the Canvas
13
13
  * Navigator, then the Canvas Inspector of the selected Page laid over it, if any.
14
14
  */
15
- function CanvasSidebar(t0) {
15
+ function ContentSidebar(t0) {
16
16
  const $ = c(16);
17
17
  const { page, navigator, onShowWholeCanvas, owner: t1, pageRecord, runtimeBasePath } = t0;
18
18
  const owner = t1 === void 0 ? null : t1;
@@ -61,7 +61,7 @@ function CanvasSidebar(t0) {
61
61
  } else t7 = $[12];
62
62
  let t8;
63
63
  if ($[13] !== t2 || $[14] !== t6) {
64
- t8 = /* @__PURE__ */ jsxs(CanvasSidebarFrame, {
64
+ t8 = /* @__PURE__ */ jsxs(ContentSidebarFrame, {
65
65
  label: t2,
66
66
  children: [t6, t7]
67
67
  });
@@ -73,4 +73,4 @@ function CanvasSidebar(t0) {
73
73
  }
74
74
 
75
75
  //#endregion
76
- export { CanvasSidebar };
76
+ export { ContentSidebar };
@@ -1,13 +1,13 @@
1
1
  import { c } from "react/compiler-runtime";
2
2
  import { jsx } from "react/jsx-runtime";
3
3
 
4
- //#region src/features/canvas/sidebar/CanvasSidebarFrame.tsx
4
+ //#region src/features/canvas/sidebar/ContentSidebarFrame.tsx
5
5
  /**
6
- * The Canvas sidebar's own box, laid over the Canvas's left side: the Canvas Navigator or the
6
+ * The Content Sidebar's own box, laid over the Canvas's left side: the Canvas Navigator or the
7
7
  * Canvas Inspector, or a stand-in for either, goes in it. Only its cards have a background:
8
8
  * around them, the Canvas shows through.
9
9
  */
10
- function CanvasSidebarFrame(t0) {
10
+ function ContentSidebarFrame(t0) {
11
11
  const $ = c(9);
12
12
  let children;
13
13
  let label;
@@ -46,4 +46,4 @@ function CanvasSidebarFrame(t0) {
46
46
  }
47
47
 
48
48
  //#endregion
49
- export { CanvasSidebarFrame };
49
+ export { ContentSidebarFrame };
@@ -1,17 +1,17 @@
1
1
  import { SidebarStack, SidebarStackView } from "../../preview/components/SidebarStack.js";
2
2
  import { CanvasInspectorBody, CanvasInspectorHeaderSkeleton } from "./CanvasInspector.js";
3
- import { CanvasSidebarFrame } from "./CanvasSidebarFrame.js";
4
3
  import { CanvasViewHeader } from "./CanvasViewHeader.js";
4
+ import { ContentSidebarFrame } from "./ContentSidebarFrame.js";
5
5
  import { CuratedPageSkeleton, LayoutPageSkeleton } from "./PageInspectorSkeleton.js";
6
6
  import { c } from "react/compiler-runtime";
7
7
  import { jsx, jsxs } from "react/jsx-runtime";
8
8
 
9
- //#region src/features/canvas/sidebar/CanvasSidebarSkeleton.tsx
9
+ //#region src/features/canvas/sidebar/ContentSidebarSkeleton.tsx
10
10
  /**
11
- * Stands in for the Canvas sidebar while the Canvas loads, where the sidebar will show. For a
11
+ * Stands in for the Content Sidebar while the Canvas loads, where the sidebar will show. For a
12
12
  * selected Page, it takes the Canvas Inspector's layout. Without one, it is empty.
13
13
  */
14
- function CanvasSidebarSkeleton(t0) {
14
+ function ContentSidebarSkeleton(t0) {
15
15
  const $ = c(5);
16
16
  const { page: t1, layoutPage: t2 } = t0;
17
17
  const page = t1 === void 0 ? true : t1;
@@ -33,8 +33,8 @@ function CanvasSidebarSkeleton(t0) {
33
33
  } else t3 = $[2];
34
34
  let t4;
35
35
  if ($[3] !== t3) {
36
- t4 = /* @__PURE__ */ jsx(CanvasSidebarFrame, {
37
- "data-canvas-sidebar-skeleton": true,
36
+ t4 = /* @__PURE__ */ jsx(ContentSidebarFrame, {
37
+ "data-content-sidebar-skeleton": true,
38
38
  children: t3
39
39
  });
40
40
  $[3] = t3;
@@ -44,4 +44,4 @@ function CanvasSidebarSkeleton(t0) {
44
44
  }
45
45
 
46
46
  //#endregion
47
- export { CanvasSidebarSkeleton };
47
+ export { ContentSidebarSkeleton };
@@ -0,0 +1,49 @@
1
+ //#region src/features/og/documentFonts.ts
2
+ const GOOGLE_FONTS_CSS2 = "https://fonts.googleapis.com/css2";
3
+ /**
4
+ * The Google Fonts families the document's stylesheet links load, in link order, so page images
5
+ * render in the site's fonts. Other stylesheets are ignored.
6
+ */
7
+ function documentGoogleFonts(document) {
8
+ return (Array.isArray(document.link) ? document.link : []).flatMap((link) => {
9
+ if (typeof link !== "object" || link === null) return [];
10
+ const { rel, href } = link;
11
+ if (rel !== "stylesheet" || typeof href !== "string") return [];
12
+ const url = URL.parse(href);
13
+ if (!url || `${url.origin}${url.pathname}` !== GOOGLE_FONTS_CSS2) return [];
14
+ return url.searchParams.getAll("family").map(parseFamily);
15
+ });
16
+ }
17
+ /**
18
+ * One css2 `family` parameter: `Inter`, or a name with its axes and their values, such as
19
+ * `Archivo:ital,wght@0,100..900;1,100..900` (one `;`-separated tuple per face).
20
+ */
21
+ function parseFamily(param) {
22
+ const [name = "", spec] = param.split(":");
23
+ if (!spec) return { name };
24
+ const [axisList = "", tupleList = ""] = spec.split("@");
25
+ const axes = axisList.split(",");
26
+ const tuples = tupleList.split(";").map((tuple) => tuple.split(","));
27
+ const valuesOf = (axis) => {
28
+ const index = axes.indexOf(axis);
29
+ return index < 0 ? [] : [...new Set(tuples.map((tuple) => tuple[index] ?? ""))];
30
+ };
31
+ const weights = valuesOf("wght");
32
+ const weightRange = weights.find(isRange);
33
+ const otherAxes = Object.fromEntries(axes.filter((axis) => axis !== "wght" && axis !== "ital").map((axis) => {
34
+ const [value = ""] = valuesOf(axis);
35
+ return [axis, isRange(value) ? value : Number(value)];
36
+ }));
37
+ return {
38
+ name,
39
+ ...weights.length > 0 && { weight: weightRange ?? weights.map(Number) },
40
+ ...axes.includes("ital") && { style: valuesOf("ital").map((ital) => ital === "1" ? "italic" : "normal") },
41
+ ...Object.keys(otherAxes).length > 0 && { axes: otherAxes }
42
+ };
43
+ }
44
+ function isRange(value) {
45
+ return value.includes("..");
46
+ }
47
+
48
+ //#endregion
49
+ export { documentGoogleFonts };
@@ -1,8 +1,17 @@
1
- import { ReactNode } from "react";
2
- import { ImageResponse as ImageResponse$1, ImageResponseOptions } from "@takumi-rs/image-response";
1
+ import { ReactElement } from "react";
2
+ import { GoogleFontFamily } from "takumi-js/helpers";
3
+ import { ImageResponse } from "takumi-js/response";
3
4
  //#region src/features/og/imageResponse.d.ts
4
- export declare class ImageResponse extends ImageResponse$1 {
5
- constructor(component: ReactNode, options?: ImageResponseOptions);
5
+ export interface ImageStyle {
6
+ /** The site's compiled stylesheet, which the image's `className`s match. */
7
+ css?: string;
8
+ /** The Google Fonts families the site loads, in fallback order. */
9
+ fonts: GoogleFontFamily[];
6
10
  }
11
+ /** Renders `element` as a PNG response, styled like the site. */
12
+ export declare function createImageResponse(element: ReactElement, size: {
13
+ width: number;
14
+ height: number;
15
+ }, { css, fonts }: ImageStyle): Promise<Response>;
7
16
  //#endregion
8
- export type { ImageResponseOptions };
17
+ export { ImageResponse };
@@ -1,26 +1,25 @@
1
- import { DEFAULT_FONTS } from "./defaultFonts.js";
2
- import { ImageResponse as ImageResponse$1 } from "@takumi-rs/image-response";
1
+ import { googleFonts } from "takumi-js/helpers";
2
+ import { ImageResponse } from "takumi-js/response";
3
3
 
4
4
  //#region src/features/og/imageResponse.ts
5
- /**
6
- * OG image renderer for the Worker.
7
- *
8
- * Under the `workerd` export condition, `@takumi-rs/image-response` picks Takumi's wasm
9
- * backend, which imports the wasm binary itself. The Cloudflare Vite plugin turns that
10
- * `.wasm` import into a `WebAssembly.Module`, and Takumi lazy-inits it inside the
11
- * response stream.
12
- *
13
- * Geist is bundled in `./defaultFonts` to compensate for the wasm renderer shipping with
14
- * no embedded fonts.
15
- */
16
- var ImageResponse = class extends ImageResponse$1 {
17
- constructor(component, options) {
18
- super(component, {
19
- ...options,
20
- fonts: options?.fonts ?? DEFAULT_FONTS
21
- });
5
+ /** Renders `element` as a PNG response, styled like the site. */
6
+ async function createImageResponse(element, size, { css, fonts }) {
7
+ return new ImageResponse(element, {
8
+ ...size,
9
+ css,
10
+ fonts: await loadFonts(fonts)
11
+ });
12
+ }
13
+ /** The families' font files, loaded lazily. Without them, the image falls back to Geist. */
14
+ async function loadFonts(families) {
15
+ if (families.length === 0) return [];
16
+ try {
17
+ return await googleFonts(families);
18
+ } catch (error) {
19
+ console.warn("[camox] Page image fonts failed to load; rendering with Geist.", error);
20
+ return [];
22
21
  }
23
- };
22
+ }
24
23
 
25
24
  //#endregion
26
- export { ImageResponse };
25
+ export { ImageResponse, createImageResponse };
@@ -78,11 +78,14 @@ function DefaultPageImage(t0) {
78
78
  } else t5 = $[8];
79
79
  return t5;
80
80
  }
81
- /** Renders a page image as a PNG response. Server only. */
82
- async function renderPageImage(element) {
81
+ /**
82
+ * Renders a page image as a PNG response, styled like the site: its elements' `className`s match
83
+ * the site's compiled stylesheet, and its text uses the site's fonts. Server only.
84
+ */
85
+ async function renderPageImage(element, style) {
83
86
  if (import.meta.env?.SSR === false) throw new Error("OG images can only be rendered on the server.");
84
- const { ImageResponse } = await import("camox/_internal/imageResponse");
85
- return new ImageResponse(element, PAGE_IMAGE_SIZE);
87
+ const { createImageResponse } = await import("camox/_internal/imageResponse");
88
+ return createImageResponse(element, PAGE_IMAGE_SIZE, style);
86
89
  }
87
90
 
88
91
  //#endregion
@@ -14,7 +14,7 @@ import { CanvasLoadingScreen } from "../canvas/CanvasLoadingScreen.js";
14
14
  import { canvasStore } from "../canvas/canvasStore.js";
15
15
  import { previewStore, selectIsCanvasShown } from "./previewStore.js";
16
16
  import { SHOW_WHOLE_CANVAS_SHORTCUT, TOGGLE_CANVAS_SHORTCUT } from "./previewConstants.js";
17
- import { CanvasSidebarSkeleton } from "../canvas/sidebar/CanvasSidebarSkeleton.js";
17
+ import { ContentSidebarSkeleton } from "../canvas/sidebar/ContentSidebarSkeleton.js";
18
18
  import { takeShowCanvasRequest } from "../provider/signInShortcut.js";
19
19
  import { PreviewEditingOwnerContext } from "./previewSelection.js";
20
20
  import { RendererFramesProvider, RendererSlot, useRendererHost, useRendererStatus } from "../renderer/RendererFrames.js";
@@ -577,7 +577,7 @@ const PreviewShell = (t0) => {
577
577
  const t14 = !!derivedLayout;
578
578
  let t15;
579
579
  if ($[20] !== t13 || $[21] !== t14) {
580
- t15 = /* @__PURE__ */ jsx(CanvasSidebarSkeleton, {
580
+ t15 = /* @__PURE__ */ jsx(ContentSidebarSkeleton, {
581
581
  page: t13,
582
582
  layoutPage: t14
583
583
  });
@@ -14,8 +14,8 @@ import { useMutation } from "@tanstack/react-query";
14
14
  import { Copy, Trash2 } from "lucide-react";
15
15
  import { toast } from "@camox/ui/toaster";
16
16
  import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from "@camox/ui/alert-dialog";
17
- import { Command as Command$1, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut } from "@camox/ui/command";
18
17
  import { Popover, PopoverContent, PopoverTrigger } from "@camox/ui/popover";
18
+ import { Command as Command$1, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator, CommandShortcut } from "@camox/ui/command";
19
19
 
20
20
  //#region src/features/preview/components/BlockActionsPopover.tsx
21
21
  const BlockActionsPopover = ({ block, children, open, onOpenChange, align = "start", isLayoutBlock, layoutSlot }) => {
@@ -5,9 +5,9 @@ import { jsx, jsxs } from "react/jsx-runtime";
5
5
  import { Button } from "@camox/ui/button";
6
6
  import { ChevronsUpDown, SearchIcon } from "lucide-react";
7
7
  import { Combobox } from "@base-ui/react/combobox";
8
+ import { Popover, PopoverContent, PopoverTrigger } from "@camox/ui/popover";
8
9
  import { commandFilter } from "@camox/ui/command";
9
10
  import { InputGroup, InputGroupAddon, InputGroupInput } from "@camox/ui/input-group";
10
- import { Popover, PopoverContent, PopoverTrigger } from "@camox/ui/popover";
11
11
  import { defaultRangeExtractor, useVirtualizer } from "@tanstack/react-virtual";
12
12
 
13
13
  //#region src/features/preview/components/IconFieldEditor.tsx
@@ -10,8 +10,8 @@ import { Input } from "@camox/ui/input";
10
10
  import { Label } from "@camox/ui/label";
11
11
  import { Switch } from "@camox/ui/switch";
12
12
  import { Check, ChevronsUpDown } from "lucide-react";
13
- import { Command as Command$1, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "@camox/ui/command";
14
13
  import { Popover, PopoverContent, PopoverTrigger } from "@camox/ui/popover";
14
+ import { Command as Command$1, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList } from "@camox/ui/command";
15
15
  import { Tabs, TabsList, TabsTrigger } from "@camox/ui/tabs";
16
16
 
17
17
  //#region src/features/preview/components/LinkFieldEditor.tsx
@@ -16,8 +16,8 @@ import { Check, ChevronsUpDown, Pencil, Plus, Trash2 } from "lucide-react";
16
16
  import { toast } from "@camox/ui/toaster";
17
17
  import { Skeleton } from "@camox/ui/skeleton";
18
18
  import { AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent, AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle } from "@camox/ui/alert-dialog";
19
- import { Command as Command$1, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator } from "@camox/ui/command";
20
19
  import { Popover, PopoverContent, PopoverTrigger } from "@camox/ui/popover";
20
+ import { Command as Command$1, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, CommandSeparator } from "@camox/ui/command";
21
21
 
22
22
  //#region src/features/preview/components/PagePicker.tsx
23
23
  const CREATE_PAGE_VALUE = "__create_page__";
@@ -1,6 +1,6 @@
1
1
  import { previewStore, selectIsCanvasShown } from "../previewStore.js";
2
- import { TOGGLE_CANVAS_SHORTCUT } from "../previewConstants.js";
3
2
  import { formatShortcut } from "../../../lib/shortcuts.js";
3
+ import { TOGGLE_CANVAS_SHORTCUT } from "../previewConstants.js";
4
4
  import { prefetchCanvas } from "./CanvasPreview.js";
5
5
  import { DeviceSelector } from "../../../components/DeviceSelector.js";
6
6
  import { c } from "react/compiler-runtime";