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:
committed by
Ian Storm Taylor
parent
67e397100e
commit
5471343ae8
@@ -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
|
||||
|
@@ -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.
|
||||
*
|
||||
|
@@ -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
|
||||
}
|
||||
|
Reference in New Issue
Block a user