We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
I'm working with React v17. I have a ContentEditable div which has the ability to mention a variable using tributejs.
ContentEditable
tributejs
Being able to place the cursor in front of the mention, just like how it works in Tribute's examples.
1. Versions:
"react": "^17.0.2", "react-contenteditable": "^3.3.5", "tributejs": "^5.1.3",
2. Related code:
let savedRange: Range const Editor = ({ placeholders }: Props) => { const { t } = useTranslation('template') const { field: { onChange, onBlur, value }, fieldState: { error } } = useController({ name: 'content', rules: { validate: () => { const isValid = editorRef.current.innerText.trim().length return !isValid ? (t('validationContentRequired') as string) : true } } }) const editorRef = useRef(null) const tributeRef = useRef<Tribute<TemplatePlaceholder>>() const initTribute = useCallback( (editorElm: HTMLElement) => { tributeRef.current = new Tribute({ values: placeholders, requireLeadingSpace: false, lookup: 'preview', containerClass: 'suggestion-container', menuContainer: document.getElementById('root'), noMatchTemplate: function () { return '<span style:"visibility: hidden;"></span>' }, selectTemplate: function (item: TributeItem<TemplatePlaceholder>) { return item ? `<span placeholder="${item.original.name}" preview="${item.original.preview}" original='${item.original.original}' contenteditable="false" >${t(item.original.name)}</span>` : '' }, menuItemTemplate: function (item: TributeItem<TemplatePlaceholder>) { return item ? t(item.original.name) : '' } }) tributeRef.current.attach(editorElm) }, [placeholders, t] ) useEffect(() => { const editorElm = editorRef.current if (!editorElm) return undefined if (placeholders && !tributeRef.current) { initTribute(editorElm) } return () => { if (tributeRef.current) { tributeRef.current.detach(editorElm) tributeRef.current = null } } }, [placeholders, initTribute]) const saveCaretPosition = () => { savedRange = RangeUtils.getCaretPosition() } return ( <> <div className={classNames('editor__wrapper editor', { 'editor--error': !!error })}> <div className='editor__content'> <ContentEditable className='w-full h-full outline-none' innerRef={editorRef} html={value || ''} onKeyDown={event => { if (event.key === 'Enter') { document.execCommand('insertLineBreak') event.preventDefault() } }} onChange={(event: ContentEditableEvent) => { onChange(event.target.value) }} onBlur={() => { saveCaretPosition() onBlur() }} onPaste={handlePaste} spellCheck={false} contentEditable={true} /> </div> </div> {!!error && <ErrorMessage>{error.message}</ErrorMessage>} </> ) } export default React.memo(Editor)
const placeHolderRegex = /<span placeholder="(\w+)" preview="([\w ]*)" original=["|']([\w{} ]*|<a[^<]*<\/a>)["|']>([^>]*|<a[^<]*<\/a> ?)<\/span>/gi const contenteditableRegex = /[ ]*contenteditable=["|']false["|']*/gi const linePlaceholderRegex = /{{ (\w+) }}/gi const transformMentionToPlaceholder = (content: string, type: string) => { content = content.replace(contenteditableRegex, '') content = content.replace(/"/gi, '"') if (type === TemplateTypes.Mail) { return content.replace(placeHolderRegex, `<span placeholder="$1" preview="$2" original='$3'>$3</span>`) } if (type === TemplateTypes.Line) { return content .replace(placeHolderRegex, `$3`) .replace(/<(\/)?div>/g, '') .replace(/<br>/g, '\n') } return content } const transformContentToMention = useCallback( (content: string, type = TemplateTypes.Mail) => { content = content?.replace(contenteditableRegex, '') switch (type) { case TemplateTypes.Mail: return content?.replace(placeHolderRegex, (_, p1, p2, p3) => { return `<span placeholder="${p1}" preview="${p2}" original='${p3}' contenteditable="false">${t(p1)}</span>` }) case TemplateTypes.Line: return content ?.replace(linePlaceholderRegex, (_, p) => { return `<span placeholder="${p}" preview="${p}" original="{{ ${p} }}" contenteditable="false">${t( p )}</span>` }) .replace(/\n/g, '<br>') default: return '' } }, [t] )
The text was updated successfully, but these errors were encountered:
No branches or pull requests
What happened?
I'm working with React v17.
I have a
ContentEditable
div which has the ability to mention a variable usingtributejs
.What did you expect to happen?
Being able to place the cursor in front of the mention, just like how it works in Tribute's examples.
Screenshot:
Reference:
1. Versions:
2. Related code:
The text was updated successfully, but these errors were encountered: