Files
outline/shared/editor/lib/Extension.ts
T
Tom Moor 8c716b173a chore: Update editor generics (#12247)
* chore: Update editor generics

* fix: Address PR review on editor generics

- Restore null-guard on Link click handler so anchors aren't inert when no onClickLink is provided
- Mark onClickLink optional in LinkOptions and openLink command to match runtime
- Remove dead `collapsed` option from HeadingOptions
- Make ToggleBlock dictionary optional and restore optional-chained access for server-side schema instantiation

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-02 18:54:27 -04:00

112 lines
2.8 KiB
TypeScript

import type { PluginSimple } from "markdown-it";
import type { InputRule } from "prosemirror-inputrules";
import type { NodeType, MarkType, Schema } from "prosemirror-model";
import type { Command, Plugin, Selection } from "prosemirror-state";
import type { Editor } from "../../../app/editor";
export type CommandFactory = (attrs?: unknown, options?: unknown) => Command;
export type WidgetProps = {
rtl: boolean;
readOnly: boolean | undefined;
selection?: Selection;
};
export default class Extension<TOptions extends object = object> {
options: TOptions;
editor: Editor;
constructor(options: Partial<TOptions> = {}) {
this.options = {
...this.defaultOptions,
...options,
} as TOptions;
}
bindEditor(editor: Editor) {
this.editor = editor;
}
get type() {
return "extension";
}
get name() {
return "";
}
get plugins(): Plugin[] {
return [];
}
get rulePlugins(): PluginSimple[] {
return [];
}
get defaultOptions(): Partial<TOptions> {
return {};
}
/**
* Whether this extension is needed in read-only mode. When false (default), pure Extension types
* are not instantiated and their commands are blocked. Node and Mark extensions are always
* instantiated for the schema regardless of this setting.
*/
get allowInReadOnly(): boolean {
return false;
}
get focusAfterExecution(): boolean {
return true;
}
/**
* A widget is a React component to be rendered in the editor's context, independent of any
* specific node or mark. It can be used to render things like toolbars, menus, etc. Note that
* all widgets are observed automatically, so you can use observable values.
*
* @returns A React component
*/
widget(_props: WidgetProps): React.ReactElement | undefined {
return undefined;
}
/**
* A map of ProseMirror keymap bindings. It can be used to bind keyboard shortcuts to commands.
*
* @returns An object mapping key bindings to commands
*/
keys(_options: {
type?: NodeType | MarkType;
schema: Schema;
}): Record<string, Command | CommandFactory> {
return {};
}
/**
* A map of ProseMirror input rules. It can be used to automatically replace certain patterns
* while typing.
*
* @returns An array of input rules
*/
inputRules(_options: {
type?: NodeType | MarkType;
schema: Schema;
}): InputRule[] {
return [];
}
/**
* A map of ProseMirror commands. It can be used to expose commands to the editor. If a single
* command is returned, it will be available under the extension's name.
*
* @returns An object mapping command names to command factories, or a command factory
*/
commands(_options: {
type?: NodeType | MarkType;
schema: Schema;
}): Record<string, CommandFactory> | CommandFactory | undefined {
return {};
}
}