UNPKG

9.99 kBTypeScriptView Raw
1import type { AcceptUndefined, CommandFunction, CommandFunctionProps, EditorState, EditorView, FromToProps, Handler, MakeRequired, Static } from '@remirror/core-types';
2import { DecorationSet } from '@remirror/pm/view';
3import { DelayedCommand, DelayedPromiseCreator } from '../commands';
4import { Helper, PlainExtension } from '../extension';
5import type { CreateExtensionPlugin } from '../types';
6export interface DecorationsOptions {
7 /**
8 * This setting is for adding a decoration to the selected text and can be
9 * used to preserve the marker for the selection when the editor loses focus.
10 *
11 * You can set it as `'selection'` to match the default styles provided by
12 * `@remirror/styles`.
13 *
14 * @defaultValue undefined
15 */
16 persistentSelectionClass?: AcceptUndefined<string | boolean>;
17 /**
18 * Add custom decorations to the editor via `extension.addHandler`. This can
19 * be used via the `useDecorations` hook available from `remirror/react`.
20 */
21 decorations: Handler<(state: EditorState) => DecorationSet>;
22 /**
23 * The className that is added to all placeholder positions
24 *
25 * '@defaultValue 'placeholder'
26 */
27 placeholderClassName?: Static<string>;
28 /**
29 * The default element that is used for all placeholders.
30 *
31 * @defaultValue 'span'
32 */
33 placeholderNodeName?: Static<string>;
34}
35/**
36 * Simplify the process of adding decorations to the editor. All the decorations
37 * added to the document this way are automatically tracked which allows for
38 * custom components to be nested inside decorations.
39 *
40 * @category Builtin Extension
41 */
42export declare class DecorationsExtension extends PlainExtension<DecorationsOptions> {
43 get name(): "decorations";
44 /**
45 * The placeholder decorations.
46 */
47 private placeholders;
48 /**
49 * A map of the html elements to their decorations.
50 */
51 private readonly placeholderWidgets;
52 onCreate(): void;
53 /**
54 * Create the extension plugin for inserting decorations into the editor.
55 */
56 createPlugin(): CreateExtensionPlugin;
57 updateDecorations(): CommandFunction;
58 /**
59 * Command to dispatch a transaction adding the placeholder decoration to
60 * be tracked.
61 *
62 * @param id - the value that is used to identify this tracker. This can
63 * be any value. A promise, a function call, a string.
64 * @param options - the options to call the tracked position with. You can
65 * specify the range `{ from: number; to: number }` as well as the class
66 * name.
67 */
68 addPlaceholder(id: unknown, placeholder: DecorationPlaceholder, deleteSelection?: boolean): CommandFunction;
69 /**
70 * A command to updated the placeholder decoration.
71 *
72 * To update multiple placeholders you can use chained commands.
73 *
74 * ```ts
75 * let idsWithData: Array<{id: unknown, data: number}>;
76 *
77 * for (const { id, data } of idsWithData) {
78 * chain.updatePlaceholder(id, data);
79 * }
80 *
81 * chain.run();
82 * ```
83 */
84 updatePlaceholder<Data = any>(id: unknown, data: Data): CommandFunction;
85 /**
86 * A command to remove the specified placeholder decoration.
87 */
88 removePlaceholder(id: unknown): CommandFunction;
89 /**
90 * A command to remove all active placeholder decorations.
91 */
92 clearPlaceholders(): CommandFunction;
93 /**
94 * Find the position for the tracker with the ID specified.
95 *
96 * @param id - the unique position id which can be any type
97 */
98 findPlaceholder(id: unknown): Helper<FromToProps | undefined>;
99 /**
100 * Find the positions of all the trackers in document.
101 */
102 findAllPlaceholders(): Helper<Map<unknown, FromToProps>>;
103 /**
104 * Add some decorations based on the provided settings.
105 */
106 createDecorations(state: EditorState): DecorationSet;
107 /**
108 * This stores all tracked positions in the editor and maps them via the
109 * transaction updates.
110 */
111 onApplyState(): void;
112 /**
113 * Add a widget placeholder and track it as a widget placeholder.
114 */
115 private addWidgetPlaceholder;
116 /**
117 * Add an inline placeholder.
118 */
119 private addInlinePlaceholder;
120 /**
121 * Add a placeholder for nodes.
122 */
123 private addNodePlaceholder;
124 /**
125 * Add the node and class name to the placeholder object.
126 */
127 private withRequiredBase;
128 /**
129 * Get the command metadata.
130 */
131 private getMeta;
132 /**
133 * Set the metadata for the command.
134 */
135 private setMeta;
136 /**
137 * Add a placeholder decoration with the specified params to the transaction
138 * and return the transaction.
139 *
140 * It is up to you to dispatch the transaction or you can just use the
141 * commands.
142 */
143 private addPlaceholderTransaction;
144 /**
145 * Update the data stored by a placeholder.
146 *
147 * This replaces the whole data value.
148 */
149 private updatePlaceholderTransaction;
150 /**
151 * Discards a previously defined tracker once not needed.
152 *
153 * This should be used to cleanup once the position is no longer needed.
154 */
155 private removePlaceholderTransaction;
156 /**
157 * This helper returns a transaction that clears all position trackers when
158 * any exist.
159 *
160 * Otherwise it returns undefined.
161 */
162 private clearPlaceholdersTransaction;
163 /**
164 * Handles delayed commands which rely on the
165 */
166 private readonly createPlaceholderCommand;
167}
168export interface DecorationPlaceholderMeta {
169 /**
170 * The trackers to add.
171 */
172 added?: Array<WithBase<DecorationPlaceholder>>;
173 /**
174 * The trackers to update with new data. Data is an object and is used to
175 * include properties like `progress` for progress indicators. Only `widget`
176 * decorations can be updated in this way.
177 */
178 updated?: Array<{
179 id: unknown;
180 data: any;
181 }>;
182 /**
183 * The trackers to remove.
184 */
185 removed?: unknown[];
186 /**
187 * When set to true will delete all the active trackers.
188 */
189 clearTrackers?: boolean;
190}
191interface BasePlaceholder {
192 /**
193 * A custom class name to use for the placeholder decoration. All the trackers
194 * will automatically be given the class name `remirror-tracker-position`
195 *
196 * @defaultValue ''
197 */
198 className?: string;
199 /**
200 * A custom html element or string for a created element tag name.
201 *
202 * @defaultValue 'tracker'
203 */
204 nodeName?: string;
205}
206interface DataProps<Data = any> {
207 /**
208 * The data to store for this placeholder.
209 */
210 data?: Data;
211}
212interface InlinePlaceholder<Data = any> extends BasePlaceholder, Partial<FromToProps>, DataProps<Data> {
213 type: 'inline';
214}
215interface NodePlaceholder<Data = any> extends BasePlaceholder, DataProps<Data> {
216 /**
217 * Set this as a node tracker.
218 */
219 type: 'node';
220 /**
221 * If provided the The `pos` must be directly before the node in order to be
222 * valid. If not provided it will select the parent node of the current
223 * selection.
224 */
225 pos: number | null;
226}
227export interface WidgetPlaceholder<Data = any> extends BasePlaceholder, DataProps<Data> {
228 /**
229 * Declare this as a widget tracker.
230 *
231 * Widget trackers support adding custom components to the created dom
232 * element.
233 */
234 type: 'widget';
235 /**
236 * Widget trackers only support fixed positions.
237 */
238 pos: number;
239 /**
240 * Called the first time this widget decoration is added to the dom.
241 */
242 createElement?(view: EditorView, pos: number): HTMLElement;
243 /**
244 * Called whenever the position tracker updates with the new position.
245 */
246 onUpdate?(view: EditorView, pos: number, element: HTMLElement, data: any): void;
247 /**
248 * Called when the widget decoration is removed from the dom.
249 */
250 onDestroy?(view: EditorView, element: HTMLElement): void;
251}
252declare type WithBase<Type extends BasePlaceholder> = MakeRequired<Type, keyof BasePlaceholder> & {
253 id: unknown;
254};
255export declare type DecorationPlaceholder = WidgetPlaceholder | NodePlaceholder | InlinePlaceholder;
256export interface DelayedPlaceholderCommandProps<Value> {
257 /**
258 * A function that returns a promise.
259 */
260 promise: DelayedPromiseCreator<Value>;
261 /**
262 * The placeholder configuration.
263 */
264 placeholder: DecorationPlaceholder;
265 /**
266 * Called when the promise succeeds and the placeholder still exists. If no
267 * placeholder can be found (for example, the user has deleted the entire
268 * document) then the failure handler is called instead.
269 */
270 onSuccess: (value: Value, range: FromToProps, commandProps: CommandFunctionProps) => boolean;
271 /**
272 * Called when a failure is encountered.
273 */
274 onFailure?: CommandFunction<{
275 error: any;
276 }>;
277}
278declare global {
279 namespace Remirror {
280 interface ExtensionStore {
281 /**
282 * Create delayed command which automatically adds a placeholder to the
283 * document while the delayed command is being run and also automatically
284 * removes it once it has completed.
285 */
286 createPlaceholderCommand<Value = any>(props: DelayedPlaceholderCommandProps<Value>): DelayedCommand<Value>;
287 }
288 interface BaseExtension {
289 /**
290 * Create a decoration set which adds decorations to your editor. The
291 * first parameter is the `EditorState`.
292 *
293 * This can be used in combination with the `onApplyState` handler which
294 * can map the decoration.
295 *
296 * @param state - the editor state which was passed in.
297 */
298 createDecorations?(state: EditorState): DecorationSet;
299 }
300 interface AllExtensions {
301 decorations: DecorationsExtension;
302 }
303 }
304}
305export {};