diff --git a/draft-js/draft-js-tests.tsx b/draft-js/draft-js-tests.tsx new file mode 100644 index 0000000000..91706cd7e0 --- /dev/null +++ b/draft-js/draft-js-tests.tsx @@ -0,0 +1,183 @@ +/// +/// +/// + +import * as React from "react"; + +import { +Editor, + EditorState, + Entity, + CharacterMetadata, + ContentBlock, + Modifier, + SelectionState, + genKey +} from "draft-js"; + +export class Tag extends React.Component { + constructor(props: any) { + super(props); + } + + remove = (): void => { + this.props.blockProps.removeBlock(this.props.block.getKey()); + } + + render () { + const {block} = this.props; + if (block.getEntityAt(0)) { + const data = Entity.get(block.getEntityAt(0)).getData(); + + return ( +
+ {data.content.name} + + clear + +
+ ); + } + } +} + +export class Hint extends React.Component { + constructor(props: any) { + super(props); + } + + render () { + const {block} = this.props; + if (block.getEntityAt(0)) { + const data = Entity.get(block.getEntityAt(0)).getData(); + + return ( +
+ {this.props.blockProps.autocomplete} + {data.content.text} +
+ ); + } + } +} + +export function removeBlock(editorState: EditorState, blockKey: string) { + const content = editorState.getCurrentContent(); + + const targetRange = new SelectionState({ + anchorKey: blockKey, + anchorOffset: 0, + focusKey: blockKey, + focusOffset: 1 + }); + + const withoutTag = Modifier.removeRange(content, targetRange, "backward"); + const resetBlock = Modifier.setBlockType( + withoutTag, + withoutTag.getSelectionAfter(), + "unstyled" + ); + + const newState = EditorState.push(editorState, resetBlock, "remove-range"); + return EditorState.forceSelection(newState, resetBlock.getSelectionAfter()); +} + +export function applyEntity(editorState: EditorState, blockKey: string, entityKey: string) { + const content = editorState.getCurrentContent(); + + const targetRange = new SelectionState({ + anchorKey: blockKey, + anchorOffset: 0, + focusKey: blockKey, + focusOffset: 1 + }); + + const withNewEntity = Modifier.applyEntity( + content, + targetRange, + entityKey + ) + + const newState = EditorState.push(editorState, withNewEntity, "change-entity"); + return EditorState.forceSelection(newState, withNewEntity.getSelectionAfter()); +} + +export function addTagBlock(content: any, editorState: EditorState): any { + const contentState = editorState.getCurrentContent(); + + const entityKey = Entity.create( + "TOKEN", + "IMMUTABLE", + {content} + ); + + const charData = CharacterMetadata.create({entity: entityKey}); + const tag = new ContentBlock({ + key: genKey(), + type: "tag", + text: "", + characterList: [], + }); + + const withTag = contentState.set("blockMap", contentState.getBlockMap().set(tag.key, tag)); + + const withRemovedPreviousBlock = withTag.set("blockMap", withTag.getBlockMap().delete(contentState.getSelectionBefore().getAnchorKey())) + + const withTagBlock = EditorState.push(editorState, withRemovedPreviousBlock, "insert-fragment"); + + return withTagBlock; +} + +export function addHintBlock(content: any, editorState: EditorState): any { + const contentState = editorState.getCurrentContent(); + const selectionState = editorState.getSelection(); + + const entityKey = Entity.create( + "TOKEN", + "IMMUTABLE", + {content} + ); + + const charData = CharacterMetadata.create({entity: entityKey}); + const hint = new ContentBlock({ + key: genKey(), + type: "hint", + text: "", + characterList: [], + }); + const empty = new ContentBlock({ + key: genKey(), + type: "unstyled", + text: "", + characterList: [], + }); + + const withEmpty = contentState.set("blockMap", contentState.getBlockMap().set(empty.key, empty)); + const withHint = withEmpty.set("blockMap", withEmpty.getBlockMap().set(hint.key, hint)); + return { + editorState: EditorState.forceSelection(EditorState.push(editorState, withHint, "insert-fragment"), selectionState), + blockKey: hint.key + } + +} + +export class SearchField extends React.Component { + public onChange: any; + + constructor(props: any) { + super(props); + this.onChange = (editorState: EditorState) => { + this.setState({editorState}) + }; + } + + render() { + const {editorState} = this.state; + return ( + + ) + } +} diff --git a/draft-js/draft-js.d.ts b/draft-js/draft-js.d.ts new file mode 100644 index 0000000000..8135a260c5 --- /dev/null +++ b/draft-js/draft-js.d.ts @@ -0,0 +1,271 @@ +// Type definitions for draft-js 0.1.0 +// Project: https://github.com/facebook/draft-js +// Definitions by: Pavel Evsegneev +// Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped +declare module "draft-js" { + module Draft { + interface IEditor { + new(): Editor + } + + interface EditorState { + getCurrentContent(): ContentState, + getSelection(): SelectionState, + getCurrentInlineStyle(): any, + getBlockTree(): any, + + createEmpty(decorator?: any): EditorState, + createWithContent(contentState: ContentState, decorator?: any): EditorState, + create(config: any): EditorState, + push(editorState: EditorState, contentState: ContentState, actionType: string): EditorState, + undo(editorState: EditorState): EditorState, + redo(editorState: EditorState): EditorState, + acceptSelection(editorState: EditorState, selectionState: SelectionState): EditorState, + forceSelection(editorState: EditorState, selectionState: SelectionState): EditorState, + + moveFocusToEnd(editorState: EditorState): EditorState + } + + interface CompositeDecorator { + getDecorations(): Array, + getComponentForKey(): any, + getPropsForKey(): any + } + + interface Entity { + create(type: string, mutability: string, data?: Object): EntityInstance, + add(instance: EntityInstance): string, + get(key: string): EntityInstance, + mergeData(key: string, toMerge: any): EntityInstance, + replaceData(key: string, newData: any): EntityInstance + } + + interface EntityInstance { + getData(): any, + getKey(): string, + getMutability(): string + } + + interface BlockMapBuilder { + createFromArray(blocks: Array): BlockMap + } + + interface CharacterMetadata { + create(config?: any): CharacterMetadata, + + applyStyle(record: CharacterMetadata, + style: string): CharacterMetadata, + + removeStyle(record: CharacterMetadata, + style: string): CharacterMetadata, + + applyEntity(record: CharacterMetadata, + entityKey?: string): CharacterMetadata, + + getStyle(): any, + hasStyle(style: string): boolean, + + getEntity(): string + } + + interface IContentBlock { + new(draftContentBlock: any): ContentBlock; + } + interface ContentBlock { + key: string, + type: string, + text: string, + characterList: any, + depth: number, + + getKey(): string, + getType(): string, + getText(): string, + getCharacterList(): any, + getLength(): number, + getDepth(): number, + getInlineStyleAt(offset: number): any, + getEntityAt(offset: number): string, + findStyleRanges(filterFn: Function, callback: Function): void, + findEntityRanges(filterFn: Function, callback: Function): void + + } + + interface ContentState { + createFromText(text: string): ContentState, + createFromBlockArray(blocks: Array): ContentState, + + getBlockMap(): BlockMap, + getSelectionBefore(): SelectionState, + getSelectionAfter(): SelectionState, + + getBlockForKey(key: string): ContentBlock, + getKeyBefore(key: string): string, + getKeyAfter(key: string): string, + + getBlockBefore(key: string): ContentBlock, + getBlockAfter(key: string): ContentBlock, + + getBlocksAsArray(): Array, + + getPlainText(): string, + hasText(): boolean, + + set(key: string, value: any): ContentState, + toJS(): any + } + + interface ISelectionState { + new(draftSelectionState: any): SelectionState; + createEmpty(blockKey: string): SelectionState; + } + + interface SelectionState { + getStartKey(): string, + getStartOffset(): number, + getEndKey(): string, + getEndOffset(): number, + getAnchorKey(): string, + getAnchorOffset(): number, + getFocusKey(): string, + getFocusOffset(): number, + + getIsBackward(): boolean, + getHasFocus(): boolean, + isCollapsed(): boolean, + + hasEdgeWithin(blockKey: string, start: number, end: number): boolean, + serialize(): string, + + get(key: string): any, + set(key: string, value: any): SelectionState + } + + interface BlockMap { + get(key: string): ContentBlock, + set(key: string, value: any): BlockMap, + delete(key: string): BlockMap + } + + interface Modifier { + replaceText(contentState: ContentState, + rangeToReplace: SelectionState, + text: string, + inlineStyle?: any, + entityKey?: string): ContentState, + + insertText(contentState: ContentState, + targetRange: SelectionState, + text: string, + inlineStyle?: any, + entityKey?: string): ContentState, + + moveText(contentState: ContentState, + removalRange: SelectionState, + targetRange: SelectionState): ContentState, + + replaceWithFragment(contentState: ContentState, + targetRange: SelectionState, + fragment: BlockMap): ContentState, + + removeRange(contentState: ContentState, + rangeToRemove: SelectionState, + removalDirection: string): ContentState, + + splitBlock(contentState: ContentState, + selectionState: SelectionState): ContentState, + + applyInlineStyle(contentState: ContentState, + selectionState: SelectionState, + inlineStyle: string): ContentState, + + removeInlineStyle(contentState: ContentState, + selectionState: SelectionState, + inlineStyle: string): ContentState, + + setBlockType(contentState: ContentState, + selectionState: SelectionState, + blockType: string): ContentState, + + applyEntity(contentState: ContentState, + selectionState: SelectionState, + entityKey: string): ContentState + } + + interface RichUtils { + currentBlockContainsLink(editorState: EditorState): boolean, + getCurrentBlockType(editor: EditorState): string, + handleKeyCommand(editorState: EditorState, command: string): any, + insertSoftNewline(editorState: EditorState): EditorState, + onBackspace(editorState: EditorState): EditorState, + onDelete(editorState: EditorState): EditorState, + onTab(event: Event, editorState: EditorState, maxDepth: number): EditorState, + toggleBlockType(editorState: EditorState, blockType: string): EditorState, + toggleCode(editorState: EditorState): EditorState, + toggleLink(editorState: EditorState, targetSelection: SelectionState, entityKey: string): EditorState, + tryToRemoveBlockStyle(editorState: EditorState): EditorState + } + + interface EditorProps { + editorState: EditorState, + onChange(editorState: EditorState): void, + + placeholder?: string, + textAlignment?: any, + blockRendererFn?: (ContentBlock: ContentBlock) => any, + blockStyleFn?: (ContentBlock: ContentBlock) => string, + customStyleMap?: any, + + readOnly?: boolean, + spellCheck?: boolean, + stripPastedStyles?: boolean, + + handleReturn?: (e: any) => boolean, + handleKeyCommand?: (command: string) => boolean, + handleBeforeInput?: (chars: string) => boolean, + handlePastedFiles?: (files: Array) => boolean, + handleDroppedFiles?: (selection: SelectionState, files: Array) => boolean, + handleDrop?: (selection: SelectionState, dataTransfer: any, isInternal: any) => boolean, + + onEscape?: (e: any) => void, + onTab?: (e: any) => void, + onUpArrow?: (e: any) => void, + onDownArrow?: (e: any) => void, + + suppressContentEditableWarning?: any + } + + interface Editor { + props: EditorProps + state: any, + refs: any, + context: any, + setState(): any, + render(): any, + forceUpdate(): any + } + + var Editor: IEditor; + var EditorState: EditorState; + + var CompositeDecorator: CompositeDecorator; + var Entity: Entity; + var EntityInstance: EntityInstance; + + var BlockMapBuilder: BlockMapBuilder; + var CharacterMetadata: CharacterMetadata; + var ContentBlock: IContentBlock; + var ContentState: ContentState; + var SelectionState: ISelectionState; + + var Modifier: Modifier; + var RichUtils: RichUtils; + + function convertFromRaw(rawState: any): Array; + function convertToRaw(contentState: ContentState): any; + function genKey(): string + } + + export = Draft; + +}