diff --git a/types/slate-react/index.d.ts b/types/slate-react/index.d.ts index 4cf4e202f4..033523f4a5 100644 --- a/types/slate-react/index.d.ts +++ b/types/slate-react/index.d.ts @@ -11,6 +11,7 @@ // Jack Allen // Benjamin Evenson // Kay Delaney +// Brian Ingles // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped // TypeScript Version: 2.8 import { @@ -101,15 +102,15 @@ export interface RenderInlineProps extends RenderNodeProps { export type EventHook = (event: T, editor: Editor, next: () => any) => any; -export interface Plugin extends CorePlugin { - decorateNode?: (node: SlateNode, editor: CoreEditor, next: () => any) => any; - renderAnnotation?: (props: RenderAnnotationProps, editor: CoreEditor, next: () => any) => any; - renderBlock?: (props: RenderBlockProps, editor: CoreEditor, next: () => any) => any; - renderDecoration?: (props: RenderDecorationProps, editor: CoreEditor, next: () => any) => any; - renderDocument?: (props: RenderDocumentProps, editor: CoreEditor, next: () => any) => any; - renderEditor?: (props: EditorProps, editor: CoreEditor, next: () => any) => any; - renderInline?: (props: RenderInlineProps, editor: CoreEditor, next: () => any) => any; - renderMark?: (props: RenderMarkProps, editor: CoreEditor, next: () => any) => any; +export interface Plugin extends CorePlugin { + decorateNode?: (node: SlateNode, editor: T, next: () => any) => any; + renderAnnotation?: (props: RenderAnnotationProps, editor: T, next: () => any) => any; + renderBlock?: (props: RenderBlockProps, editor: T, next: () => any) => any; + renderDecoration?: (props: RenderDecorationProps, editor: T, next: () => any) => any; + renderDocument?: (props: RenderDocumentProps, editor: T, next: () => any) => any; + renderEditor?: (props: EditorProps, editor: T, next: () => any) => any; + renderInline?: (props: RenderInlineProps, editor: T, next: () => any) => any; + renderMark?: (props: RenderMarkProps, editor: T, next: () => any) => any; shouldNodeComponentUpdate?: ( previousProps: RenderNodeProps, @@ -123,6 +124,7 @@ export interface Plugin extends CorePlugin { onClick?: EventHook; onCompositionEnd?: EventHook; onCompositionStart?: EventHook; + onContextMenu?: EventHook; onCopy?: EventHook; onCut?: EventHook; onDragEnd?: EventHook; @@ -139,8 +141,8 @@ export interface Plugin extends CorePlugin { onSelect?: EventHook; } -export type PluginOrPlugins = Plugin | Plugins; -export interface Plugins extends Array {} +export type PluginOrPlugins = Plugin | Plugins; +export interface Plugins extends Array> {} export interface OnChangeParam { operations: Immutable.List; @@ -148,14 +150,14 @@ export interface OnChangeParam { } export type OnChangeFn = (change: OnChangeParam) => any; -export interface BasicEditorProps { +export interface BasicEditorProps { value: Value; autoCorrect?: boolean; autoFocus?: boolean; className?: string; onChange?: OnChangeFn; placeholder?: any; - plugins?: Plugins; + plugins?: Plugins; readOnly?: boolean; role?: string; schema?: SchemaProperties; @@ -164,7 +166,7 @@ export interface BasicEditorProps { tabIndex?: number; } -export type EditorProps = BasicEditorProps & Plugin; +export type EditorProps = BasicEditorProps & Plugin; export interface EditorState { value: Value; diff --git a/types/slate-react/slate-react-tests.tsx b/types/slate-react/slate-react-tests.tsx index 4005557817..e3e81e662f 100644 --- a/types/slate-react/slate-react-tests.tsx +++ b/types/slate-react/slate-react-tests.tsx @@ -1,11 +1,32 @@ import { Editor, Plugin, EditorProps, OnChangeFn, RenderBlockProps, RenderInlineProps } from 'slate-react'; -import { Value, Editor as Controller, Point, Range, Inline, Mark, Document, Decoration, Operation } from 'slate'; +import { Value, Point, Range, Inline, Mark, Document, Decoration, Operation } from 'slate'; import * as React from "react"; import { List } from "immutable"; +declare module 'slate-react' { + // Plugins can add command and query method. + // Testing that if we extend the interface, the compiler is aware of the + // new methods inside of other plugin functions. + interface Editor { + someCommand: () => Editor; + someQuery: () => string; + } +} + class MyPlugin implements Plugin { - renderBlock(props: RenderBlockProps, editor: Controller, next: () => void) { + commands = { + someCommand: (editor: Editor) => editor, + }; + queries = { + someQuery: (editor: Editor) => 'query result', + }; + + renderBlock(props: RenderBlockProps, editor: Editor, next: () => void) { const { node } = props; + + editor.someCommand(); + const queryResult: string = editor.someQuery(); + if (node) { switch (node.object) { case 'block': @@ -15,7 +36,7 @@ class MyPlugin implements Plugin { } } } - renderInline(props: RenderInlineProps, editor: Controller, next: () => void) { + renderInline(props: RenderInlineProps, editor: Editor, next: () => void) { const { node } = props; if (node) { switch (node.object) { @@ -38,6 +59,7 @@ const eventPlugin: Plugin = { onClick: (event, editor, next) => {[event.nativeEvent, event.clientX, ]; }, onCompositionEnd: (event, editor, next) => {[event.nativeEvent, event.data, ]; }, onCompositionStart: (event, editor, next) => {[event.nativeEvent, event.data, ]; }, + onContextMenu: (event, editor, next) => {[event.nativeEvent, event.clientX, ]; }, onCopy: (event, editor, next) => {[event.nativeEvent, event.clipboardData, ]; }, onCut: (event, editor, next) => {[event.nativeEvent, event.clipboardData, ]; }, onDragEnd: (event, editor, next) => {[event.nativeEvent.dataTransfer, event.clientX, ]; }, diff --git a/types/slate/index.d.ts b/types/slate/index.d.ts index 6c99a3c35d..ba0b9ded09 100644 --- a/types/slate/index.d.ts +++ b/types/slate/index.d.ts @@ -15,6 +15,7 @@ // Yuichiro Tsuchiya // Kamil KamiƄski // Jay Chen +// Brian Ingles // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped // TypeScript Version: 2.8 import * as Immutable from "immutable"; @@ -1457,28 +1458,28 @@ export interface Query { args: any[]; } -export type CommandFunc = (editor: Editor, ...args: any[]) => Editor; -export type QueryFunc = (editor: Editor, ...args: any[]) => any; +export type CommandFunc = (editor: T, ...args: any[]) => T; +export type QueryFunc = (editor: T, ...args: any[]) => any; -export interface Plugin { - normalizeNode?: (node: Node, editor: Editor, next: () => void) => ((editor: Editor) => void) | void; - onChange?: (editor: Editor, next: () => void) => void; - onCommand?: (command: Command, editor: Editor, next: () => void) => void; - onConstruct?: (editor: Editor, next: () => void) => void; - onQuery?: (query: Query, editor: Editor, next: () => void) => void; - validateNode?: (node: Node, editor: Editor, next: () => void) => SlateError | void; +export interface Plugin { + normalizeNode?: (node: Node, editor: T, next: () => void) => ((editor: T) => void) | void; + onChange?: (editor: T, next: () => void) => void; + onCommand?: (command: Command, editor: T, next: () => void) => void; + onConstruct?: (editor: T, next: () => void) => void; + onQuery?: (query: Query, editor: T, next: () => void) => void; + validateNode?: (node: Node, editor: T, next: () => void) => SlateError | void; - commands?: {[name: string]: CommandFunc}; - queries?: {[name: string]: QueryFunc}; + commands?: {[name: string]: CommandFunc}; + queries?: {[name: string]: QueryFunc}; schema?: SchemaProperties; } -export interface Plugins extends Array {} +export interface Plugins extends Array | Plugins> {} -export interface EditorProperties { +export interface EditorProperties { object?: "editor"; onChange?: (change: { operations: Immutable.List; value: Value }) => void; - plugins?: Plugins; + plugins?: Plugins; readOnly?: boolean; value?: Value; } @@ -1495,11 +1496,11 @@ export class Editor implements Controller { middleware: object; onChange: (change: { operations: Immutable.List, value: Value }) => void; operations: Immutable.List; - plugins: Plugin[]; + plugins: Array>; readOnly: boolean; value: Value; - constructor(attributes: EditorProperties, options?: EditorOptions); + constructor(attributes: EditorProperties, options?: EditorOptions); /** * Synchronously flush the current changes to editor, calling onChange. diff --git a/types/slate/slate-tests.ts b/types/slate/slate-tests.ts index f4dc4a7e47..2ea8cb1843 100644 --- a/types/slate/slate-tests.ts +++ b/types/slate/slate-tests.ts @@ -1,5 +1,6 @@ import { Block, + Controller, Value, Data, BlockJSON, @@ -108,6 +109,47 @@ const schema2: SchemaProperties = { } }; +const pluginDefault: Plugin = { + normalizeNode: (node: Node, editor, next: () => void) => { + // $ExpectType Controller + editor; + }, + onChange: (editor, next: () => void) => { + // $ExpectType Controller + editor; + }, + onCommand: (command: Command, editor, next: () => void) => { + // $ExpectType Controller + editor; + }, + onConstruct: (editor, next: () => void) => { + // $ExpectType Controller + editor; + }, + onQuery: (query: Query, editor, next: () => void) => { + // $ExpectType Controller + editor; + }, + validateNode: (node: Node, editor, next: () => void) => { + // $ExpectType Controller + editor; + }, + + commands: { + someCommand: (editor, ...args: any[]) => { + // $ExpectType Controller + editor; + return editor; + } + }, + queries: { + someQuery: (editor, ...args: any[]) => { + // $ExpectType Controller + editor; + } + }, +}; + const pluginCommandName = 'plugin_command'; const pluginCommandFunc = (editor: Editor, ...args: any[]) => editor; @@ -115,7 +157,7 @@ const pluginQueryName = 'plugin_query'; const pluginQueryResult = 1000; const pluginQueryFunc = (editor: Editor, ...args: any[]) => pluginQueryResult; -const plugin: Plugin = { +const plugin: Plugin = { normalizeNode: (node: Node, editor: Editor, next: () => void) => next(), onChange: (editor: Editor, next: () => void) => next(), onCommand: (command: Command, editor: Editor, next: () => void) => next(),