remirror/remirror

View on GitHub
packages/@remirror/core-types/src/core-types.ts

Summary

Maintainability
A
0 mins
Test Coverage
F
0%
import type {
  __INTERNAL_REMIRROR_IDENTIFIER_KEY__,
  RemirrorIdentifier,
} from '@remirror/core-constants';
import type {
  CommandFunction,
  CommandFunctionParameter,
  EditorSchema,
  EditorState,
  EditorView,
  ProsemirrorCommandFunction,
  ProsemirrorNode,
  Selection,
} from '@remirror/pm';
import type { MarkSpec, NodeSpec } from '@remirror/pm/model';
import type { Decoration, NodeView } from '@remirror/pm/view';

import type { Literal, ObjectMark, ProsemirrorAttributes } from './base-types';
import type { FromToParameter, MarkWithAttributes, NodeWithAttributes } from './parameter-builders';

/**
 * A JSON representation of the prosemirror Node.
 *
 * @remarks
 * This is used to represent the top level doc nodes content.
 */
export interface RemirrorJSON {
  type: string;
  marks?: Array<ObjectMark | string>;
  text?: string;
  content?: RemirrorJSON[];
  attrs?: Record<string, Literal>;
}

export interface StateJSON {
  [key: string]: unknown;
  doc: RemirrorJSON;
  selection: FromToParameter;
}

type GetAttributesFunction = (p: string[]) => ProsemirrorAttributes | undefined;

/**
 * A function which takes a regex match array (strings) or a single string match
 * and transforms it into an `Attributes` object.
 */
export type GetAttributes = ProsemirrorAttributes | GetAttributesFunction;

export interface GetAttributesParameter {
  /**
   * A helper function for setting receiving a match array / string and setting
   * the attributes for a node.
   */
  getAttributes: GetAttributes;
}

/**
 * Supported content for the remirror editor.
 *
 * @remarks
 *
 * Content can either be
 * - a string (which will be parsed by the stringHandler)
 * - JSON object matching Prosemirror expected shape
 * - A top level ProsemirrorNode
 *
 * @typeParam Schema - the underlying editor schema.
 */
export type RemirrorContentType<Schema extends EditorSchema = EditorSchema> =
  | string
  | RemirrorJSON
  | ProsemirrorNode<Schema>
  | EditorState<Schema>;

export interface NextParameter<Schema extends EditorSchema = EditorSchema>
  extends CommandFunctionParameter<Schema> {
  /**
   * A method to run the next (lower priority) command in the chain of
   * keybindings.
   *
   * @remarks
   *
   * This can be used to chain together keyboard commands between extensions.
   * It's possible that you will need to combine actions when a key is pressed
   * while still running the default action. This method allows for the
   * greater degree of control.
   *
   * By default, matching keyboard commands from the different extension are
   * chained together (in order of priority) until one returns `true`. Calling
   * `next` changes this default behaviour. The default keyboard chaining
   * stops and you are given full control of the keyboard command chain.
   */
  next: () => boolean;
}

/**
 * The command function passed to any of the keybindings.
 */
export type KeyBindingCommandFunction<Schema extends EditorSchema = EditorSchema> = CommandFunction<
  Schema,
  NextParameter<Schema>
>;

/**
 * A map of keyboard bindings and their corresponding command functions (a.k.a
 * editing actions).
 *
 * @typeParam Schema - the underlying editor schema.
 *
 * @remarks
 *
 * Each keyboard binding returns an object mapping the keys pressed to the
 * {@link KeyBindingCommandFunction}. By default the highest priority extension
 * will be run first. If it returns true, then nothing else will be run after.
 * If it returns `false` then the next (lower priority) extension defining the
 * same keybinding will be run.
 *
 * It is possible to combine the commands being run by using the `next`
 * parameter. When called it will run the keybinding command function for the
 * proceeding (lower priority) extension. The act of calling the `next` method
 * will prevent the default flow from executing.
 */
export type KeyBindings<Schema extends EditorSchema = EditorSchema> = Partial<
  Record<
    'Enter' | 'ArrowDown' | 'ArrowUp' | 'ArrowLeft' | 'ArrowRight' | 'Esc' | 'Delete' | 'Backspace',
    KeyBindingCommandFunction<Schema>
  >
> &
  Record<string, KeyBindingCommandFunction<Schema>>;

export type ProsemirrorKeyBindings<Schema extends EditorSchema = EditorSchema> = Record<
  string,
  ProsemirrorCommandFunction<Schema>
>;

export interface DOMCompatibleAttributes {
  [attribute: string]: string | number | undefined;
}

type DOMOutputSpecPos1 = DOMOutputSpecPosX | DOMCompatibleAttributes;
type DOMOutputSpecPosX = string | 0 | [string, 0] | [string, DOMCompatibleAttributes, 0];

/**
 * Defines the return type of the toDOM methods for both Nodes and marks
 *
 * @remarks
 * This differs from the default Prosemirror type definition which seemed didn't
 * work at the time of writing.
 *
 * Additionally we don't want to support domNodes in the toDOM spec since this
 * will create problems once SSR is fully supported
 */
export type DOMOutputSpec =
  | string
  | [string, 0?]
  | [string, DOMCompatibleAttributes, 0?]
  | [
      string,
      DOMOutputSpecPos1?,
      DOMOutputSpecPosX?,
      DOMOutputSpecPosX?,
      DOMOutputSpecPosX?,
      DOMOutputSpecPosX?,
      DOMOutputSpecPosX?,
      DOMOutputSpecPosX?,
      DOMOutputSpecPosX?,
      DOMOutputSpecPosX?,
      DOMOutputSpecPosX?,
    ];

/**
 * The schema spec definition for a node extension
 */
export interface NodeExtensionSpec
  extends Pick<
    NodeSpec,
    | 'content'
    | 'marks'
    | 'group'
    | 'inline'
    | 'atom'
    | 'attrs'
    | 'selectable'
    | 'draggable'
    | 'code'
    | 'defining'
    | 'isolating'
    | 'parseDOM'
    | 'toDebugString'
  > {
  /**
   * Defines the default way a node of this type should be serialized to
   * DOM/HTML (as used by [[`DOMSerializer.fromSchema`]].
   *
   * Should return a [[`DOMOutputSpec`]] that describes a DOM node, with an
   * optional number zero (“hole”) in it to indicate where the node's content
   * should be inserted.
   */
  toDOM?: (node: NodeWithAttributes) => DOMOutputSpec;
}

/**
 * The schema spec definition for a mark extension
 */
export interface MarkExtensionSpec
  extends Pick<MarkSpec, 'attrs' | 'inclusive' | 'excludes' | 'group' | 'spanning' | 'parseDOM'> {
  /**
   * Defines the default way marks of this type should be serialized to
   * DOM/HTML.
   */
  toDOM?: (mark: MarkWithAttributes, inline: boolean) => DOMOutputSpec;
}

/**
 * The method signature used to call the Prosemirror `nodeViews`
 *
 * @param node - the node which uses this nodeView
 * @param view - the editor view used by this nodeView
 * @param getPos - a utility method to get the absolute cursor position of the
 * node.
 * @param decorations - a list of the decorations affecting this node view (in
 * case the node view needs to update it's presentation)
 */
export type NodeViewMethod<View extends NodeView = NodeView> = (
  node: ProsemirrorNode,
  view: EditorView,
  getPos: (() => number) | boolean,
  decorations: Decoration[],
) => View;

/**
 * The core shape of any remirror specific object.
 */
export interface RemirrorIdentifierShape {
  [__INTERNAL_REMIRROR_IDENTIFIER_KEY__]: RemirrorIdentifier;
}

/**
 * A parameter for a non empty selection which defines the anchor (the non
 * movable part of the selection) and the head (the movable part of the
 * selection).
 */
export interface AnchorHeadParameter {
  /**
   * The non-movable part of the selection.
   */
  anchor: number;

  /**
   * The movable part of the selection.
   */
  head: number;
}

/**
 * The type of arguments acceptable for a selection.
 *
 * - Can be a selection
 * - A range of `{ from: number; to: number }`
 * - A single position with a `number`
 * - `'start' | 'end'`
 */
export type PrimitiveSelection =
  | Selection
  | FromToParameter
  | AnchorHeadParameter
  | number
  | 'start'
  | 'end'
  | 'all';