Whenever I pose a question, the solution always seems to reveal itself shortly after. In Draft.js, there exists a feature called "decorators", which is thoroughly explained in this documentation:
The concept behind decorators involves creating a set of functions or components. The 'strategy' function defines the strategy, while the 'component' represents the actual component to be used.
const compositeDecorator = new CompositeDecorator([
{
strategy: handleStrategy,
component: HandleSpan,
},
{
strategy: hashtagStrategy,
component: HashtagSpan,
},
]);
In defining strategies, regex can prove to be quite handy. With regex, users have the flexibility to create custom syntaxes or utilize those from template engines for widget embedding purposes. The sample strategies provided in the documentation serve as a helpful starting point:
// Note: these regex examples are not ideal and should not be directly copied!
const HANDLE_REGEX = /\@[\w]+/g;
const HASHTAG_REGEX = /\#[\w\u0590-\u05ff]+/g;
function handleStrategy(contentBlock, callback, contentState) {
findWithRegex(HANDLE_REGEX, contentBlock, callback);
}
function hashtagStrategy(contentBlock, callback, contentState) {
findWithRegex(HASHTAG_REGEX, contentBlock, callback);
}
function findWithRegex(regex, contentBlock, callback) {
const text = contentBlock.getText();
let matchArr, start;
while ((matchArr = regex.exec(text)) !== null) {
start = matchArr.index;
callback(start, start + matchArr[0].length);
}
}
Lastly, we have the components themselves:
const HandleSpan = (props) => {
return <span {...props} style={styles.handle}>{props.children}</span>;
};
const HashtagSpan = (props) => {
return <span {...props} style={styles.hashtag}>{props.children}</span>;
};