remons-markdown-editor 1.0.0-beta.2 → 1.0.0-beta.21

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.
Files changed (34) hide show
  1. package/dist/App.d.ts +2 -0
  2. package/dist/MarkdownEditor.d.ts +23 -0
  3. package/dist/components/Dialog/EditDialog.d.ts +21 -0
  4. package/dist/components/Editor/codemirrorExtensions.d.ts +12 -0
  5. package/dist/components/Editor/containerWidget.d.ts +20 -0
  6. package/dist/components/Editor/index.d.ts +16 -0
  7. package/dist/components/Icon/index.d.ts +2 -0
  8. package/dist/components/Panel/SplitPanels.d.ts +7 -0
  9. package/dist/components/Preview/index.d.ts +10 -0
  10. package/dist/components/Toolbar/buttons.d.ts +59 -0
  11. package/dist/components/Toolbar/config.d.ts +6 -0
  12. package/dist/components/Toolbar/hooks/useToolbar.d.ts +14 -0
  13. package/dist/components/Toolbar/index.d.ts +13 -0
  14. package/dist/components/Toolbar/renderers/TablePicker/TableDropdown.d.ts +5 -0
  15. package/dist/components/Toolbar/renderers/TablePicker/index.d.ts +9 -0
  16. package/dist/components/Toolbar/renderers/ToolbarItemRenderer.d.ts +7 -0
  17. package/dist/hooks/useFullscreen.d.ts +4 -0
  18. package/dist/hooks/useRegisterToolbar.d.ts +101 -0
  19. package/dist/hooks/useScrollSync.d.ts +6 -0
  20. package/dist/index.cjs +1612 -1202
  21. package/dist/index.cjs.map +1 -1
  22. package/dist/index.css +184 -113
  23. package/dist/index.d.ts +5 -98
  24. package/dist/index.js +1588 -1182
  25. package/dist/index.js.map +1 -1
  26. package/dist/main.d.ts +0 -0
  27. package/dist/registry/componentRegistry.d.ts +34 -0
  28. package/dist/types/index.d.ts +148 -0
  29. package/dist/utils/parseContainer.d.ts +18 -0
  30. package/dist/utils/writeContainer.d.ts +16 -0
  31. package/package.json +77 -81
  32. package/readme.md +309 -91
  33. package/dist/index.css.map +0 -1
  34. package/dist/index.d.cts +0 -98
@@ -0,0 +1,148 @@
1
+ import { EditorView } from '@codemirror/view';
2
+ import { EditorState as CMEditorState } from '@codemirror/state';
3
+ import { FormInstance } from 'antd';
4
+ import { default as React } from 'react';
5
+ export interface ToolbarButtonConfig {
6
+ id?: string;
7
+ icon?: React.ComponentType | React.ReactNode;
8
+ label?: string;
9
+ children?: ToolbarButtonConfig[];
10
+ handler?: (view: EditorView, state: CMEditorState) => void;
11
+ separatorBefore?: boolean;
12
+ customRender?: () => React.ReactNode;
13
+ wrapTags?: [string, string];
14
+ disabled?: boolean;
15
+ }
16
+ /**
17
+ * 内置表单组件类型映射
18
+ * 用于 fields 驱动的自动表单渲染,无需手写 Form 结构
19
+ */
20
+ export type FormComponentType = 'input' | 'textarea' | 'number' | 'select' | 'switch' | 'slider' | 'rate' | 'color' | 'date' | 'dateRange';
21
+ /**
22
+ * 弹窗属性配置
23
+ * 支持简单模式(key + defaultValue)和完整模式(带 componentType 自动渲染)
24
+ */
25
+ export interface DialogField {
26
+ /** 字段键名,用于 Markdown 属性填充 */
27
+ key: string;
28
+ /** 字段显示名称(表单 label) */
29
+ name?: string;
30
+ /** 默认值 */
31
+ defaultValue?: string;
32
+ /**
33
+ * 表单组件类型(可选)
34
+ * 配置后 EditDialog 会自动渲染对应的 antd 表单组件,无需手写 Form 结构
35
+ * 如需完全自定义,可省略此项并提供 renderDialog
36
+ */
37
+ componentType?: FormComponentType;
38
+ /**
39
+ * 组件额外属性(可选)
40
+ * 传递对应 antd 组件的 props
41
+ */
42
+ componentProps?: Record<string, any>;
43
+ }
44
+ /**
45
+ * 组件 Schema
46
+ * 每个容器组件(如 :::linkCard)定义可编辑字段和弹窗渲染逻辑
47
+ * 也支持简单的标签包裹模式(通过 wrapTags)
48
+ */
49
+ export interface ComponentSchema {
50
+ /** 容器名称,对应 :::name 语法 */
51
+ name: string;
52
+ /** 工具栏按钮显示的标签 */
53
+ label: string;
54
+ /** 工具栏按钮显示的图标 */
55
+ icon?: React.ReactNode;
56
+ /**
57
+ * 标签包裹配置:设置为 [openTag, closeTag] 时,使用标签包裹模式(而非 :::name 容器)
58
+ * 配置后无需提供 fields 和 renderDialog
59
+ */
60
+ wrapTags?: [string, string];
61
+ /** 弹窗属性配置 — 用于定义 Markdown 内容中需要填充的字段(wrapTags 模式下可选) */
62
+ fields?: DialogField[];
63
+ /**
64
+ * 弹窗内容渲染函数(wrapTags 模式下可选)
65
+ * 接收当前属性值、表单实例和回调函数,由用户完全自定义弹窗内容的渲染
66
+ *
67
+ * 如果省略 renderDialog 并为 fields 配置了 componentType,
68
+ * 弹窗会自动生成表单,无需手写 Form 结构。
69
+ * 支持的 componentType:'input' | 'textarea' | 'number' | 'select' | 'switch' | 'slider' | 'rate' | 'color' | 'date' | 'dateRange'
70
+ * 示例:
71
+ * ```tsx
72
+ * fields: [
73
+ * { key: 'type', name: '类型', componentType: 'select',
74
+ * componentProps: { options: [{ value: 'price', label: '价格' }, { value: 'info', label: '信息' }] } },
75
+ * { key: 'content', name: '内容', componentType: 'textarea',
76
+ * componentProps: { rows: 3 } },
77
+ * { key: 'enabled', name: '启用', componentType: 'switch' },
78
+ * ],
79
+ * ```
80
+ *
81
+ * @example 使用 Form.Item 自动绑定(推荐)
82
+ * ```tsx
83
+ * renderDialog: ({ form }) => (
84
+ * <Form form={form} layout="vertical">
85
+ * <Form.Item name="type" label="类型">
86
+ * <Input />
87
+ * </Form.Item>
88
+ * </Form>
89
+ * )
90
+ * ```
91
+ *
92
+ * @example 手动控制
93
+ * ```tsx
94
+ * renderDialog: ({ props, onChange }) => (
95
+ * <Input value={props.content} onChange={e => onChange('content', e.target.value)} />
96
+ * )
97
+ * ```
98
+ *
99
+ * @example 完全自定义弹窗
100
+ * ```tsx
101
+ * renderDialog: ({ props, onSave }) => (
102
+ * <MyCustomEditor value={props.content} onSave={({ content }) => onSave({ content })} />
103
+ * )
104
+ * ```
105
+ */
106
+ renderDialog?: (context: DialogRenderContext) => React.ReactNode;
107
+ }
108
+ /**
109
+ * 弹窗渲染上下文
110
+ * 提供多种表单控制方式,用户可根据需求选择:
111
+ * - `form` + `Form.Item`:推荐方式,自动管理状态
112
+ * - `props` + `onChange`:手动控制,适用于自定义组件
113
+ * - `onSave`:完全自定义弹窗,直接调用保存
114
+ */
115
+ export interface DialogRenderContext {
116
+ /** 当前属性值(合并默认值与当前的值) */
117
+ props: Record<string, string>;
118
+ /** 表单实例,用于 Form.Item 自动绑定 */
119
+ form: FormInstance;
120
+ /** 属性变更回调(手动控制方式) */
121
+ onChange: (key: string, value: string) => void;
122
+ /** 直接保存属性(完全自定义方式,调用后弹窗不会自动关闭) */
123
+ onSave: (props: Record<string, string>) => void;
124
+ }
125
+ /**
126
+ * 图片上传配置
127
+ */
128
+ export interface ImageUploadConfig {
129
+ /**
130
+ * 图片上传接口地址
131
+ * 需与 onUploadImage 二选一(优先级低于 onUploadImage)
132
+ */
133
+ uploadUrl?: string;
134
+ /**
135
+ * 自定义上传函数(优先级高于 uploadUrl)
136
+ * 传入此函数时,将完全接管上传逻辑
137
+ * @param file 要上传的图片文件
138
+ * @returns Promise<string> - 返回图片 URL,失败返回 null
139
+ */
140
+ onUploadImage?: (file: File) => Promise<string | null>;
141
+ /**
142
+ * 处理服务器返回结果的回调,允许转换 URL
143
+ * 当使用 uploadUrl 方式上传时,可以使用此回调来自定义处理响应数据
144
+ * @param result 服务器返回的原始响应数据
145
+ * @returns 图片 URL,如果返回 null 则上传失败
146
+ */
147
+ onGetUploadUrl?: (result: any) => string | null;
148
+ }
@@ -0,0 +1,18 @@
1
+ /**
2
+ * 解析容器属性 JSON 字符串。
3
+ * 支持标准 JSON 和宽松格式: { key: 'value', key2: 'value2' }
4
+ */
5
+ export declare function parseContainerProps(jsonStr: string): Record<string, string>;
6
+ /**
7
+ * 在编辑器文档中查找容器块。
8
+ * 返回包含类型、属性和行位置的容器位置数组。
9
+ */
10
+ export interface ContainerBlock {
11
+ startPos: number;
12
+ typeName: string;
13
+ propsLineFrom: number;
14
+ propsLineTo: number;
15
+ props: Record<string, string>;
16
+ endPos: number;
17
+ }
18
+ export declare function findContainers(docText: string): ContainerBlock[];
@@ -0,0 +1,16 @@
1
+ import { EditorView } from '@codemirror/view';
2
+ /**
3
+ * 从属性对象生成 JSON 属性行。
4
+ * 格式: { key: 'value', key2: 'value2' }
5
+ */
6
+ export declare function writeContainerProps(props: Record<string, string>): string;
7
+ /**
8
+ * 更新编辑器文档中的容器属性。
9
+ * 替换 JSON 属性行(::: 打开行之后的一行)为新属性。
10
+ */
11
+ export declare function updateContainerProps(view: EditorView, propsLineFrom: number, propsLineTo: number, newProps: Record<string, string>): void;
12
+ /**
13
+ * 在当前光标位置插入新容器。
14
+ * 创建 :::type 打开行 + JSON 属性 + ::: 关闭行的结构。
15
+ */
16
+ export declare function insertContainer(view: EditorView, typeName: string, defaultProps: Record<string, string>): void;
package/package.json CHANGED
@@ -1,81 +1,77 @@
1
- {
2
- "name": "remons-markdown-editor",
3
- "version": "1.0.0-beta.2",
4
- "type": "module",
5
- "description": "一个可复用的 React Markdown 编辑器组件,支持工具栏、预览和自定义容器",
6
- "main": "dist/index.cjs",
7
- "module": "dist/index.js",
8
- "types": "dist/index.d.ts",
9
- "style": "dist/index.css",
10
- "repository": {
11
- "type": "git",
12
- "url": "https://github.com/remons/markdown-editor"
13
- },
14
- "homepage": "https://github.com/remons/markdown-editor#readme",
15
- "sideEffects": [
16
- "*.css"
17
- ],
18
- "files": [
19
- "dist"
20
- ],
21
- "exports": {
22
- ".": {
23
- "import": {
24
- "types": "./dist/index.d.ts",
25
- "default": "./dist/index.js"
26
- },
27
- "require": {
28
- "types": "./dist/index.d.cts",
29
- "default": "./dist/index.cjs"
30
- }
31
- },
32
- "./style.css": "./dist/index.css"
33
- },
34
- "scripts": {
35
- "dev": "vite",
36
- "build": "tsc -b && vite build",
37
- "build:lib": "tsup",
38
- "lint": "oxlint",
39
- "preview": "vite preview"
40
- },
41
- "publishConfig": {
42
- "registry": "https://registry.npmjs.org/"
43
- },
44
- "peerDependencies": {
45
- "react": "^18.0.0 || ^19.0.0",
46
- "react-dom": "^18.0.0 || ^19.0.0"
47
- },
48
- "dependencies": {
49
- "@ant-design/icons": "^6.3.4",
50
- "@codemirror/commands": "^6.11.0",
51
- "@codemirror/highlight": "^0.19.8",
52
- "@codemirror/lang-markdown": "^6.3.2",
53
- "@codemirror/language": "^6.12.4",
54
- "@codemirror/state": "^6.5.2",
55
- "@codemirror/theme-one-dark": "^6.1.2",
56
- "@codemirror/view": "^6.36.4",
57
- "@lezer/common": "^1.2.3",
58
- "@lezer/highlight": "^1.2.3",
59
- "antd": "^6.6.3",
60
- "codemirror": "^6.0.1",
61
- "highlight.js": "^11.12.0",
62
- "less": "^4.9.1",
63
- "markdown-it": "^14.1.0",
64
- "react": "^19.2.8",
65
- "react-dom": "^19.2.8",
66
- "remons-markdown-plugins": "^1.0.0-beta.3",
67
- "remons-render-markdown": "^2.0.1-beta.1"
68
- },
69
- "devDependencies": {
70
- "@types/markdown-it": "^14.1.2",
71
- "@types/node": "^24.13.3",
72
- "@types/react": "^19.2.18",
73
- "@types/react-dom": "^19.2.4",
74
- "@vitejs/plugin-react": "^6.1.0",
75
- "oxlint": "^1.79.0",
76
- "tsup": "^8.5.1",
77
- "typescript": "~6.0.2",
78
- "vite": "^8.2.2"
79
- },
80
- "license": "MIT"
81
- }
1
+ {
2
+ "name": "remons-markdown-editor",
3
+ "version": "1.0.0-beta.21",
4
+ "type": "module",
5
+ "description": "一个可复用的 React Markdown 编辑器组件,支持工具栏、预览和自定义容器",
6
+ "main": "dist/index.cjs",
7
+ "module": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "style": "dist/index.css",
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "https://github.com/liRemons/markdown-editor"
13
+ },
14
+ "homepage": "https://github.com/liRemons/markdown-editor#readme",
15
+ "sideEffects": [
16
+ "*.css"
17
+ ],
18
+ "files": [
19
+ "dist"
20
+ ],
21
+ "exports": {
22
+ ".": {
23
+ "import": {
24
+ "types": "./dist/index.d.ts",
25
+ "default": "./dist/index.js"
26
+ },
27
+ "require": {
28
+ "types": "./dist/index.d.cts",
29
+ "default": "./dist/index.cjs"
30
+ }
31
+ },
32
+ "./style.css": "./dist/index.css"
33
+ },
34
+ "scripts": {
35
+ "dev": "vite",
36
+ "build": "tsc -b && vite build",
37
+ "build:lib": "vite build --mode lib",
38
+ "lint": "oxlint",
39
+ "preview": "vite preview"
40
+ },
41
+ "publishConfig": {
42
+ "registry": "https://registry.npmjs.org/"
43
+ },
44
+ "dependencies": {
45
+ "@ant-design/icons": "^6.3.4",
46
+ "@codemirror/commands": "^6.11.0",
47
+ "@codemirror/highlight": "^0.19.8",
48
+ "@codemirror/lang-markdown": "^6.3.2",
49
+ "@codemirror/language": "^6.12.4",
50
+ "@codemirror/state": "^6.5.2",
51
+ "@codemirror/theme-one-dark": "^6.1.2",
52
+ "@codemirror/view": "^6.36.4",
53
+ "@lezer/common": "^1.2.3",
54
+ "@lezer/highlight": "^1.2.3",
55
+ "antd": "^6.6.3",
56
+ "codemirror": "^6.0.1",
57
+ "highlight.js": "^11.12.0",
58
+ "remons-markdown-plugins": "^1.0.0-beta.13",
59
+ "remons-render-markdown": "^1.0.28-beta.11"
60
+ },
61
+ "peerDependencies": {
62
+ "react": "^18.0.0",
63
+ "react-dom": "^18.0.0"
64
+ },
65
+ "devDependencies": {
66
+ "@types/node": "^24.13.3",
67
+ "@types/react": "^18.0.0",
68
+ "@types/react-dom": "^18.0.0",
69
+ "@vitejs/plugin-react": "^6.1.0",
70
+ "less": "^4.9.1",
71
+ "oxlint": "^1.79.0",
72
+ "typescript": "~6.0.2",
73
+ "vite": "^8.2.2",
74
+ "vite-plugin-dts": "^5.1.0"
75
+ },
76
+ "license": "MIT"
77
+ }