@blocklet/editor 2.4.102 → 2.4.104

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.
@@ -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
- if (!children || children.length === 0)
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: children.length }) })] }), _jsx(Collapse, { in: expanded, timeout: "auto", unmountOnExit: true, children: _jsx(Box, { sx: {
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: children.map((child) => {
120
- const fullname = `${name}.${child.properties.name}`;
121
- return _jsx(Field, { ...child.properties, name: fullname }, fullname);
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-param-field", sx: {
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,5 @@
1
+ import { type LexicalNode } from 'lexical';
2
+ export interface FieldDescProps {
3
+ childNodes: LexicalNode[];
4
+ }
5
+ export default function FieldDesc({ childNodes }: FieldDescProps): import("react/jsx-runtime").JSX.Element;
@@ -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,7 @@
1
+ import { FieldProps } from './Field';
2
+ export interface FieldGroupProps {
3
+ children?: {
4
+ properties: FieldProps;
5
+ }[];
6
+ }
7
+ export default function FieldGroup({ children }: FieldGroupProps): import("react/jsx-runtime").JSX.Element | null;
@@ -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;
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',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blocklet/editor",
3
- "version": "2.4.102",
3
+ "version": "2.4.104",
4
4
  "main": "lib/index.js",
5
5
  "sideEffects": false,
6
6
  "publishConfig": {
@@ -27,7 +27,7 @@
27
27
  "dependencies": {
28
28
  "@blocklet/code-editor": "^0.5.20",
29
29
  "@blocklet/embed": "^0.2.5",
30
- "@blocklet/js-sdk": "^1.16.51",
30
+ "@blocklet/js-sdk": "^1.16.52-beta-20250918-114058-f5efc10b",
31
31
  "@blocklet/pages-kit": "^0.6.72",
32
32
  "@blocklet/pages-kit-runtime": "^0.6.72",
33
33
  "@excalidraw/excalidraw": "^0.18.0",
@@ -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.102"
76
+ "@blocklet/pdf": "2.4.104"
77
77
  },
78
78
  "devDependencies": {
79
79
  "@babel/core": "^7.25.2",