@etrepum/lexical-builder 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
package/README.md ADDED
@@ -0,0 +1,3 @@
1
+ # `@etrepum/lexical-builder`
2
+
3
+ **EXPERIMENTAL** A high-level way to manage Lexical config and plug-ins for any framework
@@ -0,0 +1,247 @@
1
+ /// <reference types="react" />
2
+ /// <reference types="react-dom" />
3
+ /**
4
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
5
+ *
6
+ * This source code is licensed under the MIT license found in the
7
+ * LICENSE file in the root directory of this source tree.
8
+ *
9
+ */
10
+ import { CreateEditorArgs, EditorState, LexicalEditor } from "lexical";
11
+ /**
12
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
13
+ *
14
+ * This source code is licensed under the MIT license found in the
15
+ * LICENSE file in the root directory of this source tree.
16
+ *
17
+ */
18
+ import { HistoryState } from "@lexical/history";
19
+ import { LexicalComposerContextWithEditor } from "@lexical/react/LexicalComposerContext";
20
+ import * as React from "react";
21
+ import { Root } from "react-dom/client";
22
+ interface AutoFocusConfig {
23
+ defaultSelection?: "rootStart" | "rootEnd";
24
+ }
25
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
26
+ type AnyLexicalPlan = LexicalPlan<any, string>;
27
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
28
+ type AnyLexicalPlanArgument = LexicalPlanArgument<any, string>;
29
+ type PlanConfigBase = Record<never, never>;
30
+ type NormalizedLexicalPlanArgument<Config extends PlanConfigBase, Name extends string> = [
31
+ LexicalPlan<Config, Name>,
32
+ Config,
33
+ ...Config[]
34
+ ];
35
+ interface LexicalPlanRegistry {
36
+ }
37
+ interface RegisterState {
38
+ signal: AbortSignal;
39
+ getPeerConfig<Name extends keyof LexicalPlanRegistry>(name: string): undefined | LexicalPlanConfig<LexicalPlanRegistry[Name]>;
40
+ getDependencyConfig<Dependency extends AnyLexicalPlan>(dep: Dependency): LexicalPlanConfig<Dependency>;
41
+ }
42
+ type LexicalPlanArgument<Config extends PlanConfigBase, Name extends string> = LexicalPlan<Config, Name> | NormalizedLexicalPlanArgument<Config, Name>;
43
+ interface LexicalPlan<Config extends PlanConfigBase = PlanConfigBase, Name extends string = string> {
44
+ /** The name of the Plan, must be unique */
45
+ name: Name;
46
+ /** Plan names that must not be loaded with this Plan */
47
+ conflictsWith?: string[];
48
+ /** Other Plans that this Plan depends on, can also be used to configure them */
49
+ dependencies?: AnyLexicalPlanArgument[];
50
+ /**
51
+ * Other Plans, by name, that this Plan can optionally depend on or
52
+ * configure, if they are directly depended on by another Plan
53
+ */
54
+ peerDependencies?: {
55
+ [k in keyof LexicalPlanRegistry]?: LexicalPeerConfig<k>;
56
+ };
57
+ /**
58
+ * @internal Disable root element events (for internal Meta use)
59
+ */
60
+ disableEvents?: CreateEditorArgs["disableEvents"];
61
+ /**
62
+ * Used when this editor is nested inside of another editor
63
+ */
64
+ parentEditor?: CreateEditorArgs["parentEditor"];
65
+ /**
66
+ * The namespace of this Editor. If two editors share the same
67
+ * namespace, JSON will be the clipboard interchange format.
68
+ * Otherwise HTML will be used.
69
+ */
70
+ namespace?: CreateEditorArgs["namespace"];
71
+ /**
72
+ * The nodes that this Plan adds to the Editor configuration, will be merged with other Plans
73
+ */
74
+ nodes?: CreateEditorArgs["nodes"];
75
+ /**
76
+ * EditorThemeClasses that will be deep merged with other Plans
77
+ */
78
+ theme?: CreateEditorArgs["theme"];
79
+ /**
80
+ * Overrides for HTML serialization (exportDOM) and
81
+ * deserialization (importDOM) that does not require subclassing and node
82
+ * replacement
83
+ */
84
+ html?: CreateEditorArgs["html"];
85
+ /**
86
+ * Whether the initial state of the editor is editable or not
87
+ */
88
+ editable?: CreateEditorArgs["editable"];
89
+ /**
90
+ * The editor will catch errors that happen during updates and
91
+ * reconciliation and call this. It defaults to
92
+ * `(error) => console.error(error)`.
93
+ *
94
+ * @param error The Error object
95
+ * @param editor The editor that this error came from
96
+ */
97
+ onError?: (error: Error, editor: LexicalEditor) => void;
98
+ /**
99
+ * The initial EditorState as a JSON string, an EditorState, or a function
100
+ * to update the editor once.
101
+ */
102
+ $initialEditorState?: InitialEditorStateType;
103
+ /**
104
+ * The default configuration specific to this Plan
105
+ */
106
+ config: Config;
107
+ /**
108
+ * By default, Config is shallow merged `{...a, ...b}`, if your Plan
109
+ * requires other strategies (such as concatenating an Array) you can
110
+ * implement it here.
111
+ *
112
+ * @param a The current configuration
113
+ * @param b The partial configuration to merge
114
+ * @returns The merged configuration
115
+ */
116
+ mergeConfig?: (a: Config, b?: Partial<Config>) => Config;
117
+ /**
118
+ * Add behavior to the editor (register transforms, listeners, etc.) after
119
+ * the Editor is created.
120
+ *
121
+ * @param editor The editor this Plan is being registered with
122
+ * @param config The merged configuration specific to this Plan
123
+ * @param state An object containing an AbortSignal that can be
124
+ * used, and methods for accessing the merged configuration of
125
+ * dependencies and peerDependencies
126
+ * @returns A clean-up function
127
+ */
128
+ register?: (editor: LexicalEditor, config: Config, state: RegisterState) => () => void;
129
+ }
130
+ type LexicalPeerConfig<Name extends keyof LexicalPlanRegistry | string> = [
131
+ Name
132
+ ] extends [
133
+ keyof LexicalPlanRegistry
134
+ ] ? LexicalPlanRegistry[Name] : PlanConfigBase;
135
+ type LexicalPlanConfig<Plan extends AnyLexicalPlan> = Plan["config"];
136
+ type LexicalPlanName<Plan extends AnyLexicalPlan> = Plan["name"];
137
+ interface EditorHandle {
138
+ editor: LexicalEditor;
139
+ dispose: () => void;
140
+ }
141
+ type InitialEditorStateType = null | string | EditorState | ((editor: LexicalEditor) => void);
142
+ declare const AutoFocusPlan: LexicalPlan<AutoFocusConfig, "@etrepum/lexical-builder/AutoFocusPlan">;
143
+ declare function definePlan<Config extends PlanConfigBase, Name extends string>(plan: LexicalPlan<Config, Name>): LexicalPlan<Config, Name>;
144
+ declare function configPlan<Plan extends AnyLexicalPlan>(plan: Plan, config: Partial<LexicalPlanConfig<Plan>>): [
145
+ Plan,
146
+ Partial<LexicalPlanConfig<Plan>>
147
+ ];
148
+ declare const DragonPlan: LexicalPlan<{}, "@lexical/dragon">;
149
+ interface HistoryConfig {
150
+ delay: number;
151
+ createInitialHistoryState: () => HistoryState;
152
+ }
153
+ declare const HistoryPlan: LexicalPlan<HistoryConfig, "@etrepum/lexical-builder/HistoryPlan">;
154
+ declare class PlanRep<Plan extends AnyLexicalPlan> {
155
+ builder: LexicalBuilder;
156
+ configs: Set<LexicalPlanConfig<Plan>>;
157
+ _config?: LexicalPlanConfig<Plan>;
158
+ plan: Plan;
159
+ constructor(builder: LexicalBuilder, plan: Plan);
160
+ getPeerConfig<Name extends keyof LexicalPlanRegistry>(name: string): undefined | LexicalPlanConfig<LexicalPlanRegistry[Name]>;
161
+ getDependencyConfig<Dependency extends AnyLexicalPlan>(dep: Dependency): LexicalPlanConfig<Dependency>;
162
+ getConfig(): LexicalPlanConfig<Plan>;
163
+ }
164
+ /** @experimental */
165
+ declare class LexicalBuilder {
166
+ phases: Map<AnyLexicalPlan, PlanRep<AnyLexicalPlan>>[];
167
+ planMap: Map<AnyLexicalPlan, [
168
+ number,
169
+ PlanRep<AnyLexicalPlan>
170
+ ]>;
171
+ planNameMap: Map<string, PlanRep<AnyLexicalPlan>>;
172
+ conflicts: Map<string, string>;
173
+ constructor();
174
+ static fromPlans(...args: AnyLexicalPlanArgument[]): LexicalBuilder;
175
+ buildEditor(): EditorHandle;
176
+ addPlan(arg: AnyLexicalPlanArgument): number;
177
+ sortedPlanReps(): Generator<PlanRep<AnyLexicalPlan>, void, undefined>;
178
+ registerEditor(editor: LexicalEditor): () => void;
179
+ buildCreateEditorArgs(): Pick<CreateEditorArgs, "disableEvents" | "namespace" | "nodes" | "theme" | "html" | "editable"> & Pick<AnyLexicalPlan, "onError" | "$initialEditorState">;
180
+ }
181
+ declare const PlainTextPlan: LexicalPlan<{}, "@lexical/plain-text">;
182
+ type ErrorBoundaryProps = {
183
+ children: JSX.Element;
184
+ onError: (error: Error) => void;
185
+ };
186
+ type ErrorBoundaryType = React.ComponentClass<ErrorBoundaryProps> | React.FC<ErrorBoundaryProps>;
187
+ interface EditorChildrenComponentProps {
188
+ context: LexicalComposerContextWithEditor;
189
+ placeholder: null | JSX.Element;
190
+ contentEditable: null | JSX.Element;
191
+ children?: React.ReactNode;
192
+ }
193
+ type EditorChildrenComponentType = (props: EditorChildrenComponentProps) => JSX.Element | null;
194
+ interface DecoratorComponentProps {
195
+ context: LexicalComposerContextWithEditor;
196
+ }
197
+ type DecoratorComponentType = JSX.Element | ((props: DecoratorComponentProps) => JSX.Element | null);
198
+ interface EditorComponentProps {
199
+ EditorChildrenComponent: EditorChildrenComponentType;
200
+ children?: React.ReactNode;
201
+ placeholder: ((isEditable: boolean) => null | JSX.Element) | null | JSX.Element;
202
+ contentEditable: JSX.Element | null;
203
+ ErrorBoundary: ErrorBoundaryType;
204
+ }
205
+ type EditorComponentType = (props: Partial<EditorComponentProps>) => JSX.Element;
206
+ interface ReactConfig {
207
+ contentEditable: JSX.Element | null;
208
+ placeholder: ((isEditable: boolean) => null | JSX.Element) | null | JSX.Element;
209
+ ErrorBoundary: ErrorBoundaryType;
210
+ EditorChildrenComponent: EditorChildrenComponentType;
211
+ setComponent: (component: undefined | EditorComponentType, context: LexicalComposerContextWithEditor) => void;
212
+ decorators: readonly DecoratorComponentType[];
213
+ }
214
+ interface LexicalPlanComposerProps {
215
+ plan: AnyLexicalPlanArgument;
216
+ children: React.ReactNode;
217
+ }
218
+ declare function LexicalPlanComposer({ plan, children }: LexicalPlanComposerProps): import("react/jsx-runtime").JSX.Element | null;
219
+ declare const ReactPlan: LexicalPlan<ReactConfig, "@etrepum/lexical-builder/ReactPlan">;
220
+ interface HostMountCommandArg {
221
+ root: Root;
222
+ }
223
+ type Container = Element | DocumentFragment;
224
+ interface MountPluginCommandArg {
225
+ key: string;
226
+ element: JSX.Element | null;
227
+ domNode?: Container | null;
228
+ }
229
+ declare function mountReactPluginComponent<P extends Record<never, never> = Record<never, never>>(editor: LexicalEditor, opts: {
230
+ Component: null | React.ComponentType<P>;
231
+ props: (P & React.Attributes) | null;
232
+ } & Omit<MountPluginCommandArg, "element">): void;
233
+ declare function mountReactPluginElement(editor: LexicalEditor, opts: MountPluginCommandArg): void;
234
+ declare function mountReactPluginHost(editor: LexicalEditor, container: Container): void;
235
+ declare const REACT_PLUGIN_HOST_MOUNT_COMMAND: import("lexical").LexicalCommand<HostMountCommandArg>;
236
+ declare const REACT_MOUNT_PLUGIN_COMMAND: import("lexical").LexicalCommand<MountPluginCommandArg>;
237
+ declare const ReactPluginHostPlan: LexicalPlan<{}, "@etrepum/lexical-builder/ReactPluginHostPlan">;
238
+ declare const RichTextPlan: LexicalPlan<{}, "@lexical/rich-text">;
239
+ /**
240
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
241
+ *
242
+ * This source code is licensed under the MIT license found in the
243
+ * LICENSE file in the root directory of this source tree.
244
+ *
245
+ */
246
+ export { AutoFocusConfig, AutoFocusPlan, configPlan, definePlan, DragonPlan, HistoryConfig, HistoryPlan, LexicalBuilder, PlainTextPlan, DecoratorComponentProps, DecoratorComponentType, EditorChildrenComponentProps, EditorChildrenComponentType, EditorComponentProps, EditorComponentType, LexicalPlanComposer, LexicalPlanComposerProps, ReactConfig, ReactPlan, HostMountCommandArg, MountPluginCommandArg, mountReactPluginComponent, mountReactPluginElement, mountReactPluginHost, REACT_MOUNT_PLUGIN_COMMAND, REACT_PLUGIN_HOST_MOUNT_COMMAND, ReactPluginHostPlan, RichTextPlan, AnyLexicalPlan, AnyLexicalPlanArgument, EditorHandle, InitialEditorStateType, LexicalPeerConfig, LexicalPlan, LexicalPlanArgument, LexicalPlanConfig, LexicalPlanName, LexicalPlanRegistry, NormalizedLexicalPlanArgument, PlanConfigBase, RegisterState, ErrorBoundaryType };
247
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","sourceRoot":"","sources":["../src/index.ts","../src/types.ts","../src/definePlan.ts","../src/safeCast.ts","../src/AutoFocusPlan.ts","../src/DragonPlan.ts","../src/HistoryPlan.ts","../src/shared/invariant.ts","../src/deepThemeMergeInPlace.ts","../src/initializeEditor.ts","../src/shallowMergeConfig.ts","../src/PlanRep.ts","../src/LexicalBuilder.ts","../src/PlainTextPlan.ts","../src/registerSubscription.ts","../src/registerShowPlaceholder.ts","../src/shared/useLayoutEffect.ts","../src/useReactDecorators.tsx","../src/useRegisterSubscription.ts","../src/ReactPlan.tsx","../src/ReactPluginHostPlan.tsx","../src/RichTextPlan.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;GAMG;AAEH,OAAO,k0BAAuC,CAAwB"}