@blocklet/editor 2.4.101 → 2.4.103
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/lib/ext/CustomComponent/CustomComponentNode.js +2 -0
- package/lib/ext/CustomComponent/components/Field.d.ts +14 -4
- package/lib/ext/CustomComponent/components/Field.js +21 -9
- package/lib/ext/CustomComponent/components/FieldDesc.d.ts +5 -0
- package/lib/ext/CustomComponent/components/FieldDesc.js +13 -0
- package/lib/ext/CustomComponent/components/FieldGroup.d.ts +7 -0
- package/lib/ext/CustomComponent/components/FieldGroup.js +16 -0
- package/lib/ext/CustomComponent/components/StaticEditor.d.ts +7 -0
- package/lib/ext/CustomComponent/components/StaticEditor.js +24 -0
- package/lib/ext/CustomComponent/components/index.d.ts +4 -0
- package/lib/ext/CustomComponent/components/index.js +5 -0
- package/lib/ext/PagesKitComponent/PagesKitComponentNode.d.ts +1 -1
- package/lib/ext/PagesKitComponent/PagesKitComponentNode.js +3 -2
- package/lib/main/index.js +0 -1
- package/lib/main/nodes/MermaidNode.d.ts +1 -1
- package/lib/main/nodes/MermaidNode.js +3 -2
- package/package.json +2 -2
|
@@ -71,6 +71,8 @@ export class CustomComponentNode extends DecoratorBlockNode {
|
|
|
71
71
|
'x-code-group': () => ({ conversion: convertCustomComponentElement, priority: 1 }),
|
|
72
72
|
'x-steps': () => ({ conversion: convertCustomComponentElement, priority: 1 }),
|
|
73
73
|
'x-field': () => ({ conversion: convertCustomComponentElement, priority: 1 }),
|
|
74
|
+
'x-field-group': () => ({ conversion: convertCustomComponentElement, priority: 1 }),
|
|
75
|
+
'x-field-desc': () => ({ conversion: convertCustomComponentElement, priority: 1 }),
|
|
74
76
|
};
|
|
75
77
|
}
|
|
76
78
|
static importJSON(serializedNode) {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { FieldDescProps } from './FieldDesc';
|
|
1
2
|
export declare const X_FIELD_TRANSLATIONS: {
|
|
2
3
|
en: {
|
|
3
4
|
required: string;
|
|
@@ -10,6 +11,16 @@ export declare const X_FIELD_TRANSLATIONS: {
|
|
|
10
11
|
subfields: string;
|
|
11
12
|
};
|
|
12
13
|
};
|
|
14
|
+
type ChildMap = {
|
|
15
|
+
field: FieldProps;
|
|
16
|
+
'field-desc': FieldDescProps;
|
|
17
|
+
};
|
|
18
|
+
type Child = {
|
|
19
|
+
[K in keyof ChildMap]: {
|
|
20
|
+
component: K;
|
|
21
|
+
properties: ChildMap[K];
|
|
22
|
+
};
|
|
23
|
+
}[keyof ChildMap];
|
|
13
24
|
export interface FieldProps {
|
|
14
25
|
name: string;
|
|
15
26
|
type: string;
|
|
@@ -17,8 +28,7 @@ export interface FieldProps {
|
|
|
17
28
|
required?: 'false' | 'true';
|
|
18
29
|
deprecated?: 'false' | 'true';
|
|
19
30
|
desc?: string;
|
|
20
|
-
children?:
|
|
21
|
-
properties: FieldProps;
|
|
22
|
-
}[];
|
|
31
|
+
children?: Child[];
|
|
23
32
|
}
|
|
24
|
-
export default function Field({ name, type, default: defaultVal, required, deprecated, desc, children }: FieldProps): import("react/jsx-runtime").JSX.Element;
|
|
33
|
+
export default function Field({ name, type, default: defaultVal, required, deprecated, desc, children, }: FieldProps): import("react/jsx-runtime").JSX.Element;
|
|
34
|
+
export {};
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { Stack, Box, styled, alpha, Collapse } from '@mui/material';
|
|
3
3
|
import { Add } from '@mui/icons-material';
|
|
4
|
-
import { useState, useEffect } from 'react';
|
|
4
|
+
import { useState, useEffect, useMemo } from 'react';
|
|
5
5
|
import { useLocaleContext } from '@arcblock/ux/lib/Locale/context';
|
|
6
6
|
import { translate } from '@arcblock/ux/lib/Locale/util';
|
|
7
7
|
import { useMemoizedFn } from 'ahooks';
|
|
8
8
|
import useMobile from '../../../main/hooks/use-mobile';
|
|
9
|
+
import FieldDesc from './FieldDesc';
|
|
9
10
|
// 多语言翻译
|
|
10
11
|
export const X_FIELD_TRANSLATIONS = {
|
|
11
12
|
en: {
|
|
@@ -64,7 +65,7 @@ const Bar = styled(Box)(({ theme }) => ({
|
|
|
64
65
|
flexWrap: 'wrap',
|
|
65
66
|
gap: theme.spacing(1.25),
|
|
66
67
|
}));
|
|
67
|
-
export default function Field({ name, type, default: defaultVal, required, deprecated, desc, children }) {
|
|
68
|
+
export default function Field({ name, type, default: defaultVal, required, deprecated, desc, children = [], }) {
|
|
68
69
|
const { locale = 'en' } = useLocaleContext();
|
|
69
70
|
const t = useMemoizedFn((key, data = {}) => translate(X_FIELD_TRANSLATIONS, key, locale, 'en', data));
|
|
70
71
|
const isMobile = useMobile();
|
|
@@ -84,10 +85,20 @@ export default function Field({ name, type, default: defaultVal, required, depre
|
|
|
84
85
|
background: ({ palette }) => alpha(palette.warning.light, 0.1),
|
|
85
86
|
fontWeight: 500,
|
|
86
87
|
}, children: t('deprecated') })), defaultVal && (_jsxs(Tag, { sx: { backgroundColor: ({ palette }) => alpha(palette.grey[100], 0.6) }, children: [_jsx(Box, { component: "span", sx: { color: 'text.secondary', mr: 0.5 }, children: "default:" }), defaultVal] }))] }));
|
|
88
|
+
// desc 子节点
|
|
89
|
+
const childDesc = useMemo(() => {
|
|
90
|
+
const index = children.findIndex((v) => v.component === 'field-desc');
|
|
91
|
+
if (index >= 0) {
|
|
92
|
+
return children[index];
|
|
93
|
+
}
|
|
94
|
+
return undefined;
|
|
95
|
+
}, [children]);
|
|
87
96
|
// 渲染子 Field
|
|
88
97
|
const renderChildren = () => {
|
|
89
|
-
|
|
98
|
+
const childFields = children.filter((v) => v.component === 'field');
|
|
99
|
+
if (childFields.length === 0) {
|
|
90
100
|
return null;
|
|
101
|
+
}
|
|
91
102
|
return (_jsxs(Box, { sx: { mt: 1 }, children: [_jsxs(Box, { sx: {
|
|
92
103
|
display: 'flex',
|
|
93
104
|
alignItems: 'center',
|
|
@@ -107,7 +118,7 @@ export default function Field({ name, type, default: defaultVal, required, depre
|
|
|
107
118
|
display: 'flex',
|
|
108
119
|
alignItems: 'center',
|
|
109
120
|
justifyContent: 'center',
|
|
110
|
-
}, children: _jsx(Add, {}) }), _jsx(Box, { sx: { color: 'text.secondary', fontSize: '14px', flex: 1 }, children: t('subfields', { num:
|
|
121
|
+
}, children: _jsx(Add, {}) }), _jsx(Box, { sx: { color: 'text.secondary', fontSize: '14px', flex: 1 }, children: t('subfields', { num: childFields.length }) })] }), _jsx(Collapse, { in: expanded, timeout: "auto", unmountOnExit: true, children: _jsx(Box, { sx: {
|
|
111
122
|
pl: 1.5,
|
|
112
123
|
borderLeft: '1px dashed',
|
|
113
124
|
borderColor: highlightedFieldId === fieldId ? 'primary.main' : 'divider',
|
|
@@ -116,12 +127,13 @@ export default function Field({ name, type, default: defaultVal, required, depre
|
|
|
116
127
|
highlightManager.enterField(fieldId);
|
|
117
128
|
}, onMouseLeave: () => {
|
|
118
129
|
highlightManager.leaveField(fieldId);
|
|
119
|
-
}, children: _jsx(Stack, { spacing: 1, children:
|
|
120
|
-
const
|
|
121
|
-
|
|
130
|
+
}, children: _jsx(Stack, { spacing: 1, children: childFields.map((child) => {
|
|
131
|
+
const properties = child.properties;
|
|
132
|
+
const fullname = `${name}.${properties.name}`;
|
|
133
|
+
return _jsx(Field, { ...properties, name: fullname }, fullname);
|
|
122
134
|
}) }) }) })] }));
|
|
123
135
|
};
|
|
124
|
-
return (_jsxs(Stack, { className: "x-
|
|
136
|
+
return (_jsxs(Stack, { className: "x-field", sx: {
|
|
125
137
|
borderBottom: '1px solid',
|
|
126
138
|
borderColor: 'divider',
|
|
127
139
|
pt: 1.25,
|
|
@@ -130,5 +142,5 @@ export default function Field({ name, type, default: defaultVal, required, depre
|
|
|
130
142
|
'& &:last-child': {
|
|
131
143
|
borderBottom: 'none',
|
|
132
144
|
},
|
|
133
|
-
}, children: [_jsxs(Bar, { children: [name && _jsx(Box, { sx: { color: 'primary.main', fontWeight: 500 }, children: name }), !isMobile && metaInfo] }), isMobile && _jsx(Bar, { sx: { mt: 1.25 }, children: metaInfo }), desc && _jsx(Box, { sx: { color: 'text.secondary', mt: 2 }, children: desc }), renderChildren()] }));
|
|
145
|
+
}, children: [_jsxs(Bar, { children: [name && _jsx(Box, { sx: { color: 'primary.main', fontWeight: 500 }, children: name }), !isMobile && metaInfo] }), isMobile && _jsx(Bar, { sx: { mt: 1.25 }, children: metaInfo }), desc && _jsx(Box, { sx: { color: 'text.secondary', mt: 2 }, children: desc }), childDesc && _jsx(FieldDesc, { ...childDesc.properties }), renderChildren()] }));
|
|
134
146
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import StaticEditor from './StaticEditor';
|
|
3
|
+
export default function FieldDesc({ childNodes }) {
|
|
4
|
+
return (_jsx(StaticEditor, { childNodes: childNodes, sx: {
|
|
5
|
+
'&>p:first-child': {
|
|
6
|
+
color: 'text.secondary',
|
|
7
|
+
marginTop: (theme) => `${theme.spacing(2)} !important`,
|
|
8
|
+
marginLeft: 0,
|
|
9
|
+
marginRight: 0,
|
|
10
|
+
marginBottom: 0,
|
|
11
|
+
},
|
|
12
|
+
} }));
|
|
13
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { Box } from '@mui/material';
|
|
3
|
+
import Field from './Field';
|
|
4
|
+
export default function FieldGroup({ children = [] }) {
|
|
5
|
+
if (children.length === 0) {
|
|
6
|
+
return null;
|
|
7
|
+
}
|
|
8
|
+
return (_jsx(Box, { className: "x-field-group", sx: {
|
|
9
|
+
'& > .x-field:last-child': {
|
|
10
|
+
borderBottom: 'none',
|
|
11
|
+
},
|
|
12
|
+
}, children: children.map((child) => {
|
|
13
|
+
const { properties } = child;
|
|
14
|
+
return _jsx(Field, { ...properties });
|
|
15
|
+
}) }));
|
|
16
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { type LexicalNode } from 'lexical';
|
|
2
|
+
import { SxProps, Theme } from '@mui/material';
|
|
3
|
+
export interface StaticEditorProps {
|
|
4
|
+
childNodes: LexicalNode[];
|
|
5
|
+
sx?: SxProps<Theme>;
|
|
6
|
+
}
|
|
7
|
+
export default function StaticEditor({ childNodes, sx }: StaticEditorProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
|
3
|
+
import { $generateHtmlFromNodes } from '@lexical/html';
|
|
4
|
+
import DOMPurify from 'dompurify';
|
|
5
|
+
import { Box } from '@mui/material';
|
|
6
|
+
export default function StaticEditor({ childNodes, sx }) {
|
|
7
|
+
const [editor] = useLexicalComposerContext();
|
|
8
|
+
const editorState = editor.parseEditorState(JSON.stringify({
|
|
9
|
+
root: {
|
|
10
|
+
children: [
|
|
11
|
+
{
|
|
12
|
+
type: 'paragraph',
|
|
13
|
+
children: childNodes,
|
|
14
|
+
},
|
|
15
|
+
],
|
|
16
|
+
type: 'root',
|
|
17
|
+
},
|
|
18
|
+
}));
|
|
19
|
+
let html = '';
|
|
20
|
+
editorState.read(() => {
|
|
21
|
+
html = $generateHtmlFromNodes(editor);
|
|
22
|
+
});
|
|
23
|
+
return _jsx(Box, { dangerouslySetInnerHTML: { __html: DOMPurify.sanitize(html) }, sx: sx });
|
|
24
|
+
}
|
|
@@ -2,10 +2,14 @@ import Card from './Card';
|
|
|
2
2
|
import Cards from './Cards';
|
|
3
3
|
import Code from './Code';
|
|
4
4
|
import Field from './Field';
|
|
5
|
+
import FieldDesc from './FieldDesc';
|
|
6
|
+
import FieldGroup from './FieldGroup';
|
|
5
7
|
declare const components: {
|
|
6
8
|
code: typeof Code;
|
|
7
9
|
card: typeof Card;
|
|
8
10
|
cards: typeof Cards;
|
|
9
11
|
field: typeof Field;
|
|
12
|
+
'field-desc': typeof FieldDesc;
|
|
13
|
+
'field-group': typeof FieldGroup;
|
|
10
14
|
};
|
|
11
15
|
export default components;
|
|
@@ -2,10 +2,15 @@ import Card from './Card';
|
|
|
2
2
|
import Cards from './Cards';
|
|
3
3
|
import Code from './Code';
|
|
4
4
|
import Field from './Field';
|
|
5
|
+
import FieldDesc from './FieldDesc';
|
|
6
|
+
import FieldGroup from './FieldGroup';
|
|
7
|
+
// key 为 '-' 分隔的 html tagName
|
|
5
8
|
const components = {
|
|
6
9
|
code: Code,
|
|
7
10
|
card: Card,
|
|
8
11
|
cards: Cards,
|
|
9
12
|
field: Field,
|
|
13
|
+
'field-desc': FieldDesc,
|
|
14
|
+
'field-group': FieldGroup,
|
|
10
15
|
};
|
|
11
16
|
export default components;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { DOMConversionMap, DOMExportOutput, EditorConfig, ElementFormatType, LexicalEditor, LexicalNode, NodeKey, Spread } from 'lexical';
|
|
2
2
|
import { DecoratorBlockNode, SerializedDecoratorBlockNode } from '@lexical/react/LexicalDecoratorBlockNode';
|
|
3
|
-
import type
|
|
3
|
+
import { type JSX } from 'react';
|
|
4
4
|
import type { Properties } from './utils';
|
|
5
5
|
export interface ComponentData {
|
|
6
6
|
id: string;
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { BlockWithAlignableContents } from '@lexical/react/LexicalBlockWithAlignableContents';
|
|
3
3
|
import { DecoratorBlockNode } from '@lexical/react/LexicalDecoratorBlockNode';
|
|
4
|
-
import {
|
|
4
|
+
import { lazy, Suspense } from 'react';
|
|
5
|
+
const LazyPagesKitComponentRenderer = lazy(() => import('./PagesKitComponentRenderer').then((mod) => ({ default: mod.PagesKitComponentRenderer })));
|
|
5
6
|
function PagesKitComponent({ className, format, nodeKey, data, onPropertiesChange }) {
|
|
6
|
-
return (_jsx(BlockWithAlignableContents, { className: className, format: format, nodeKey: nodeKey, children: _jsx(
|
|
7
|
+
return (_jsx(BlockWithAlignableContents, { className: className, format: format, nodeKey: nodeKey, children: _jsx(Suspense, { fallback: null, children: _jsx(LazyPagesKitComponentRenderer, { id: data.id, name: data.name, properties: data.properties, onPropertiesChange: onPropertiesChange }) }) }));
|
|
7
8
|
}
|
|
8
9
|
function convertPagesKitComponentElement(domNode) {
|
|
9
10
|
const pagesKitComponentStr = domNode.getAttribute('data-lexical-pages-kit-component');
|
package/lib/main/index.js
CHANGED
|
@@ -25,7 +25,6 @@ import { TableContext } from './plugins/TablePlugin';
|
|
|
25
25
|
import { useCustomTheme } from './themes/customTheme';
|
|
26
26
|
import { PLAYGROUND_TRANSFORMERS } from './plugins/MarkdownTransformers';
|
|
27
27
|
export default function BlockletEditor({ editorState, nodes = PlaygroundNodes, editable = true, markdown, ...props }) {
|
|
28
|
-
const muiTheme = useTheme();
|
|
29
28
|
const theme = useCustomTheme();
|
|
30
29
|
const initialConfig = {
|
|
31
30
|
namespace: 'Playground',
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { DOMConversionMap, DOMExportOutput, LexicalNode, NodeKey, SerializedLexicalNode, Spread } from 'lexical';
|
|
2
2
|
import { DecoratorNode } from 'lexical';
|
|
3
|
-
import type
|
|
3
|
+
import { type JSX } from 'react';
|
|
4
4
|
export interface MermaidPayload {
|
|
5
5
|
code: string;
|
|
6
6
|
theme?: string;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
2
|
import { DecoratorNode } from 'lexical';
|
|
3
|
-
import
|
|
3
|
+
import { lazy, Suspense } from 'react';
|
|
4
|
+
const LazyMermaidComponent = lazy(() => import('./MermaidComponent'));
|
|
4
5
|
function convertMermaidElement(domNode) {
|
|
5
6
|
if (domNode && domNode.classList?.contains('mermaid')) {
|
|
6
7
|
const code = domNode.textContent || '';
|
|
@@ -84,7 +85,7 @@ export class MermaidNode extends DecoratorNode {
|
|
|
84
85
|
return false;
|
|
85
86
|
}
|
|
86
87
|
decorate() {
|
|
87
|
-
return _jsx(
|
|
88
|
+
return (_jsx(Suspense, { fallback: null, children: _jsx(LazyMermaidComponent, { code: this.__code, theme: this.__theme, mode: this.__mode }) }));
|
|
88
89
|
}
|
|
89
90
|
}
|
|
90
91
|
export function $createMermaidNode({ code, theme, mode, key }) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@blocklet/editor",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.103",
|
|
4
4
|
"main": "lib/index.js",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"publishConfig": {
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
"ufo": "^1.5.4",
|
|
74
74
|
"url-join": "^4.0.1",
|
|
75
75
|
"zustand": "^4.5.5",
|
|
76
|
-
"@blocklet/pdf": "2.4.
|
|
76
|
+
"@blocklet/pdf": "2.4.103"
|
|
77
77
|
},
|
|
78
78
|
"devDependencies": {
|
|
79
79
|
"@babel/core": "^7.25.2",
|