@lexical/html 0.43.1-nightly.20260416.0 → 0.44.0

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/types.d.ts ADDED
@@ -0,0 +1,293 @@
1
+ /**
2
+ * Copyright (c) Meta Platforms, Inc. and affiliates.
3
+ *
4
+ * This source code is licensed under the MIT license found in the
5
+ * LICENSE file in the root directory of this source tree.
6
+ *
7
+ */
8
+ import type { DOMRenderContextSymbol } from './constants';
9
+ import type { BaseSelection, DOMExportOutput, ElementDOMSlot, Klass, LexicalEditor, LexicalNode, StateConfig } from 'lexical';
10
+ /**
11
+ * @experimental
12
+ *
13
+ * Any ContextSymbol for {@link ContextConfig} (currently only {@link DOMRenderContextSymbol})
14
+ */
15
+ export type AnyContextSymbol = typeof DOMRenderContextSymbol;
16
+ /**
17
+ * @experimental
18
+ *
19
+ * Context with a phantom type for its purpose (such as {@link DOMRenderContextSymbol}).
20
+ *
21
+ * A ContextRecord is a data structure used in the export and import pipelines
22
+ * to allow for information to be passed throughout the chain without explicit
23
+ * argument passing, e.g. to specify whether the intended use case for HTML
24
+ * export is for serialization or for clipboard copy.
25
+ */
26
+ export type ContextRecord<_K extends symbol> = Record<string | symbol, unknown>;
27
+ /**
28
+ * @experimental
29
+ *
30
+ * A data structure much like StateConfig (they share implementation details)
31
+ * but for managing context during an export or import pipeline rather than
32
+ * individual node state.
33
+ */
34
+ export type ContextConfig<Sym extends symbol, V> = StateConfig<symbol, V> & {
35
+ readonly [K in Sym]?: true;
36
+ };
37
+ /**
38
+ * @experimental
39
+ *
40
+ * Update the context at `cfg` with updater, constructed with {@link contextUpdater}
41
+ */
42
+ export type ContextConfigUpdater<Ctx extends AnyContextSymbol, V> = {
43
+ readonly cfg: ContextConfig<Ctx, V>;
44
+ /**
45
+ * @param prev The current or default value
46
+ * @returns The new value
47
+ */
48
+ readonly updater: (prev: V) => V;
49
+ };
50
+ /**
51
+ * @experimental
52
+ *
53
+ * Set the the context at `cfg` to a specific value, constructed with {@link contextValue}
54
+ */
55
+ export type ContextConfigPair<Ctx extends AnyContextSymbol, V> = readonly [
56
+ ContextConfig<Ctx, V>,
57
+ V
58
+ ];
59
+ /**
60
+ * @experimental
61
+ *
62
+ * Set or update a context value, constructed with {@link contextValue} or {@link contextUpdater}
63
+ */
64
+ export type ContextPairOrUpdater<Ctx extends AnyContextSymbol, V> = ContextConfigPair<Ctx, V> | ContextConfigUpdater<Ctx, V>;
65
+ /** @experimental */
66
+ export type AnyContextConfigPairOrUpdater<Ctx extends AnyContextSymbol> = ContextPairOrUpdater<Ctx, any>;
67
+ /** @experimental */
68
+ export interface DOMRenderExtensionOutput {
69
+ /** @internal */
70
+ defaults: undefined | ContextRecord<typeof DOMRenderContextSymbol>;
71
+ }
72
+ /**
73
+ * @experimental
74
+ *
75
+ * Context configuration for render context, created with {@link createRenderState}
76
+ */
77
+ export type RenderStateConfig<V> = ContextConfig<typeof DOMRenderContextSymbol, V>;
78
+ /**
79
+ * @experimental
80
+ *
81
+ * Any setter or updater for {@link RenderStateConfig}
82
+ */
83
+ export type AnyRenderStateConfigPairOrUpdater = AnyContextConfigPairOrUpdater<typeof DOMRenderContextSymbol>;
84
+ /**
85
+ * @experimental
86
+ *
87
+ * Any {@link RenderStateConfig}
88
+ */
89
+ export type AnyRenderStateConfig = RenderStateConfig<any>;
90
+ /**
91
+ * @experimental
92
+ *
93
+ * Configuration for {@link DOMRenderExtension}
94
+ */
95
+ export interface DOMRenderConfig {
96
+ /**
97
+ * {@link DOMRenderMatch} overrides to customize node behavior,
98
+ * the final priority of these will be based on the following criteria:
99
+ *
100
+ * - Wildcards (`'*'`) have highest priority
101
+ * - Predicates (`$isParagraphNode`) have next priority
102
+ * - Subclasses have higher priority (e.g. `ParagraphNode` before `ElementNode`)
103
+ * - Extensions closer to the root have higher priority
104
+ * - Extensions depended on later have higher priority
105
+ * - Overrides defined later have higher priority
106
+ */
107
+ overrides: AnyDOMRenderMatch[];
108
+ /**
109
+ * Default context to provide in all exports, the configurations are created
110
+ * with {@link createRenderState} and should be created at the module-level.
111
+ *
112
+ * Only specify these if overriding the default value globally, since each
113
+ * configuration has a built-in default value that will be used if not
114
+ * already present in the context.
115
+ */
116
+ contextDefaults: AnyRenderStateConfigPairOrUpdater[];
117
+ }
118
+ /**
119
+ * @experimental
120
+ * Any {@link DOMRenderMatch}
121
+ */
122
+ export type AnyDOMRenderMatch = DOMRenderMatch<any>;
123
+ /**
124
+ * @experimental
125
+ *
126
+ * Match a node (and any subclass of that node) by its LexicalNode class,
127
+ * or with a guard (e.g. `ElementNode` or `$isElementNode`).
128
+ *
129
+ * Note that using the class compiles to significantly more efficient code
130
+ * than using a guard.
131
+ */
132
+ export type NodeMatch<T extends LexicalNode> = Klass<T> | ((node: LexicalNode) => node is T);
133
+ /**
134
+ * @experimental
135
+ *
136
+ * Used to define overrides for the render and export
137
+ * behavior for nodes matching the `nodes` predicate.
138
+ *
139
+ * All of these overrides are in a middleware style where you may use the
140
+ * result of `$next()` to enhance the result of the default implementation
141
+ * (or a lower priority override) by calling it and manipulating the result,
142
+ * or you may choose not to call `$next()` to entirely replace the behavior.
143
+ *
144
+ * It is not permitted to update the lexical editor state during any of
145
+ * these calls, you should only be doing read-only operations.
146
+ */
147
+ export interface DOMRenderMatch<T extends LexicalNode> {
148
+ /**
149
+ * '*' for all nodes, or an array of `NodeClass | $isNodeGuard` to match
150
+ * nodes more specifically. Using classes is more efficient, but will
151
+ * also target subclasses.
152
+ */
153
+ readonly nodes: '*' | readonly NodeMatch<T>[];
154
+ /**
155
+ * Control where an ElementNode's children are inserted into the DOM,
156
+ * this is useful to add a wrapping node or accessory nodes before or
157
+ * after the children. The root of the node returned by createDOM must
158
+ * still be exactly one HTMLElement.
159
+ *
160
+ * Generally you will call `$next()` to get an ElementDOMSlot and then use
161
+ * its methods to create a new one.
162
+ *
163
+ * @param node The LexicalNode
164
+ * @param dom The rendered HTMLElement
165
+ * @param $next Call the next implementation
166
+ * @param editor The editor
167
+ * @returns The `ElementDOMSlot` for this node
168
+ */
169
+ $getDOMSlot?: <N extends LexicalNode>(node: N, dom: HTMLElement, $next: () => ElementDOMSlot<HTMLElement>, editor: LexicalEditor) => ElementDOMSlot<HTMLElement>;
170
+ /**
171
+ * Called during the reconciliation process to determine which nodes
172
+ * to insert into the DOM for this Lexical Node. This is also the default
173
+ * implementation of `$exportDOM` for most nodes.
174
+ *
175
+ * This method must return exactly one `HTMLElement`.
176
+ *
177
+ * Nested elements are not supported except with `DecoratorNode`
178
+ * (which have unmanaged contents) or `ElementNode` using an appropriate
179
+ * `$getDOMSlot` return value.
180
+ *
181
+ * @param node The LexicalNode
182
+ * @param $next Call the next implementation
183
+ * @param editor The editor
184
+ * @returns The HTMLElement for this node to be rendered in the editor
185
+ */
186
+ $createDOM?: (node: T, $next: () => HTMLElement, editor: LexicalEditor) => HTMLElement;
187
+ /**
188
+ * Called when a node changes and should update the DOM
189
+ * in whatever way is necessary to make it align with any changes that might
190
+ * have happened during the update.
191
+ *
192
+ * Returning `true` here will cause lexical to unmount and recreate the DOM
193
+ * node (by calling `$createDOM`). You would need to do this if the element
194
+ * tag changes, for instance.
195
+ *
196
+ * @param nextNode The current version of this node
197
+ * @param prevNode The previous version of this node
198
+ * @param dom The previously rendered HTMLElement for this node
199
+ * @param $next Call the next implementation
200
+ * @param editor The editor
201
+ * @returns `false` if no update needed or was performed in-place, `true` if `$createDOM` should be called to re-create the node
202
+ */
203
+ $updateDOM?: (nextNode: T, prevNode: T, dom: HTMLElement, $next: () => boolean, editor: LexicalEditor) => boolean;
204
+ /**
205
+ * Called after a node is created or updated and should make any in-place
206
+ * updates to the DOM in whatever way is necessary to make it align with
207
+ * any changes that might have happened during the `$createDOM` or
208
+ * `$updateDOM`. This also runs after any children have been reconciled.
209
+ *
210
+ * Use this when you have code that you would need to duplicate in both
211
+ * methods, or if there is a need to ensure that the children are also
212
+ * reconciled before performing this in-place update.
213
+ *
214
+ * Unlike other overrides, all applicable `$decorateDOM` functions are
215
+ * called unconditionally. There is no `$next` argument, because there
216
+ * are no known use cases for avoiding the next implementation and due
217
+ * to the void return value it would be error-prone and add boilerplate
218
+ * to require calling it.
219
+ *
220
+ * The ordering here is equivalent to an implicit `$next` call *first*.
221
+ *
222
+ * @param nextNode The current version of this node
223
+ * @param prevNode The previous version of this node if `$updateDOM` returned `false`, or `null` if `$createDOM` was just called
224
+ * @param dom The previously rendered `HTMLElement` for this node
225
+ * @param editor The editor
226
+ */
227
+ $decorateDOM?: (nextNode: T, prevNode: null | T, dom: HTMLElement, editor: LexicalEditor) => void;
228
+ /**
229
+ * Controls how the this node is serialized to HTML. This is important for
230
+ * copy and paste between Lexical and non-Lexical editors, or Lexical
231
+ * editors with different namespaces, in which case the primary transfer
232
+ * format is HTML. It's also important if you're serializing to HTML for
233
+ * any other reason via {@link @lexical/html!$generateHtmlFromNodes}.
234
+ *
235
+ * @param node The LexicalNode
236
+ * @param $next Call the next implementation
237
+ * @param editor The editor
238
+ * @returns A {@link DOMExportOutput} structure that defines how the node should be exported to HTML
239
+ */
240
+ $exportDOM?: (node: T, $next: () => DOMExportOutput, editor: LexicalEditor) => DOMExportOutput;
241
+ /**
242
+ * Equivalent to `ElementNode.excludeFromCopy`, if it returns `true` this
243
+ * lexical node will not be exported to DOM (but if it's an `ElementNode`
244
+ * its children may still be inserted in its place).
245
+ *
246
+ * Has higher precedence than `$shouldInclude` and `$extractWithChild`.
247
+ *
248
+ * @param node The LexicalNode
249
+ * @param selection The current selection
250
+ * @param $next The next implementation
251
+ * @param editor The editor
252
+ * @returns true to exclude this node, false otherwise
253
+ */
254
+ $shouldExclude?: (node: T, selection: null | BaseSelection, $next: () => boolean, editor: LexicalEditor) => boolean;
255
+ /**
256
+ * Return `true` if this node should be included in the export, typically based
257
+ * on the current selection (all nodes by default are included when there
258
+ * is no selection).
259
+ *
260
+ * The default implementation is equivalent to
261
+ * `selection ? node.isSelected(selection) : true`.
262
+ *
263
+ * This has lower precedence than `$extractWithChild` and `$shouldExclude`.
264
+ *
265
+ * @param node The current node
266
+ * @param selection The current selection
267
+ * @param $next The next implementation
268
+ * @param editor The editor
269
+ * @returns `true` if this node should be included in the export, `false` otherwise
270
+ */
271
+ $shouldInclude?: (node: T, selection: null | BaseSelection, $next: () => boolean, editor: LexicalEditor) => boolean;
272
+ /**
273
+ * Return `true` if this node should be included in the export based on
274
+ * `childNode`, even if it would not otherwise be included based on its
275
+ * `$shouldInclude` result.
276
+ *
277
+ * Typically used to ensure that required wrapping nodes are always
278
+ * present with its children, e.g. a ListNode when some of its ListItemNode
279
+ * children are selected.
280
+ *
281
+ * This has higher precedence than `$extractWithChild` and lower precedence
282
+ * than `$shouldExclude`.
283
+ *
284
+ * @param node The lexical node
285
+ * @param childNode A child of this lexical node
286
+ * @param selection The current selection
287
+ * @param destination Currently always `'html'`
288
+ * @param $next The next implementation
289
+ * @param editor The editor
290
+ * @returns true if this
291
+ */
292
+ $extractWithChild?: (node: T, childNode: LexicalNode, selection: null | BaseSelection, destination: 'clone' | 'html', $next: () => boolean, editor: LexicalEditor) => boolean;
293
+ }