@cmssy/react 9.1.1 → 9.3.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/block-error-boundary.cjs +90 -0
- package/dist/block-error-boundary.d.cts +22 -0
- package/dist/block-error-boundary.d.ts +22 -0
- package/dist/block-error-boundary.js +88 -0
- package/dist/client.cjs +127 -14
- package/dist/client.js +127 -14
- package/dist/index.cjs +213 -48
- package/dist/index.d.cts +6 -3
- package/dist/index.d.ts +6 -3
- package/dist/index.js +214 -49
- package/package.json +7 -2
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
'use strict';
|
|
3
|
+
|
|
4
|
+
var react = require('react');
|
|
5
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
6
|
+
|
|
7
|
+
// src/components/block-error.ts
|
|
8
|
+
function blockErrorMessage(err) {
|
|
9
|
+
return err instanceof Error ? err.message : String(err);
|
|
10
|
+
}
|
|
11
|
+
var SOURCE_LABELS = {
|
|
12
|
+
loader: "loader failed",
|
|
13
|
+
render: "render failed",
|
|
14
|
+
unregistered: "type not registered"
|
|
15
|
+
};
|
|
16
|
+
var cardStyle = {
|
|
17
|
+
boxSizing: "border-box",
|
|
18
|
+
margin: "8px 0",
|
|
19
|
+
padding: "12px 16px",
|
|
20
|
+
border: "1px dashed #ef4444",
|
|
21
|
+
borderRadius: "8px",
|
|
22
|
+
background: "rgba(239, 68, 68, 0.08)",
|
|
23
|
+
color: "#ef4444",
|
|
24
|
+
fontFamily: "ui-monospace, SFMono-Regular, Menlo, Consolas, 'Liberation Mono', monospace",
|
|
25
|
+
fontSize: "13px",
|
|
26
|
+
lineHeight: 1.5,
|
|
27
|
+
textAlign: "left"
|
|
28
|
+
};
|
|
29
|
+
var headingStyle = {
|
|
30
|
+
fontWeight: 700,
|
|
31
|
+
marginBottom: "4px"
|
|
32
|
+
};
|
|
33
|
+
var metaStyle = {
|
|
34
|
+
opacity: 0.8,
|
|
35
|
+
marginBottom: "4px"
|
|
36
|
+
};
|
|
37
|
+
var messageStyle = {
|
|
38
|
+
whiteSpace: "pre-wrap",
|
|
39
|
+
overflowWrap: "anywhere"
|
|
40
|
+
};
|
|
41
|
+
function BlockErrorCard({
|
|
42
|
+
blockType,
|
|
43
|
+
blockId,
|
|
44
|
+
error
|
|
45
|
+
}) {
|
|
46
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { role: "alert", "data-cmssy-block-error": error.source, style: cardStyle, children: [
|
|
47
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: headingStyle, children: [
|
|
48
|
+
'Block "',
|
|
49
|
+
blockType,
|
|
50
|
+
'" - ',
|
|
51
|
+
SOURCE_LABELS[error.source]
|
|
52
|
+
] }),
|
|
53
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: metaStyle, children: [
|
|
54
|
+
"id: ",
|
|
55
|
+
blockId
|
|
56
|
+
] }),
|
|
57
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: messageStyle, children: error.message })
|
|
58
|
+
] });
|
|
59
|
+
}
|
|
60
|
+
var BlockErrorBoundary = class extends react.Component {
|
|
61
|
+
state = { failed: false, error: void 0 };
|
|
62
|
+
static getDerivedStateFromError(error) {
|
|
63
|
+
return { failed: true, error };
|
|
64
|
+
}
|
|
65
|
+
componentDidCatch(error) {
|
|
66
|
+
if (typeof console !== "undefined") {
|
|
67
|
+
console.error(
|
|
68
|
+
`[cmssy] block "${this.props.blockType}" (${this.props.blockId}) failed to render`,
|
|
69
|
+
error
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
render() {
|
|
74
|
+
if (!this.state.failed) return this.props.children;
|
|
75
|
+
if (!this.props.editMode) return null;
|
|
76
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
77
|
+
BlockErrorCard,
|
|
78
|
+
{
|
|
79
|
+
blockType: this.props.blockType,
|
|
80
|
+
blockId: this.props.blockId,
|
|
81
|
+
error: {
|
|
82
|
+
source: "render",
|
|
83
|
+
message: blockErrorMessage(this.state.error)
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
|
|
90
|
+
exports.BlockErrorBoundary = BlockErrorBoundary;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { Component, ReactNode } from 'react';
|
|
3
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
|
+
|
|
5
|
+
interface BlockErrorBoundaryProps {
|
|
6
|
+
blockType: string;
|
|
7
|
+
blockId: string;
|
|
8
|
+
editMode?: boolean;
|
|
9
|
+
children?: ReactNode;
|
|
10
|
+
}
|
|
11
|
+
interface BlockErrorBoundaryState {
|
|
12
|
+
failed: boolean;
|
|
13
|
+
error: unknown;
|
|
14
|
+
}
|
|
15
|
+
declare class BlockErrorBoundary extends Component<BlockErrorBoundaryProps, BlockErrorBoundaryState> {
|
|
16
|
+
state: BlockErrorBoundaryState;
|
|
17
|
+
static getDerivedStateFromError(error: unknown): BlockErrorBoundaryState;
|
|
18
|
+
componentDidCatch(error: unknown): void;
|
|
19
|
+
render(): string | number | bigint | boolean | react_jsx_runtime.JSX.Element | Iterable<ReactNode> | Promise<string | number | bigint | boolean | react.ReactPortal | react.ReactElement<unknown, string | react.JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | null | undefined;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export { BlockErrorBoundary, type BlockErrorBoundaryProps };
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import * as react from 'react';
|
|
2
|
+
import { Component, ReactNode } from 'react';
|
|
3
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
4
|
+
|
|
5
|
+
interface BlockErrorBoundaryProps {
|
|
6
|
+
blockType: string;
|
|
7
|
+
blockId: string;
|
|
8
|
+
editMode?: boolean;
|
|
9
|
+
children?: ReactNode;
|
|
10
|
+
}
|
|
11
|
+
interface BlockErrorBoundaryState {
|
|
12
|
+
failed: boolean;
|
|
13
|
+
error: unknown;
|
|
14
|
+
}
|
|
15
|
+
declare class BlockErrorBoundary extends Component<BlockErrorBoundaryProps, BlockErrorBoundaryState> {
|
|
16
|
+
state: BlockErrorBoundaryState;
|
|
17
|
+
static getDerivedStateFromError(error: unknown): BlockErrorBoundaryState;
|
|
18
|
+
componentDidCatch(error: unknown): void;
|
|
19
|
+
render(): string | number | bigint | boolean | react_jsx_runtime.JSX.Element | Iterable<ReactNode> | Promise<string | number | bigint | boolean | react.ReactPortal | react.ReactElement<unknown, string | react.JSXElementConstructor<any>> | Iterable<ReactNode> | null | undefined> | null | undefined;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export { BlockErrorBoundary, type BlockErrorBoundaryProps };
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { Component } from 'react';
|
|
3
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
4
|
+
|
|
5
|
+
// src/components/block-error.ts
|
|
6
|
+
function blockErrorMessage(err) {
|
|
7
|
+
return err instanceof Error ? err.message : String(err);
|
|
8
|
+
}
|
|
9
|
+
var SOURCE_LABELS = {
|
|
10
|
+
loader: "loader failed",
|
|
11
|
+
render: "render failed",
|
|
12
|
+
unregistered: "type not registered"
|
|
13
|
+
};
|
|
14
|
+
var cardStyle = {
|
|
15
|
+
boxSizing: "border-box",
|
|
16
|
+
margin: "8px 0",
|
|
17
|
+
padding: "12px 16px",
|
|
18
|
+
border: "1px dashed #ef4444",
|
|
19
|
+
borderRadius: "8px",
|
|
20
|
+
background: "rgba(239, 68, 68, 0.08)",
|
|
21
|
+
color: "#ef4444",
|
|
22
|
+
fontFamily: "ui-monospace, SFMono-Regular, Menlo, Consolas, 'Liberation Mono', monospace",
|
|
23
|
+
fontSize: "13px",
|
|
24
|
+
lineHeight: 1.5,
|
|
25
|
+
textAlign: "left"
|
|
26
|
+
};
|
|
27
|
+
var headingStyle = {
|
|
28
|
+
fontWeight: 700,
|
|
29
|
+
marginBottom: "4px"
|
|
30
|
+
};
|
|
31
|
+
var metaStyle = {
|
|
32
|
+
opacity: 0.8,
|
|
33
|
+
marginBottom: "4px"
|
|
34
|
+
};
|
|
35
|
+
var messageStyle = {
|
|
36
|
+
whiteSpace: "pre-wrap",
|
|
37
|
+
overflowWrap: "anywhere"
|
|
38
|
+
};
|
|
39
|
+
function BlockErrorCard({
|
|
40
|
+
blockType,
|
|
41
|
+
blockId,
|
|
42
|
+
error
|
|
43
|
+
}) {
|
|
44
|
+
return /* @__PURE__ */ jsxs("div", { role: "alert", "data-cmssy-block-error": error.source, style: cardStyle, children: [
|
|
45
|
+
/* @__PURE__ */ jsxs("div", { style: headingStyle, children: [
|
|
46
|
+
'Block "',
|
|
47
|
+
blockType,
|
|
48
|
+
'" - ',
|
|
49
|
+
SOURCE_LABELS[error.source]
|
|
50
|
+
] }),
|
|
51
|
+
/* @__PURE__ */ jsxs("div", { style: metaStyle, children: [
|
|
52
|
+
"id: ",
|
|
53
|
+
blockId
|
|
54
|
+
] }),
|
|
55
|
+
/* @__PURE__ */ jsx("div", { style: messageStyle, children: error.message })
|
|
56
|
+
] });
|
|
57
|
+
}
|
|
58
|
+
var BlockErrorBoundary = class extends Component {
|
|
59
|
+
state = { failed: false, error: void 0 };
|
|
60
|
+
static getDerivedStateFromError(error) {
|
|
61
|
+
return { failed: true, error };
|
|
62
|
+
}
|
|
63
|
+
componentDidCatch(error) {
|
|
64
|
+
if (typeof console !== "undefined") {
|
|
65
|
+
console.error(
|
|
66
|
+
`[cmssy] block "${this.props.blockType}" (${this.props.blockId}) failed to render`,
|
|
67
|
+
error
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
render() {
|
|
72
|
+
if (!this.state.failed) return this.props.children;
|
|
73
|
+
if (!this.props.editMode) return null;
|
|
74
|
+
return /* @__PURE__ */ jsx(
|
|
75
|
+
BlockErrorCard,
|
|
76
|
+
{
|
|
77
|
+
blockType: this.props.blockType,
|
|
78
|
+
blockId: this.props.blockId,
|
|
79
|
+
error: {
|
|
80
|
+
source: "render",
|
|
81
|
+
message: blockErrorMessage(this.state.error)
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
);
|
|
85
|
+
}
|
|
86
|
+
};
|
|
87
|
+
|
|
88
|
+
export { BlockErrorBoundary };
|
package/dist/client.cjs
CHANGED
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
|
|
4
4
|
var react = require('react');
|
|
5
5
|
var core = require('@cmssy/core');
|
|
6
|
+
var blockErrorBoundary = require('@cmssy/react/block-error-boundary');
|
|
6
7
|
var jsxRuntime = require('react/jsx-runtime');
|
|
7
8
|
|
|
8
9
|
// src/registry.ts
|
|
@@ -421,13 +422,85 @@ function useDragAgent(config) {
|
|
|
421
422
|
}, [config.editorOrigin]);
|
|
422
423
|
return { dropY };
|
|
423
424
|
}
|
|
425
|
+
|
|
426
|
+
// src/components/block-error.ts
|
|
427
|
+
var BLOCK_ERROR_KEY = "__cmssyBlockError";
|
|
428
|
+
var SOURCES = [
|
|
429
|
+
"loader",
|
|
430
|
+
"render",
|
|
431
|
+
"unregistered"
|
|
432
|
+
];
|
|
433
|
+
function unregisteredBlockError(type) {
|
|
434
|
+
return {
|
|
435
|
+
source: "unregistered",
|
|
436
|
+
message: `Block type "${type}" is not registered in this site's blocks array.`
|
|
437
|
+
};
|
|
438
|
+
}
|
|
439
|
+
function readBlockError(value) {
|
|
440
|
+
if (typeof value !== "object" || value === null) return void 0;
|
|
441
|
+
const marked = value[BLOCK_ERROR_KEY];
|
|
442
|
+
if (typeof marked !== "object" || marked === null) return void 0;
|
|
443
|
+
const { message, source } = marked;
|
|
444
|
+
if (typeof message !== "string") return void 0;
|
|
445
|
+
if (!SOURCES.includes(source)) return void 0;
|
|
446
|
+
return { message, source };
|
|
447
|
+
}
|
|
448
|
+
var SOURCE_LABELS = {
|
|
449
|
+
loader: "loader failed",
|
|
450
|
+
render: "render failed",
|
|
451
|
+
unregistered: "type not registered"
|
|
452
|
+
};
|
|
453
|
+
var cardStyle = {
|
|
454
|
+
boxSizing: "border-box",
|
|
455
|
+
margin: "8px 0",
|
|
456
|
+
padding: "12px 16px",
|
|
457
|
+
border: "1px dashed #ef4444",
|
|
458
|
+
borderRadius: "8px",
|
|
459
|
+
background: "rgba(239, 68, 68, 0.08)",
|
|
460
|
+
color: "#ef4444",
|
|
461
|
+
fontFamily: "ui-monospace, SFMono-Regular, Menlo, Consolas, 'Liberation Mono', monospace",
|
|
462
|
+
fontSize: "13px",
|
|
463
|
+
lineHeight: 1.5,
|
|
464
|
+
textAlign: "left"
|
|
465
|
+
};
|
|
466
|
+
var headingStyle = {
|
|
467
|
+
fontWeight: 700,
|
|
468
|
+
marginBottom: "4px"
|
|
469
|
+
};
|
|
470
|
+
var metaStyle = {
|
|
471
|
+
opacity: 0.8,
|
|
472
|
+
marginBottom: "4px"
|
|
473
|
+
};
|
|
474
|
+
var messageStyle = {
|
|
475
|
+
whiteSpace: "pre-wrap",
|
|
476
|
+
overflowWrap: "anywhere"
|
|
477
|
+
};
|
|
478
|
+
function BlockErrorCard({
|
|
479
|
+
blockType,
|
|
480
|
+
blockId,
|
|
481
|
+
error
|
|
482
|
+
}) {
|
|
483
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", { role: "alert", "data-cmssy-block-error": error.source, style: cardStyle, children: [
|
|
484
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: headingStyle, children: [
|
|
485
|
+
'Block "',
|
|
486
|
+
blockType,
|
|
487
|
+
'" - ',
|
|
488
|
+
SOURCE_LABELS[error.source]
|
|
489
|
+
] }),
|
|
490
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { style: metaStyle, children: [
|
|
491
|
+
"id: ",
|
|
492
|
+
blockId
|
|
493
|
+
] }),
|
|
494
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { style: messageStyle, children: error.message })
|
|
495
|
+
] });
|
|
496
|
+
}
|
|
424
497
|
var WARN_CAP = 256;
|
|
425
498
|
var warned = /* @__PURE__ */ new Set();
|
|
426
499
|
function UnknownBlock({ type }) {
|
|
427
500
|
if (typeof window !== "undefined" && !warned.has(type)) {
|
|
428
501
|
if (warned.size >= WARN_CAP) warned.clear();
|
|
429
502
|
warned.add(type);
|
|
430
|
-
console.
|
|
503
|
+
console.error(`[cmssy] no component registered for block type "${type}"`);
|
|
431
504
|
}
|
|
432
505
|
return /* @__PURE__ */ jsxRuntime.jsx("div", { "data-cmssy-unknown-block": type });
|
|
433
506
|
}
|
|
@@ -440,32 +513,71 @@ function CmssyBlock({
|
|
|
440
513
|
patchedStyle,
|
|
441
514
|
patchedAdvanced,
|
|
442
515
|
editable,
|
|
516
|
+
editMode,
|
|
443
517
|
layoutPosition,
|
|
444
518
|
context,
|
|
445
519
|
data
|
|
446
520
|
}) {
|
|
521
|
+
const inEditMode = editMode ?? editable ?? false;
|
|
447
522
|
const Component = Object.hasOwn(blockMap, block.type) ? blockMap[block.type] : void 0;
|
|
448
|
-
const
|
|
449
|
-
const
|
|
450
|
-
const style = patchedStyle ? { ...core.asBucket(block.style), ...patchedStyle } : core.asBucket(block.style);
|
|
451
|
-
const advanced = patchedAdvanced ? { ...core.asBucket(block.advanced), ...patchedAdvanced } : core.asBucket(block.advanced);
|
|
452
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
523
|
+
const blockError = readBlockError(data);
|
|
524
|
+
const wrap = (children, hidden = false) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
453
525
|
"div",
|
|
454
526
|
{
|
|
455
527
|
"data-block-id": block.id,
|
|
456
528
|
"data-block-type": block.type,
|
|
457
529
|
"data-layout-position": layoutPosition,
|
|
458
530
|
draggable: editable || void 0,
|
|
459
|
-
style:
|
|
460
|
-
children
|
|
461
|
-
content,
|
|
462
|
-
style,
|
|
463
|
-
advanced,
|
|
464
|
-
context,
|
|
465
|
-
data
|
|
466
|
-
}) : /* @__PURE__ */ jsxRuntime.jsx(UnknownBlock, { type: block.type })
|
|
531
|
+
style: hidden ? { display: "none" } : void 0,
|
|
532
|
+
children
|
|
467
533
|
}
|
|
468
534
|
);
|
|
535
|
+
if (!Component) {
|
|
536
|
+
return inEditMode ? wrap(
|
|
537
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
538
|
+
BlockErrorCard,
|
|
539
|
+
{
|
|
540
|
+
blockType: block.type,
|
|
541
|
+
blockId: block.id,
|
|
542
|
+
error: unregisteredBlockError(block.type)
|
|
543
|
+
}
|
|
544
|
+
)
|
|
545
|
+
) : wrap(/* @__PURE__ */ jsxRuntime.jsx(UnknownBlock, { type: block.type }), true);
|
|
546
|
+
}
|
|
547
|
+
if (blockError) {
|
|
548
|
+
if (!inEditMode) return null;
|
|
549
|
+
return wrap(
|
|
550
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
551
|
+
BlockErrorCard,
|
|
552
|
+
{
|
|
553
|
+
blockType: block.type,
|
|
554
|
+
blockId: block.id,
|
|
555
|
+
error: blockError
|
|
556
|
+
}
|
|
557
|
+
)
|
|
558
|
+
);
|
|
559
|
+
}
|
|
560
|
+
const base = core.getBlockContentForLanguage(block.content, locale, defaultLocale);
|
|
561
|
+
const content = patchedContent ? { ...base, ...patchedContent } : base;
|
|
562
|
+
const style = patchedStyle ? { ...core.asBucket(block.style), ...patchedStyle } : core.asBucket(block.style);
|
|
563
|
+
const advanced = patchedAdvanced ? { ...core.asBucket(block.advanced), ...patchedAdvanced } : core.asBucket(block.advanced);
|
|
564
|
+
return wrap(
|
|
565
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
566
|
+
blockErrorBoundary.BlockErrorBoundary,
|
|
567
|
+
{
|
|
568
|
+
blockType: block.type,
|
|
569
|
+
blockId: block.id,
|
|
570
|
+
editMode: inEditMode,
|
|
571
|
+
children: react.createElement(Component, {
|
|
572
|
+
content,
|
|
573
|
+
style,
|
|
574
|
+
advanced,
|
|
575
|
+
context,
|
|
576
|
+
data
|
|
577
|
+
})
|
|
578
|
+
}
|
|
579
|
+
)
|
|
580
|
+
);
|
|
469
581
|
}
|
|
470
582
|
function CmssyEditablePage({
|
|
471
583
|
page,
|
|
@@ -674,6 +786,7 @@ function CmssyEditableLayout({
|
|
|
674
786
|
defaultLocale,
|
|
675
787
|
blockMap,
|
|
676
788
|
patchedContent: patches[block.id],
|
|
789
|
+
editMode: true,
|
|
677
790
|
layoutPosition: position,
|
|
678
791
|
context,
|
|
679
792
|
data: data?.[block.id]
|
package/dist/client.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import { createContext, useState, useRef, useEffect, useMemo, useContext, useCallback, createElement } from 'react';
|
|
3
3
|
import { fields, resolveInitialTarget, buildBlockContext, postToEditor, PROTOCOL_VERSION, parseEditorMessage, getBlockContentForLanguage, asBucket, toMinorUnits, formatPrice } from '@cmssy/core';
|
|
4
4
|
export { formatPrice, fractionDigits, fromMinorUnits, toMinorUnits } from '@cmssy/core';
|
|
5
|
+
import { BlockErrorBoundary } from '@cmssy/react/block-error-boundary';
|
|
5
6
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
6
7
|
|
|
7
8
|
// src/registry.ts
|
|
@@ -420,13 +421,85 @@ function useDragAgent(config) {
|
|
|
420
421
|
}, [config.editorOrigin]);
|
|
421
422
|
return { dropY };
|
|
422
423
|
}
|
|
424
|
+
|
|
425
|
+
// src/components/block-error.ts
|
|
426
|
+
var BLOCK_ERROR_KEY = "__cmssyBlockError";
|
|
427
|
+
var SOURCES = [
|
|
428
|
+
"loader",
|
|
429
|
+
"render",
|
|
430
|
+
"unregistered"
|
|
431
|
+
];
|
|
432
|
+
function unregisteredBlockError(type) {
|
|
433
|
+
return {
|
|
434
|
+
source: "unregistered",
|
|
435
|
+
message: `Block type "${type}" is not registered in this site's blocks array.`
|
|
436
|
+
};
|
|
437
|
+
}
|
|
438
|
+
function readBlockError(value) {
|
|
439
|
+
if (typeof value !== "object" || value === null) return void 0;
|
|
440
|
+
const marked = value[BLOCK_ERROR_KEY];
|
|
441
|
+
if (typeof marked !== "object" || marked === null) return void 0;
|
|
442
|
+
const { message, source } = marked;
|
|
443
|
+
if (typeof message !== "string") return void 0;
|
|
444
|
+
if (!SOURCES.includes(source)) return void 0;
|
|
445
|
+
return { message, source };
|
|
446
|
+
}
|
|
447
|
+
var SOURCE_LABELS = {
|
|
448
|
+
loader: "loader failed",
|
|
449
|
+
render: "render failed",
|
|
450
|
+
unregistered: "type not registered"
|
|
451
|
+
};
|
|
452
|
+
var cardStyle = {
|
|
453
|
+
boxSizing: "border-box",
|
|
454
|
+
margin: "8px 0",
|
|
455
|
+
padding: "12px 16px",
|
|
456
|
+
border: "1px dashed #ef4444",
|
|
457
|
+
borderRadius: "8px",
|
|
458
|
+
background: "rgba(239, 68, 68, 0.08)",
|
|
459
|
+
color: "#ef4444",
|
|
460
|
+
fontFamily: "ui-monospace, SFMono-Regular, Menlo, Consolas, 'Liberation Mono', monospace",
|
|
461
|
+
fontSize: "13px",
|
|
462
|
+
lineHeight: 1.5,
|
|
463
|
+
textAlign: "left"
|
|
464
|
+
};
|
|
465
|
+
var headingStyle = {
|
|
466
|
+
fontWeight: 700,
|
|
467
|
+
marginBottom: "4px"
|
|
468
|
+
};
|
|
469
|
+
var metaStyle = {
|
|
470
|
+
opacity: 0.8,
|
|
471
|
+
marginBottom: "4px"
|
|
472
|
+
};
|
|
473
|
+
var messageStyle = {
|
|
474
|
+
whiteSpace: "pre-wrap",
|
|
475
|
+
overflowWrap: "anywhere"
|
|
476
|
+
};
|
|
477
|
+
function BlockErrorCard({
|
|
478
|
+
blockType,
|
|
479
|
+
blockId,
|
|
480
|
+
error
|
|
481
|
+
}) {
|
|
482
|
+
return /* @__PURE__ */ jsxs("div", { role: "alert", "data-cmssy-block-error": error.source, style: cardStyle, children: [
|
|
483
|
+
/* @__PURE__ */ jsxs("div", { style: headingStyle, children: [
|
|
484
|
+
'Block "',
|
|
485
|
+
blockType,
|
|
486
|
+
'" - ',
|
|
487
|
+
SOURCE_LABELS[error.source]
|
|
488
|
+
] }),
|
|
489
|
+
/* @__PURE__ */ jsxs("div", { style: metaStyle, children: [
|
|
490
|
+
"id: ",
|
|
491
|
+
blockId
|
|
492
|
+
] }),
|
|
493
|
+
/* @__PURE__ */ jsx("div", { style: messageStyle, children: error.message })
|
|
494
|
+
] });
|
|
495
|
+
}
|
|
423
496
|
var WARN_CAP = 256;
|
|
424
497
|
var warned = /* @__PURE__ */ new Set();
|
|
425
498
|
function UnknownBlock({ type }) {
|
|
426
499
|
if (typeof window !== "undefined" && !warned.has(type)) {
|
|
427
500
|
if (warned.size >= WARN_CAP) warned.clear();
|
|
428
501
|
warned.add(type);
|
|
429
|
-
console.
|
|
502
|
+
console.error(`[cmssy] no component registered for block type "${type}"`);
|
|
430
503
|
}
|
|
431
504
|
return /* @__PURE__ */ jsx("div", { "data-cmssy-unknown-block": type });
|
|
432
505
|
}
|
|
@@ -439,32 +512,71 @@ function CmssyBlock({
|
|
|
439
512
|
patchedStyle,
|
|
440
513
|
patchedAdvanced,
|
|
441
514
|
editable,
|
|
515
|
+
editMode,
|
|
442
516
|
layoutPosition,
|
|
443
517
|
context,
|
|
444
518
|
data
|
|
445
519
|
}) {
|
|
520
|
+
const inEditMode = editMode ?? editable ?? false;
|
|
446
521
|
const Component = Object.hasOwn(blockMap, block.type) ? blockMap[block.type] : void 0;
|
|
447
|
-
const
|
|
448
|
-
const
|
|
449
|
-
const style = patchedStyle ? { ...asBucket(block.style), ...patchedStyle } : asBucket(block.style);
|
|
450
|
-
const advanced = patchedAdvanced ? { ...asBucket(block.advanced), ...patchedAdvanced } : asBucket(block.advanced);
|
|
451
|
-
return /* @__PURE__ */ jsx(
|
|
522
|
+
const blockError = readBlockError(data);
|
|
523
|
+
const wrap = (children, hidden = false) => /* @__PURE__ */ jsx(
|
|
452
524
|
"div",
|
|
453
525
|
{
|
|
454
526
|
"data-block-id": block.id,
|
|
455
527
|
"data-block-type": block.type,
|
|
456
528
|
"data-layout-position": layoutPosition,
|
|
457
529
|
draggable: editable || void 0,
|
|
458
|
-
style:
|
|
459
|
-
children
|
|
460
|
-
content,
|
|
461
|
-
style,
|
|
462
|
-
advanced,
|
|
463
|
-
context,
|
|
464
|
-
data
|
|
465
|
-
}) : /* @__PURE__ */ jsx(UnknownBlock, { type: block.type })
|
|
530
|
+
style: hidden ? { display: "none" } : void 0,
|
|
531
|
+
children
|
|
466
532
|
}
|
|
467
533
|
);
|
|
534
|
+
if (!Component) {
|
|
535
|
+
return inEditMode ? wrap(
|
|
536
|
+
/* @__PURE__ */ jsx(
|
|
537
|
+
BlockErrorCard,
|
|
538
|
+
{
|
|
539
|
+
blockType: block.type,
|
|
540
|
+
blockId: block.id,
|
|
541
|
+
error: unregisteredBlockError(block.type)
|
|
542
|
+
}
|
|
543
|
+
)
|
|
544
|
+
) : wrap(/* @__PURE__ */ jsx(UnknownBlock, { type: block.type }), true);
|
|
545
|
+
}
|
|
546
|
+
if (blockError) {
|
|
547
|
+
if (!inEditMode) return null;
|
|
548
|
+
return wrap(
|
|
549
|
+
/* @__PURE__ */ jsx(
|
|
550
|
+
BlockErrorCard,
|
|
551
|
+
{
|
|
552
|
+
blockType: block.type,
|
|
553
|
+
blockId: block.id,
|
|
554
|
+
error: blockError
|
|
555
|
+
}
|
|
556
|
+
)
|
|
557
|
+
);
|
|
558
|
+
}
|
|
559
|
+
const base = getBlockContentForLanguage(block.content, locale, defaultLocale);
|
|
560
|
+
const content = patchedContent ? { ...base, ...patchedContent } : base;
|
|
561
|
+
const style = patchedStyle ? { ...asBucket(block.style), ...patchedStyle } : asBucket(block.style);
|
|
562
|
+
const advanced = patchedAdvanced ? { ...asBucket(block.advanced), ...patchedAdvanced } : asBucket(block.advanced);
|
|
563
|
+
return wrap(
|
|
564
|
+
/* @__PURE__ */ jsx(
|
|
565
|
+
BlockErrorBoundary,
|
|
566
|
+
{
|
|
567
|
+
blockType: block.type,
|
|
568
|
+
blockId: block.id,
|
|
569
|
+
editMode: inEditMode,
|
|
570
|
+
children: createElement(Component, {
|
|
571
|
+
content,
|
|
572
|
+
style,
|
|
573
|
+
advanced,
|
|
574
|
+
context,
|
|
575
|
+
data
|
|
576
|
+
})
|
|
577
|
+
}
|
|
578
|
+
)
|
|
579
|
+
);
|
|
468
580
|
}
|
|
469
581
|
function CmssyEditablePage({
|
|
470
582
|
page,
|
|
@@ -673,6 +785,7 @@ function CmssyEditableLayout({
|
|
|
673
785
|
defaultLocale,
|
|
674
786
|
blockMap,
|
|
675
787
|
patchedContent: patches[block.id],
|
|
788
|
+
editMode: true,
|
|
676
789
|
layoutPosition: position,
|
|
677
790
|
context,
|
|
678
791
|
data: data?.[block.id]
|