diff --git a/examples/mentions/index.js b/examples/mentions/index.js index 4970c0e9a..0e860df5f 100644 --- a/examples/mentions/index.js +++ b/examples/mentions/index.js @@ -41,12 +41,24 @@ import Suggestions from './Suggestions' const USER_MENTION_NODE_TYPE = 'userMention' /** - * The annotation mark type that the menu will position itself against. The + * The annotation type that the menu will position itself against. The * "context" is just the current text after the @ symbol. * @type {String} */ -const CONTEXT_MARK_TYPE = 'mentionContext' +const CONTEXT_ANNOTATION_TYPE = 'mentionContext' + +/** + * Get a unique key for the search highlight annotations. + * + * @return {String} + */ + +let n = 0 + +function getMentionKey() { + return `highlight_${n++}` +} const schema = { inlines: { @@ -119,7 +131,8 @@ class MentionsExample extends React.Component { onChange={this.onChange} ref={this.editorRef} renderInline={this.renderInline} - renderMark={this.renderMark} + renderBlock={this.renderBlock} + renderAnnotation={this.renderAnnotation} schema={schema} /> {props.children}

+ } + + return next() + } + renderInline(props, editor, next) { const { attributes, node } = props @@ -216,11 +239,13 @@ class MentionsExample extends React.Component { const { selection } = change.value let annotations = change.value.annotations.filter( - value => value.mark.type !== CONTEXT_MARK_TYPE + annotation => annotation.type !== CONTEXT_ANNOTATION_TYPE ) if (inputValue && hasValidAncestors(change.value)) { - annotations = annotations.push({ + const key = getMentionKey() + + annotations = annotations.set(key, { anchor: { key: selection.start.key, offset: selection.start.offset - inputValue.length, @@ -229,15 +254,14 @@ class MentionsExample extends React.Component { key: selection.start.key, offset: selection.start.offset, }, - mark: { - type: CONTEXT_MARK_TYPE, - }, + type: CONTEXT_ANNOTATION_TYPE, + key: getMentionKey(), }) } this.setState({ value: change.value }, () => { // We need to set annotations after the value flushes into the editor. - this.editorRef.current.setannotations(annotations) + this.editorRef.current.setAnnotations(annotations) }) return } @@ -292,14 +316,9 @@ class MentionsExample extends React.Component { function hasValidAncestors(value) { const { document, selection } = value - const invalidParent = document.getClosest( - selection.start.key, - // In this simple case, we only want mentions to live inside a paragraph. - // This check can be adjusted for more complex rich text implementations. - node => node.type !== 'paragraph' - ) - - return !invalidParent + // In this simple case, we only want mentions to live inside a paragraph. + // This check can be adjusted for more complex rich text implementations. + return document.getParent(selection.start.key).type === 'paragraph' } export default MentionsExample diff --git a/packages/slate/src/commands/on-value.js b/packages/slate/src/commands/on-value.js index 4d877be18..f9e6f115f 100644 --- a/packages/slate/src/commands/on-value.js +++ b/packages/slate/src/commands/on-value.js @@ -58,6 +58,18 @@ Commands.setAnnotation = (editor, annotation, newProperties) => { }) } +Commands.setAnnotations = (editor, annotations = []) => { + const { value } = editor + const newProperties = Value.createProperties({ annotations }) + const prevProperties = pick(value, Object.keys(newProperties)) + + editor.applyOperation({ + type: 'set_value', + properties: prevProperties, + newProperties, + }) +} + /** * Export. * diff --git a/packages/slate/src/models/value.js b/packages/slate/src/models/value.js index 8a999969f..41bb47b05 100644 --- a/packages/slate/src/models/value.js +++ b/packages/slate/src/models/value.js @@ -68,7 +68,7 @@ class Value extends Record(DEFAULTS) { if (isPlainObject(a)) { const p = {} if ('annotations' in a) - p.annotations = Annotation.createList(a.annotations) + p.annotations = Annotation.createMap(a.annotations) if ('data' in a) p.data = Data.create(a.data) return p }