From 3b7a1bf72d0c3951416c771f7f149bfbda411111 Mon Sep 17 00:00:00 2001 From: Dylan Schiemann Date: Tue, 26 Apr 2022 18:28:58 +0100 Subject: [PATCH] Revert "Revert "Added types for options and common string literals"" (#4974) * Revert "Revert "Added types for options and common string literals (#4968)" (#4969)" This reverts commit b940640fc8f96abdd8725de1f0af0c6ba56156b9. * Add changeset --- .changeset/unlucky-goats-return.md | 5 + packages/slate/src/create-editor.ts | 5 +- packages/slate/src/interfaces/editor.ts | 408 +++++++++------------ packages/slate/src/interfaces/node.ts | 120 +++--- packages/slate/src/interfaces/path.ts | 35 +- packages/slate/src/interfaces/point-ref.ts | 3 +- packages/slate/src/interfaces/point.ts | 9 +- packages/slate/src/interfaces/range.ts | 31 +- packages/slate/src/interfaces/text.ts | 12 +- packages/slate/src/interfaces/types.ts | 19 + packages/slate/src/transforms/node.ts | 41 ++- packages/slate/src/transforms/selection.ts | 58 ++- packages/slate/src/transforms/text.ts | 67 ++-- 13 files changed, 377 insertions(+), 436 deletions(-) create mode 100644 .changeset/unlucky-goats-return.md create mode 100644 packages/slate/src/interfaces/types.ts diff --git a/.changeset/unlucky-goats-return.md b/.changeset/unlucky-goats-return.md new file mode 100644 index 000000000..ef9fa4286 --- /dev/null +++ b/.changeset/unlucky-goats-return.md @@ -0,0 +1,5 @@ +--- +'slate': minor +--- + +Added types for options and common string literals, thanks @JoshuaKGoldberg diff --git a/packages/slate/src/create-editor.ts b/packages/slate/src/create-editor.ts index 7fc54974f..8b8051478 100644 --- a/packages/slate/src/create-editor.ts +++ b/packages/slate/src/create-editor.ts @@ -14,6 +14,7 @@ import { Transforms, } from './' import { DIRTY_PATHS, DIRTY_PATH_KEYS, FLUSHING } from './utils/weak-maps' +import { TextUnit } from './interfaces/types' /** * Create a new Slate `Editor` object. @@ -121,7 +122,7 @@ export const createEditor = (): Editor => { } }, - deleteBackward: (unit: 'character' | 'word' | 'line' | 'block') => { + deleteBackward: (unit: TextUnit) => { const { selection } = editor if (selection && Range.isCollapsed(selection)) { @@ -129,7 +130,7 @@ export const createEditor = (): Editor => { } }, - deleteForward: (unit: 'character' | 'word' | 'line' | 'block') => { + deleteForward: (unit: TextUnit) => { const { selection } = editor if (selection && Range.isCollapsed(selection)) { diff --git a/packages/slate/src/interfaces/editor.ts b/packages/slate/src/interfaces/editor.ts index dd0cb7f87..4d2b4aa1d 100644 --- a/packages/slate/src/interfaces/editor.ts +++ b/packages/slate/src/interfaces/editor.ts @@ -15,7 +15,6 @@ import { RangeRef, Span, Text, - Transforms, } from '..' import { DIRTY_PATHS, @@ -32,11 +31,22 @@ import { } from '../utils/string' import { Descendant } from './node' import { Element } from './element' +import { + LeafEdge, + SelectionMode, + TextDirection, + TextUnit, + TextUnitAdjustment, + RangeDirection, + MaximizeMode, +} from './types' export type BaseSelection = Range | null export type Selection = ExtendedType<'Selection', BaseSelection> +export type EditorMarks = Omit + /** * The `Editor` interface stores all the state of a Slate editor. It is extended * by plugins that wish to add their own helpers and implement new behaviors. @@ -46,7 +56,7 @@ export interface BaseEditor { children: Descendant[] selection: Selection operations: Operation[] - marks: Omit | null + marks: EditorMarks | null // Schema-specific node behaviors. isInline: (element: Element) => boolean @@ -57,9 +67,9 @@ export interface BaseEditor { // Overrideable core actions. addMark: (key: string, value: any) => void apply: (operation: Operation) => void - deleteBackward: (unit: 'character' | 'word' | 'line' | 'block') => void - deleteForward: (unit: 'character' | 'word' | 'line' | 'block') => void - deleteFragment: (direction?: 'forward' | 'backward') => void + deleteBackward: (unit: TextUnit) => void + deleteForward: (unit: TextUnit) => void + deleteFragment: (direction?: TextDirection) => void getFragment: () => Descendant[] insertBreak: () => void insertSoftBreak: () => void @@ -71,52 +81,151 @@ export interface BaseEditor { export type Editor = ExtendedType<'Editor', BaseEditor> +export interface EditorAboveOptions { + at?: Location + match?: NodeMatch + mode?: MaximizeMode + voids?: boolean +} + +export interface EditorAfterOptions { + distance?: number + unit?: TextUnitAdjustment + voids?: boolean +} + +export interface EditorBeforeOptions { + distance?: number + unit?: TextUnitAdjustment + voids?: boolean +} + +export interface EditorDirectedDeletionOptions { + unit?: TextUnit +} + +export interface EditorFragmentDeletionOptions { + direction?: TextDirection +} + +export interface EditorLeafOptions { + depth?: number + edge?: LeafEdge +} + +export interface EditorLevelsOptions { + at?: Location + match?: NodeMatch + reverse?: boolean + voids?: boolean +} + +export interface EditorNextOptions { + at?: Location + match?: NodeMatch + mode?: SelectionMode + voids?: boolean +} + +export interface EditorNodeOptions { + depth?: number + edge?: LeafEdge +} + +export interface EditorNodesOptions { + at?: Location | Span + match?: NodeMatch + mode?: SelectionMode + universal?: boolean + reverse?: boolean + voids?: boolean +} + +export interface EditorNormalizeOptions { + force?: boolean +} + +export interface EditorParentOptions { + depth?: number + edge?: LeafEdge +} + +export interface EditorPathOptions { + depth?: number + edge?: LeafEdge +} + +export interface EditorPathRefOptions { + affinity?: TextDirection | null +} + +export interface EditorPointOptions { + edge?: LeafEdge +} + +export interface EditorPointRefOptions { + affinity?: TextDirection | null +} + +export interface EditorPositionsOptions { + at?: Location + unit?: TextUnitAdjustment + reverse?: boolean + voids?: boolean +} + +export interface EditorPreviousOptions { + at?: Location + match?: NodeMatch + mode?: SelectionMode + voids?: boolean +} + +export interface EditorRangeRefOptions { + affinity?: RangeDirection | null +} + +export interface EditorStringOptions { + voids?: boolean +} + +export interface EditorUnhangRangeOptions { + voids?: boolean +} + +export interface EditorVoidOptions { + at?: Location + mode?: MaximizeMode + voids?: boolean +} + export interface EditorInterface { above: ( editor: Editor, - options?: { - at?: Location - match?: NodeMatch - mode?: 'highest' | 'lowest' - voids?: boolean - } + options?: EditorAboveOptions ) => NodeEntry | undefined addMark: (editor: Editor, key: string, value: any) => void after: ( editor: Editor, at: Location, - options?: { - distance?: number - unit?: 'offset' | 'character' | 'word' | 'line' | 'block' - voids?: boolean - } + options?: EditorAfterOptions ) => Point | undefined before: ( editor: Editor, at: Location, - options?: { - distance?: number - unit?: 'offset' | 'character' | 'word' | 'line' | 'block' - voids?: boolean - } + options?: EditorBeforeOptions ) => Point | undefined deleteBackward: ( editor: Editor, - options?: { - unit?: 'character' | 'word' | 'line' | 'block' - } + options?: EditorDirectedDeletionOptions ) => void deleteForward: ( editor: Editor, - options?: { - unit?: 'character' | 'word' | 'line' | 'block' - } + options?: EditorDirectedDeletionOptions ) => void deleteFragment: ( editor: Editor, - options?: { - direction?: 'forward' | 'backward' - } + options?: EditorFragmentDeletionOptions ) => void edges: (editor: Editor, at: Location) => [Point, Point] end: (editor: Editor, at: Location) => Point @@ -144,119 +253,55 @@ export interface EditorInterface { leaf: ( editor: Editor, at: Location, - options?: { - depth?: number - edge?: 'start' | 'end' - } + options?: EditorLeafOptions ) => NodeEntry levels: ( editor: Editor, - options?: { - at?: Location - match?: NodeMatch - reverse?: boolean - voids?: boolean - } + options?: EditorLevelsOptions ) => Generator, void, undefined> marks: (editor: Editor) => Omit | null next: ( editor: Editor, - options?: { - at?: Location - match?: NodeMatch - mode?: 'all' | 'highest' | 'lowest' - voids?: boolean - } + options?: EditorNextOptions ) => NodeEntry | undefined - node: ( - editor: Editor, - at: Location, - options?: { - depth?: number - edge?: 'start' | 'end' - } - ) => NodeEntry + node: (editor: Editor, at: Location, options?: EditorNodeOptions) => NodeEntry nodes: ( editor: Editor, - options?: { - at?: Location | Span - match?: NodeMatch - mode?: 'all' | 'highest' | 'lowest' - universal?: boolean - reverse?: boolean - voids?: boolean - } + options?: EditorNodesOptions ) => Generator, void, undefined> - normalize: ( - editor: Editor, - options?: { - force?: boolean - } - ) => void + normalize: (editor: Editor, options?: EditorNormalizeOptions) => void parent: ( editor: Editor, at: Location, - options?: { - depth?: number - edge?: 'start' | 'end' - } + options?: EditorParentOptions ) => NodeEntry - path: ( - editor: Editor, - at: Location, - options?: { - depth?: number - edge?: 'start' | 'end' - } - ) => Path + path: (editor: Editor, at: Location, options?: EditorPathOptions) => Path pathRef: ( editor: Editor, path: Path, - options?: { - affinity?: 'backward' | 'forward' | null - } + options?: EditorPathRefOptions ) => PathRef pathRefs: (editor: Editor) => Set - point: ( - editor: Editor, - at: Location, - options?: { - edge?: 'start' | 'end' - } - ) => Point + point: (editor: Editor, at: Location, options?: EditorPointOptions) => Point pointRef: ( editor: Editor, point: Point, - options?: { - affinity?: 'backward' | 'forward' | null - } + options?: EditorPointRefOptions ) => PointRef pointRefs: (editor: Editor) => Set positions: ( editor: Editor, - options?: { - at?: Location - unit?: 'offset' | 'character' | 'word' | 'line' | 'block' - reverse?: boolean - voids?: boolean - } + options?: EditorPositionsOptions ) => Generator previous: ( editor: Editor, - options?: { - at?: Location - match?: NodeMatch - mode?: 'all' | 'highest' | 'lowest' - voids?: boolean - } + options?: EditorPreviousOptions ) => NodeEntry | undefined range: (editor: Editor, at: Location, to?: Location) => Range rangeRef: ( editor: Editor, range: Range, - options?: { - affinity?: 'backward' | 'forward' | 'outward' | 'inward' | null - } + options?: EditorRangeRefOptions ) => RangeRef rangeRefs: (editor: Editor) => Set removeMark: (editor: Editor, key: string) => void @@ -265,24 +310,16 @@ export interface EditorInterface { string: ( editor: Editor, at: Location, - options?: { - voids?: boolean - } + options?: EditorStringOptions ) => string unhangRange: ( editor: Editor, range: Range, - options?: { - voids?: boolean - } + options?: EditorUnhangRangeOptions ) => Range void: ( editor: Editor, - options?: { - at?: Location - mode?: 'highest' | 'lowest' - voids?: boolean - } + options?: EditorVoidOptions ) => NodeEntry | undefined withoutNormalizing: (editor: Editor, fn: () => void) => void } @@ -296,12 +333,7 @@ export const Editor: EditorInterface = { above( editor: Editor, - options: { - at?: Location - match?: NodeMatch - mode?: 'highest' | 'lowest' - voids?: boolean - } = {} + options: EditorAboveOptions = {} ): NodeEntry | undefined { const { voids = false, @@ -347,11 +379,7 @@ export const Editor: EditorInterface = { after( editor: Editor, at: Location, - options: { - distance?: number - unit?: 'offset' | 'character' | 'word' | 'line' | 'block' - voids?: boolean - } = {} + options: EditorAfterOptions = {} ): Point | undefined { const anchor = Editor.point(editor, at, { edge: 'end' }) const focus = Editor.end(editor, []) @@ -385,11 +413,7 @@ export const Editor: EditorInterface = { before( editor: Editor, at: Location, - options: { - distance?: number - unit?: 'offset' | 'character' | 'word' | 'line' | 'block' - voids?: boolean - } = {} + options: EditorBeforeOptions = {} ): Point | undefined { const anchor = Editor.start(editor, []) const focus = Editor.point(editor, at, { edge: 'start' }) @@ -423,9 +447,7 @@ export const Editor: EditorInterface = { deleteBackward( editor: Editor, - options: { - unit?: 'character' | 'word' | 'line' | 'block' - } = {} + options: EditorDirectedDeletionOptions = {} ): void { const { unit = 'character' } = options editor.deleteBackward(unit) @@ -437,9 +459,7 @@ export const Editor: EditorInterface = { deleteForward( editor: Editor, - options: { - unit?: 'character' | 'word' | 'line' | 'block' - } = {} + options: EditorDirectedDeletionOptions = {} ): void { const { unit = 'character' } = options editor.deleteForward(unit) @@ -451,9 +471,7 @@ export const Editor: EditorInterface = { deleteFragment( editor: Editor, - options: { - direction?: 'forward' | 'backward' - } = {} + options: EditorFragmentDeletionOptions = {} ): void { const { direction = 'forward' } = options editor.deleteFragment(direction) @@ -699,10 +717,7 @@ export const Editor: EditorInterface = { leaf( editor: Editor, at: Location, - options: { - depth?: number - edge?: 'start' | 'end' - } = {} + options: EditorLeafOptions = {} ): NodeEntry { const path = Editor.path(editor, at, options) const node = Node.leaf(editor, path) @@ -715,12 +730,7 @@ export const Editor: EditorInterface = { *levels( editor: Editor, - options: { - at?: Location - match?: NodeMatch - reverse?: boolean - voids?: boolean - } = {} + options: EditorLevelsOptions = {} ): Generator, void, undefined> { const { at = editor.selection, reverse = false, voids = false } = options let { match } = options @@ -812,12 +822,7 @@ export const Editor: EditorInterface = { next( editor: Editor, - options: { - at?: Location - match?: NodeMatch - mode?: 'all' | 'highest' | 'lowest' - voids?: boolean - } = {} + options: EditorNextOptions = {} ): NodeEntry | undefined { const { mode = 'lowest', voids = false } = options let { match, at = editor.selection } = options @@ -858,10 +863,7 @@ export const Editor: EditorInterface = { node( editor: Editor, at: Location, - options: { - depth?: number - edge?: 'start' | 'end' - } = {} + options: EditorNodeOptions = {} ): NodeEntry { const path = Editor.path(editor, at, options) const node = Node.get(editor, path) @@ -874,14 +876,7 @@ export const Editor: EditorInterface = { *nodes( editor: Editor, - options: { - at?: Location | Span - match?: NodeMatch - mode?: 'all' | 'highest' | 'lowest' - universal?: boolean - reverse?: boolean - voids?: boolean - } = {} + options: EditorNodesOptions = {} ): Generator, void, undefined> { const { at = editor.selection, @@ -982,12 +977,7 @@ export const Editor: EditorInterface = { * Normalize any dirty objects in the editor. */ - normalize( - editor: Editor, - options: { - force?: boolean - } = {} - ): void { + normalize(editor: Editor, options: EditorNormalizeOptions = {}): void { const { force = false } = options const getDirtyPaths = (editor: Editor) => { return DIRTY_PATHS.get(editor) || [] @@ -1072,10 +1062,7 @@ export const Editor: EditorInterface = { parent( editor: Editor, at: Location, - options: { - depth?: number - edge?: 'start' | 'end' - } = {} + options: EditorParentOptions = {} ): NodeEntry { const path = Editor.path(editor, at, options) const parentPath = Path.parent(path) @@ -1087,14 +1074,7 @@ export const Editor: EditorInterface = { * Get the path of a location. */ - path( - editor: Editor, - at: Location, - options: { - depth?: number - edge?: 'start' | 'end' - } = {} - ): Path { + path(editor: Editor, at: Location, options: EditorPathOptions = {}): Path { const { depth, edge } = options if (Path.isPath(at)) { @@ -1140,9 +1120,7 @@ export const Editor: EditorInterface = { pathRef( editor: Editor, path: Path, - options: { - affinity?: 'backward' | 'forward' | null - } = {} + options: EditorPathRefOptions = {} ): PathRef { const { affinity = 'forward' } = options const ref: PathRef = { @@ -1181,13 +1159,7 @@ export const Editor: EditorInterface = { * Get the start or end point of a location. */ - point( - editor: Editor, - at: Location, - options: { - edge?: 'start' | 'end' - } = {} - ): Point { + point(editor: Editor, at: Location, options: EditorPointOptions = {}): Point { const { edge = 'start' } = options if (Path.isPath(at)) { @@ -1228,9 +1200,7 @@ export const Editor: EditorInterface = { pointRef( editor: Editor, point: Point, - options: { - affinity?: 'backward' | 'forward' | null - } = {} + options: EditorPointRefOptions = {} ): PointRef { const { affinity = 'forward' } = options const ref: PointRef = { @@ -1280,12 +1250,7 @@ export const Editor: EditorInterface = { *positions( editor: Editor, - options: { - at?: Location - unit?: 'offset' | 'character' | 'word' | 'line' | 'block' - reverse?: boolean - voids?: boolean - } = {} + options: EditorPositionsOptions = {} ): Generator { const { at = editor.selection, @@ -1469,12 +1434,7 @@ export const Editor: EditorInterface = { previous( editor: Editor, - options: { - at?: Location - match?: NodeMatch - mode?: 'all' | 'highest' | 'lowest' - voids?: boolean - } = {} + options: EditorPreviousOptions = {} ): NodeEntry | undefined { const { mode = 'lowest', voids = false } = options let { match, at = editor.selection } = options @@ -1541,9 +1501,7 @@ export const Editor: EditorInterface = { rangeRef( editor: Editor, range: Range, - options: { - affinity?: 'backward' | 'forward' | 'outward' | 'inward' | null - } = {} + options: EditorRangeRefOptions = {} ): RangeRef { const { affinity = 'forward' } = options const ref: RangeRef = { @@ -1618,9 +1576,7 @@ export const Editor: EditorInterface = { string( editor: Editor, at: Location, - options: { - voids?: boolean - } = {} + options: EditorStringOptions = {} ): string { const { voids = false } = options const range = Editor.range(editor, at) @@ -1655,9 +1611,7 @@ export const Editor: EditorInterface = { unhangRange( editor: Editor, range: Range, - options: { - voids?: boolean - } = {} + options: EditorUnhangRangeOptions = {} ): Range { const { voids = false } = options let [start, end] = Range.edges(range) @@ -1702,11 +1656,7 @@ export const Editor: EditorInterface = { void( editor: Editor, - options: { - at?: Location - mode?: 'highest' | 'lowest' - voids?: boolean - } = {} + options: EditorVoidOptions = {} ): NodeEntry | undefined { return Editor.above(editor, { ...options, diff --git a/packages/slate/src/interfaces/node.ts b/packages/slate/src/interfaces/node.ts index e12a3a764..d78339f1a 100644 --- a/packages/slate/src/interfaces/node.ts +++ b/packages/slate/src/interfaces/node.ts @@ -10,42 +10,68 @@ import { Element, ElementEntry } from './element' export type BaseNode = Editor | Element | Text export type Node = Editor | Element | Text +export interface NodeAncestorsOptions { + reverse?: boolean +} + +export interface NodeChildrenOptions { + reverse?: boolean +} + +export interface NodeDescendantsOptions { + from?: Path + to?: Path + reverse?: boolean + pass?: (node: NodeEntry) => boolean +} + +export interface NodeElementsOptions { + from?: Path + to?: Path + reverse?: boolean + pass?: (node: NodeEntry) => boolean +} + +export interface NodeLevelsOptions { + reverse?: boolean +} + +export interface NodeNodesOptions { + from?: Path + to?: Path + reverse?: boolean + pass?: (entry: NodeEntry) => boolean +} + +export interface NodeTextsOptions { + from?: Path + to?: Path + reverse?: boolean + pass?: (node: NodeEntry) => boolean +} + export interface NodeInterface { ancestor: (root: Node, path: Path) => Ancestor ancestors: ( root: Node, path: Path, - options?: { - reverse?: boolean - } + options?: NodeAncestorsOptions ) => Generator, void, undefined> child: (root: Node, index: number) => Descendant children: ( root: Node, path: Path, - options?: { - reverse?: boolean - } + options?: NodeChildrenOptions ) => Generator, void, undefined> common: (root: Node, path: Path, another: Path) => NodeEntry descendant: (root: Node, path: Path) => Descendant descendants: ( root: Node, - options?: { - from?: Path - to?: Path - reverse?: boolean - pass?: (node: NodeEntry) => boolean - } + options?: NodeDescendantsOptions ) => Generator, void, undefined> elements: ( root: Node, - options?: { - from?: Path - to?: Path - reverse?: boolean - pass?: (node: NodeEntry) => boolean - } + options?: NodeElementsOptions ) => Generator extractProps: (node: Node) => NodeProps first: (root: Node, path: Path) => NodeEntry @@ -59,30 +85,18 @@ export interface NodeInterface { levels: ( root: Node, path: Path, - options?: { - reverse?: boolean - } + options?: NodeLevelsOptions ) => Generator matches: (node: Node, props: Partial) => boolean nodes: ( root: Node, - options?: { - from?: Path - to?: Path - reverse?: boolean - pass?: (entry: NodeEntry) => boolean - } + options?: NodeNodesOptions ) => Generator parent: (root: Node, path: Path) => Ancestor string: (node: Node) => string texts: ( root: Node, - options?: { - from?: Path - to?: Path - reverse?: boolean - pass?: (node: NodeEntry) => boolean - } + options?: NodeTextsOptions ) => Generator, void, undefined> } @@ -115,9 +129,7 @@ export const Node: NodeInterface = { *ancestors( root: Node, path: Path, - options: { - reverse?: boolean - } = {} + options: NodeAncestorsOptions = {} ): Generator, void, undefined> { for (const p of Path.ancestors(path, options)) { const n = Node.ancestor(root, p) @@ -157,9 +169,7 @@ export const Node: NodeInterface = { *children( root: Node, path: Path, - options: { - reverse?: boolean - } = {} + options: NodeChildrenOptions = {} ): Generator, void, undefined> { const { reverse = false } = options const ancestor = Node.ancestor(root, path) @@ -206,12 +216,7 @@ export const Node: NodeInterface = { *descendants( root: Node, - options: { - from?: Path - to?: Path - reverse?: boolean - pass?: (node: NodeEntry) => boolean - } = {} + options: NodeDescendantsOptions = {} ): Generator, void, undefined> { for (const [node, path] of Node.nodes(root, options)) { if (path.length !== 0) { @@ -230,12 +235,7 @@ export const Node: NodeInterface = { *elements( root: Node, - options: { - from?: Path - to?: Path - reverse?: boolean - pass?: (node: NodeEntry) => boolean - } = {} + options: NodeElementsOptions = {} ): Generator { for (const [node, path] of Node.nodes(root, options)) { if (Element.isElement(node)) { @@ -445,9 +445,7 @@ export const Node: NodeInterface = { *levels( root: Node, path: Path, - options: { - reverse?: boolean - } = {} + options: NodeLevelsOptions = {} ): Generator { for (const p of Path.levels(path, options)) { const n = Node.get(root, p) @@ -478,12 +476,7 @@ export const Node: NodeInterface = { *nodes( root: Node, - options: { - from?: Path - to?: Path - reverse?: boolean - pass?: (entry: NodeEntry) => boolean - } = {} + options: NodeNodesOptions = {} ): Generator { const { pass, reverse = false } = options const { from = [], to } = options @@ -589,12 +582,7 @@ export const Node: NodeInterface = { *texts( root: Node, - options: { - from?: Path - to?: Path - reverse?: boolean - pass?: (node: NodeEntry) => boolean - } = {} + options: NodeTextsOptions = {} ): Generator, void, undefined> { for (const [node, path] of Node.nodes(root, options)) { if (Text.isText(node)) { diff --git a/packages/slate/src/interfaces/path.ts b/packages/slate/src/interfaces/path.ts index 37981338d..085508671 100644 --- a/packages/slate/src/interfaces/path.ts +++ b/packages/slate/src/interfaces/path.ts @@ -1,5 +1,6 @@ import { produce } from 'immer' import { Operation } from '..' +import { TextDirection } from './types' /** * `Path` arrays are a list of indexes that describe a node's exact position in @@ -9,8 +10,20 @@ import { Operation } from '..' export type Path = number[] +export interface PathAncestorsOptions { + reverse?: boolean +} + +export interface PathLevelsOptions { + reverse?: boolean +} + +export interface PathTransformOptions { + affinity?: TextDirection | null +} + export interface PathInterface { - ancestors: (path: Path, options?: { reverse?: boolean }) => Path[] + ancestors: (path: Path, options?: PathAncestorsOptions) => Path[] common: (path: Path, another: Path) => Path compare: (path: Path, another: Path) => -1 | 0 | 1 endsAfter: (path: Path, another: Path) => boolean @@ -27,12 +40,7 @@ export interface PathInterface { isParent: (path: Path, another: Path) => boolean isPath: (value: any) => value is Path isSibling: (path: Path, another: Path) => boolean - levels: ( - path: Path, - options?: { - reverse?: boolean - } - ) => Path[] + levels: (path: Path, options?: PathLevelsOptions) => Path[] next: (path: Path) => Path operationCanTransformPath: (operation: Operation) => boolean parent: (path: Path) => Path @@ -41,7 +49,7 @@ export interface PathInterface { transform: ( path: Path, operation: Operation, - options?: { affinity?: 'forward' | 'backward' | null } + options?: PathTransformOptions ) => Path | null } @@ -53,7 +61,7 @@ export const Path: PathInterface = { * `reverse: true` option is passed, they are reversed. */ - ancestors(path: Path, options: { reverse?: boolean } = {}): Path[] { + ancestors(path: Path, options: PathAncestorsOptions = {}): Path[] { const { reverse = false } = options let paths = Path.levels(path, options) @@ -257,12 +265,7 @@ export const Path: PathInterface = { * true` option is passed, they are reversed. */ - levels( - path: Path, - options: { - reverse?: boolean - } = {} - ): Path[] { + levels(path: Path, options: PathLevelsOptions = {}): Path[] { const { reverse = false } = options const list: Path[] = [] @@ -367,7 +370,7 @@ export const Path: PathInterface = { transform( path: Path | null, operation: Operation, - options: { affinity?: 'forward' | 'backward' | null } = {} + options: PathTransformOptions = {} ): Path | null { return produce(path, p => { const { affinity = 'forward' } = options diff --git a/packages/slate/src/interfaces/point-ref.ts b/packages/slate/src/interfaces/point-ref.ts index 95222b971..c46327e44 100644 --- a/packages/slate/src/interfaces/point-ref.ts +++ b/packages/slate/src/interfaces/point-ref.ts @@ -1,4 +1,5 @@ import { Operation, Point } from '..' +import { TextDirection } from './types' /** * `PointRef` objects keep a specific point in a document synced over time as new @@ -8,7 +9,7 @@ import { Operation, Point } from '..' export interface PointRef { current: Point | null - affinity: 'forward' | 'backward' | null + affinity: TextDirection | null unref(): Point | null } diff --git a/packages/slate/src/interfaces/point.ts b/packages/slate/src/interfaces/point.ts index 1997c34a6..5ea788ff8 100644 --- a/packages/slate/src/interfaces/point.ts +++ b/packages/slate/src/interfaces/point.ts @@ -1,6 +1,7 @@ import { isPlainObject } from 'is-plain-object' import { produce } from 'immer' import { ExtendedType, Operation, Path } from '..' +import { TextDirection } from './types' /** * `Point` objects refer to a specific location in a text node in a Slate @@ -16,6 +17,10 @@ export interface BasePoint { export type Point = ExtendedType<'Point', BasePoint> +export interface PointTransformOptions { + affinity?: TextDirection | null +} + export interface PointInterface { compare: (point: Point, another: Point) => -1 | 0 | 1 isAfter: (point: Point, another: Point) => boolean @@ -25,7 +30,7 @@ export interface PointInterface { transform: ( point: Point, op: Operation, - options?: { affinity?: 'forward' | 'backward' | null } + options?: PointTransformOptions ) => Point | null } @@ -93,7 +98,7 @@ export const Point: PointInterface = { transform( point: Point | null, op: Operation, - options: { affinity?: 'forward' | 'backward' | null } = {} + options: PointTransformOptions = {} ): Point | null { return produce(point, p => { if (p === null) { diff --git a/packages/slate/src/interfaces/range.ts b/packages/slate/src/interfaces/range.ts index 16352acbb..03668443b 100644 --- a/packages/slate/src/interfaces/range.ts +++ b/packages/slate/src/interfaces/range.ts @@ -1,6 +1,7 @@ import { produce } from 'immer' import { isPlainObject } from 'is-plain-object' import { ExtendedType, Operation, Path, Point, PointEntry } from '..' +import { RangeDirection } from './types' /** * `Range` objects are a set of points that refer to a specific span of a Slate @@ -15,13 +16,16 @@ export interface BaseRange { export type Range = ExtendedType<'Range', BaseRange> +export interface RangeEdgesOptions { + reverse?: boolean +} + +export interface RangeTransformOptions { + affinity?: RangeDirection | null +} + export interface RangeInterface { - edges: ( - range: Range, - options?: { - reverse?: boolean - } - ) => [Point, Point] + edges: (range: Range, options?: RangeEdgesOptions) => [Point, Point] end: (range: Range) => Point equals: (range: Range, another: Range) => boolean includes: (range: Range, target: Path | Point | Range) => boolean @@ -36,9 +40,7 @@ export interface RangeInterface { transform: ( range: Range, op: Operation, - options?: { - affinity?: 'forward' | 'backward' | 'outward' | 'inward' | null - } + options?: RangeTransformOptions ) => Range | null } @@ -48,12 +50,7 @@ export const Range: RangeInterface = { * in the document. */ - edges( - range: Range, - options: { - reverse?: boolean - } = {} - ): [Point, Point] { + edges(range: Range, options: RangeEdgesOptions = {}): [Point, Point] { const { reverse = false } = options const { anchor, focus } = range return Range.isBackward(range) === reverse @@ -209,9 +206,7 @@ export const Range: RangeInterface = { transform( range: Range | null, op: Operation, - options: { - affinity?: 'forward' | 'backward' | 'outward' | 'inward' | null - } = {} + options: RangeTransformOptions = {} ): Range | null { return produce(range, r => { if (r === null) { diff --git a/packages/slate/src/interfaces/text.ts b/packages/slate/src/interfaces/text.ts index a7a8a490e..a876a67db 100644 --- a/packages/slate/src/interfaces/text.ts +++ b/packages/slate/src/interfaces/text.ts @@ -15,8 +15,12 @@ export interface BaseText { export type Text = ExtendedType<'Text', BaseText> +export interface TextEqualsOptions { + loose?: boolean +} + export interface TextInterface { - equals: (text: Text, another: Text, options?: { loose?: boolean }) => boolean + equals: (text: Text, another: Text, options?: TextEqualsOptions) => boolean isText: (value: any) => value is Text isTextList: (value: any) => value is Text[] isTextProps: (props: any) => props is Partial @@ -31,11 +35,7 @@ export const Text: TextInterface = { * When loose is set, the text is not compared. This is * used to check whether sibling text nodes can be merged. */ - equals( - text: Text, - another: Text, - options: { loose?: boolean } = {} - ): boolean { + equals(text: Text, another: Text, options: TextEqualsOptions = {}): boolean { const { loose = false } = options function omitText(obj: Record) { diff --git a/packages/slate/src/interfaces/types.ts b/packages/slate/src/interfaces/types.ts new file mode 100644 index 000000000..32a898144 --- /dev/null +++ b/packages/slate/src/interfaces/types.ts @@ -0,0 +1,19 @@ +export type LeafEdge = 'start' | 'end' + +export type MaximizeMode = RangeMode | 'all' + +export type MoveUnit = 'offset' | 'character' | 'word' | 'line' + +export type RangeDirection = TextDirection | 'outward' | 'inward' + +export type RangeMode = 'highest' | 'lowest' + +export type SelectionEdge = 'anchor' | 'focus' | 'start' | 'end' + +export type SelectionMode = 'all' | 'highest' | 'lowest' + +export type TextDirection = 'forward' | 'backward' + +export type TextUnit = 'character' | 'word' | 'line' | 'block' + +export type TextUnitAdjustment = TextUnit | 'offset' diff --git a/packages/slate/src/transforms/node.ts b/packages/slate/src/transforms/node.ts index 11f3791dc..7574ebc84 100644 --- a/packages/slate/src/transforms/node.ts +++ b/packages/slate/src/transforms/node.ts @@ -13,6 +13,7 @@ import { } from '..' import { NodeMatch, PropsCompare, PropsMerge } from '../interfaces/editor' import { PointRef } from '../interfaces/point-ref' +import { RangeMode, MaximizeMode } from '../interfaces/types' export interface NodeTransforms { insertNodes: ( @@ -21,7 +22,7 @@ export interface NodeTransforms { options?: { at?: Location match?: NodeMatch - mode?: 'highest' | 'lowest' + mode?: RangeMode hanging?: boolean select?: boolean voids?: boolean @@ -32,7 +33,7 @@ export interface NodeTransforms { options?: { at?: Location match?: NodeMatch - mode?: 'all' | 'highest' | 'lowest' + mode?: MaximizeMode voids?: boolean } ) => void @@ -41,7 +42,7 @@ export interface NodeTransforms { options?: { at?: Location match?: NodeMatch - mode?: 'highest' | 'lowest' + mode?: RangeMode hanging?: boolean voids?: boolean } @@ -51,7 +52,7 @@ export interface NodeTransforms { options: { at?: Location match?: NodeMatch - mode?: 'all' | 'highest' | 'lowest' + mode?: MaximizeMode to: Path voids?: boolean } @@ -61,7 +62,7 @@ export interface NodeTransforms { options?: { at?: Location match?: NodeMatch - mode?: 'highest' | 'lowest' + mode?: RangeMode hanging?: boolean voids?: boolean } @@ -72,7 +73,7 @@ export interface NodeTransforms { options?: { at?: Location match?: NodeMatch - mode?: 'all' | 'highest' | 'lowest' + mode?: MaximizeMode hanging?: boolean split?: boolean voids?: boolean @@ -85,7 +86,7 @@ export interface NodeTransforms { options?: { at?: Location match?: NodeMatch - mode?: 'highest' | 'lowest' + mode?: RangeMode always?: boolean height?: number voids?: boolean @@ -97,7 +98,7 @@ export interface NodeTransforms { options?: { at?: Location match?: NodeMatch - mode?: 'all' | 'highest' | 'lowest' + mode?: MaximizeMode split?: boolean voids?: boolean } @@ -107,7 +108,7 @@ export interface NodeTransforms { options?: { at?: Location match?: NodeMatch - mode?: 'all' | 'highest' | 'lowest' + mode?: MaximizeMode split?: boolean voids?: boolean } @@ -118,7 +119,7 @@ export interface NodeTransforms { options?: { at?: Location match?: NodeMatch - mode?: 'all' | 'highest' | 'lowest' + mode?: MaximizeMode split?: boolean voids?: boolean } @@ -136,7 +137,7 @@ export const NodeTransforms: NodeTransforms = { options: { at?: Location match?: NodeMatch - mode?: 'highest' | 'lowest' + mode?: RangeMode hanging?: boolean select?: boolean voids?: boolean @@ -255,7 +256,7 @@ export const NodeTransforms: NodeTransforms = { options: { at?: Location match?: NodeMatch - mode?: 'all' | 'highest' | 'lowest' + mode?: MaximizeMode voids?: boolean } = {} ): void { @@ -319,7 +320,7 @@ export const NodeTransforms: NodeTransforms = { options: { at?: Location match?: NodeMatch - mode?: 'highest' | 'lowest' + mode?: RangeMode hanging?: boolean voids?: boolean } = {} @@ -459,7 +460,7 @@ export const NodeTransforms: NodeTransforms = { options: { at?: Location match?: NodeMatch - mode?: 'all' | 'highest' | 'lowest' + mode?: MaximizeMode to: Path voids?: boolean } @@ -520,7 +521,7 @@ export const NodeTransforms: NodeTransforms = { options: { at?: Location match?: NodeMatch - mode?: 'highest' | 'lowest' + mode?: RangeMode hanging?: boolean voids?: boolean } = {} @@ -567,7 +568,7 @@ export const NodeTransforms: NodeTransforms = { options: { at?: Location match?: NodeMatch - mode?: 'all' | 'highest' | 'lowest' + mode?: MaximizeMode hanging?: boolean split?: boolean voids?: boolean @@ -692,7 +693,7 @@ export const NodeTransforms: NodeTransforms = { options: { at?: Location match?: NodeMatch - mode?: 'highest' | 'lowest' + mode?: RangeMode always?: boolean height?: number voids?: boolean @@ -821,7 +822,7 @@ export const NodeTransforms: NodeTransforms = { options: { at?: Location match?: NodeMatch - mode?: 'all' | 'highest' | 'lowest' + mode?: MaximizeMode split?: boolean voids?: boolean } = {} @@ -849,7 +850,7 @@ export const NodeTransforms: NodeTransforms = { options: { at?: Location match?: NodeMatch - mode?: 'all' | 'highest' | 'lowest' + mode?: MaximizeMode split?: boolean voids?: boolean } = {} @@ -915,7 +916,7 @@ export const NodeTransforms: NodeTransforms = { options: { at?: Location match?: NodeMatch - mode?: 'all' | 'highest' | 'lowest' + mode?: MaximizeMode split?: boolean voids?: boolean } = {} diff --git a/packages/slate/src/transforms/selection.ts b/packages/slate/src/transforms/selection.ts index d82dffc54..91275caed 100644 --- a/packages/slate/src/transforms/selection.ts +++ b/packages/slate/src/transforms/selection.ts @@ -1,29 +1,30 @@ import { Editor, Location, Point, Range, Transforms } from '..' +import { SelectionEdge, MoveUnit } from '../interfaces/types' + +export interface SelectionCollapseOptions { + edge?: SelectionEdge +} + +export interface SelectionMoveOptions { + distance?: number + unit?: MoveUnit + reverse?: boolean + edge?: SelectionEdge +} + +export interface SelectionSetPointOptions { + edge?: SelectionEdge +} export interface SelectionTransforms { - collapse: ( - editor: Editor, - options?: { - edge?: 'anchor' | 'focus' | 'start' | 'end' - } - ) => void + collapse: (editor: Editor, options?: SelectionCollapseOptions) => void deselect: (editor: Editor) => void - move: ( - editor: Editor, - options?: { - distance?: number - unit?: 'offset' | 'character' | 'word' | 'line' - reverse?: boolean - edge?: 'anchor' | 'focus' | 'start' | 'end' - } - ) => void + move: (editor: Editor, options?: SelectionMoveOptions) => void select: (editor: Editor, target: Location) => void setPoint: ( editor: Editor, props: Partial, - options?: { - edge?: 'anchor' | 'focus' | 'start' | 'end' - } + options?: SelectionSetPointOptions ) => void setSelection: (editor: Editor, props: Partial) => void } @@ -33,12 +34,7 @@ export const SelectionTransforms: SelectionTransforms = { * Collapse the selection. */ - collapse( - editor: Editor, - options: { - edge?: 'anchor' | 'focus' | 'start' | 'end' - } = {} - ): void { + collapse(editor: Editor, options: SelectionCollapseOptions = {}): void { const { edge = 'anchor' } = options const { selection } = editor @@ -77,15 +73,7 @@ export const SelectionTransforms: SelectionTransforms = { * Move the selection's point forward or backward. */ - move( - editor: Editor, - options: { - distance?: number - unit?: 'offset' | 'character' | 'word' | 'line' - reverse?: boolean - edge?: 'anchor' | 'focus' | 'start' | 'end' - } = {} - ): void { + move(editor: Editor, options: SelectionMoveOptions = {}): void { const { selection } = editor const { distance = 1, unit = 'character', reverse = false } = options let { edge = null } = options @@ -164,9 +152,7 @@ export const SelectionTransforms: SelectionTransforms = { setPoint( editor: Editor, props: Partial, - options: { - edge?: 'anchor' | 'focus' | 'start' | 'end' - } = {} + options: SelectionSetPointOptions = {} ): void { const { selection } = editor let { edge = 'both' } = options diff --git a/packages/slate/src/transforms/text.ts b/packages/slate/src/transforms/text.ts index 51c9f6a0e..406876554 100644 --- a/packages/slate/src/transforms/text.ts +++ b/packages/slate/src/transforms/text.ts @@ -10,35 +10,39 @@ import { Range, Transforms, } from '..' +import { TextUnit } from '../interfaces/types' + +export interface TextDeleteOptions { + at?: Location + distance?: number + unit?: TextUnit + reverse?: boolean + hanging?: boolean + voids?: boolean +} + +export interface TextInsertFragmentOptions { + at?: Location + hanging?: boolean + voids?: boolean +} + +export interface TextInsertTextOptions { + at?: Location + voids?: boolean +} export interface TextTransforms { - delete: ( - editor: Editor, - options?: { - at?: Location - distance?: number - unit?: 'character' | 'word' | 'line' | 'block' - reverse?: boolean - hanging?: boolean - voids?: boolean - } - ) => void + delete: (editor: Editor, options?: TextDeleteOptions) => void insertFragment: ( editor: Editor, fragment: Node[], - options?: { - at?: Location - hanging?: boolean - voids?: boolean - } + options?: TextInsertFragmentOptions ) => void insertText: ( editor: Editor, text: string, - options?: { - at?: Location - voids?: boolean - } + options?: TextInsertTextOptions ) => void } @@ -47,17 +51,7 @@ export const TextTransforms: TextTransforms = { * Delete content in the editor. */ - delete( - editor: Editor, - options: { - at?: Location - distance?: number - unit?: 'character' | 'word' | 'line' | 'block' - reverse?: boolean - hanging?: boolean - voids?: boolean - } = {} - ): void { + delete(editor: Editor, options: TextDeleteOptions = {}): void { Editor.withoutNormalizing(editor, () => { const { reverse = false, @@ -231,11 +225,7 @@ export const TextTransforms: TextTransforms = { insertFragment( editor: Editor, fragment: Node[], - options: { - at?: Location - hanging?: boolean - voids?: boolean - } = {} + options: TextInsertFragmentOptions = {} ): void { Editor.withoutNormalizing(editor, () => { const { hanging = false, voids = false } = options @@ -462,10 +452,7 @@ export const TextTransforms: TextTransforms = { insertText( editor: Editor, text: string, - options: { - at?: Location - voids?: boolean - } = {} + options: TextInsertTextOptions = {} ): void { Editor.withoutNormalizing(editor, () => { const { voids = false } = options