@coze-editor/react 0.1.0-alpha.dac011 → 0.1.0-alpha.e5f73a
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/esm/index.js +100 -10
- package/dist/esm/index.js.map +1 -1
- package/dist/index.d.mts +23 -4
- package/dist/index.d.ts +23 -4
- package/dist/index.js +105 -14
- package/dist/index.js.map +1 -1
- package/package.json +5 -4
package/dist/esm/index.js
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
// src/renderer.tsx
|
|
2
|
-
import
|
|
2
|
+
import React3, {
|
|
3
3
|
useEffect,
|
|
4
4
|
useRef as useRef2,
|
|
5
|
-
useState as
|
|
5
|
+
useState as useState3,
|
|
6
|
+
useMemo,
|
|
7
|
+
useLayoutEffect
|
|
6
8
|
} from "react";
|
|
9
|
+
import { FacetCombineStrategy } from "@coze-editor/utils";
|
|
7
10
|
import {
|
|
8
11
|
create
|
|
9
12
|
} from "@coze-editor/core";
|
|
13
|
+
import { Facet } from "@codemirror/state";
|
|
10
14
|
|
|
11
15
|
// src/provider.tsx
|
|
12
16
|
import React, {
|
|
@@ -41,37 +45,87 @@ function EditorProvider({ children }) {
|
|
|
41
45
|
return /* @__PURE__ */ React.createElement(InternalEditorContext.Provider, { value: editor }, /* @__PURE__ */ React.createElement(InternalSetEditorContext.Provider, { value: setEditor }, /* @__PURE__ */ React.createElement(InjectorContext.Provider, { value: injectorRef.current }, children)));
|
|
42
46
|
}
|
|
43
47
|
|
|
48
|
+
// src/connector.tsx
|
|
49
|
+
import React2, { useState as useState2, useCallback, Fragment } from "react";
|
|
50
|
+
function createPortalConnector() {
|
|
51
|
+
let add = (id, portal) => {
|
|
52
|
+
};
|
|
53
|
+
let remove = (id) => {
|
|
54
|
+
};
|
|
55
|
+
function connect(id, portal) {
|
|
56
|
+
add(id, portal);
|
|
57
|
+
}
|
|
58
|
+
function disconnect(id) {
|
|
59
|
+
remove(id);
|
|
60
|
+
}
|
|
61
|
+
function Portal() {
|
|
62
|
+
const [items, setItems] = useState2([]);
|
|
63
|
+
const addItem = useCallback((id, portal) => {
|
|
64
|
+
setItems((prevItems) => {
|
|
65
|
+
const nextItems = [...prevItems];
|
|
66
|
+
const index = nextItems.findIndex((item) => item.id === id);
|
|
67
|
+
if (index > -1) {
|
|
68
|
+
nextItems[index] = { id, portal };
|
|
69
|
+
} else {
|
|
70
|
+
nextItems.push({ id, portal });
|
|
71
|
+
}
|
|
72
|
+
return nextItems;
|
|
73
|
+
});
|
|
74
|
+
}, []);
|
|
75
|
+
const removeItem = useCallback((id) => {
|
|
76
|
+
setItems((items2) => items2.filter((item) => item.id !== id));
|
|
77
|
+
}, []);
|
|
78
|
+
add = addItem;
|
|
79
|
+
remove = removeItem;
|
|
80
|
+
return /* @__PURE__ */ React2.createElement(Fragment, null, items.map((item) => item.portal));
|
|
81
|
+
}
|
|
82
|
+
return {
|
|
83
|
+
connect,
|
|
84
|
+
disconnect,
|
|
85
|
+
Portal
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
44
89
|
// src/renderer.tsx
|
|
45
90
|
function firstLetterToUppercase(str) {
|
|
46
91
|
return str.charAt(0).toUpperCase() + str.substring(1);
|
|
47
92
|
}
|
|
93
|
+
var connector = Facet.define({
|
|
94
|
+
combine: FacetCombineStrategy.First
|
|
95
|
+
});
|
|
48
96
|
function Renderer(props) {
|
|
49
97
|
const {
|
|
50
98
|
plugins,
|
|
51
99
|
defaultValue,
|
|
100
|
+
root,
|
|
52
101
|
options,
|
|
53
102
|
domProps = {},
|
|
54
103
|
extensions,
|
|
55
104
|
didMount,
|
|
56
105
|
children
|
|
57
106
|
} = props;
|
|
58
|
-
const [api, setAPI] =
|
|
107
|
+
const [api, setAPI] = useState3();
|
|
59
108
|
const ref = useRef2(null);
|
|
60
109
|
const apiRef = useRef2(null);
|
|
61
110
|
const propsRef = useRef2(null);
|
|
62
111
|
const setEditor = useSetEditor();
|
|
63
112
|
const injector = useInjector();
|
|
113
|
+
const pc = useMemo(() => createPortalConnector(), []);
|
|
114
|
+
const connectorRef = useRef2(pc);
|
|
115
|
+
connectorRef.current = pc;
|
|
116
|
+
const { Portal } = pc;
|
|
64
117
|
propsRef.current = props;
|
|
65
|
-
|
|
118
|
+
useLayoutEffect(() => {
|
|
66
119
|
const { render, eventKeys } = create({
|
|
67
120
|
plugins,
|
|
68
121
|
injector
|
|
69
122
|
});
|
|
70
123
|
const exported = render({
|
|
71
124
|
parent: ref.current,
|
|
125
|
+
root,
|
|
72
126
|
defaultValue,
|
|
73
127
|
options: options ?? {},
|
|
74
|
-
extensions
|
|
128
|
+
extensions: [connector.of(connectorRef.current), ...extensions ?? []]
|
|
75
129
|
});
|
|
76
130
|
apiRef.current = exported;
|
|
77
131
|
eventKeys.forEach((eventName) => {
|
|
@@ -100,28 +154,64 @@ function Renderer(props) {
|
|
|
100
154
|
useEffect(() => {
|
|
101
155
|
apiRef.current.$set(props.options ?? {});
|
|
102
156
|
}, [props.options]);
|
|
103
|
-
return /* @__PURE__ */
|
|
157
|
+
return /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement("div", { ...domProps, ref }), children, /* @__PURE__ */ React3.createElement(Portal, null));
|
|
104
158
|
}
|
|
105
159
|
|
|
106
160
|
// src/create-renderer.tsx
|
|
107
|
-
import
|
|
161
|
+
import React4, { useMemo as useMemo2 } from "react";
|
|
108
162
|
var OriginRenderer = Renderer;
|
|
109
|
-
function createRenderer(plugins,
|
|
163
|
+
function createRenderer(plugins, options) {
|
|
164
|
+
let builtinExtensions = [];
|
|
165
|
+
let defaultOptions = {};
|
|
166
|
+
if (Array.isArray(options)) {
|
|
167
|
+
builtinExtensions = options;
|
|
168
|
+
} else if (options && typeof options === "object") {
|
|
169
|
+
defaultOptions = options.defaultOptions ?? {};
|
|
170
|
+
}
|
|
110
171
|
return function CustomRenderer(props) {
|
|
111
172
|
const userExtensions = props.extensions;
|
|
112
|
-
const extensions =
|
|
173
|
+
const extensions = useMemo2(
|
|
113
174
|
() => [...builtinExtensions ?? [], ...userExtensions ?? []],
|
|
114
175
|
[userExtensions]
|
|
115
176
|
);
|
|
116
|
-
return /* @__PURE__ */
|
|
177
|
+
return /* @__PURE__ */ React4.createElement(
|
|
178
|
+
OriginRenderer,
|
|
179
|
+
{
|
|
180
|
+
...props,
|
|
181
|
+
options: {
|
|
182
|
+
...defaultOptions,
|
|
183
|
+
...props.options ?? {}
|
|
184
|
+
},
|
|
185
|
+
extensions,
|
|
186
|
+
plugins
|
|
187
|
+
}
|
|
188
|
+
);
|
|
189
|
+
};
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
// src/editor.tsx
|
|
193
|
+
import React5 from "react";
|
|
194
|
+
function Editor(props) {
|
|
195
|
+
return /* @__PURE__ */ React5.createElement(EditorProvider, null, /* @__PURE__ */ React5.createElement(Renderer, { ...props }));
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// src/create-editor.tsx
|
|
199
|
+
import React6 from "react";
|
|
200
|
+
function createEditor(plugins, options) {
|
|
201
|
+
const CustomRenderer = createRenderer(plugins, options);
|
|
202
|
+
return function CustomEditor(props) {
|
|
203
|
+
return /* @__PURE__ */ React6.createElement(EditorProvider, null, /* @__PURE__ */ React6.createElement(CustomRenderer, { ...props }));
|
|
117
204
|
};
|
|
118
205
|
}
|
|
119
206
|
|
|
120
207
|
// src/index.ts
|
|
121
208
|
export * from "@coze-editor/core";
|
|
122
209
|
export {
|
|
210
|
+
Editor,
|
|
123
211
|
EditorProvider,
|
|
124
212
|
Renderer,
|
|
213
|
+
connector,
|
|
214
|
+
createEditor,
|
|
125
215
|
createRenderer,
|
|
126
216
|
useEditor,
|
|
127
217
|
useInjector
|
package/dist/esm/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/renderer.tsx","../../src/provider.tsx","../../src/create-renderer.tsx","../../src/index.ts"],"sourcesContent":["// Copyright (c) 2025 coze-dev\n// SPDX-License-Identifier: MIT\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport React, {\n type CSSProperties,\n useEffect,\n useRef,\n useState,\n type ReactNode,\n} from 'react';\n\nimport {\n type EditorPluginSpec,\n type InferEditorAPIFromPlugins,\n type InferEvents,\n type InferValues,\n create,\n} from '@coze-editor/core';\nimport { type Extension } from '@codemirror/state';\n\nimport { useInjector, useSetEditor } from './provider';\n\ntype UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (\n k: infer I,\n) => void\n ? I\n : never;\n\ntype InferReactEvents<T extends Record<string, any>> = UnionToIntersection<{\n [K in keyof T as `on${Capitalize<string & K>}`]?: (e: T[K]) => void;\n}>;\n\nfunction firstLetterToUppercase(str: string) {\n return str.charAt(0).toUpperCase() + str.substring(1);\n}\n\ntype InferRendererProps<T extends EditorPluginSpec<string, any, any>[]> = {\n domProps?: {\n style?: CSSProperties;\n className?: string;\n };\n defaultValue?: string;\n options?: Partial<InferValues<T[number]>>;\n extensions?: Extension[];\n didMount?: (api: InferEditorAPIFromPlugins<T>) => void;\n children?: ReactNode;\n} & (InferEvents<T[number]> extends Record<string, any>\n ? InferReactEvents<InferEvents<T[number]>>\n : unknown);\n\nfunction Renderer<T extends EditorPluginSpec<string, any, any>[]>(\n props: { plugins: T } & InferRendererProps<T>,\n) {\n const {\n plugins,\n defaultValue,\n options,\n domProps = {},\n extensions,\n didMount,\n children,\n } = props;\n\n const [api, setAPI] = useState<any>();\n const ref = useRef(null);\n const apiRef = useRef<any>(null);\n const propsRef = useRef<typeof props | null>(null);\n const setEditor = useSetEditor();\n const injector = useInjector();\n\n propsRef.current = props;\n\n useEffect(() => {\n const { render, eventKeys } = create({\n plugins,\n injector,\n });\n\n const exported = render({\n parent: ref.current!,\n defaultValue,\n options: options ?? {},\n extensions,\n });\n\n apiRef.current = exported;\n\n eventKeys.forEach((eventName: any) => {\n exported.$on(eventName, e => {\n const handler = (propsRef.current as any)?.[\n `on${firstLetterToUppercase(eventName)}`\n ];\n if (typeof handler === 'function') {\n handler(e);\n }\n });\n });\n\n if (typeof didMount === 'function') {\n didMount(exported);\n }\n\n setAPI(exported);\n\n return () => {\n exported.$destroy();\n };\n }, []);\n\n useEffect(() => {\n if (!api || !setEditor) {\n return;\n }\n\n setEditor(api);\n }, [api, setEditor]);\n\n useEffect(() => {\n apiRef.current.$set(props.options ?? {});\n }, [props.options]);\n\n return (\n <>\n <div {...domProps} ref={ref} />\n {children}\n </>\n );\n}\n\nexport { Renderer };\n\nexport type { InferRendererProps };\n","// Copyright (c) 2025 coze-dev\n// SPDX-License-Identifier: MIT\n\nimport React, {\n type Dispatch,\n type ReactNode,\n createContext,\n useContext,\n useRef,\n useState,\n} from 'react';\n\nimport { type Injector, createInjector } from '@coze-editor/core';\n\nconst InternalEditorContext = createContext<unknown>(null);\nconst InternalSetEditorContext = createContext<Dispatch<any> | null>(null);\nconst InjectorContext = createContext<Injector | undefined>(undefined);\n\nfunction useEditor<T>(): T {\n return useContext(InternalEditorContext) as T;\n}\n\nfunction useSetEditor(): Dispatch<any> | null {\n return useContext(InternalSetEditorContext);\n}\n\nfunction useInjector(): Injector {\n const injector = useContext(InjectorContext);\n\n if (!injector) {\n throw new Error('useInjector should be used in EditorProvider');\n }\n\n return injector;\n}\n\nfunction EditorProvider({ children }: { children?: ReactNode }) {\n const [editor, setEditor] = useState(null);\n const injectorRef = useRef<Injector | null>(null);\n\n if (!injectorRef.current) {\n injectorRef.current = createInjector();\n }\n\n return (\n <InternalEditorContext.Provider value={editor}>\n <InternalSetEditorContext.Provider value={setEditor}>\n <InjectorContext.Provider value={injectorRef.current}>\n {children}\n </InjectorContext.Provider>\n </InternalSetEditorContext.Provider>\n </InternalEditorContext.Provider>\n );\n}\n\nexport { EditorProvider, useEditor, useSetEditor, useInjector };\n","// Copyright (c) 2025 coze-dev\n// SPDX-License-Identifier: MIT\n\nimport React, { useMemo } from 'react';\n\nimport { type EditorPluginSpec } from '@coze-editor/core';\nimport { type Extension } from '@codemirror/state';\n\nimport { Renderer, type InferRendererProps } from './renderer';\n\nconst OriginRenderer: (props: any) => JSX.Element = Renderer;\n\nfunction createRenderer<T extends EditorPluginSpec<string, any, any>[]>(\n plugins: T,\n builtinExtensions?: Extension[],\n) {\n return function CustomRenderer(props: InferRendererProps<T>) {\n const userExtensions = props.extensions;\n\n const extensions: Extension[] = useMemo(\n () => [...(builtinExtensions ?? []), ...(userExtensions ?? [])],\n [userExtensions],\n );\n\n return (\n <OriginRenderer {...props} extensions={extensions} plugins={plugins} />\n );\n };\n}\n\nexport { createRenderer };\n","// Copyright (c) 2025 coze-dev\n// SPDX-License-Identifier: MIT\n\nexport { Renderer, type InferRendererProps } from './renderer';\n\nexport { createRenderer } from './create-renderer';\n\nexport { EditorProvider, useEditor, useInjector } from './provider';\n\nexport * from '@coze-editor/core';\n"],"mappings":"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","names":["React","useRef","useState","useState","useRef","React","React","React"]}
|
|
1
|
+
{"version":3,"sources":["../../src/renderer.tsx","../../src/provider.tsx","../../src/connector.tsx","../../src/create-renderer.tsx","../../src/editor.tsx","../../src/create-editor.tsx","../../src/index.ts"],"sourcesContent":["// Copyright (c) 2025 coze-dev\n// SPDX-License-Identifier: MIT\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport React, {\n type CSSProperties,\n useEffect,\n useRef,\n useState,\n type ReactNode,\n useMemo,\n useLayoutEffect,\n} from 'react';\n\nimport { FacetCombineStrategy } from '@coze-editor/utils';\nimport {\n type EditorPluginSpec,\n type InferEditorAPIFromPlugins,\n type InferEvents,\n type InferValues,\n create,\n} from '@coze-editor/core';\nimport { Facet, type Extension } from '@codemirror/state';\n\nimport { useInjector, useSetEditor } from './provider';\nimport { type Connector, createPortalConnector } from './connector';\n\ntype UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (\n k: infer I,\n) => void\n ? I\n : never;\n\ntype InferReactEvents<T extends Record<string, any>> = UnionToIntersection<{\n [K in keyof T as `on${Capitalize<string & K>}`]?: (e: T[K]) => void;\n}>;\n\nfunction firstLetterToUppercase(str: string) {\n return str.charAt(0).toUpperCase() + str.substring(1);\n}\n\ntype InferRendererProps<T extends EditorPluginSpec<string, any, any>[]> = {\n domProps?: {\n style?: CSSProperties;\n className?: string;\n };\n defaultValue?: string;\n root?: Document | ShadowRoot;\n options?: Partial<InferValues<T[number]>>;\n extensions?: Extension[];\n didMount?: (api: InferEditorAPIFromPlugins<T>) => void;\n children?: ReactNode;\n} & (InferEvents<T[number]> extends Record<string, any>\n ? InferReactEvents<InferEvents<T[number]>>\n : unknown);\n\nconst connector = Facet.define<Connector, Connector>({\n combine: FacetCombineStrategy.First,\n});\n\nfunction Renderer<T extends EditorPluginSpec<string, any, any>[]>(\n props: { plugins: T } & InferRendererProps<T>,\n) {\n const {\n plugins,\n defaultValue,\n root,\n options,\n domProps = {},\n extensions,\n didMount,\n children,\n } = props;\n\n const [api, setAPI] = useState<any>();\n const ref = useRef(null);\n const apiRef = useRef<any>(null);\n const propsRef = useRef<typeof props | null>(null);\n const setEditor = useSetEditor();\n const injector = useInjector();\n\n const pc = useMemo(() => createPortalConnector(), []);\n const connectorRef = useRef<Connector>(pc);\n connectorRef.current = pc;\n const { Portal } = pc;\n\n propsRef.current = props;\n\n useLayoutEffect(() => {\n const { render, eventKeys } = create({\n plugins,\n injector,\n });\n\n const exported = render({\n parent: ref.current!,\n root,\n defaultValue,\n options: options ?? {},\n extensions: [connector.of(connectorRef.current), ...(extensions ?? [])],\n });\n\n apiRef.current = exported;\n\n eventKeys.forEach((eventName: any) => {\n exported.$on(eventName, e => {\n const handler = (propsRef.current as any)?.[\n `on${firstLetterToUppercase(eventName)}`\n ];\n if (typeof handler === 'function') {\n handler(e);\n }\n });\n });\n\n if (typeof didMount === 'function') {\n didMount(exported);\n }\n\n setAPI(exported);\n\n return () => {\n exported.$destroy();\n };\n }, []);\n\n useEffect(() => {\n if (!api || !setEditor) {\n return;\n }\n\n setEditor(api);\n }, [api, setEditor]);\n\n useEffect(() => {\n apiRef.current.$set(props.options ?? {});\n }, [props.options]);\n\n return (\n <>\n <div {...domProps} ref={ref} />\n {children}\n <Portal />\n </>\n );\n}\n\nexport { Renderer, connector };\n\nexport type { InferRendererProps };\n","// Copyright (c) 2025 coze-dev\n// SPDX-License-Identifier: MIT\n\nimport React, {\n type Dispatch,\n type ReactNode,\n createContext,\n useContext,\n useRef,\n useState,\n} from 'react';\n\nimport { type Injector, createInjector } from '@coze-editor/core';\n\nconst InternalEditorContext = createContext<unknown>(null);\nconst InternalSetEditorContext = createContext<Dispatch<any> | null>(null);\nconst InjectorContext = createContext<Injector | undefined>(undefined);\n\nfunction useEditor<T>(): T {\n return useContext(InternalEditorContext) as T;\n}\n\nfunction useSetEditor(): Dispatch<any> | null {\n return useContext(InternalSetEditorContext);\n}\n\nfunction useInjector(): Injector {\n const injector = useContext(InjectorContext);\n\n if (!injector) {\n throw new Error('useInjector should be used in EditorProvider');\n }\n\n return injector;\n}\n\nfunction EditorProvider({ children }: { children?: ReactNode }) {\n const [editor, setEditor] = useState(null);\n const injectorRef = useRef<Injector | null>(null);\n\n if (!injectorRef.current) {\n injectorRef.current = createInjector();\n }\n\n return (\n <InternalEditorContext.Provider value={editor}>\n <InternalSetEditorContext.Provider value={setEditor}>\n <InjectorContext.Provider value={injectorRef.current}>\n {children}\n </InjectorContext.Provider>\n </InternalSetEditorContext.Provider>\n </InternalEditorContext.Provider>\n );\n}\n\nexport { EditorProvider, useEditor, useSetEditor, useInjector };\n","import React, { useState, useCallback, Fragment } from 'react';\nimport type { ReactPortal } from 'react';\n\ntype PortalItem = {\n id: string;\n portal: ReactPortal;\n};\n\nfunction createPortalConnector() {\n let add = (id: string, portal: ReactPortal) => {};\n let remove = (id: string) => {};\n\n function connect(id: string, portal: ReactPortal) {\n add(id, portal);\n }\n\n function disconnect(id: string) {\n remove(id);\n }\n\n function Portal() {\n const [items, setItems] = useState<PortalItem[]>([]);\n\n const addItem = useCallback((id: string, portal: ReactPortal) => {\n setItems(prevItems => {\n const nextItems = [...prevItems];\n const index = nextItems.findIndex(item => item.id === id);\n if (index > -1) {\n nextItems[index] = { id, portal };\n } else {\n nextItems.push({ id, portal });\n }\n return nextItems;\n });\n }, []);\n const removeItem = useCallback((id: string) => {\n setItems(items => items.filter(item => item.id !== id));\n }, []);\n\n add = addItem;\n remove = removeItem;\n\n return <Fragment>{items.map(item => item.portal)}</Fragment>;\n }\n\n return {\n connect,\n disconnect,\n Portal,\n };\n}\n\ntype Connector = ReturnType<typeof createPortalConnector>;\n\nexport { createPortalConnector };\nexport type { Connector };\n","// Copyright (c) 2025 coze-dev\n// SPDX-License-Identifier: MIT\n\nimport React, { useMemo } from 'react';\n\nimport { type EditorPluginSpec } from '@coze-editor/core';\nimport { type Extension } from '@codemirror/state';\n\nimport { Renderer, type InferRendererProps } from './renderer';\n\nconst OriginRenderer: (props: any) => JSX.Element = Renderer;\n\ninterface CreateRendererOptions<T> {\n defaultOptions?: T;\n}\n\nfunction createRenderer<\n T extends EditorPluginSpec<string, any, any>[],\n U extends InferRendererProps<T> = InferRendererProps<T>,\n>(plugins: T, options?: Extension[] | CreateRendererOptions<U['options']>) {\n let builtinExtensions: Extension[] = [];\n let defaultOptions = {};\n\n // 兼容历史类型\n if (Array.isArray(options)) {\n builtinExtensions = options;\n } else if (options && typeof options === 'object') {\n defaultOptions = options.defaultOptions ?? {};\n }\n\n return function CustomRenderer(props: InferRendererProps<T>) {\n const userExtensions = props.extensions;\n\n const extensions: Extension[] = useMemo(\n () => [...(builtinExtensions ?? []), ...(userExtensions ?? [])],\n [userExtensions],\n );\n\n return (\n <OriginRenderer\n {...props}\n options={{\n ...defaultOptions,\n ...(props.options ?? {}),\n }}\n extensions={extensions}\n plugins={plugins}\n />\n );\n };\n}\n\nexport { createRenderer };\nexport type { CreateRendererOptions };\n","import React from 'react';\n\nimport { type EditorPluginSpec } from '@coze-editor/core';\n\nimport { type InferRendererProps, Renderer } from './renderer';\nimport { EditorProvider } from './provider';\n\nfunction Editor<T extends EditorPluginSpec<string, any, any>[]>(\n props: { plugins: T } & InferRendererProps<T>,\n) {\n return (\n <EditorProvider>\n <Renderer {...props} />\n </EditorProvider>\n );\n}\n\nexport { Editor };\n","import React from 'react';\n\nimport { type EditorPluginSpec } from '@coze-editor/core';\n\nimport { type InferRendererProps } from './renderer';\nimport { EditorProvider } from './provider';\nimport { createRenderer, type CreateRendererOptions } from './create-renderer';\n\nfunction createEditor<\n T extends EditorPluginSpec<string, any, any>[],\n U extends InferRendererProps<T> = InferRendererProps<T>,\n>(plugins: T, options?: CreateRendererOptions<U['options']>) {\n const CustomRenderer = createRenderer(plugins, options);\n\n return function CustomEditor(props: InferRendererProps<T>) {\n return (\n <EditorProvider>\n <CustomRenderer {...props} />\n </EditorProvider>\n );\n };\n}\n\nexport { createEditor };\n","// Copyright (c) 2025 coze-dev\n// SPDX-License-Identifier: MIT\n\nexport { Renderer, connector, type InferRendererProps } from './renderer';\n\nexport { createRenderer, type CreateRendererOptions } from './create-renderer';\n\nexport { EditorProvider, useEditor, useInjector } from './provider';\n\nexport { Editor } from './editor';\n\nexport { createEditor } from './create-editor';\n\nexport * from '@coze-editor/core';\n"],"mappings":"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","names":["React","useRef","useState","React","useState","items","useState","useRef","React","React","useMemo","useMemo","React","React","React","React","React"]}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { CSSProperties, ReactNode } from 'react';
|
|
2
|
+
import React, { CSSProperties, ReactNode } from 'react';
|
|
3
3
|
import { EditorPluginSpec, InferValues, InferEditorAPIFromPlugins, InferEvents, Injector } from '@coze-editor/core';
|
|
4
4
|
export * from '@coze-editor/core';
|
|
5
|
-
import { Extension } from '@codemirror/state';
|
|
5
|
+
import { Extension, Facet } from '@codemirror/state';
|
|
6
6
|
|
|
7
7
|
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
|
|
8
8
|
type InferReactEvents<T extends Record<string, any>> = UnionToIntersection<{
|
|
@@ -14,16 +14,29 @@ type InferRendererProps<T extends EditorPluginSpec<string, any, any>[]> = {
|
|
|
14
14
|
className?: string;
|
|
15
15
|
};
|
|
16
16
|
defaultValue?: string;
|
|
17
|
+
root?: Document | ShadowRoot;
|
|
17
18
|
options?: Partial<InferValues<T[number]>>;
|
|
18
19
|
extensions?: Extension[];
|
|
19
20
|
didMount?: (api: InferEditorAPIFromPlugins<T>) => void;
|
|
20
21
|
children?: ReactNode;
|
|
21
22
|
} & (InferEvents<T[number]> extends Record<string, any> ? InferReactEvents<InferEvents<T[number]>> : unknown);
|
|
23
|
+
declare const connector: Facet<{
|
|
24
|
+
connect: (id: string, portal: React.ReactPortal) => void;
|
|
25
|
+
disconnect: (id: string) => void;
|
|
26
|
+
Portal: () => react_jsx_runtime.JSX.Element;
|
|
27
|
+
}, {
|
|
28
|
+
connect: (id: string, portal: React.ReactPortal) => void;
|
|
29
|
+
disconnect: (id: string) => void;
|
|
30
|
+
Portal: () => react_jsx_runtime.JSX.Element;
|
|
31
|
+
}>;
|
|
22
32
|
declare function Renderer<T extends EditorPluginSpec<string, any, any>[]>(props: {
|
|
23
33
|
plugins: T;
|
|
24
34
|
} & InferRendererProps<T>): react_jsx_runtime.JSX.Element;
|
|
25
35
|
|
|
26
|
-
|
|
36
|
+
interface CreateRendererOptions<T> {
|
|
37
|
+
defaultOptions?: T;
|
|
38
|
+
}
|
|
39
|
+
declare function createRenderer<T extends EditorPluginSpec<string, any, any>[], U extends InferRendererProps<T> = InferRendererProps<T>>(plugins: T, options?: Extension[] | CreateRendererOptions<U['options']>): (props: InferRendererProps<T>) => react_jsx_runtime.JSX.Element;
|
|
27
40
|
|
|
28
41
|
declare function useEditor<T>(): T;
|
|
29
42
|
declare function useInjector(): Injector;
|
|
@@ -31,4 +44,10 @@ declare function EditorProvider({ children }: {
|
|
|
31
44
|
children?: ReactNode;
|
|
32
45
|
}): react_jsx_runtime.JSX.Element;
|
|
33
46
|
|
|
34
|
-
|
|
47
|
+
declare function Editor<T extends EditorPluginSpec<string, any, any>[]>(props: {
|
|
48
|
+
plugins: T;
|
|
49
|
+
} & InferRendererProps<T>): react_jsx_runtime.JSX.Element;
|
|
50
|
+
|
|
51
|
+
declare function createEditor<T extends EditorPluginSpec<string, any, any>[], U extends InferRendererProps<T> = InferRendererProps<T>>(plugins: T, options?: CreateRendererOptions<U['options']>): (props: InferRendererProps<T>) => react_jsx_runtime.JSX.Element;
|
|
52
|
+
|
|
53
|
+
export { type CreateRendererOptions, Editor, EditorProvider, type InferRendererProps, Renderer, connector, createEditor, createRenderer, useEditor, useInjector };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { CSSProperties, ReactNode } from 'react';
|
|
2
|
+
import React, { CSSProperties, ReactNode } from 'react';
|
|
3
3
|
import { EditorPluginSpec, InferValues, InferEditorAPIFromPlugins, InferEvents, Injector } from '@coze-editor/core';
|
|
4
4
|
export * from '@coze-editor/core';
|
|
5
|
-
import { Extension } from '@codemirror/state';
|
|
5
|
+
import { Extension, Facet } from '@codemirror/state';
|
|
6
6
|
|
|
7
7
|
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (k: infer I) => void ? I : never;
|
|
8
8
|
type InferReactEvents<T extends Record<string, any>> = UnionToIntersection<{
|
|
@@ -14,16 +14,29 @@ type InferRendererProps<T extends EditorPluginSpec<string, any, any>[]> = {
|
|
|
14
14
|
className?: string;
|
|
15
15
|
};
|
|
16
16
|
defaultValue?: string;
|
|
17
|
+
root?: Document | ShadowRoot;
|
|
17
18
|
options?: Partial<InferValues<T[number]>>;
|
|
18
19
|
extensions?: Extension[];
|
|
19
20
|
didMount?: (api: InferEditorAPIFromPlugins<T>) => void;
|
|
20
21
|
children?: ReactNode;
|
|
21
22
|
} & (InferEvents<T[number]> extends Record<string, any> ? InferReactEvents<InferEvents<T[number]>> : unknown);
|
|
23
|
+
declare const connector: Facet<{
|
|
24
|
+
connect: (id: string, portal: React.ReactPortal) => void;
|
|
25
|
+
disconnect: (id: string) => void;
|
|
26
|
+
Portal: () => react_jsx_runtime.JSX.Element;
|
|
27
|
+
}, {
|
|
28
|
+
connect: (id: string, portal: React.ReactPortal) => void;
|
|
29
|
+
disconnect: (id: string) => void;
|
|
30
|
+
Portal: () => react_jsx_runtime.JSX.Element;
|
|
31
|
+
}>;
|
|
22
32
|
declare function Renderer<T extends EditorPluginSpec<string, any, any>[]>(props: {
|
|
23
33
|
plugins: T;
|
|
24
34
|
} & InferRendererProps<T>): react_jsx_runtime.JSX.Element;
|
|
25
35
|
|
|
26
|
-
|
|
36
|
+
interface CreateRendererOptions<T> {
|
|
37
|
+
defaultOptions?: T;
|
|
38
|
+
}
|
|
39
|
+
declare function createRenderer<T extends EditorPluginSpec<string, any, any>[], U extends InferRendererProps<T> = InferRendererProps<T>>(plugins: T, options?: Extension[] | CreateRendererOptions<U['options']>): (props: InferRendererProps<T>) => react_jsx_runtime.JSX.Element;
|
|
27
40
|
|
|
28
41
|
declare function useEditor<T>(): T;
|
|
29
42
|
declare function useInjector(): Injector;
|
|
@@ -31,4 +44,10 @@ declare function EditorProvider({ children }: {
|
|
|
31
44
|
children?: ReactNode;
|
|
32
45
|
}): react_jsx_runtime.JSX.Element;
|
|
33
46
|
|
|
34
|
-
|
|
47
|
+
declare function Editor<T extends EditorPluginSpec<string, any, any>[]>(props: {
|
|
48
|
+
plugins: T;
|
|
49
|
+
} & InferRendererProps<T>): react_jsx_runtime.JSX.Element;
|
|
50
|
+
|
|
51
|
+
declare function createEditor<T extends EditorPluginSpec<string, any, any>[], U extends InferRendererProps<T> = InferRendererProps<T>>(plugins: T, options?: CreateRendererOptions<U['options']>): (props: InferRendererProps<T>) => react_jsx_runtime.JSX.Element;
|
|
52
|
+
|
|
53
|
+
export { type CreateRendererOptions, Editor, EditorProvider, type InferRendererProps, Renderer, connector, createEditor, createRenderer, useEditor, useInjector };
|
package/dist/index.js
CHANGED
|
@@ -30,8 +30,11 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
30
30
|
// src/index.ts
|
|
31
31
|
var index_exports = {};
|
|
32
32
|
__export(index_exports, {
|
|
33
|
+
Editor: () => Editor,
|
|
33
34
|
EditorProvider: () => EditorProvider,
|
|
34
35
|
Renderer: () => Renderer,
|
|
36
|
+
connector: () => connector,
|
|
37
|
+
createEditor: () => createEditor,
|
|
35
38
|
createRenderer: () => createRenderer,
|
|
36
39
|
useEditor: () => useEditor,
|
|
37
40
|
useInjector: () => useInjector
|
|
@@ -39,8 +42,10 @@ __export(index_exports, {
|
|
|
39
42
|
module.exports = __toCommonJS(index_exports);
|
|
40
43
|
|
|
41
44
|
// src/renderer.tsx
|
|
42
|
-
var
|
|
45
|
+
var import_react3 = __toESM(require("react"));
|
|
46
|
+
var import_utils = require("@coze-editor/utils");
|
|
43
47
|
var import_core2 = require("@coze-editor/core");
|
|
48
|
+
var import_state = require("@codemirror/state");
|
|
44
49
|
|
|
45
50
|
// src/provider.tsx
|
|
46
51
|
var import_react = __toESM(require("react"));
|
|
@@ -70,37 +75,87 @@ function EditorProvider({ children }) {
|
|
|
70
75
|
return /* @__PURE__ */ import_react.default.createElement(InternalEditorContext.Provider, { value: editor }, /* @__PURE__ */ import_react.default.createElement(InternalSetEditorContext.Provider, { value: setEditor }, /* @__PURE__ */ import_react.default.createElement(InjectorContext.Provider, { value: injectorRef.current }, children)));
|
|
71
76
|
}
|
|
72
77
|
|
|
78
|
+
// src/connector.tsx
|
|
79
|
+
var import_react2 = __toESM(require("react"));
|
|
80
|
+
function createPortalConnector() {
|
|
81
|
+
let add = (id, portal) => {
|
|
82
|
+
};
|
|
83
|
+
let remove = (id) => {
|
|
84
|
+
};
|
|
85
|
+
function connect(id, portal) {
|
|
86
|
+
add(id, portal);
|
|
87
|
+
}
|
|
88
|
+
function disconnect(id) {
|
|
89
|
+
remove(id);
|
|
90
|
+
}
|
|
91
|
+
function Portal() {
|
|
92
|
+
const [items, setItems] = (0, import_react2.useState)([]);
|
|
93
|
+
const addItem = (0, import_react2.useCallback)((id, portal) => {
|
|
94
|
+
setItems((prevItems) => {
|
|
95
|
+
const nextItems = [...prevItems];
|
|
96
|
+
const index = nextItems.findIndex((item) => item.id === id);
|
|
97
|
+
if (index > -1) {
|
|
98
|
+
nextItems[index] = { id, portal };
|
|
99
|
+
} else {
|
|
100
|
+
nextItems.push({ id, portal });
|
|
101
|
+
}
|
|
102
|
+
return nextItems;
|
|
103
|
+
});
|
|
104
|
+
}, []);
|
|
105
|
+
const removeItem = (0, import_react2.useCallback)((id) => {
|
|
106
|
+
setItems((items2) => items2.filter((item) => item.id !== id));
|
|
107
|
+
}, []);
|
|
108
|
+
add = addItem;
|
|
109
|
+
remove = removeItem;
|
|
110
|
+
return /* @__PURE__ */ import_react2.default.createElement(import_react2.Fragment, null, items.map((item) => item.portal));
|
|
111
|
+
}
|
|
112
|
+
return {
|
|
113
|
+
connect,
|
|
114
|
+
disconnect,
|
|
115
|
+
Portal
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
|
|
73
119
|
// src/renderer.tsx
|
|
74
120
|
function firstLetterToUppercase(str) {
|
|
75
121
|
return str.charAt(0).toUpperCase() + str.substring(1);
|
|
76
122
|
}
|
|
123
|
+
var connector = import_state.Facet.define({
|
|
124
|
+
combine: import_utils.FacetCombineStrategy.First
|
|
125
|
+
});
|
|
77
126
|
function Renderer(props) {
|
|
78
127
|
const {
|
|
79
128
|
plugins,
|
|
80
129
|
defaultValue,
|
|
130
|
+
root,
|
|
81
131
|
options,
|
|
82
132
|
domProps = {},
|
|
83
133
|
extensions,
|
|
84
134
|
didMount,
|
|
85
135
|
children
|
|
86
136
|
} = props;
|
|
87
|
-
const [api, setAPI] = (0,
|
|
88
|
-
const ref = (0,
|
|
89
|
-
const apiRef = (0,
|
|
90
|
-
const propsRef = (0,
|
|
137
|
+
const [api, setAPI] = (0, import_react3.useState)();
|
|
138
|
+
const ref = (0, import_react3.useRef)(null);
|
|
139
|
+
const apiRef = (0, import_react3.useRef)(null);
|
|
140
|
+
const propsRef = (0, import_react3.useRef)(null);
|
|
91
141
|
const setEditor = useSetEditor();
|
|
92
142
|
const injector = useInjector();
|
|
143
|
+
const pc = (0, import_react3.useMemo)(() => createPortalConnector(), []);
|
|
144
|
+
const connectorRef = (0, import_react3.useRef)(pc);
|
|
145
|
+
connectorRef.current = pc;
|
|
146
|
+
const { Portal } = pc;
|
|
93
147
|
propsRef.current = props;
|
|
94
|
-
(0,
|
|
148
|
+
(0, import_react3.useLayoutEffect)(() => {
|
|
95
149
|
const { render, eventKeys } = (0, import_core2.create)({
|
|
96
150
|
plugins,
|
|
97
151
|
injector
|
|
98
152
|
});
|
|
99
153
|
const exported = render({
|
|
100
154
|
parent: ref.current,
|
|
155
|
+
root,
|
|
101
156
|
defaultValue,
|
|
102
157
|
options: options ?? {},
|
|
103
|
-
extensions
|
|
158
|
+
extensions: [connector.of(connectorRef.current), ...extensions ?? []]
|
|
104
159
|
});
|
|
105
160
|
apiRef.current = exported;
|
|
106
161
|
eventKeys.forEach((eventName) => {
|
|
@@ -120,29 +175,62 @@ function Renderer(props) {
|
|
|
120
175
|
exported.$destroy();
|
|
121
176
|
};
|
|
122
177
|
}, []);
|
|
123
|
-
(0,
|
|
178
|
+
(0, import_react3.useEffect)(() => {
|
|
124
179
|
if (!api || !setEditor) {
|
|
125
180
|
return;
|
|
126
181
|
}
|
|
127
182
|
setEditor(api);
|
|
128
183
|
}, [api, setEditor]);
|
|
129
|
-
(0,
|
|
184
|
+
(0, import_react3.useEffect)(() => {
|
|
130
185
|
apiRef.current.$set(props.options ?? {});
|
|
131
186
|
}, [props.options]);
|
|
132
|
-
return /* @__PURE__ */
|
|
187
|
+
return /* @__PURE__ */ import_react3.default.createElement(import_react3.default.Fragment, null, /* @__PURE__ */ import_react3.default.createElement("div", { ...domProps, ref }), children, /* @__PURE__ */ import_react3.default.createElement(Portal, null));
|
|
133
188
|
}
|
|
134
189
|
|
|
135
190
|
// src/create-renderer.tsx
|
|
136
|
-
var
|
|
191
|
+
var import_react4 = __toESM(require("react"));
|
|
137
192
|
var OriginRenderer = Renderer;
|
|
138
|
-
function createRenderer(plugins,
|
|
193
|
+
function createRenderer(plugins, options) {
|
|
194
|
+
let builtinExtensions = [];
|
|
195
|
+
let defaultOptions = {};
|
|
196
|
+
if (Array.isArray(options)) {
|
|
197
|
+
builtinExtensions = options;
|
|
198
|
+
} else if (options && typeof options === "object") {
|
|
199
|
+
defaultOptions = options.defaultOptions ?? {};
|
|
200
|
+
}
|
|
139
201
|
return function CustomRenderer(props) {
|
|
140
202
|
const userExtensions = props.extensions;
|
|
141
|
-
const extensions = (0,
|
|
203
|
+
const extensions = (0, import_react4.useMemo)(
|
|
142
204
|
() => [...builtinExtensions ?? [], ...userExtensions ?? []],
|
|
143
205
|
[userExtensions]
|
|
144
206
|
);
|
|
145
|
-
return /* @__PURE__ */
|
|
207
|
+
return /* @__PURE__ */ import_react4.default.createElement(
|
|
208
|
+
OriginRenderer,
|
|
209
|
+
{
|
|
210
|
+
...props,
|
|
211
|
+
options: {
|
|
212
|
+
...defaultOptions,
|
|
213
|
+
...props.options ?? {}
|
|
214
|
+
},
|
|
215
|
+
extensions,
|
|
216
|
+
plugins
|
|
217
|
+
}
|
|
218
|
+
);
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// src/editor.tsx
|
|
223
|
+
var import_react5 = __toESM(require("react"));
|
|
224
|
+
function Editor(props) {
|
|
225
|
+
return /* @__PURE__ */ import_react5.default.createElement(EditorProvider, null, /* @__PURE__ */ import_react5.default.createElement(Renderer, { ...props }));
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// src/create-editor.tsx
|
|
229
|
+
var import_react6 = __toESM(require("react"));
|
|
230
|
+
function createEditor(plugins, options) {
|
|
231
|
+
const CustomRenderer = createRenderer(plugins, options);
|
|
232
|
+
return function CustomEditor(props) {
|
|
233
|
+
return /* @__PURE__ */ import_react6.default.createElement(EditorProvider, null, /* @__PURE__ */ import_react6.default.createElement(CustomRenderer, { ...props }));
|
|
146
234
|
};
|
|
147
235
|
}
|
|
148
236
|
|
|
@@ -150,8 +238,11 @@ function createRenderer(plugins, builtinExtensions) {
|
|
|
150
238
|
__reExport(index_exports, require("@coze-editor/core"), module.exports);
|
|
151
239
|
// Annotate the CommonJS export names for ESM import in node:
|
|
152
240
|
0 && (module.exports = {
|
|
241
|
+
Editor,
|
|
153
242
|
EditorProvider,
|
|
154
243
|
Renderer,
|
|
244
|
+
connector,
|
|
245
|
+
createEditor,
|
|
155
246
|
createRenderer,
|
|
156
247
|
useEditor,
|
|
157
248
|
useInjector,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/renderer.tsx","../src/provider.tsx","../src/create-renderer.tsx"],"sourcesContent":["// Copyright (c) 2025 coze-dev\n// SPDX-License-Identifier: MIT\n\nexport { Renderer, type InferRendererProps } from './renderer';\n\nexport { createRenderer } from './create-renderer';\n\nexport { EditorProvider, useEditor, useInjector } from './provider';\n\nexport * from '@coze-editor/core';\n","// Copyright (c) 2025 coze-dev\n// SPDX-License-Identifier: MIT\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport React, {\n type CSSProperties,\n useEffect,\n useRef,\n useState,\n type ReactNode,\n} from 'react';\n\nimport {\n type EditorPluginSpec,\n type InferEditorAPIFromPlugins,\n type InferEvents,\n type InferValues,\n create,\n} from '@coze-editor/core';\nimport { type Extension } from '@codemirror/state';\n\nimport { useInjector, useSetEditor } from './provider';\n\ntype UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (\n k: infer I,\n) => void\n ? I\n : never;\n\ntype InferReactEvents<T extends Record<string, any>> = UnionToIntersection<{\n [K in keyof T as `on${Capitalize<string & K>}`]?: (e: T[K]) => void;\n}>;\n\nfunction firstLetterToUppercase(str: string) {\n return str.charAt(0).toUpperCase() + str.substring(1);\n}\n\ntype InferRendererProps<T extends EditorPluginSpec<string, any, any>[]> = {\n domProps?: {\n style?: CSSProperties;\n className?: string;\n };\n defaultValue?: string;\n options?: Partial<InferValues<T[number]>>;\n extensions?: Extension[];\n didMount?: (api: InferEditorAPIFromPlugins<T>) => void;\n children?: ReactNode;\n} & (InferEvents<T[number]> extends Record<string, any>\n ? InferReactEvents<InferEvents<T[number]>>\n : unknown);\n\nfunction Renderer<T extends EditorPluginSpec<string, any, any>[]>(\n props: { plugins: T } & InferRendererProps<T>,\n) {\n const {\n plugins,\n defaultValue,\n options,\n domProps = {},\n extensions,\n didMount,\n children,\n } = props;\n\n const [api, setAPI] = useState<any>();\n const ref = useRef(null);\n const apiRef = useRef<any>(null);\n const propsRef = useRef<typeof props | null>(null);\n const setEditor = useSetEditor();\n const injector = useInjector();\n\n propsRef.current = props;\n\n useEffect(() => {\n const { render, eventKeys } = create({\n plugins,\n injector,\n });\n\n const exported = render({\n parent: ref.current!,\n defaultValue,\n options: options ?? {},\n extensions,\n });\n\n apiRef.current = exported;\n\n eventKeys.forEach((eventName: any) => {\n exported.$on(eventName, e => {\n const handler = (propsRef.current as any)?.[\n `on${firstLetterToUppercase(eventName)}`\n ];\n if (typeof handler === 'function') {\n handler(e);\n }\n });\n });\n\n if (typeof didMount === 'function') {\n didMount(exported);\n }\n\n setAPI(exported);\n\n return () => {\n exported.$destroy();\n };\n }, []);\n\n useEffect(() => {\n if (!api || !setEditor) {\n return;\n }\n\n setEditor(api);\n }, [api, setEditor]);\n\n useEffect(() => {\n apiRef.current.$set(props.options ?? {});\n }, [props.options]);\n\n return (\n <>\n <div {...domProps} ref={ref} />\n {children}\n </>\n );\n}\n\nexport { Renderer };\n\nexport type { InferRendererProps };\n","// Copyright (c) 2025 coze-dev\n// SPDX-License-Identifier: MIT\n\nimport React, {\n type Dispatch,\n type ReactNode,\n createContext,\n useContext,\n useRef,\n useState,\n} from 'react';\n\nimport { type Injector, createInjector } from '@coze-editor/core';\n\nconst InternalEditorContext = createContext<unknown>(null);\nconst InternalSetEditorContext = createContext<Dispatch<any> | null>(null);\nconst InjectorContext = createContext<Injector | undefined>(undefined);\n\nfunction useEditor<T>(): T {\n return useContext(InternalEditorContext) as T;\n}\n\nfunction useSetEditor(): Dispatch<any> | null {\n return useContext(InternalSetEditorContext);\n}\n\nfunction useInjector(): Injector {\n const injector = useContext(InjectorContext);\n\n if (!injector) {\n throw new Error('useInjector should be used in EditorProvider');\n }\n\n return injector;\n}\n\nfunction EditorProvider({ children }: { children?: ReactNode }) {\n const [editor, setEditor] = useState(null);\n const injectorRef = useRef<Injector | null>(null);\n\n if (!injectorRef.current) {\n injectorRef.current = createInjector();\n }\n\n return (\n <InternalEditorContext.Provider value={editor}>\n <InternalSetEditorContext.Provider value={setEditor}>\n <InjectorContext.Provider value={injectorRef.current}>\n {children}\n </InjectorContext.Provider>\n </InternalSetEditorContext.Provider>\n </InternalEditorContext.Provider>\n );\n}\n\nexport { EditorProvider, useEditor, useSetEditor, useInjector };\n","// Copyright (c) 2025 coze-dev\n// SPDX-License-Identifier: MIT\n\nimport React, { useMemo } from 'react';\n\nimport { type EditorPluginSpec } from '@coze-editor/core';\nimport { type Extension } from '@codemirror/state';\n\nimport { Renderer, type InferRendererProps } from './renderer';\n\nconst OriginRenderer: (props: any) => JSX.Element = Renderer;\n\nfunction createRenderer<T extends EditorPluginSpec<string, any, any>[]>(\n plugins: T,\n builtinExtensions?: Extension[],\n) {\n return function CustomRenderer(props: InferRendererProps<T>) {\n const userExtensions = props.extensions;\n\n const extensions: Extension[] = useMemo(\n () => [...(builtinExtensions ?? []), ...(userExtensions ?? [])],\n [userExtensions],\n );\n\n return (\n <OriginRenderer {...props} extensions={extensions} plugins={plugins} />\n );\n };\n}\n\nexport { createRenderer };\n"],"mappings":"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","names":["import_react","import_core","React","React","import_react","React"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/renderer.tsx","../src/provider.tsx","../src/connector.tsx","../src/create-renderer.tsx","../src/editor.tsx","../src/create-editor.tsx"],"sourcesContent":["// Copyright (c) 2025 coze-dev\n// SPDX-License-Identifier: MIT\n\nexport { Renderer, connector, type InferRendererProps } from './renderer';\n\nexport { createRenderer, type CreateRendererOptions } from './create-renderer';\n\nexport { EditorProvider, useEditor, useInjector } from './provider';\n\nexport { Editor } from './editor';\n\nexport { createEditor } from './create-editor';\n\nexport * from '@coze-editor/core';\n","// Copyright (c) 2025 coze-dev\n// SPDX-License-Identifier: MIT\n\n/* eslint-disable @typescript-eslint/no-explicit-any */\nimport React, {\n type CSSProperties,\n useEffect,\n useRef,\n useState,\n type ReactNode,\n useMemo,\n useLayoutEffect,\n} from 'react';\n\nimport { FacetCombineStrategy } from '@coze-editor/utils';\nimport {\n type EditorPluginSpec,\n type InferEditorAPIFromPlugins,\n type InferEvents,\n type InferValues,\n create,\n} from '@coze-editor/core';\nimport { Facet, type Extension } from '@codemirror/state';\n\nimport { useInjector, useSetEditor } from './provider';\nimport { type Connector, createPortalConnector } from './connector';\n\ntype UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends (\n k: infer I,\n) => void\n ? I\n : never;\n\ntype InferReactEvents<T extends Record<string, any>> = UnionToIntersection<{\n [K in keyof T as `on${Capitalize<string & K>}`]?: (e: T[K]) => void;\n}>;\n\nfunction firstLetterToUppercase(str: string) {\n return str.charAt(0).toUpperCase() + str.substring(1);\n}\n\ntype InferRendererProps<T extends EditorPluginSpec<string, any, any>[]> = {\n domProps?: {\n style?: CSSProperties;\n className?: string;\n };\n defaultValue?: string;\n root?: Document | ShadowRoot;\n options?: Partial<InferValues<T[number]>>;\n extensions?: Extension[];\n didMount?: (api: InferEditorAPIFromPlugins<T>) => void;\n children?: ReactNode;\n} & (InferEvents<T[number]> extends Record<string, any>\n ? InferReactEvents<InferEvents<T[number]>>\n : unknown);\n\nconst connector = Facet.define<Connector, Connector>({\n combine: FacetCombineStrategy.First,\n});\n\nfunction Renderer<T extends EditorPluginSpec<string, any, any>[]>(\n props: { plugins: T } & InferRendererProps<T>,\n) {\n const {\n plugins,\n defaultValue,\n root,\n options,\n domProps = {},\n extensions,\n didMount,\n children,\n } = props;\n\n const [api, setAPI] = useState<any>();\n const ref = useRef(null);\n const apiRef = useRef<any>(null);\n const propsRef = useRef<typeof props | null>(null);\n const setEditor = useSetEditor();\n const injector = useInjector();\n\n const pc = useMemo(() => createPortalConnector(), []);\n const connectorRef = useRef<Connector>(pc);\n connectorRef.current = pc;\n const { Portal } = pc;\n\n propsRef.current = props;\n\n useLayoutEffect(() => {\n const { render, eventKeys } = create({\n plugins,\n injector,\n });\n\n const exported = render({\n parent: ref.current!,\n root,\n defaultValue,\n options: options ?? {},\n extensions: [connector.of(connectorRef.current), ...(extensions ?? [])],\n });\n\n apiRef.current = exported;\n\n eventKeys.forEach((eventName: any) => {\n exported.$on(eventName, e => {\n const handler = (propsRef.current as any)?.[\n `on${firstLetterToUppercase(eventName)}`\n ];\n if (typeof handler === 'function') {\n handler(e);\n }\n });\n });\n\n if (typeof didMount === 'function') {\n didMount(exported);\n }\n\n setAPI(exported);\n\n return () => {\n exported.$destroy();\n };\n }, []);\n\n useEffect(() => {\n if (!api || !setEditor) {\n return;\n }\n\n setEditor(api);\n }, [api, setEditor]);\n\n useEffect(() => {\n apiRef.current.$set(props.options ?? {});\n }, [props.options]);\n\n return (\n <>\n <div {...domProps} ref={ref} />\n {children}\n <Portal />\n </>\n );\n}\n\nexport { Renderer, connector };\n\nexport type { InferRendererProps };\n","// Copyright (c) 2025 coze-dev\n// SPDX-License-Identifier: MIT\n\nimport React, {\n type Dispatch,\n type ReactNode,\n createContext,\n useContext,\n useRef,\n useState,\n} from 'react';\n\nimport { type Injector, createInjector } from '@coze-editor/core';\n\nconst InternalEditorContext = createContext<unknown>(null);\nconst InternalSetEditorContext = createContext<Dispatch<any> | null>(null);\nconst InjectorContext = createContext<Injector | undefined>(undefined);\n\nfunction useEditor<T>(): T {\n return useContext(InternalEditorContext) as T;\n}\n\nfunction useSetEditor(): Dispatch<any> | null {\n return useContext(InternalSetEditorContext);\n}\n\nfunction useInjector(): Injector {\n const injector = useContext(InjectorContext);\n\n if (!injector) {\n throw new Error('useInjector should be used in EditorProvider');\n }\n\n return injector;\n}\n\nfunction EditorProvider({ children }: { children?: ReactNode }) {\n const [editor, setEditor] = useState(null);\n const injectorRef = useRef<Injector | null>(null);\n\n if (!injectorRef.current) {\n injectorRef.current = createInjector();\n }\n\n return (\n <InternalEditorContext.Provider value={editor}>\n <InternalSetEditorContext.Provider value={setEditor}>\n <InjectorContext.Provider value={injectorRef.current}>\n {children}\n </InjectorContext.Provider>\n </InternalSetEditorContext.Provider>\n </InternalEditorContext.Provider>\n );\n}\n\nexport { EditorProvider, useEditor, useSetEditor, useInjector };\n","import React, { useState, useCallback, Fragment } from 'react';\nimport type { ReactPortal } from 'react';\n\ntype PortalItem = {\n id: string;\n portal: ReactPortal;\n};\n\nfunction createPortalConnector() {\n let add = (id: string, portal: ReactPortal) => {};\n let remove = (id: string) => {};\n\n function connect(id: string, portal: ReactPortal) {\n add(id, portal);\n }\n\n function disconnect(id: string) {\n remove(id);\n }\n\n function Portal() {\n const [items, setItems] = useState<PortalItem[]>([]);\n\n const addItem = useCallback((id: string, portal: ReactPortal) => {\n setItems(prevItems => {\n const nextItems = [...prevItems];\n const index = nextItems.findIndex(item => item.id === id);\n if (index > -1) {\n nextItems[index] = { id, portal };\n } else {\n nextItems.push({ id, portal });\n }\n return nextItems;\n });\n }, []);\n const removeItem = useCallback((id: string) => {\n setItems(items => items.filter(item => item.id !== id));\n }, []);\n\n add = addItem;\n remove = removeItem;\n\n return <Fragment>{items.map(item => item.portal)}</Fragment>;\n }\n\n return {\n connect,\n disconnect,\n Portal,\n };\n}\n\ntype Connector = ReturnType<typeof createPortalConnector>;\n\nexport { createPortalConnector };\nexport type { Connector };\n","// Copyright (c) 2025 coze-dev\n// SPDX-License-Identifier: MIT\n\nimport React, { useMemo } from 'react';\n\nimport { type EditorPluginSpec } from '@coze-editor/core';\nimport { type Extension } from '@codemirror/state';\n\nimport { Renderer, type InferRendererProps } from './renderer';\n\nconst OriginRenderer: (props: any) => JSX.Element = Renderer;\n\ninterface CreateRendererOptions<T> {\n defaultOptions?: T;\n}\n\nfunction createRenderer<\n T extends EditorPluginSpec<string, any, any>[],\n U extends InferRendererProps<T> = InferRendererProps<T>,\n>(plugins: T, options?: Extension[] | CreateRendererOptions<U['options']>) {\n let builtinExtensions: Extension[] = [];\n let defaultOptions = {};\n\n // 兼容历史类型\n if (Array.isArray(options)) {\n builtinExtensions = options;\n } else if (options && typeof options === 'object') {\n defaultOptions = options.defaultOptions ?? {};\n }\n\n return function CustomRenderer(props: InferRendererProps<T>) {\n const userExtensions = props.extensions;\n\n const extensions: Extension[] = useMemo(\n () => [...(builtinExtensions ?? []), ...(userExtensions ?? [])],\n [userExtensions],\n );\n\n return (\n <OriginRenderer\n {...props}\n options={{\n ...defaultOptions,\n ...(props.options ?? {}),\n }}\n extensions={extensions}\n plugins={plugins}\n />\n );\n };\n}\n\nexport { createRenderer };\nexport type { CreateRendererOptions };\n","import React from 'react';\n\nimport { type EditorPluginSpec } from '@coze-editor/core';\n\nimport { type InferRendererProps, Renderer } from './renderer';\nimport { EditorProvider } from './provider';\n\nfunction Editor<T extends EditorPluginSpec<string, any, any>[]>(\n props: { plugins: T } & InferRendererProps<T>,\n) {\n return (\n <EditorProvider>\n <Renderer {...props} />\n </EditorProvider>\n );\n}\n\nexport { Editor };\n","import React from 'react';\n\nimport { type EditorPluginSpec } from '@coze-editor/core';\n\nimport { type InferRendererProps } from './renderer';\nimport { EditorProvider } from './provider';\nimport { createRenderer, type CreateRendererOptions } from './create-renderer';\n\nfunction createEditor<\n T extends EditorPluginSpec<string, any, any>[],\n U extends InferRendererProps<T> = InferRendererProps<T>,\n>(plugins: T, options?: CreateRendererOptions<U['options']>) {\n const CustomRenderer = createRenderer(plugins, options);\n\n return function CustomEditor(props: InferRendererProps<T>) {\n return (\n <EditorProvider>\n <CustomRenderer {...props} />\n </EditorProvider>\n );\n };\n}\n\nexport { createEditor };\n"],"mappings":"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","names":["import_react","import_core","React","import_react","items","React","React","import_react","React","import_react","React","import_react","React"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@coze-editor/react",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.e5f73a",
|
|
4
4
|
"description": "react",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "fengzilong",
|
|
@@ -23,7 +23,8 @@
|
|
|
23
23
|
"lint": "eslint && tsc --noEmit"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@coze-editor/core": "0.1.0-alpha.
|
|
26
|
+
"@coze-editor/core": "0.1.0-alpha.e5f73a",
|
|
27
|
+
"@coze-editor/utils": "0.1.0-alpha.e5f73a"
|
|
27
28
|
},
|
|
28
29
|
"devDependencies": {
|
|
29
30
|
"@codemirror/state": "^6.4.1",
|
|
@@ -42,8 +43,8 @@
|
|
|
42
43
|
"peerDependencies": {
|
|
43
44
|
"@codemirror/state": "^6.4.1",
|
|
44
45
|
"@codemirror/view": "^6.26.1",
|
|
45
|
-
"react": "
|
|
46
|
-
"react-dom": "
|
|
46
|
+
"react": ">=16.8",
|
|
47
|
+
"react-dom": ">=16.8"
|
|
47
48
|
},
|
|
48
49
|
"packageManager": "pnpm@9.15.0",
|
|
49
50
|
"publishConfig": {
|