camox 0.42.0 → 0.44.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/bin/camox.mjs +9 -1
- package/dist/core/components/lexical/{GradientNode.js → HighlightNode.js} +34 -34
- package/dist/core/components/lexical/InlineLexicalEditor.js +14 -14
- package/dist/core/components/lexical/InlineStylesPlugin.js +25 -9
- package/dist/core/components/lexical/SelectionBroadcaster.js +7 -7
- package/dist/core/components/lexical/SidebarLexicalEditor.js +24 -24
- package/dist/core/components/lexical/TextLinkPopover.js +191 -208
- package/dist/core/components/lexical/editorConfig.js +2 -2
- package/dist/core/createApp.d.ts +31 -4
- package/dist/core/createApp.js +2 -1
- package/dist/core/createBlock.js +24 -10
- package/dist/core/createLayout.d.ts +16 -3
- package/dist/core/createLayout.js +15 -15
- package/dist/core/derivedRoutes.js +1 -1
- package/dist/core/dom.d.ts +17 -0
- package/dist/core/dom.js +22 -0
- package/dist/core/editing/createEditableBlock.d.ts +135 -1
- package/dist/core/editing/createEditableBlock.js +209 -74
- package/dist/core/lib/contentType.d.ts +5 -0
- package/dist/core/lib/contentType.js +11 -0
- package/dist/core/lib/fieldTypes.js +1 -0
- package/dist/core/lib/iconTypes.d.ts +13 -0
- package/dist/core/lib/icons.d.ts +6 -0
- package/dist/core/lib/icons.js +130 -0
- package/dist/core/lib/lexicalReact.js +4 -4
- package/dist/core/lib/lexicalState.js +8 -8
- package/dist/core/lib/modifierFormats.js +2 -2
- package/dist/core/lib/textLinks.js +5 -2
- package/dist/core/lib/textStyles.d.ts +3 -3
- package/dist/core/lib/textStyles.js +9 -14
- package/dist/core/pageDestinations.js +37 -0
- package/dist/features/content/components/AssetCard.js +104 -68
- package/dist/features/og/imageResponse.node.js +11 -9
- package/dist/features/preview/CamoxPreview.js +148 -146
- package/dist/features/preview/commentsEnabled.js +2 -2
- package/dist/features/preview/components/AddBlockSidebar.js +1 -1
- package/dist/features/preview/components/AssetLightbox.js +17 -6
- package/dist/features/preview/components/AttachedComments.js +224 -87
- package/dist/features/preview/components/BlockActionsPopover.js +1 -1
- package/dist/features/preview/components/CommentTargetQuote.js +22 -21
- package/dist/features/preview/components/CreatePageModal.js +4 -4
- package/dist/features/preview/components/DerivedLayoutDialog.js +36 -21
- package/dist/features/preview/components/DerivedLayoutSidebar.js +45 -26
- package/dist/features/preview/components/DerivedPageInfoSidebar.js +38 -26
- package/dist/features/preview/components/FieldOverlayStyles.js +29 -9
- package/dist/features/preview/components/FieldToolbar.js +12 -12
- package/dist/features/preview/components/IconFieldEditor.js +231 -0
- package/dist/features/preview/components/ItemFieldsEditor.js +21 -14
- package/dist/features/preview/components/LinkFieldEditor.js +212 -209
- package/dist/features/preview/components/OverlayTracker.js +1 -1
- package/dist/features/preview/components/PageEditorSidebar.js +1 -1
- package/dist/features/preview/components/PageInfoSidebar.js +28 -28
- package/dist/features/preview/components/PagePicker.js +46 -46
- package/dist/features/preview/components/PageTree.js +1 -1
- package/dist/features/preview/components/PreviewPanel.js +1 -1
- package/dist/features/preview/components/PreviewToolbar.js +224 -225
- package/dist/features/preview/components/PublicationRow.js +8 -4
- package/dist/features/preview/components/SendFeedbackDialog.js +83 -0
- package/dist/features/preview/components/useRepeatableItemActions.js +1 -1
- package/dist/features/preview/overlayHighlights.js +54 -0
- package/dist/features/preview/previewCommentsStore.js +54 -34
- package/dist/features/preview/previewSelection.js +28 -23
- package/dist/features/preview/publication.js +10 -0
- package/dist/features/preview/usePageComments.js +39 -0
- package/dist/features/provider/CoreCamoxProvider.js +38 -6
- package/dist/features/provider/LocalhostPreviewProvider.js +81 -45
- package/dist/features/provider/components/CommandPalette.js +35 -84
- package/dist/features/runtime/pageApp.js +32 -28
- package/dist/features/runtime/pageServer.js +4 -1
- package/dist/features/runtime/runtime.d.ts +2 -0
- package/dist/features/runtime/runtime.js +45 -21
- package/dist/features/studio/components/EnvironmentMenu.js +76 -63
- package/dist/features/studio/components/Navbar.js +53 -80
- package/dist/features/vite/auth.js +1 -50
- package/dist/features/vite/iconGeneration.js +16 -0
- package/dist/features/vite/layoutGeneration.js +7 -3
- package/dist/features/vite/vite.d.ts +4 -2
- package/dist/features/vite/vite.js +24 -3
- package/dist/hooks/use-page-destinations.js +53 -0
- package/dist/lib/auth.js +40 -20
- package/dist/lib/preview-handoff.js +13 -0
- package/dist/lib/queries.js +12 -1
- package/dist/lib/server-auth-cookie.js +21 -0
- package/dist/lib/use-project-room.js +5 -2
- package/dist/studio-overlays.css +19 -15
- package/dist/studio.css +1 -1
- package/package.json +9 -4
- package/skills/camox/SKILL.md +38 -9
- package/skills/camox/references/block-definitions.md +107 -286
- package/skills/camox/references/cli-common.md +16 -4
- package/skills/camox/references/cli-content.md +158 -0
- package/skills/camox/references/cli-environments.md +1 -1
- package/skills/camox/references/dom-integrations.md +93 -0
- package/skills/camox/references/field-styling.md +50 -0
- package/skills/camox/references/layout-definitions.md +33 -147
- package/skills/camox/references/routed-layouts.md +71 -0
- package/skills/camoxify/SKILL.md +66 -0
- package/skills/camox/references/cli-blocks.md +0 -78
- package/skills/camox/references/cli-pages.md +0 -53
|
@@ -2,13 +2,14 @@ import { useLocation } from "../../features/navigation/navigation.js";
|
|
|
2
2
|
import { useProjectSlug } from "../../lib/auth.js";
|
|
3
3
|
import { isFileMarker, isItemMarker, resolveFileMarker, useNormalizedData } from "../../lib/normalized-data.js";
|
|
4
4
|
import { Type as Type$1, resolveToMarkdown } from "../lib/contentType.js";
|
|
5
|
+
import { IconSvg } from "../lib/icons.js";
|
|
5
6
|
import { buildImageSrcSet, getDefaultImageSizes, getDefaultImageWidth, transformImageUrl } from "../lib/imageTransform.js";
|
|
6
7
|
import { markdownToReactNodes } from "../lib/lexicalReact.js";
|
|
7
8
|
import { blockMutations, pageQueries, projectQueries, repeatableItemMutations } from "../../lib/queries.js";
|
|
8
9
|
import { previewStore, selectIsCommentMode } from "../../features/preview/previewStore.js";
|
|
9
10
|
import { usePreviewSelection } from "../../features/preview/previewSelection.js";
|
|
10
|
-
import { postOverlayMessage } from "../../features/preview/overlayMessages.js";
|
|
11
11
|
import { useFrame } from "../../features/preview/components/Frame.js";
|
|
12
|
+
import { postOverlayMessage } from "../../features/preview/overlayMessages.js";
|
|
12
13
|
import { AddBlockControlBar } from "../components/AddBlockControlBar.js";
|
|
13
14
|
import { InlineLexicalEditor } from "../components/lexical/InlineLexicalEditor.js";
|
|
14
15
|
import { useFieldSelection } from "../hooks/useFieldSelection.js";
|
|
@@ -185,9 +186,9 @@ function createEditableBlock(options) {
|
|
|
185
186
|
};
|
|
186
187
|
const Field = (t0) => {
|
|
187
188
|
const $ = c(34);
|
|
188
|
-
if ($[0] !== "
|
|
189
|
+
if ($[0] !== "8c4e70844cd2f2752041099dd31f8aabc30492cc078e28f85c1026ddf30f63b6") {
|
|
189
190
|
for (let $i = 0; $i < 34; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
190
|
-
$[0] = "
|
|
191
|
+
$[0] = "8c4e70844cd2f2752041099dd31f8aabc30492cc078e28f85c1026ddf30f63b6";
|
|
191
192
|
}
|
|
192
193
|
const { name, textStyle, linkStyle, children } = t0;
|
|
193
194
|
const selectTarget = usePreviewSelection();
|
|
@@ -387,11 +388,132 @@ function createEditableBlock(options) {
|
|
|
387
388
|
} else t17 = $[33];
|
|
388
389
|
return t17;
|
|
389
390
|
};
|
|
391
|
+
const Icon = (t0) => {
|
|
392
|
+
const $ = c(34);
|
|
393
|
+
if ($[0] !== "8c4e70844cd2f2752041099dd31f8aabc30492cc078e28f85c1026ddf30f63b6") {
|
|
394
|
+
for (let $i = 0; $i < 34; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
395
|
+
$[0] = "8c4e70844cd2f2752041099dd31f8aabc30492cc078e28f85c1026ddf30f63b6";
|
|
396
|
+
}
|
|
397
|
+
let name;
|
|
398
|
+
let props;
|
|
399
|
+
if ($[1] !== t0) {
|
|
400
|
+
({name, ...props} = t0);
|
|
401
|
+
$[1] = t0;
|
|
402
|
+
$[2] = name;
|
|
403
|
+
$[3] = props;
|
|
404
|
+
} else {
|
|
405
|
+
name = $[2];
|
|
406
|
+
props = $[3];
|
|
407
|
+
}
|
|
408
|
+
const block = React.use(Context);
|
|
409
|
+
const item = React.use(RepeaterItemContext);
|
|
410
|
+
const selectTarget = usePreviewSelection();
|
|
411
|
+
if (!block) throw new Error("Icon must be used within a Block Component");
|
|
412
|
+
const editable = useIsEditable(block.mode);
|
|
413
|
+
const fieldName = String(name);
|
|
414
|
+
const value = item ? item.itemContent[name] : block.content[name];
|
|
415
|
+
let t1;
|
|
416
|
+
if ($[4] !== block.blockId || $[5] !== fieldName || $[6] !== item) {
|
|
417
|
+
t1 = getOverlayFieldId(block.blockId, item, fieldName);
|
|
418
|
+
$[4] = block.blockId;
|
|
419
|
+
$[5] = fieldName;
|
|
420
|
+
$[6] = item;
|
|
421
|
+
$[7] = t1;
|
|
422
|
+
} else t1 = $[7];
|
|
423
|
+
const fieldId = t1;
|
|
424
|
+
const { window: iframeWindow } = useFrame();
|
|
425
|
+
const [isHovered, setIsHovered] = React.useState(false);
|
|
426
|
+
const isFocused = useFieldSelection(block.blockId, fieldName, "Icon", item?.itemId);
|
|
427
|
+
let t2;
|
|
428
|
+
if ($[8] !== fieldId) {
|
|
429
|
+
t2 = { fieldId };
|
|
430
|
+
$[8] = fieldId;
|
|
431
|
+
$[9] = t2;
|
|
432
|
+
} else t2 = $[9];
|
|
433
|
+
const isHoveredFromSidebar = useOverlayMessage(iframeWindow, editable, "CAMOX_HOVER_FIELD", "CAMOX_HOVER_FIELD_END", t2);
|
|
434
|
+
const overlayState = useOverlayState(isHovered || isHoveredFromSidebar, isFocused);
|
|
435
|
+
const t3 = editable ? fieldId : void 0;
|
|
436
|
+
const t4 = editable ? "icon" : void 0;
|
|
437
|
+
let t5;
|
|
438
|
+
if ($[10] !== editable || $[11] !== overlayState) {
|
|
439
|
+
t5 = editable ? overlayState : {};
|
|
440
|
+
$[10] = editable;
|
|
441
|
+
$[11] = overlayState;
|
|
442
|
+
$[12] = t5;
|
|
443
|
+
} else t5 = $[12];
|
|
444
|
+
const t6 = editable && options.synced ? "synced" : void 0;
|
|
445
|
+
let t7;
|
|
446
|
+
let t8;
|
|
447
|
+
if ($[13] !== editable || $[14] !== props) {
|
|
448
|
+
t7 = (event) => {
|
|
449
|
+
if (editable) setIsHovered(true);
|
|
450
|
+
props.onMouseEnter?.(event);
|
|
451
|
+
};
|
|
452
|
+
t8 = (event_0) => {
|
|
453
|
+
if (editable) setIsHovered(false);
|
|
454
|
+
props.onMouseLeave?.(event_0);
|
|
455
|
+
};
|
|
456
|
+
$[13] = editable;
|
|
457
|
+
$[14] = props;
|
|
458
|
+
$[15] = t7;
|
|
459
|
+
$[16] = t8;
|
|
460
|
+
} else {
|
|
461
|
+
t7 = $[15];
|
|
462
|
+
t8 = $[16];
|
|
463
|
+
}
|
|
464
|
+
let t9;
|
|
465
|
+
if ($[17] !== block.blockId || $[18] !== editable || $[19] !== fieldName || $[20] !== item || $[21] !== props.onClickCapture || $[22] !== selectTarget) {
|
|
466
|
+
t9 = editable ? (event_1) => selectTarget(item?.itemId != null ? {
|
|
467
|
+
type: "item-field",
|
|
468
|
+
blockId: block.blockId,
|
|
469
|
+
itemId: item.itemId,
|
|
470
|
+
fieldName,
|
|
471
|
+
fieldType: "Icon"
|
|
472
|
+
} : {
|
|
473
|
+
type: "block-field",
|
|
474
|
+
blockId: block.blockId,
|
|
475
|
+
fieldName,
|
|
476
|
+
fieldType: "Icon"
|
|
477
|
+
}, event_1) : props.onClickCapture;
|
|
478
|
+
$[17] = block.blockId;
|
|
479
|
+
$[18] = editable;
|
|
480
|
+
$[19] = fieldName;
|
|
481
|
+
$[20] = item;
|
|
482
|
+
$[21] = props.onClickCapture;
|
|
483
|
+
$[22] = selectTarget;
|
|
484
|
+
$[23] = t9;
|
|
485
|
+
} else t9 = $[23];
|
|
486
|
+
let t10;
|
|
487
|
+
if ($[24] !== props || $[25] !== t3 || $[26] !== t4 || $[27] !== t5 || $[28] !== t6 || $[29] !== t7 || $[30] !== t8 || $[31] !== t9 || $[32] !== value) {
|
|
488
|
+
t10 = /* @__PURE__ */ jsx(IconSvg, {
|
|
489
|
+
...props,
|
|
490
|
+
iconId: value,
|
|
491
|
+
"data-camox-field-id": t3,
|
|
492
|
+
"data-camox-field-type": t4,
|
|
493
|
+
...t5,
|
|
494
|
+
"data-camox-overlay-mode": t6,
|
|
495
|
+
onMouseEnter: t7,
|
|
496
|
+
onMouseLeave: t8,
|
|
497
|
+
onClickCapture: t9
|
|
498
|
+
});
|
|
499
|
+
$[24] = props;
|
|
500
|
+
$[25] = t3;
|
|
501
|
+
$[26] = t4;
|
|
502
|
+
$[27] = t5;
|
|
503
|
+
$[28] = t6;
|
|
504
|
+
$[29] = t7;
|
|
505
|
+
$[30] = t8;
|
|
506
|
+
$[31] = t9;
|
|
507
|
+
$[32] = value;
|
|
508
|
+
$[33] = t10;
|
|
509
|
+
} else t10 = $[33];
|
|
510
|
+
return t10;
|
|
511
|
+
};
|
|
390
512
|
const Embed = (t0) => {
|
|
391
513
|
const $ = c(39);
|
|
392
|
-
if ($[0] !== "
|
|
514
|
+
if ($[0] !== "8c4e70844cd2f2752041099dd31f8aabc30492cc078e28f85c1026ddf30f63b6") {
|
|
393
515
|
for (let $i = 0; $i < 39; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
394
|
-
$[0] = "
|
|
516
|
+
$[0] = "8c4e70844cd2f2752041099dd31f8aabc30492cc078e28f85c1026ddf30f63b6";
|
|
395
517
|
}
|
|
396
518
|
const { name, children } = t0;
|
|
397
519
|
const selectTarget = usePreviewSelection();
|
|
@@ -557,9 +679,9 @@ function createEditableBlock(options) {
|
|
|
557
679
|
};
|
|
558
680
|
const Link = (t0) => {
|
|
559
681
|
const $ = c(32);
|
|
560
|
-
if ($[0] !== "
|
|
682
|
+
if ($[0] !== "8c4e70844cd2f2752041099dd31f8aabc30492cc078e28f85c1026ddf30f63b6") {
|
|
561
683
|
for (let $i = 0; $i < 32; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
562
|
-
$[0] = "
|
|
684
|
+
$[0] = "8c4e70844cd2f2752041099dd31f8aabc30492cc078e28f85c1026ddf30f63b6";
|
|
563
685
|
}
|
|
564
686
|
const { name, children } = t0;
|
|
565
687
|
const selectTarget = usePreviewSelection();
|
|
@@ -766,9 +888,9 @@ function createEditableBlock(options) {
|
|
|
766
888
|
};
|
|
767
889
|
const Image = (t0) => {
|
|
768
890
|
const $ = c(22);
|
|
769
|
-
if ($[0] !== "
|
|
891
|
+
if ($[0] !== "8c4e70844cd2f2752041099dd31f8aabc30492cc078e28f85c1026ddf30f63b6") {
|
|
770
892
|
for (let $i = 0; $i < 22; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
771
|
-
$[0] = "
|
|
893
|
+
$[0] = "8c4e70844cd2f2752041099dd31f8aabc30492cc078e28f85c1026ddf30f63b6";
|
|
772
894
|
}
|
|
773
895
|
const { name, children } = t0;
|
|
774
896
|
const selectTarget = usePreviewSelection();
|
|
@@ -886,9 +1008,9 @@ function createEditableBlock(options) {
|
|
|
886
1008
|
};
|
|
887
1009
|
const File = (t0) => {
|
|
888
1010
|
const $ = c(9);
|
|
889
|
-
if ($[0] !== "
|
|
1011
|
+
if ($[0] !== "8c4e70844cd2f2752041099dd31f8aabc30492cc078e28f85c1026ddf30f63b6") {
|
|
890
1012
|
for (let $i = 0; $i < 9; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
891
|
-
$[0] = "
|
|
1013
|
+
$[0] = "8c4e70844cd2f2752041099dd31f8aabc30492cc078e28f85c1026ddf30f63b6";
|
|
892
1014
|
}
|
|
893
1015
|
const { name, children } = t0;
|
|
894
1016
|
const blockContext = React.use(Context);
|
|
@@ -962,10 +1084,10 @@ function createEditableBlock(options) {
|
|
|
962
1084
|
const ImageList = _AssetList;
|
|
963
1085
|
const FileList = _AssetList;
|
|
964
1086
|
const RepeaterItemWrapper = (t0) => {
|
|
965
|
-
const $ = c(
|
|
966
|
-
if ($[0] !== "
|
|
967
|
-
for (let $i = 0; $i <
|
|
968
|
-
$[0] = "
|
|
1087
|
+
const $ = c(23);
|
|
1088
|
+
if ($[0] !== "8c4e70844cd2f2752041099dd31f8aabc30492cc078e28f85c1026ddf30f63b6") {
|
|
1089
|
+
for (let $i = 0; $i < 23; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
1090
|
+
$[0] = "8c4e70844cd2f2752041099dd31f8aabc30492cc078e28f85c1026ddf30f63b6";
|
|
969
1091
|
}
|
|
970
1092
|
const { itemId, blockId, mode, children } = t0;
|
|
971
1093
|
const isContentEditable = useIsEditable(mode);
|
|
@@ -974,22 +1096,33 @@ function createEditableBlock(options) {
|
|
|
974
1096
|
const isCommentMode = useSelector(previewStore, selectIsCommentMode);
|
|
975
1097
|
const [isLocallyHovered, setIsLocallyHovered] = React.useState(false);
|
|
976
1098
|
const isRepeaterHovered = React.useContext(RepeaterHoverContext);
|
|
977
|
-
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
982
|
-
blockId: t1,
|
|
983
|
-
itemId: t2
|
|
1099
|
+
let t1;
|
|
1100
|
+
if ($[1] !== blockId || $[2] !== itemId) {
|
|
1101
|
+
t1 = (state) => {
|
|
1102
|
+
const selection = state.context.selection;
|
|
1103
|
+
return selection?.type === "item" && selection.blockId === blockId && selection.itemId === itemId;
|
|
984
1104
|
};
|
|
985
|
-
$[1] =
|
|
986
|
-
$[2] =
|
|
987
|
-
$[3] =
|
|
988
|
-
} else
|
|
989
|
-
const
|
|
1105
|
+
$[1] = blockId;
|
|
1106
|
+
$[2] = itemId;
|
|
1107
|
+
$[3] = t1;
|
|
1108
|
+
} else t1 = $[3];
|
|
1109
|
+
const isSelected = useSelector(previewStore, t1);
|
|
1110
|
+
const t2 = String(blockId);
|
|
1111
|
+
const t3 = String(itemId);
|
|
990
1112
|
let t4;
|
|
991
|
-
if ($[4] !==
|
|
992
|
-
t4 =
|
|
1113
|
+
if ($[4] !== t2 || $[5] !== t3) {
|
|
1114
|
+
t4 = {
|
|
1115
|
+
blockId: t2,
|
|
1116
|
+
itemId: t3
|
|
1117
|
+
};
|
|
1118
|
+
$[4] = t2;
|
|
1119
|
+
$[5] = t3;
|
|
1120
|
+
$[6] = t4;
|
|
1121
|
+
} else t4 = $[6];
|
|
1122
|
+
const overlayState = useOverlayState(useOverlayMessage(iframeWindow, isContentEditable, "CAMOX_HOVER_REPEATER_ITEM", "CAMOX_HOVER_REPEATER_ITEM_END", t4) || isRepeaterHovered || isCommentMode && isLocallyHovered, isSelected);
|
|
1123
|
+
let t5;
|
|
1124
|
+
if ($[7] !== blockId || $[8] !== isCommentMode || $[9] !== isContentEditable || $[10] !== itemId || $[11] !== selectTarget) {
|
|
1125
|
+
t5 = (event) => {
|
|
993
1126
|
if (!isContentEditable || !isCommentMode || itemId == null) return;
|
|
994
1127
|
const target = event.target;
|
|
995
1128
|
if (target.closest("[data-camox-field-id]")) return;
|
|
@@ -1000,57 +1133,57 @@ function createEditableBlock(options) {
|
|
|
1000
1133
|
itemId
|
|
1001
1134
|
}, event);
|
|
1002
1135
|
};
|
|
1003
|
-
$[
|
|
1004
|
-
$[
|
|
1005
|
-
$[
|
|
1006
|
-
$[
|
|
1007
|
-
$[
|
|
1008
|
-
$[
|
|
1009
|
-
} else
|
|
1010
|
-
const handleClick =
|
|
1011
|
-
const
|
|
1012
|
-
let t6;
|
|
1136
|
+
$[7] = blockId;
|
|
1137
|
+
$[8] = isCommentMode;
|
|
1138
|
+
$[9] = isContentEditable;
|
|
1139
|
+
$[10] = itemId;
|
|
1140
|
+
$[11] = selectTarget;
|
|
1141
|
+
$[12] = t5;
|
|
1142
|
+
} else t5 = $[12];
|
|
1143
|
+
const handleClick = t5;
|
|
1144
|
+
const t6 = isContentEditable ? itemId : void 0;
|
|
1013
1145
|
let t7;
|
|
1014
|
-
if ($[10] === Symbol.for("react.memo_cache_sentinel")) {
|
|
1015
|
-
t6 = () => setIsLocallyHovered(true);
|
|
1016
|
-
t7 = () => setIsLocallyHovered(false);
|
|
1017
|
-
$[10] = t6;
|
|
1018
|
-
$[11] = t7;
|
|
1019
|
-
} else {
|
|
1020
|
-
t6 = $[10];
|
|
1021
|
-
t7 = $[11];
|
|
1022
|
-
}
|
|
1023
1146
|
let t8;
|
|
1024
|
-
if ($[
|
|
1025
|
-
|
|
1026
|
-
|
|
1027
|
-
$[13] =
|
|
1147
|
+
if ($[13] === Symbol.for("react.memo_cache_sentinel")) {
|
|
1148
|
+
t7 = () => setIsLocallyHovered(true);
|
|
1149
|
+
t8 = () => setIsLocallyHovered(false);
|
|
1150
|
+
$[13] = t7;
|
|
1028
1151
|
$[14] = t8;
|
|
1029
|
-
} else
|
|
1152
|
+
} else {
|
|
1153
|
+
t7 = $[13];
|
|
1154
|
+
t8 = $[14];
|
|
1155
|
+
}
|
|
1030
1156
|
let t9;
|
|
1031
|
-
if ($[15] !==
|
|
1032
|
-
t9 =
|
|
1033
|
-
|
|
1157
|
+
if ($[15] !== isContentEditable || $[16] !== overlayState) {
|
|
1158
|
+
t9 = isContentEditable ? overlayState : {};
|
|
1159
|
+
$[15] = isContentEditable;
|
|
1160
|
+
$[16] = overlayState;
|
|
1161
|
+
$[17] = t9;
|
|
1162
|
+
} else t9 = $[17];
|
|
1163
|
+
let t10;
|
|
1164
|
+
if ($[18] !== children || $[19] !== handleClick || $[20] !== t6 || $[21] !== t9) {
|
|
1165
|
+
t10 = /* @__PURE__ */ jsx("div", {
|
|
1166
|
+
"data-camox-repeater-item-id": t6,
|
|
1034
1167
|
onClickCapture: handleClick,
|
|
1035
|
-
onMouseEnter:
|
|
1036
|
-
onMouseLeave:
|
|
1037
|
-
...
|
|
1168
|
+
onMouseEnter: t7,
|
|
1169
|
+
onMouseLeave: t8,
|
|
1170
|
+
...t9,
|
|
1038
1171
|
"data-camox-overlay-mode": options.synced ? "synced" : void 0,
|
|
1039
1172
|
children
|
|
1040
1173
|
});
|
|
1041
|
-
$[
|
|
1042
|
-
$[
|
|
1043
|
-
$[
|
|
1044
|
-
$[
|
|
1045
|
-
$[
|
|
1046
|
-
} else
|
|
1047
|
-
return
|
|
1174
|
+
$[18] = children;
|
|
1175
|
+
$[19] = handleClick;
|
|
1176
|
+
$[20] = t6;
|
|
1177
|
+
$[21] = t9;
|
|
1178
|
+
$[22] = t10;
|
|
1179
|
+
} else t10 = $[22];
|
|
1180
|
+
return t10;
|
|
1048
1181
|
};
|
|
1049
1182
|
const RepeaterHoverProvider = (t0) => {
|
|
1050
1183
|
const $ = c(7);
|
|
1051
|
-
if ($[0] !== "
|
|
1184
|
+
if ($[0] !== "8c4e70844cd2f2752041099dd31f8aabc30492cc078e28f85c1026ddf30f63b6") {
|
|
1052
1185
|
for (let $i = 0; $i < 7; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
1053
|
-
$[0] = "
|
|
1186
|
+
$[0] = "8c4e70844cd2f2752041099dd31f8aabc30492cc078e28f85c1026ddf30f63b6";
|
|
1054
1187
|
}
|
|
1055
1188
|
const { blockId, fieldName, children } = t0;
|
|
1056
1189
|
const isContentEditable = useIsEditable("site");
|
|
@@ -1081,9 +1214,9 @@ function createEditableBlock(options) {
|
|
|
1081
1214
|
};
|
|
1082
1215
|
const Repeater = (t0) => {
|
|
1083
1216
|
const $ = c(27);
|
|
1084
|
-
if ($[0] !== "
|
|
1217
|
+
if ($[0] !== "8c4e70844cd2f2752041099dd31f8aabc30492cc078e28f85c1026ddf30f63b6") {
|
|
1085
1218
|
for (let $i = 0; $i < 27; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
1086
|
-
$[0] = "
|
|
1219
|
+
$[0] = "8c4e70844cd2f2752041099dd31f8aabc30492cc078e28f85c1026ddf30f63b6";
|
|
1087
1220
|
}
|
|
1088
1221
|
const { name, children } = t0;
|
|
1089
1222
|
const blockContext = React.use(Context);
|
|
@@ -1139,6 +1272,7 @@ function createEditableBlock(options) {
|
|
|
1139
1272
|
const itemApi = {
|
|
1140
1273
|
Field: ItemField,
|
|
1141
1274
|
Link: ItemLink,
|
|
1275
|
+
Icon,
|
|
1142
1276
|
Embed: ItemEmbed,
|
|
1143
1277
|
Image: ItemImage,
|
|
1144
1278
|
File: ItemFile,
|
|
@@ -1208,9 +1342,9 @@ function createEditableBlock(options) {
|
|
|
1208
1342
|
};
|
|
1209
1343
|
const BlockComponent = (t0) => {
|
|
1210
1344
|
const $ = c(74);
|
|
1211
|
-
if ($[0] !== "
|
|
1345
|
+
if ($[0] !== "8c4e70844cd2f2752041099dd31f8aabc30492cc078e28f85c1026ddf30f63b6") {
|
|
1212
1346
|
for (let $i = 0; $i < 74; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
1213
|
-
$[0] = "
|
|
1347
|
+
$[0] = "8c4e70844cd2f2752041099dd31f8aabc30492cc078e28f85c1026ddf30f63b6";
|
|
1214
1348
|
}
|
|
1215
1349
|
const { blockData, mode, isFirstBlock, showAddBlockTop, showAddBlockBottom, addBlockAfterPosition } = t0;
|
|
1216
1350
|
const isContentEditable = useIsEditable(mode);
|
|
@@ -1520,9 +1654,9 @@ function createEditableBlock(options) {
|
|
|
1520
1654
|
*/
|
|
1521
1655
|
const Detached = (t0) => {
|
|
1522
1656
|
const $ = c(32);
|
|
1523
|
-
if ($[0] !== "
|
|
1657
|
+
if ($[0] !== "8c4e70844cd2f2752041099dd31f8aabc30492cc078e28f85c1026ddf30f63b6") {
|
|
1524
1658
|
for (let $i = 0; $i < 32; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
1525
|
-
$[0] = "
|
|
1659
|
+
$[0] = "8c4e70844cd2f2752041099dd31f8aabc30492cc078e28f85c1026ddf30f63b6";
|
|
1526
1660
|
}
|
|
1527
1661
|
const { children } = t0;
|
|
1528
1662
|
const ctx = React.use(Context);
|
|
@@ -1651,6 +1785,7 @@ function createEditableBlock(options) {
|
|
|
1651
1785
|
};
|
|
1652
1786
|
return {
|
|
1653
1787
|
Detached,
|
|
1788
|
+
Icon,
|
|
1654
1789
|
Field,
|
|
1655
1790
|
Embed,
|
|
1656
1791
|
Link,
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { IconId, IconValue } from "./iconTypes.js";
|
|
1
2
|
import * as _$_sinclair_typebox0 from "@sinclair/typebox";
|
|
2
3
|
import { Static, TArray, TObject, TSchema, TUnsafe } from "@sinclair/typebox";
|
|
3
4
|
|
|
@@ -79,6 +80,10 @@ type FileValue = {
|
|
|
79
80
|
* All fields must have default values.
|
|
80
81
|
*/
|
|
81
82
|
declare const Type$1: {
|
|
83
|
+
Icon: (options: {
|
|
84
|
+
default: IconId;
|
|
85
|
+
title?: string;
|
|
86
|
+
}) => TUnsafe<IconValue>;
|
|
82
87
|
/**
|
|
83
88
|
* Creates a string field with a required default value.
|
|
84
89
|
*
|
|
@@ -127,6 +127,17 @@ function _fileList(options) {
|
|
|
127
127
|
* All fields must have default values.
|
|
128
128
|
*/
|
|
129
129
|
const Type$1 = {
|
|
130
|
+
Icon: (options) => {
|
|
131
|
+
const ids = typeof __CAMOX_ICON_IDS__ === "undefined" ? [] : __CAMOX_ICON_IDS__;
|
|
132
|
+
if (!ids.includes(options.default)) throw new Error(`Invalid icon default "${String(options.default)}". Configure icons in camox() first.`);
|
|
133
|
+
return Type.Unsafe({
|
|
134
|
+
type: "string",
|
|
135
|
+
fieldType: "Icon",
|
|
136
|
+
enum: [...ids],
|
|
137
|
+
default: options.default,
|
|
138
|
+
title: options.title
|
|
139
|
+
});
|
|
140
|
+
},
|
|
130
141
|
/**
|
|
131
142
|
* Creates a string field with a required default value.
|
|
132
143
|
*
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//#region src/core/lib/iconTypes.d.ts
|
|
2
|
+
declare global {
|
|
3
|
+
interface CamoxIconRegistry {}
|
|
4
|
+
}
|
|
5
|
+
type IconId = CamoxIconRegistry extends {
|
|
6
|
+
ids: infer IDs extends string;
|
|
7
|
+
} ? IDs : never;
|
|
8
|
+
declare const iconBrand: unique symbol;
|
|
9
|
+
type IconValue = string & {
|
|
10
|
+
readonly [iconBrand]: true;
|
|
11
|
+
};
|
|
12
|
+
//#endregion
|
|
13
|
+
export { IconId, IconValue };
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import { c } from "react/compiler-runtime";
|
|
2
|
+
import { useQuery } from "@tanstack/react-query";
|
|
3
|
+
import { useId } from "react";
|
|
4
|
+
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
import { ICON_CATALOG_VERSION, scopeIconSvgIds } from "@camox/api-contract";
|
|
6
|
+
|
|
7
|
+
//#region src/core/lib/icons.tsx
|
|
8
|
+
const iconQuery = (id) => ({
|
|
9
|
+
queryKey: [
|
|
10
|
+
"camox-icon",
|
|
11
|
+
ICON_CATALOG_VERSION,
|
|
12
|
+
id
|
|
13
|
+
],
|
|
14
|
+
staleTime: Infinity,
|
|
15
|
+
queryFn: async () => {
|
|
16
|
+
if (!/^[a-z0-9-]+:[a-z0-9-]+$/.test(id)) throw new Error("Invalid icon ID");
|
|
17
|
+
const response = await fetch(`${__CAMOX_API_URL__}/icons/${ICON_CATALOG_VERSION}/${id.replace(":", "/")}`);
|
|
18
|
+
if (!response.ok) throw new Error(`Unable to resolve icon ${id}`);
|
|
19
|
+
return response.json();
|
|
20
|
+
}
|
|
21
|
+
});
|
|
22
|
+
function IconSvg(t0) {
|
|
23
|
+
const $ = c(22);
|
|
24
|
+
if ($[0] !== "8eab78246422a9042abf36067eb940cbd070510c54a187ee11896f87a1f6085b") {
|
|
25
|
+
for (let $i = 0; $i < 22; $i += 1) $[$i] = Symbol.for("react.memo_cache_sentinel");
|
|
26
|
+
$[0] = "8eab78246422a9042abf36067eb940cbd070510c54a187ee11896f87a1f6085b";
|
|
27
|
+
}
|
|
28
|
+
let iconId;
|
|
29
|
+
let props;
|
|
30
|
+
if ($[1] !== t0) {
|
|
31
|
+
({iconId, ...props} = t0);
|
|
32
|
+
$[1] = t0;
|
|
33
|
+
$[2] = iconId;
|
|
34
|
+
$[3] = props;
|
|
35
|
+
} else {
|
|
36
|
+
iconId = $[2];
|
|
37
|
+
props = $[3];
|
|
38
|
+
}
|
|
39
|
+
let t1;
|
|
40
|
+
if ($[4] !== iconId) {
|
|
41
|
+
t1 = iconQuery(iconId);
|
|
42
|
+
$[4] = iconId;
|
|
43
|
+
$[5] = t1;
|
|
44
|
+
} else t1 = $[5];
|
|
45
|
+
const { data } = useQuery(t1);
|
|
46
|
+
const t2 = useId();
|
|
47
|
+
let t3;
|
|
48
|
+
if ($[6] !== t2) {
|
|
49
|
+
let t4;
|
|
50
|
+
if ($[8] === Symbol.for("react.memo_cache_sentinel")) {
|
|
51
|
+
t4 = /[^a-zA-Z0-9_-]/g;
|
|
52
|
+
$[8] = t4;
|
|
53
|
+
} else t4 = $[8];
|
|
54
|
+
t3 = t2.replace(t4, "");
|
|
55
|
+
$[6] = t2;
|
|
56
|
+
$[7] = t3;
|
|
57
|
+
} else t3 = $[7];
|
|
58
|
+
const instance = t3;
|
|
59
|
+
const t4 = data?.body ?? "";
|
|
60
|
+
const t5 = `camox-${instance}-`;
|
|
61
|
+
let t6;
|
|
62
|
+
if ($[9] !== t4 || $[10] !== t5) {
|
|
63
|
+
t6 = scopeIconSvgIds(t4, t5);
|
|
64
|
+
$[9] = t4;
|
|
65
|
+
$[10] = t5;
|
|
66
|
+
$[11] = t6;
|
|
67
|
+
} else t6 = $[11];
|
|
68
|
+
const body = t6;
|
|
69
|
+
const labeled = !!(props["aria-label"] || props["aria-labelledby"]);
|
|
70
|
+
const t7 = data?.attributes;
|
|
71
|
+
const t8 = labeled ? void 0 : true;
|
|
72
|
+
const t9 = labeled ? "img" : void 0;
|
|
73
|
+
const t10 = data?.attribution?.url ?? data?.attribution?.license;
|
|
74
|
+
const t11 = data?.attribution?.author;
|
|
75
|
+
let t12;
|
|
76
|
+
if ($[12] !== body) {
|
|
77
|
+
t12 = { __html: body };
|
|
78
|
+
$[12] = body;
|
|
79
|
+
$[13] = t12;
|
|
80
|
+
} else t12 = $[13];
|
|
81
|
+
let t13;
|
|
82
|
+
if ($[14] !== props || $[15] !== t10 || $[16] !== t11 || $[17] !== t12 || $[18] !== t7 || $[19] !== t8 || $[20] !== t9) {
|
|
83
|
+
t13 = /* @__PURE__ */ jsx("svg", {
|
|
84
|
+
...t7,
|
|
85
|
+
"aria-hidden": t8,
|
|
86
|
+
role: t9,
|
|
87
|
+
focusable: "false",
|
|
88
|
+
"data-icon-license": t10,
|
|
89
|
+
"data-icon-author": t11,
|
|
90
|
+
...props,
|
|
91
|
+
dangerouslySetInnerHTML: t12
|
|
92
|
+
});
|
|
93
|
+
$[14] = props;
|
|
94
|
+
$[15] = t10;
|
|
95
|
+
$[16] = t11;
|
|
96
|
+
$[17] = t12;
|
|
97
|
+
$[18] = t7;
|
|
98
|
+
$[19] = t8;
|
|
99
|
+
$[20] = t9;
|
|
100
|
+
$[21] = t13;
|
|
101
|
+
} else t13 = $[21];
|
|
102
|
+
return t13;
|
|
103
|
+
}
|
|
104
|
+
async function prefetchIcons(client, ...sources) {
|
|
105
|
+
const ids = /* @__PURE__ */ new Set();
|
|
106
|
+
const allowed = /* @__PURE__ */ new Set();
|
|
107
|
+
const collectSchemas = (value) => {
|
|
108
|
+
if (!value || typeof value !== "object") return;
|
|
109
|
+
const schema = value;
|
|
110
|
+
if (schema.fieldType === "Icon" && Array.isArray(schema.enum)) {
|
|
111
|
+
for (const id of schema.enum) if (typeof id === "string") allowed.add(id);
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
Object.values(value).forEach(collectSchemas);
|
|
115
|
+
};
|
|
116
|
+
sources.forEach(collectSchemas);
|
|
117
|
+
const walk = (value) => {
|
|
118
|
+
if (!value || typeof value !== "object") return;
|
|
119
|
+
for (const [key, child] of Object.entries(value)) {
|
|
120
|
+
if (key === "enum") continue;
|
|
121
|
+
if (typeof child === "string" && allowed.has(child)) ids.add(child);
|
|
122
|
+
else walk(child);
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
sources.forEach(walk);
|
|
126
|
+
await Promise.all([...ids].map((id) => client.fetchQuery(iconQuery(id))));
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
//#endregion
|
|
130
|
+
export { IconSvg, prefetchIcons };
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { FORMAT_FLAGS } from "./modifierFormats.js";
|
|
2
2
|
import { getPageIdFromTextLinkTarget, isHttpTextLinkTarget, resolveTextLinkHref, shouldOpenTextLinkInNewTab } from "./textLinks.js";
|
|
3
3
|
import { isLexicalState, markdownToLexicalState } from "./lexicalState.js";
|
|
4
|
-
import {
|
|
4
|
+
import { getHighlightStyle, getTextAppearance } from "./textStyles.js";
|
|
5
5
|
import * as React from "react";
|
|
6
6
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
7
7
|
|
|
@@ -23,9 +23,9 @@ function markdownToReactNodes(value, options = {}) {
|
|
|
23
23
|
}
|
|
24
24
|
if (node.type === "linebreak") return /* @__PURE__ */ jsx("br", {}, key);
|
|
25
25
|
const children = (node.children ?? []).map(render);
|
|
26
|
-
if (node.type === "
|
|
27
|
-
"data-camox-
|
|
28
|
-
...
|
|
26
|
+
if (node.type === "highlight") return /* @__PURE__ */ jsx("span", {
|
|
27
|
+
"data-camox-highlight": "",
|
|
28
|
+
...getHighlightStyle(options),
|
|
29
29
|
children
|
|
30
30
|
}, key);
|
|
31
31
|
if (node.type === "link") {
|
|
@@ -36,7 +36,7 @@ function lexicalStateToMarkdown(serialized) {
|
|
|
36
36
|
}
|
|
37
37
|
}
|
|
38
38
|
function extractMarkdownFromNode(node) {
|
|
39
|
-
if (node.type === "
|
|
39
|
+
if (node.type === "highlight") return `<highlight>${serializeInlineChildren(node.children ?? [])}</highlight>`;
|
|
40
40
|
if (node.type === "link") {
|
|
41
41
|
const text = serializeInlineChildren(node.children ?? []);
|
|
42
42
|
const url = typeof node.url === "string" ? node.url : "";
|
|
@@ -50,9 +50,9 @@ function extractMarkdownFromNode(node) {
|
|
|
50
50
|
function serializeInlineChildren(nodes) {
|
|
51
51
|
const marks = [
|
|
52
52
|
{
|
|
53
|
-
flag: FORMAT_FLAGS.
|
|
54
|
-
open: "<
|
|
55
|
-
close: "</
|
|
53
|
+
flag: FORMAT_FLAGS.strikethrough,
|
|
54
|
+
open: "<s>",
|
|
55
|
+
close: "</s>"
|
|
56
56
|
},
|
|
57
57
|
{
|
|
58
58
|
flag: FORMAT_FLAGS.bold,
|
|
@@ -90,7 +90,7 @@ function serializeInlineChildren(nodes) {
|
|
|
90
90
|
let text = (node.text ?? "").replace(/[\\*_[\]<>]/g, "\\$&");
|
|
91
91
|
if (node.format & FORMAT_FLAGS.italic) text = `<em>${text}</em>`;
|
|
92
92
|
if (node.format & FORMAT_FLAGS.bold) text = `<strong>${text}</strong>`;
|
|
93
|
-
if (node.format & FORMAT_FLAGS.
|
|
93
|
+
if (node.format & FORMAT_FLAGS.strikethrough) text = `<s>${text}</s>`;
|
|
94
94
|
return text;
|
|
95
95
|
}).join("");
|
|
96
96
|
}
|
|
@@ -204,7 +204,7 @@ function parseTokens(tokens, format) {
|
|
|
204
204
|
else nodes.push(...children);
|
|
205
205
|
continue;
|
|
206
206
|
}
|
|
207
|
-
const tag = token.type === "html" ? /^<(
|
|
207
|
+
const tag = token.type === "html" ? /^<(highlight|s|strong|em)>$/.exec(token.raw)?.[1] : void 0;
|
|
208
208
|
if (tag) {
|
|
209
209
|
let depth = 1;
|
|
210
210
|
let end = i + 1;
|
|
@@ -216,12 +216,12 @@ function parseTokens(tokens, format) {
|
|
|
216
216
|
}
|
|
217
217
|
if (!depth) {
|
|
218
218
|
const tagFlags = {
|
|
219
|
-
|
|
219
|
+
s: FORMAT_FLAGS.strikethrough,
|
|
220
220
|
strong: FORMAT_FLAGS.bold,
|
|
221
221
|
em: FORMAT_FLAGS.italic
|
|
222
222
|
};
|
|
223
223
|
const children = parseTokens(tokens.slice(i + 1, end), format | (tagFlags[tag] ?? 0));
|
|
224
|
-
if (tag === "
|
|
224
|
+
if (tag === "highlight") nodes.push(inlineElement("highlight", children));
|
|
225
225
|
else nodes.push(...children);
|
|
226
226
|
i = end;
|
|
227
227
|
continue;
|