@yuntijs/ui
Version:
☁️ Yunti UI - an open-source UI component library for building Cloud Native web apps
151 lines (148 loc) • 6.45 kB
JavaScript
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it.return != null) it.return(); } finally { if (didErr) throw err; } } }; }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
/**
* source:
* https://github.com/sodenn/lexical-beautiful-mentions/blob/8d2c8fbfaa63fe0100ac9f6c4bcb61e816d14a30/plugin/src/mention-converter.ts
*/
import { $createTextNode, $getRoot, $isElementNode, $isTextNode } from 'lexical';
import { DEFAULT_PUNCTUATION, LENGTH_LIMIT, TRIGGERS, VALID_CHARS } from "../constants";
import { $createMentionNode } from "./mention-node";
function findMentions(text, triggers, punctuation) {
var regex = new RegExp('(?<=\\s|^|\\()' + TRIGGERS(triggers) + '((?:' + VALID_CHARS(triggers, punctuation) + '){1,' + LENGTH_LIMIT + '})', 'g');
var matches = [];
var match;
regex.lastIndex = 0;
while ((match = regex.exec(text)) !== null) {
matches.push({
value: match[0],
index: match.index
});
}
return matches;
}
export function convertToMentionEntries(text, triggers, punctuation) {
var matches = findMentions(text, triggers, punctuation);
var result = [];
var lastIndex = 0;
var _iterator = _createForOfIteratorHelper(matches),
_step;
try {
var _loop = function _loop() {
var _step$value = _step.value,
value = _step$value.value,
index = _step$value.index;
// Add text before mention
if (index > lastIndex) {
// eslint-disable-next-line unicorn/prefer-string-slice
var textBeforeMention = text.substring(lastIndex, index);
result.push({
type: 'custom-text',
value: textBeforeMention
});
}
// Add mention
var triggerRegExp = triggers.find(function (trigger) {
return new RegExp(trigger).test(value);
});
var match = triggerRegExp && new RegExp(triggerRegExp).exec(value);
if (!match) {
// should never happen since we only find mentions with the given triggers
throw new Error('No trigger found for mention');
}
var trigger = match[0];
result.push({
type: 'mention-node',
value: value.slice(trigger.length),
trigger: trigger
});
// Update lastIndex
lastIndex = index + value.length;
};
for (_iterator.s(); !(_step = _iterator.n()).done;) {
_loop();
}
// Add text after last mention
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
if (lastIndex < text.length) {
var textAfterMentions = text.slice(Math.max(0, lastIndex));
result.push({
type: 'custom-text',
value: textAfterMentions
});
}
return result;
}
/**
* Utility function that takes a string or a text nodes and converts it to a
* list of mention and text nodes.
*
* 🚨 Only works for mentions without spaces. Ensure spaces are disabled
* via the `allowSpaces` prop.
*/
export function $convertToMentionNodes(textOrNode, triggers) {
var punctuation = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : DEFAULT_PUNCTUATION;
var text = typeof textOrNode === 'string' ? textOrNode : textOrNode.getTextContent();
var entries = convertToMentionEntries(text, triggers, punctuation);
var nodes = [];
var _iterator2 = _createForOfIteratorHelper(entries),
_step2;
try {
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
var entry = _step2.value;
if (entry.type === 'custom-text') {
var textNode = $createTextNode(entry.value);
if (typeof textOrNode !== 'string') {
textNode.setFormat(textOrNode.getFormat());
}
nodes.push(textNode);
} else {
nodes.push($createMentionNode(entry.value));
}
}
} catch (err) {
_iterator2.e(err);
} finally {
_iterator2.f();
}
return nodes;
}
/**
* Transforms text nodes containing mention strings into mention nodes.
*
* 🚨 Only works for mentions without spaces. Ensure spaces are disabled
* via the `allowSpaces` prop.
*/
export function $transformTextToMentionNodes(triggers) {
var punctuation = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : DEFAULT_PUNCTUATION;
var root = $getRoot();
var nodes = root.getChildren();
var traverseNodes = function traverseNodes(nodes) {
var _iterator3 = _createForOfIteratorHelper(nodes),
_step3;
try {
for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
var node = _step3.value;
if ($isTextNode(node)) {
var newNodes = $convertToMentionNodes(node, triggers, punctuation);
if (newNodes.length > 1) {
var parent = node.getParent();
var index = node.getIndexWithinParent();
parent === null || parent === void 0 || parent.splice(index, 1, newNodes);
}
} else if ($isElementNode(node)) {
traverseNodes(node.getChildren());
}
}
} catch (err) {
_iterator3.e(err);
} finally {
_iterator3.f();
}
};
traverseNodes(nodes);
}