camox 0.11.0 → 0.13.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.
- package/dist/core/components/lexical/InlineLexicalEditor.js +24 -1
- package/dist/core/components/lexical/SidebarLexicalEditor.js +25 -1
- package/dist/core/createBlock.d.ts +5 -2
- package/dist/core/lib/contentType.d.ts +8 -5
- package/dist/core/lib/contentType.js +2 -2
- package/dist/core/lib/lexicalReact.js +8 -2
- package/dist/core/lib/lexicalState.js +13 -1
- package/dist/features/preview/CamoxPreview.js +3 -3
- package/dist/features/preview/components/EditPageModal.js +1 -1
- package/dist/features/preview/components/{TextFormatToolbar.js → FieldToolbar.js} +73 -44
- package/dist/features/preview/components/PageContentSheet.js +47 -48
- package/dist/features/preview/components/PeekedBlock.js +1 -1
- package/dist/features/preview/components/PreviewPanel.js +3 -3
- package/dist/features/preview/components/PreviewToolbar.js +1 -1
- package/dist/features/preview/previewStore.js +2 -5
- package/dist/features/provider/CamoxProvider.js +28 -14
- package/dist/features/studio/components/EnvironmentMenu.js +6 -5
- package/dist/features/studio/components/Navbar.js +1 -1
- package/dist/features/vite/definitionsSync.js +14 -3
- package/dist/features/vite/routeGeneration.js +8 -8
- package/dist/features/vite/vite.js +78 -62
- package/dist/studio-overlays.css +1 -2
- package/dist/studio.css +1 -1
- package/package.json +11 -5
- package/skills/camox-block/SKILL.md +26 -21
|
@@ -10,7 +10,7 @@ import { LexicalComposer } from "@lexical/react/LexicalComposer";
|
|
|
10
10
|
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
|
|
11
11
|
import { OnChangePlugin } from "@lexical/react/LexicalOnChangePlugin";
|
|
12
12
|
import { RichTextPlugin } from "@lexical/react/LexicalRichTextPlugin";
|
|
13
|
-
import { COMMAND_PRIORITY_LOW, KEY_ESCAPE_COMMAND } from "lexical";
|
|
13
|
+
import { COMMAND_PRIORITY_LOW, INSERT_LINE_BREAK_COMMAND, KEY_ENTER_COMMAND, KEY_ESCAPE_COMMAND } from "lexical";
|
|
14
14
|
|
|
15
15
|
//#region src/core/components/lexical/InlineLexicalEditor.tsx
|
|
16
16
|
function ExternalStateSync(t0) {
|
|
@@ -89,6 +89,28 @@ function EscapeHandler() {
|
|
|
89
89
|
React.useEffect(t0, t1);
|
|
90
90
|
return null;
|
|
91
91
|
}
|
|
92
|
+
function EnterAsLineBreakHandler() {
|
|
93
|
+
const $ = c(3);
|
|
94
|
+
const [editor] = useLexicalComposerContext();
|
|
95
|
+
let t0;
|
|
96
|
+
let t1;
|
|
97
|
+
if ($[0] !== editor) {
|
|
98
|
+
t0 = () => editor.registerCommand(KEY_ENTER_COMMAND, (event) => {
|
|
99
|
+
event?.preventDefault();
|
|
100
|
+
editor.dispatchCommand(INSERT_LINE_BREAK_COMMAND, false);
|
|
101
|
+
return true;
|
|
102
|
+
}, COMMAND_PRIORITY_LOW);
|
|
103
|
+
t1 = [editor];
|
|
104
|
+
$[0] = editor;
|
|
105
|
+
$[1] = t0;
|
|
106
|
+
$[2] = t1;
|
|
107
|
+
} else {
|
|
108
|
+
t0 = $[1];
|
|
109
|
+
t1 = $[2];
|
|
110
|
+
}
|
|
111
|
+
React.useEffect(t0, t1);
|
|
112
|
+
return null;
|
|
113
|
+
}
|
|
92
114
|
function FocusBlurHandler(t0) {
|
|
93
115
|
const $ = c(5);
|
|
94
116
|
const { onFocus, onBlur } = t0;
|
|
@@ -157,6 +179,7 @@ function InlineLexicalEditor({ initialState, externalState, onChange, onFocus, o
|
|
|
157
179
|
/* @__PURE__ */ jsx(OnChangePlugin, { onChange: handleChange }),
|
|
158
180
|
/* @__PURE__ */ jsx(ExternalStateSync, { externalState }),
|
|
159
181
|
/* @__PURE__ */ jsx(EscapeHandler, {}),
|
|
182
|
+
/* @__PURE__ */ jsx(EnterAsLineBreakHandler, {}),
|
|
160
183
|
/* @__PURE__ */ jsx(FocusBlurHandler, {
|
|
161
184
|
onFocus: handleFocus,
|
|
162
185
|
onBlur: handleBlur
|
|
@@ -8,9 +8,32 @@ import { LexicalComposer } from "@lexical/react/LexicalComposer";
|
|
|
8
8
|
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";
|
|
9
9
|
import { OnChangePlugin } from "@lexical/react/LexicalOnChangePlugin";
|
|
10
10
|
import { RichTextPlugin } from "@lexical/react/LexicalRichTextPlugin";
|
|
11
|
+
import { COMMAND_PRIORITY_LOW, INSERT_LINE_BREAK_COMMAND, KEY_ENTER_COMMAND } from "lexical";
|
|
11
12
|
import { ContentEditable } from "@lexical/react/LexicalContentEditable";
|
|
12
13
|
|
|
13
14
|
//#region src/core/components/lexical/SidebarLexicalEditor.tsx
|
|
15
|
+
function EnterAsLineBreakHandler() {
|
|
16
|
+
const $ = c(3);
|
|
17
|
+
const [editor] = useLexicalComposerContext();
|
|
18
|
+
let t0;
|
|
19
|
+
let t1;
|
|
20
|
+
if ($[0] !== editor) {
|
|
21
|
+
t0 = () => editor.registerCommand(KEY_ENTER_COMMAND, (event) => {
|
|
22
|
+
event?.preventDefault();
|
|
23
|
+
editor.dispatchCommand(INSERT_LINE_BREAK_COMMAND, false);
|
|
24
|
+
return true;
|
|
25
|
+
}, COMMAND_PRIORITY_LOW);
|
|
26
|
+
t1 = [editor];
|
|
27
|
+
$[0] = editor;
|
|
28
|
+
$[1] = t0;
|
|
29
|
+
$[2] = t1;
|
|
30
|
+
} else {
|
|
31
|
+
t0 = $[1];
|
|
32
|
+
t1 = $[2];
|
|
33
|
+
}
|
|
34
|
+
React.useEffect(t0, t1);
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
14
37
|
function ExternalStateSync(t0) {
|
|
15
38
|
const $ = c(5);
|
|
16
39
|
const { value, isSyncingRef } = t0;
|
|
@@ -82,7 +105,8 @@ function SidebarLexicalEditor({ id, value, onChange, onFocus, onBlur }) {
|
|
|
82
105
|
/* @__PURE__ */ jsx(ExternalStateSync, {
|
|
83
106
|
value,
|
|
84
107
|
isSyncingRef
|
|
85
|
-
})
|
|
108
|
+
}),
|
|
109
|
+
/* @__PURE__ */ jsx(EnterAsLineBreakHandler, {})
|
|
86
110
|
]
|
|
87
111
|
});
|
|
88
112
|
}
|
|
@@ -26,8 +26,11 @@ interface CreateBlockOptions<TSchemaShape extends Record<string, TSchema> = Reco
|
|
|
26
26
|
* content: {
|
|
27
27
|
* title: Type.String({ default: 'Hello' }),
|
|
28
28
|
* items: Type.RepeatableItem({
|
|
29
|
-
* name: Type.String({ default: 'Item' })
|
|
30
|
-
*
|
|
29
|
+
* content: { name: Type.String({ default: 'Item' }) },
|
|
30
|
+
* minItems: 1,
|
|
31
|
+
* maxItems: 10,
|
|
32
|
+
* toMarkdown: (c) => [c.name],
|
|
33
|
+
* })
|
|
31
34
|
* }
|
|
32
35
|
*/
|
|
33
36
|
content: TSchemaShape;
|
|
@@ -93,15 +93,18 @@ declare const Type$1: {
|
|
|
93
93
|
*
|
|
94
94
|
* @example
|
|
95
95
|
* Type.RepeatableItem({
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
* },
|
|
96
|
+
* content: {
|
|
97
|
+
* title: Type.String({ default: 'Item' }),
|
|
98
|
+
* description: Type.String({ default: 'Description' }),
|
|
99
|
+
* },
|
|
99
100
|
* minItems: 1,
|
|
100
101
|
* maxItems: 10,
|
|
101
|
-
* title: 'Items'
|
|
102
|
+
* title: 'Items',
|
|
103
|
+
* toMarkdown: (c) => [`### ${c.title}`, c.description],
|
|
102
104
|
* })
|
|
103
105
|
*/
|
|
104
|
-
RepeatableItem: <T extends Record<string, TSchema>>(
|
|
106
|
+
RepeatableItem: <T extends Record<string, TSchema>>(options: {
|
|
107
|
+
content: T;
|
|
105
108
|
minItems: number;
|
|
106
109
|
maxItems: number;
|
|
107
110
|
title?: string;
|
|
@@ -96,9 +96,9 @@ const Type$1 = {
|
|
|
96
96
|
fieldType: "String"
|
|
97
97
|
});
|
|
98
98
|
},
|
|
99
|
-
RepeatableItem: (
|
|
99
|
+
RepeatableItem: (options) => {
|
|
100
100
|
if (options.minItems < 1) throw new Error("RepeatableItem requires minItems to be at least 1");
|
|
101
|
-
const objectSchema = Type.Object(
|
|
101
|
+
const objectSchema = Type.Object(options.content);
|
|
102
102
|
const defaultItem = {};
|
|
103
103
|
for (const [key, prop] of Object.entries(objectSchema.properties)) if ("default" in prop) defaultItem[key] = prop.default;
|
|
104
104
|
const defaultArray = Array(options.minItems).fill(null).map(() => ({ ...defaultItem }));
|
|
@@ -14,8 +14,14 @@ function markdownToReactNodes(value) {
|
|
|
14
14
|
let lastIndex = 0;
|
|
15
15
|
let match;
|
|
16
16
|
let key = 0;
|
|
17
|
+
const pushWithLineBreaks = (text) => {
|
|
18
|
+
text.split("\n").forEach((line, i) => {
|
|
19
|
+
if (i > 0) parts.push(/* @__PURE__ */ jsx("br", {}, key++));
|
|
20
|
+
if (line) parts.push(line);
|
|
21
|
+
});
|
|
22
|
+
};
|
|
17
23
|
while ((match = regex.exec(value)) !== null) {
|
|
18
|
-
if (match.index > lastIndex)
|
|
24
|
+
if (match.index > lastIndex) pushWithLineBreaks(value.slice(lastIndex, match.index));
|
|
19
25
|
const stars = match[1].length;
|
|
20
26
|
const content = match[2];
|
|
21
27
|
if (stars === 3) parts.push(/* @__PURE__ */ jsx("strong", { children: /* @__PURE__ */ jsx("em", { children: content }) }, key++));
|
|
@@ -23,7 +29,7 @@ function markdownToReactNodes(value) {
|
|
|
23
29
|
else parts.push(/* @__PURE__ */ jsx("em", { children: content }, key++));
|
|
24
30
|
lastIndex = match.index + match[0].length;
|
|
25
31
|
}
|
|
26
|
-
if (lastIndex < value.length)
|
|
32
|
+
if (lastIndex < value.length) pushWithLineBreaks(value.slice(lastIndex));
|
|
27
33
|
if (parts.length === 0) return value;
|
|
28
34
|
return /* @__PURE__ */ jsx(Fragment, { children: parts });
|
|
29
35
|
}
|
|
@@ -38,7 +38,7 @@ function extractMarkdown(node) {
|
|
|
38
38
|
function markdownToLexicalState(markdown) {
|
|
39
39
|
return { root: {
|
|
40
40
|
children: markdown.split(/\n\n+/).map((para) => ({
|
|
41
|
-
children:
|
|
41
|
+
children: parseParagraphWithLineBreaks(para),
|
|
42
42
|
direction: "ltr",
|
|
43
43
|
format: "",
|
|
44
44
|
indent: 0,
|
|
@@ -54,6 +54,18 @@ function markdownToLexicalState(markdown) {
|
|
|
54
54
|
version: 1
|
|
55
55
|
} };
|
|
56
56
|
}
|
|
57
|
+
function parseParagraphWithLineBreaks(para) {
|
|
58
|
+
const lines = para.split("\n");
|
|
59
|
+
const nodes = [];
|
|
60
|
+
lines.forEach((line, index) => {
|
|
61
|
+
if (index > 0) nodes.push({
|
|
62
|
+
type: "linebreak",
|
|
63
|
+
version: 1
|
|
64
|
+
});
|
|
65
|
+
nodes.push(...parseInlineMarkdown(line));
|
|
66
|
+
});
|
|
67
|
+
return nodes;
|
|
68
|
+
}
|
|
57
69
|
function parseInlineMarkdown(text) {
|
|
58
70
|
const segments = [];
|
|
59
71
|
const regex = /(\*{1,3})((?:(?!\1).)+)\1/g;
|
|
@@ -306,7 +306,7 @@ const CamoxPreview = (t0) => {
|
|
|
306
306
|
const actions = [
|
|
307
307
|
{
|
|
308
308
|
id: "enter-presentation-mode",
|
|
309
|
-
label: "
|
|
309
|
+
label: "Hide Camox Studio",
|
|
310
310
|
groupLabel: "Preview",
|
|
311
311
|
checkIfAvailable: () => isAuthenticated && !isPresentationMode,
|
|
312
312
|
execute: _temp4,
|
|
@@ -317,12 +317,12 @@ const CamoxPreview = (t0) => {
|
|
|
317
317
|
},
|
|
318
318
|
{
|
|
319
319
|
id: "exit-presentation-mode",
|
|
320
|
-
label: "
|
|
320
|
+
label: "",
|
|
321
321
|
groupLabel: "Preview",
|
|
322
322
|
checkIfAvailable: () => isAuthenticated && isPresentationMode,
|
|
323
323
|
execute: _temp5,
|
|
324
324
|
shortcut: {
|
|
325
|
-
key: "
|
|
325
|
+
key: "Enter",
|
|
326
326
|
withMeta: true
|
|
327
327
|
}
|
|
328
328
|
},
|
|
@@ -305,7 +305,7 @@ const SearchEnginePreview = (t0) => {
|
|
|
305
305
|
children: [t1, /* @__PURE__ */ jsxs(Tooltip, { children: [/* @__PURE__ */ jsx(TooltipTrigger, {
|
|
306
306
|
delay: 50,
|
|
307
307
|
render: /* @__PURE__ */ jsx(Info, { className: "text-muted-foreground size-3.5" })
|
|
308
|
-
}), /* @__PURE__ */ jsx(TooltipContent, { children: "Titles are cropped after 60 characters and descriptions after 155, like Google
|
|
308
|
+
}), /* @__PURE__ */ jsx(TooltipContent, { children: "Titles are cropped after 60 characters and descriptions after 155, like on Google Search results." })] })]
|
|
309
309
|
});
|
|
310
310
|
$[1] = t2;
|
|
311
311
|
} else t2 = $[1];
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { previewStore } from "../previewStore.js";
|
|
2
2
|
import { useIsPreviewSheetOpen } from "./PreviewSideSheet.js";
|
|
3
|
-
import { cn } from "../../../lib/utils.js";
|
|
3
|
+
import { cn, formatShortcut } from "../../../lib/utils.js";
|
|
4
4
|
import { isOverlayMessage } from "../overlayMessages.js";
|
|
5
5
|
import { FORMAT_FLAGS } from "../../../core/lib/modifierFormats.js";
|
|
6
6
|
import { c } from "react/compiler-runtime";
|
|
@@ -8,13 +8,14 @@ import { Kbd } from "@camox/ui/kbd";
|
|
|
8
8
|
import { useSelector } from "@xstate/store/react";
|
|
9
9
|
import * as React from "react";
|
|
10
10
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
11
|
+
import { Button } from "@camox/ui/button";
|
|
11
12
|
import * as Tooltip$1 from "@camox/ui/tooltip";
|
|
12
13
|
import { Bold, Italic } from "lucide-react";
|
|
13
14
|
import { ButtonGroup } from "@camox/ui/button-group";
|
|
14
15
|
import { FloatingToolbar } from "@camox/ui/floating-toolbar";
|
|
15
16
|
import { Toggle } from "@camox/ui/toggle";
|
|
16
17
|
|
|
17
|
-
//#region src/features/preview/components/
|
|
18
|
+
//#region src/features/preview/components/FieldToolbar.tsx
|
|
18
19
|
const FORMAT_BUTTONS = [{
|
|
19
20
|
key: "bold",
|
|
20
21
|
flag: FORMAT_FLAGS.bold,
|
|
@@ -28,9 +29,10 @@ const FORMAT_BUTTONS = [{
|
|
|
28
29
|
label: "Italic",
|
|
29
30
|
shortcut: "⌘ I"
|
|
30
31
|
}];
|
|
31
|
-
const
|
|
32
|
-
const $ = c(
|
|
32
|
+
const FieldToolbar = () => {
|
|
33
|
+
const $ = c(19);
|
|
33
34
|
const iframeElement = useSelector(previewStore, _temp);
|
|
35
|
+
const selection = useSelector(previewStore, _temp2);
|
|
34
36
|
const isAnySideSheetOpen = useIsPreviewSheetOpen();
|
|
35
37
|
const [hasSelection, setHasSelection] = React.useState(false);
|
|
36
38
|
const [activeFormats, setActiveFormats] = React.useState(0);
|
|
@@ -67,25 +69,53 @@ const TextFormatToolbar = () => {
|
|
|
67
69
|
$[3] = t2;
|
|
68
70
|
} else t2 = $[3];
|
|
69
71
|
const sendFormat = t2;
|
|
70
|
-
const
|
|
71
|
-
let
|
|
72
|
-
if ($[4] !==
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
72
|
+
const isVisible = (selection?.type === "block-field" || selection?.type === "item-field") && !isAnySideSheetOpen;
|
|
73
|
+
let t3;
|
|
74
|
+
if ($[4] !== selection) {
|
|
75
|
+
t3 = () => {
|
|
76
|
+
if (!selection) return;
|
|
77
|
+
previewStore.send({
|
|
78
|
+
type: "openBlockContentSheet",
|
|
79
|
+
blockId: selection.blockId
|
|
80
|
+
});
|
|
81
|
+
};
|
|
82
|
+
$[4] = selection;
|
|
83
|
+
$[5] = t3;
|
|
84
|
+
} else t3 = $[5];
|
|
85
|
+
const handleEditInForm = t3;
|
|
86
|
+
const t4 = isVisible ? "opacity-100 translate-y-0" : "opacity-0 pointer-events-none translate-y-2";
|
|
77
87
|
let t5;
|
|
78
|
-
if ($[6]
|
|
79
|
-
t5 =
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
$[6] = t5;
|
|
84
|
-
} else t5 = $[6];
|
|
88
|
+
if ($[6] !== t4) {
|
|
89
|
+
t5 = cn("bottom-17 gap-2", t4);
|
|
90
|
+
$[6] = t4;
|
|
91
|
+
$[7] = t5;
|
|
92
|
+
} else t5 = $[7];
|
|
85
93
|
let t6;
|
|
86
|
-
if ($[
|
|
87
|
-
t6 =
|
|
88
|
-
|
|
94
|
+
if ($[8] === Symbol.for("react.memo_cache_sentinel")) {
|
|
95
|
+
t6 = /* @__PURE__ */ jsx(Kbd, {
|
|
96
|
+
className: "ml-2",
|
|
97
|
+
children: formatShortcut({
|
|
98
|
+
key: "j",
|
|
99
|
+
withAlt: true
|
|
100
|
+
})
|
|
101
|
+
});
|
|
102
|
+
$[8] = t6;
|
|
103
|
+
} else t6 = $[8];
|
|
104
|
+
let t7;
|
|
105
|
+
if ($[9] !== handleEditInForm) {
|
|
106
|
+
t7 = /* @__PURE__ */ jsxs(Button, {
|
|
107
|
+
variant: "ghost",
|
|
108
|
+
size: "sm",
|
|
109
|
+
onClick: handleEditInForm,
|
|
110
|
+
children: ["Edit in form ", t6]
|
|
111
|
+
});
|
|
112
|
+
$[9] = handleEditInForm;
|
|
113
|
+
$[10] = t7;
|
|
114
|
+
} else t7 = $[10];
|
|
115
|
+
let t8;
|
|
116
|
+
if ($[11] !== activeFormats || $[12] !== hasSelection || $[13] !== sendFormat) {
|
|
117
|
+
t8 = hasSelection && /* @__PURE__ */ jsx(ButtonGroup, { children: FORMAT_BUTTONS.map((t9) => {
|
|
118
|
+
const { key, flag, icon: Icon, label, shortcut } = t9;
|
|
89
119
|
const isActive = !!(activeFormats & flag);
|
|
90
120
|
return /* @__PURE__ */ jsxs(Tooltip$1.Tooltip, { children: [/* @__PURE__ */ jsx(Tooltip$1.TooltipTrigger, {
|
|
91
121
|
render: /* @__PURE__ */ jsx(Toggle, {
|
|
@@ -100,36 +130,35 @@ const TextFormatToolbar = () => {
|
|
|
100
130
|
" ",
|
|
101
131
|
/* @__PURE__ */ jsx(Kbd, { children: shortcut })
|
|
102
132
|
] })] }, key);
|
|
103
|
-
});
|
|
104
|
-
$[
|
|
105
|
-
$[
|
|
106
|
-
$[
|
|
107
|
-
} else t6 = $[9];
|
|
108
|
-
let t7;
|
|
109
|
-
if ($[10] !== t6) {
|
|
110
|
-
t7 = /* @__PURE__ */ jsx(ButtonGroup, { children: t6 });
|
|
111
|
-
$[10] = t6;
|
|
112
|
-
$[11] = t7;
|
|
113
|
-
} else t7 = $[11];
|
|
114
|
-
let t8;
|
|
115
|
-
if ($[12] !== t4 || $[13] !== t7) {
|
|
116
|
-
t8 = /* @__PURE__ */ jsxs(FloatingToolbar, {
|
|
117
|
-
onMouseDown: _temp2,
|
|
118
|
-
className: t4,
|
|
119
|
-
children: [t5, t7]
|
|
120
|
-
});
|
|
121
|
-
$[12] = t4;
|
|
122
|
-
$[13] = t7;
|
|
133
|
+
}) });
|
|
134
|
+
$[11] = activeFormats;
|
|
135
|
+
$[12] = hasSelection;
|
|
136
|
+
$[13] = sendFormat;
|
|
123
137
|
$[14] = t8;
|
|
124
138
|
} else t8 = $[14];
|
|
125
|
-
|
|
139
|
+
let t9;
|
|
140
|
+
if ($[15] !== t5 || $[16] !== t7 || $[17] !== t8) {
|
|
141
|
+
t9 = /* @__PURE__ */ jsxs(FloatingToolbar, {
|
|
142
|
+
onMouseDown: _temp3,
|
|
143
|
+
className: t5,
|
|
144
|
+
children: [t7, t8]
|
|
145
|
+
});
|
|
146
|
+
$[15] = t5;
|
|
147
|
+
$[16] = t7;
|
|
148
|
+
$[17] = t8;
|
|
149
|
+
$[18] = t9;
|
|
150
|
+
} else t9 = $[18];
|
|
151
|
+
return t9;
|
|
126
152
|
};
|
|
127
153
|
function _temp(state) {
|
|
128
154
|
return state.context.iframeElement;
|
|
129
155
|
}
|
|
130
|
-
function _temp2(
|
|
156
|
+
function _temp2(state_0) {
|
|
157
|
+
return state_0.context.selection;
|
|
158
|
+
}
|
|
159
|
+
function _temp3(e) {
|
|
131
160
|
return e.preventDefault();
|
|
132
161
|
}
|
|
133
162
|
|
|
134
163
|
//#endregion
|
|
135
|
-
export {
|
|
164
|
+
export { FieldToolbar };
|
|
@@ -196,16 +196,15 @@ const PageContentSheet = () => {
|
|
|
196
196
|
}, [autoFocusFieldName, fieldIdPrefix]);
|
|
197
197
|
React.useEffect(() => {
|
|
198
198
|
const action = {
|
|
199
|
-
id: "
|
|
200
|
-
label: isOpen ? "Close
|
|
199
|
+
id: "toggle-content-sheet",
|
|
200
|
+
label: isOpen ? "Close form" : "Open in form",
|
|
201
201
|
groupLabel: "Preview",
|
|
202
202
|
shortcut: {
|
|
203
203
|
key: "j",
|
|
204
|
-
|
|
204
|
+
withAlt: true
|
|
205
205
|
},
|
|
206
|
-
checkIfAvailable: () =>
|
|
206
|
+
checkIfAvailable: () => blockId != null,
|
|
207
207
|
execute: () => {
|
|
208
|
-
if (!blockId) return;
|
|
209
208
|
previewStore.send({ type: "toggleContentSheet" });
|
|
210
209
|
}
|
|
211
210
|
};
|
|
@@ -325,47 +324,8 @@ const PageContentSheet = () => {
|
|
|
325
324
|
}), /* @__PURE__ */ jsxs("div", {
|
|
326
325
|
className: "flex-1 overflow-auto",
|
|
327
326
|
children: [
|
|
328
|
-
isViewingAsset && assetFieldName && isMultipleAsset && /* @__PURE__ */ jsx(MultipleAssetFieldEditor, {
|
|
329
|
-
fieldName: assetFieldName,
|
|
330
|
-
assetType,
|
|
331
|
-
currentData,
|
|
332
|
-
onFieldChange: activeFieldChangeHandler
|
|
333
|
-
}),
|
|
334
|
-
isViewingAsset && assetFieldName && !isMultipleAsset && /* @__PURE__ */ jsx(SingleAssetFieldEditor, {
|
|
335
|
-
fieldName: assetFieldName,
|
|
336
|
-
assetType,
|
|
337
|
-
currentData,
|
|
338
|
-
onFieldChange: activeFieldChangeHandler
|
|
339
|
-
}),
|
|
340
|
-
!isViewingAsset && isViewingLink && linkFieldName && /* @__PURE__ */ jsx("div", {
|
|
341
|
-
className: "px-4 py-4",
|
|
342
|
-
children: /* @__PURE__ */ jsx(LinkFieldEditor, {
|
|
343
|
-
fieldName: linkFieldName,
|
|
344
|
-
linkValue: currentData[linkFieldName] ?? {
|
|
345
|
-
type: "external",
|
|
346
|
-
text: "",
|
|
347
|
-
href: "",
|
|
348
|
-
newTab: false
|
|
349
|
-
},
|
|
350
|
-
onSave: (fieldName_1, value_3) => {
|
|
351
|
-
activeFieldChangeHandler(fieldName_1, value_3);
|
|
352
|
-
}
|
|
353
|
-
})
|
|
354
|
-
}),
|
|
355
|
-
!isViewingAsset && !isViewingLink && /* @__PURE__ */ jsx(ItemFieldsEditor, {
|
|
356
|
-
schema: currentSchema,
|
|
357
|
-
data: currentData,
|
|
358
|
-
blockId: block.id,
|
|
359
|
-
itemId: currentItemId ?? void 0,
|
|
360
|
-
onFieldChange: activeFieldChangeHandler,
|
|
361
|
-
postToIframe,
|
|
362
|
-
filesMap,
|
|
363
|
-
itemsMap,
|
|
364
|
-
fieldIdPrefix,
|
|
365
|
-
autoFocusFieldName
|
|
366
|
-
}, currentItemId ?? `block-${block.id}`),
|
|
367
327
|
currentItemId == null && !fieldHasOwnView && settingsFields.length > 0 && /* @__PURE__ */ jsxs("div", {
|
|
368
|
-
className: "border-border space-y-4 border-
|
|
328
|
+
className: "border-border space-y-4 border-b px-4 py-4",
|
|
369
329
|
children: [/* @__PURE__ */ jsx(Label, {
|
|
370
330
|
className: "text-muted-foreground",
|
|
371
331
|
children: "Settings"
|
|
@@ -373,14 +333,14 @@ const PageContentSheet = () => {
|
|
|
373
333
|
const label = field.label ?? formatFieldName(field.name);
|
|
374
334
|
const settingsValues = block.settings ?? {};
|
|
375
335
|
if (field.fieldType === "Enum") {
|
|
376
|
-
const
|
|
336
|
+
const value_3 = settingsValues[field.name] ?? (blockDef._internal.settingsSchema?.properties?.[field.name])?.default ?? "";
|
|
377
337
|
return /* @__PURE__ */ jsxs("div", {
|
|
378
338
|
className: "space-y-2",
|
|
379
339
|
children: [/* @__PURE__ */ jsx(Label, {
|
|
380
340
|
htmlFor: `setting-${field.name}`,
|
|
381
341
|
children: label
|
|
382
342
|
}), /* @__PURE__ */ jsxs(Select, {
|
|
383
|
-
value:
|
|
343
|
+
value: value_3,
|
|
384
344
|
onValueChange: (newValue) => {
|
|
385
345
|
updateSettings.mutate({
|
|
386
346
|
id: block.id,
|
|
@@ -418,7 +378,46 @@ const PageContentSheet = () => {
|
|
|
418
378
|
}
|
|
419
379
|
return null;
|
|
420
380
|
})]
|
|
421
|
-
})
|
|
381
|
+
}),
|
|
382
|
+
isViewingAsset && assetFieldName && isMultipleAsset && /* @__PURE__ */ jsx(MultipleAssetFieldEditor, {
|
|
383
|
+
fieldName: assetFieldName,
|
|
384
|
+
assetType,
|
|
385
|
+
currentData,
|
|
386
|
+
onFieldChange: activeFieldChangeHandler
|
|
387
|
+
}),
|
|
388
|
+
isViewingAsset && assetFieldName && !isMultipleAsset && /* @__PURE__ */ jsx(SingleAssetFieldEditor, {
|
|
389
|
+
fieldName: assetFieldName,
|
|
390
|
+
assetType,
|
|
391
|
+
currentData,
|
|
392
|
+
onFieldChange: activeFieldChangeHandler
|
|
393
|
+
}),
|
|
394
|
+
!isViewingAsset && isViewingLink && linkFieldName && /* @__PURE__ */ jsx("div", {
|
|
395
|
+
className: "px-4 py-4",
|
|
396
|
+
children: /* @__PURE__ */ jsx(LinkFieldEditor, {
|
|
397
|
+
fieldName: linkFieldName,
|
|
398
|
+
linkValue: currentData[linkFieldName] ?? {
|
|
399
|
+
type: "external",
|
|
400
|
+
text: "",
|
|
401
|
+
href: "",
|
|
402
|
+
newTab: false
|
|
403
|
+
},
|
|
404
|
+
onSave: (fieldName_1, value_4) => {
|
|
405
|
+
activeFieldChangeHandler(fieldName_1, value_4);
|
|
406
|
+
}
|
|
407
|
+
})
|
|
408
|
+
}),
|
|
409
|
+
!isViewingAsset && !isViewingLink && /* @__PURE__ */ jsx(ItemFieldsEditor, {
|
|
410
|
+
schema: currentSchema,
|
|
411
|
+
data: currentData,
|
|
412
|
+
blockId: block.id,
|
|
413
|
+
itemId: currentItemId ?? void 0,
|
|
414
|
+
onFieldChange: activeFieldChangeHandler,
|
|
415
|
+
postToIframe,
|
|
416
|
+
filesMap,
|
|
417
|
+
itemsMap,
|
|
418
|
+
fieldIdPrefix,
|
|
419
|
+
autoFocusFieldName
|
|
420
|
+
}, currentItemId ?? `block-${block.id}`)
|
|
422
421
|
]
|
|
423
422
|
})]
|
|
424
423
|
});
|
|
@@ -88,7 +88,7 @@ const PeekedBlock = (t0) => {
|
|
|
88
88
|
if (e.propertyName !== "grid-template-rows" || e.target !== e.currentTarget) return;
|
|
89
89
|
if (isExpanded) {
|
|
90
90
|
peekedBlockRef.current?.scrollIntoView({
|
|
91
|
-
behavior: "
|
|
91
|
+
behavior: "smooth",
|
|
92
92
|
block: "start"
|
|
93
93
|
});
|
|
94
94
|
return;
|
|
@@ -5,10 +5,10 @@ import { checkIfInputFocused } from "../../../lib/utils.js";
|
|
|
5
5
|
import { Frame, useFrame } from "./Frame.js";
|
|
6
6
|
import { useBlockActionsShortcuts } from "./BlockActionsPopover.js";
|
|
7
7
|
import { FieldOverlayStyles } from "./FieldOverlayStyles.js";
|
|
8
|
+
import { FieldToolbar } from "./FieldToolbar.js";
|
|
8
9
|
import { Overlays } from "./Overlays.js";
|
|
9
10
|
import { OverlayTracker } from "./OverlayTracker.js";
|
|
10
11
|
import { PreviewToolbar } from "./PreviewToolbar.js";
|
|
11
|
-
import { TextFormatToolbar } from "./TextFormatToolbar.js";
|
|
12
12
|
import { c } from "react/compiler-runtime";
|
|
13
13
|
import { useSelector } from "@xstate/store/react";
|
|
14
14
|
import * as React from "react";
|
|
@@ -245,7 +245,7 @@ const PreviewPanel = (t0) => {
|
|
|
245
245
|
children
|
|
246
246
|
}), /* @__PURE__ */ jsx(Overlays, { iframeElement })]
|
|
247
247
|
}),
|
|
248
|
-
/* @__PURE__ */ jsx(
|
|
248
|
+
/* @__PURE__ */ jsx(FieldToolbar, {}),
|
|
249
249
|
/* @__PURE__ */ jsx(PreviewToolbar, {})
|
|
250
250
|
]
|
|
251
251
|
}) : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
@@ -255,7 +255,7 @@ const PreviewPanel = (t0) => {
|
|
|
255
255
|
children
|
|
256
256
|
}),
|
|
257
257
|
/* @__PURE__ */ jsx(Overlays, { iframeElement }),
|
|
258
|
-
/* @__PURE__ */ jsx(
|
|
258
|
+
/* @__PURE__ */ jsx(FieldToolbar, {}),
|
|
259
259
|
/* @__PURE__ */ jsx(PreviewToolbar, {})
|
|
260
260
|
] });
|
|
261
261
|
$[8] = children;
|
|
@@ -197,7 +197,7 @@ const PreviewToolbar = () => {
|
|
|
197
197
|
} else t27 = $[44];
|
|
198
198
|
let t28;
|
|
199
199
|
if ($[45] !== t27) {
|
|
200
|
-
t28 = /* @__PURE__ */ jsxs(Tooltip$1.TooltipContent, { children: ["Hide
|
|
200
|
+
t28 = /* @__PURE__ */ jsxs(Tooltip$1.TooltipContent, { children: ["Hide Camox Studio ", t27] });
|
|
201
201
|
$[45] = t27;
|
|
202
202
|
$[46] = t28;
|
|
203
203
|
} else t28 = $[46];
|
|
@@ -43,18 +43,15 @@ const previewStore = createStore({
|
|
|
43
43
|
enterPresentationMode: (context, _, enqueue) => {
|
|
44
44
|
if (context.isPresentationMode) return context;
|
|
45
45
|
enqueue.effect(() => {
|
|
46
|
-
toast("
|
|
46
|
+
toast("Press ⌘ + Enter to restore Camox Studio", { duration: 2500 });
|
|
47
47
|
});
|
|
48
48
|
return {
|
|
49
49
|
...context,
|
|
50
50
|
isPresentationMode: true
|
|
51
51
|
};
|
|
52
52
|
},
|
|
53
|
-
exitPresentationMode: (context
|
|
53
|
+
exitPresentationMode: (context) => {
|
|
54
54
|
if (!context.isPresentationMode) return context;
|
|
55
|
-
enqueue.effect(() => {
|
|
56
|
-
toast("Leaving presentation mode");
|
|
57
|
-
});
|
|
58
55
|
return {
|
|
59
56
|
...context,
|
|
60
57
|
isPresentationMode: false
|
|
@@ -62,7 +62,7 @@ const AuthenticatedCamoxProvider = (t0) => {
|
|
|
62
62
|
return t4;
|
|
63
63
|
};
|
|
64
64
|
const UnauthenticatedCamoxProvider = (t0) => {
|
|
65
|
-
const $ = c(
|
|
65
|
+
const $ = c(16);
|
|
66
66
|
const { children } = t0;
|
|
67
67
|
const signInRedirect = useSignInRedirect();
|
|
68
68
|
const { authenticationUrl } = useAuthContext();
|
|
@@ -70,7 +70,7 @@ const UnauthenticatedCamoxProvider = (t0) => {
|
|
|
70
70
|
if ($[0] !== signInRedirect) {
|
|
71
71
|
t1 = () => {
|
|
72
72
|
const handleKeyDown = (event) => {
|
|
73
|
-
if ((event.metaKey || event.ctrlKey) && event.key === "
|
|
73
|
+
if ((event.metaKey || event.ctrlKey) && event.key === "Enter") {
|
|
74
74
|
event.preventDefault();
|
|
75
75
|
signInRedirect();
|
|
76
76
|
}
|
|
@@ -112,25 +112,39 @@ const UnauthenticatedCamoxProvider = (t0) => {
|
|
|
112
112
|
t4 = $[7];
|
|
113
113
|
}
|
|
114
114
|
React.useEffect(t3, t4);
|
|
115
|
+
const { theme } = useTheme();
|
|
115
116
|
let t5;
|
|
116
117
|
if ($[8] === Symbol.for("react.memo_cache_sentinel")) {
|
|
117
|
-
t5 =
|
|
118
|
-
theme: "light",
|
|
119
|
-
position: "bottom-right",
|
|
120
|
-
offset: { bottom: "1rem" }
|
|
121
|
-
});
|
|
118
|
+
t5 = { bottom: "1rem" };
|
|
122
119
|
$[8] = t5;
|
|
123
120
|
} else t5 = $[8];
|
|
124
121
|
let t6;
|
|
125
|
-
if ($[9] !==
|
|
126
|
-
t6 = /* @__PURE__ */
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
122
|
+
if ($[9] !== theme) {
|
|
123
|
+
t6 = /* @__PURE__ */ jsx(Toaster, {
|
|
124
|
+
theme,
|
|
125
|
+
position: "bottom-right",
|
|
126
|
+
offset: t5
|
|
127
|
+
});
|
|
128
|
+
$[9] = theme;
|
|
131
129
|
$[10] = t6;
|
|
132
130
|
} else t6 = $[10];
|
|
133
|
-
|
|
131
|
+
let t7;
|
|
132
|
+
if ($[11] !== children) {
|
|
133
|
+
t7 = /* @__PURE__ */ jsx("div", {
|
|
134
|
+
className: "bg-background min-h-screen",
|
|
135
|
+
children
|
|
136
|
+
});
|
|
137
|
+
$[11] = children;
|
|
138
|
+
$[12] = t7;
|
|
139
|
+
} else t7 = $[12];
|
|
140
|
+
let t8;
|
|
141
|
+
if ($[13] !== t6 || $[14] !== t7) {
|
|
142
|
+
t8 = /* @__PURE__ */ jsxs(Fragment, { children: [t6, t7] });
|
|
143
|
+
$[13] = t6;
|
|
144
|
+
$[14] = t7;
|
|
145
|
+
$[15] = t8;
|
|
146
|
+
} else t8 = $[15];
|
|
147
|
+
return t8;
|
|
134
148
|
};
|
|
135
149
|
function CamoxProvider({ children, camoxApp, authenticationUrl, apiUrl, projectSlug, environmentName }) {
|
|
136
150
|
const authClient = React.useMemo(() => createCamoxAuthClient(apiUrl), [apiUrl]);
|