1
0
mirror of https://github.com/ianstormtaylor/slate.git synced 2025-08-25 16:20:49 +02:00

Fixed mentions example (#2877)

This commit is contained in:
Nadeem Shaik
2019-06-12 23:37:35 +05:30
committed by Ian Storm Taylor
parent 67e397100e
commit 5471343ae8
3 changed files with 51 additions and 20 deletions

View File

@@ -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}
/>
<Suggestions
@@ -131,8 +144,8 @@ class MentionsExample extends React.Component {
)
}
renderMark(props, editor, next) {
if (props.mark.type === CONTEXT_MARK_TYPE) {
renderAnnotation(props, editor, next) {
if (props.annotation.type === CONTEXT_ANNOTATION_TYPE) {
return (
// Adding the className here is important so that the `Suggestions`
// component can find an anchor.
@@ -145,6 +158,16 @@ class MentionsExample extends React.Component {
return next()
}
renderBlock(props, editor, next) {
const { attributes, node } = props
if (node.type === 'paragraph') {
return <p {...attributes}>{props.children}</p>
}
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

View File

@@ -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.
*

View File

@@ -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
}