@coze-editor/react 0.1.0-alpha.9459ef → 0.1.0-alpha.9a9cc7
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 +96 -9
- package/dist/esm/index.js.map +1 -1
- package/dist/index.d.mts +22 -4
- package/dist/index.d.ts +22 -4
- package/dist/index.js +103 -14
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
package/dist/esm/index.js
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
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
|
|
6
7
|
} from "react";
|
|
8
|
+
import { FacetCombineStrategy } from "@coze-editor/utils";
|
|
7
9
|
import {
|
|
8
10
|
create
|
|
9
11
|
} from "@coze-editor/core";
|
|
12
|
+
import { Facet } from "@codemirror/state";
|
|
10
13
|
|
|
11
14
|
// src/provider.tsx
|
|
12
15
|
import React, {
|
|
@@ -41,10 +44,54 @@ function EditorProvider({ children }) {
|
|
|
41
44
|
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
45
|
}
|
|
43
46
|
|
|
47
|
+
// src/connector.tsx
|
|
48
|
+
import React2, { useState as useState2, useCallback, Fragment } from "react";
|
|
49
|
+
function createPortalConnector() {
|
|
50
|
+
let add = (id, portal) => {
|
|
51
|
+
};
|
|
52
|
+
let remove = (id) => {
|
|
53
|
+
};
|
|
54
|
+
function connect(id, portal) {
|
|
55
|
+
add(id, portal);
|
|
56
|
+
}
|
|
57
|
+
function disconnect(id) {
|
|
58
|
+
remove(id);
|
|
59
|
+
}
|
|
60
|
+
function Portal() {
|
|
61
|
+
const [items, setItems] = useState2([]);
|
|
62
|
+
const addItem = useCallback((id, portal) => {
|
|
63
|
+
setItems((prevItems) => {
|
|
64
|
+
const nextItems = [...prevItems];
|
|
65
|
+
const index = nextItems.findIndex((item) => item.id === id);
|
|
66
|
+
if (index > -1) {
|
|
67
|
+
nextItems[index] = { id, portal };
|
|
68
|
+
} else {
|
|
69
|
+
nextItems.push({ id, portal });
|
|
70
|
+
}
|
|
71
|
+
return nextItems;
|
|
72
|
+
});
|
|
73
|
+
}, []);
|
|
74
|
+
const removeItem = useCallback((id) => {
|
|
75
|
+
setItems((items2) => items2.filter((item) => item.id !== id));
|
|
76
|
+
}, []);
|
|
77
|
+
add = addItem;
|
|
78
|
+
remove = removeItem;
|
|
79
|
+
return /* @__PURE__ */ React2.createElement(Fragment, null, items.map((item) => item.portal));
|
|
80
|
+
}
|
|
81
|
+
return {
|
|
82
|
+
connect,
|
|
83
|
+
disconnect,
|
|
84
|
+
Portal
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
|
|
44
88
|
// src/renderer.tsx
|
|
45
89
|
function firstLetterToUppercase(str) {
|
|
46
90
|
return str.charAt(0).toUpperCase() + str.substring(1);
|
|
47
91
|
}
|
|
92
|
+
var connector = Facet.define({
|
|
93
|
+
combine: FacetCombineStrategy.First
|
|
94
|
+
});
|
|
48
95
|
function Renderer(props) {
|
|
49
96
|
const {
|
|
50
97
|
plugins,
|
|
@@ -56,12 +103,16 @@ function Renderer(props) {
|
|
|
56
103
|
didMount,
|
|
57
104
|
children
|
|
58
105
|
} = props;
|
|
59
|
-
const [api, setAPI] =
|
|
106
|
+
const [api, setAPI] = useState3();
|
|
60
107
|
const ref = useRef2(null);
|
|
61
108
|
const apiRef = useRef2(null);
|
|
62
109
|
const propsRef = useRef2(null);
|
|
63
110
|
const setEditor = useSetEditor();
|
|
64
111
|
const injector = useInjector();
|
|
112
|
+
const pc = useMemo(() => createPortalConnector(), []);
|
|
113
|
+
const connectorRef = useRef2(pc);
|
|
114
|
+
connectorRef.current = pc;
|
|
115
|
+
const { Portal } = pc;
|
|
65
116
|
propsRef.current = props;
|
|
66
117
|
useEffect(() => {
|
|
67
118
|
const { render, eventKeys } = create({
|
|
@@ -73,7 +124,7 @@ function Renderer(props) {
|
|
|
73
124
|
root,
|
|
74
125
|
defaultValue,
|
|
75
126
|
options: options ?? {},
|
|
76
|
-
extensions
|
|
127
|
+
extensions: [connector.of(connectorRef.current), ...extensions ?? []]
|
|
77
128
|
});
|
|
78
129
|
apiRef.current = exported;
|
|
79
130
|
eventKeys.forEach((eventName) => {
|
|
@@ -102,28 +153,64 @@ function Renderer(props) {
|
|
|
102
153
|
useEffect(() => {
|
|
103
154
|
apiRef.current.$set(props.options ?? {});
|
|
104
155
|
}, [props.options]);
|
|
105
|
-
return /* @__PURE__ */
|
|
156
|
+
return /* @__PURE__ */ React3.createElement(React3.Fragment, null, /* @__PURE__ */ React3.createElement("div", { ...domProps, ref }), children, /* @__PURE__ */ React3.createElement(Portal, null));
|
|
106
157
|
}
|
|
107
158
|
|
|
108
159
|
// src/create-renderer.tsx
|
|
109
|
-
import
|
|
160
|
+
import React4, { useMemo as useMemo2 } from "react";
|
|
110
161
|
var OriginRenderer = Renderer;
|
|
111
|
-
function createRenderer(plugins,
|
|
162
|
+
function createRenderer(plugins, options) {
|
|
163
|
+
let builtinExtensions = [];
|
|
164
|
+
let defaultOptions = {};
|
|
165
|
+
if (Array.isArray(options)) {
|
|
166
|
+
builtinExtensions = options;
|
|
167
|
+
} else if (options && typeof options === "object") {
|
|
168
|
+
defaultOptions = options.defaultOptions ?? {};
|
|
169
|
+
}
|
|
112
170
|
return function CustomRenderer(props) {
|
|
113
171
|
const userExtensions = props.extensions;
|
|
114
|
-
const extensions =
|
|
172
|
+
const extensions = useMemo2(
|
|
115
173
|
() => [...builtinExtensions ?? [], ...userExtensions ?? []],
|
|
116
174
|
[userExtensions]
|
|
117
175
|
);
|
|
118
|
-
return /* @__PURE__ */
|
|
176
|
+
return /* @__PURE__ */ React4.createElement(
|
|
177
|
+
OriginRenderer,
|
|
178
|
+
{
|
|
179
|
+
...props,
|
|
180
|
+
options: {
|
|
181
|
+
...defaultOptions,
|
|
182
|
+
...props.options ?? {}
|
|
183
|
+
},
|
|
184
|
+
extensions,
|
|
185
|
+
plugins
|
|
186
|
+
}
|
|
187
|
+
);
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
// src/editor.tsx
|
|
192
|
+
import React5 from "react";
|
|
193
|
+
function Editor(props) {
|
|
194
|
+
return /* @__PURE__ */ React5.createElement(EditorProvider, null, /* @__PURE__ */ React5.createElement(Renderer, { ...props }));
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// src/create-editor.tsx
|
|
198
|
+
import React6 from "react";
|
|
199
|
+
function createEditor(plugins, options) {
|
|
200
|
+
const CustomRenderer = createRenderer(plugins, options);
|
|
201
|
+
return function CustomEditor(props) {
|
|
202
|
+
return /* @__PURE__ */ React6.createElement(EditorProvider, null, /* @__PURE__ */ React6.createElement(CustomRenderer, { ...props }));
|
|
119
203
|
};
|
|
120
204
|
}
|
|
121
205
|
|
|
122
206
|
// src/index.ts
|
|
123
207
|
export * from "@coze-editor/core";
|
|
124
208
|
export {
|
|
209
|
+
Editor,
|
|
125
210
|
EditorProvider,
|
|
126
211
|
Renderer,
|
|
212
|
+
connector,
|
|
213
|
+
createEditor,
|
|
127
214
|
createRenderer,
|
|
128
215
|
useEditor,
|
|
129
216
|
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 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\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 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 root,\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} 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 useEffect(() => {\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<{
|
|
@@ -20,11 +20,23 @@ type InferRendererProps<T extends EditorPluginSpec<string, any, any>[]> = {
|
|
|
20
20
|
didMount?: (api: InferEditorAPIFromPlugins<T>) => void;
|
|
21
21
|
children?: ReactNode;
|
|
22
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
|
+
}>;
|
|
23
32
|
declare function Renderer<T extends EditorPluginSpec<string, any, any>[]>(props: {
|
|
24
33
|
plugins: T;
|
|
25
34
|
} & InferRendererProps<T>): react_jsx_runtime.JSX.Element;
|
|
26
35
|
|
|
27
|
-
|
|
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;
|
|
28
40
|
|
|
29
41
|
declare function useEditor<T>(): T;
|
|
30
42
|
declare function useInjector(): Injector;
|
|
@@ -32,4 +44,10 @@ declare function EditorProvider({ children }: {
|
|
|
32
44
|
children?: ReactNode;
|
|
33
45
|
}): react_jsx_runtime.JSX.Element;
|
|
34
46
|
|
|
35
|
-
|
|
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<{
|
|
@@ -20,11 +20,23 @@ type InferRendererProps<T extends EditorPluginSpec<string, any, any>[]> = {
|
|
|
20
20
|
didMount?: (api: InferEditorAPIFromPlugins<T>) => void;
|
|
21
21
|
children?: ReactNode;
|
|
22
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
|
+
}>;
|
|
23
32
|
declare function Renderer<T extends EditorPluginSpec<string, any, any>[]>(props: {
|
|
24
33
|
plugins: T;
|
|
25
34
|
} & InferRendererProps<T>): react_jsx_runtime.JSX.Element;
|
|
26
35
|
|
|
27
|
-
|
|
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;
|
|
28
40
|
|
|
29
41
|
declare function useEditor<T>(): T;
|
|
30
42
|
declare function useInjector(): Injector;
|
|
@@ -32,4 +44,10 @@ declare function EditorProvider({ children }: {
|
|
|
32
44
|
children?: ReactNode;
|
|
33
45
|
}): react_jsx_runtime.JSX.Element;
|
|
34
46
|
|
|
35
|
-
|
|
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,10 +75,54 @@ 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,
|
|
@@ -85,14 +134,18 @@ function Renderer(props) {
|
|
|
85
134
|
didMount,
|
|
86
135
|
children
|
|
87
136
|
} = props;
|
|
88
|
-
const [api, setAPI] = (0,
|
|
89
|
-
const ref = (0,
|
|
90
|
-
const apiRef = (0,
|
|
91
|
-
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);
|
|
92
141
|
const setEditor = useSetEditor();
|
|
93
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;
|
|
94
147
|
propsRef.current = props;
|
|
95
|
-
(0,
|
|
148
|
+
(0, import_react3.useEffect)(() => {
|
|
96
149
|
const { render, eventKeys } = (0, import_core2.create)({
|
|
97
150
|
plugins,
|
|
98
151
|
injector
|
|
@@ -102,7 +155,7 @@ function Renderer(props) {
|
|
|
102
155
|
root,
|
|
103
156
|
defaultValue,
|
|
104
157
|
options: options ?? {},
|
|
105
|
-
extensions
|
|
158
|
+
extensions: [connector.of(connectorRef.current), ...extensions ?? []]
|
|
106
159
|
});
|
|
107
160
|
apiRef.current = exported;
|
|
108
161
|
eventKeys.forEach((eventName) => {
|
|
@@ -122,29 +175,62 @@ function Renderer(props) {
|
|
|
122
175
|
exported.$destroy();
|
|
123
176
|
};
|
|
124
177
|
}, []);
|
|
125
|
-
(0,
|
|
178
|
+
(0, import_react3.useEffect)(() => {
|
|
126
179
|
if (!api || !setEditor) {
|
|
127
180
|
return;
|
|
128
181
|
}
|
|
129
182
|
setEditor(api);
|
|
130
183
|
}, [api, setEditor]);
|
|
131
|
-
(0,
|
|
184
|
+
(0, import_react3.useEffect)(() => {
|
|
132
185
|
apiRef.current.$set(props.options ?? {});
|
|
133
186
|
}, [props.options]);
|
|
134
|
-
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));
|
|
135
188
|
}
|
|
136
189
|
|
|
137
190
|
// src/create-renderer.tsx
|
|
138
|
-
var
|
|
191
|
+
var import_react4 = __toESM(require("react"));
|
|
139
192
|
var OriginRenderer = Renderer;
|
|
140
|
-
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
|
+
}
|
|
141
201
|
return function CustomRenderer(props) {
|
|
142
202
|
const userExtensions = props.extensions;
|
|
143
|
-
const extensions = (0,
|
|
203
|
+
const extensions = (0, import_react4.useMemo)(
|
|
144
204
|
() => [...builtinExtensions ?? [], ...userExtensions ?? []],
|
|
145
205
|
[userExtensions]
|
|
146
206
|
);
|
|
147
|
-
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 }));
|
|
148
234
|
};
|
|
149
235
|
}
|
|
150
236
|
|
|
@@ -152,8 +238,11 @@ function createRenderer(plugins, builtinExtensions) {
|
|
|
152
238
|
__reExport(index_exports, require("@coze-editor/core"), module.exports);
|
|
153
239
|
// Annotate the CommonJS export names for ESM import in node:
|
|
154
240
|
0 && (module.exports = {
|
|
241
|
+
Editor,
|
|
155
242
|
EditorProvider,
|
|
156
243
|
Renderer,
|
|
244
|
+
connector,
|
|
245
|
+
createEditor,
|
|
157
246
|
createRenderer,
|
|
158
247
|
useEditor,
|
|
159
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 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\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 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 root,\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} 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 useEffect(() => {\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.9a9cc7",
|
|
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.9a9cc7",
|
|
27
|
+
"@coze-editor/utils": "0.1.0-alpha.9a9cc7"
|
|
27
28
|
},
|
|
28
29
|
"devDependencies": {
|
|
29
30
|
"@codemirror/state": "^6.4.1",
|