@yuntijs/ui
Version:
☁️ Yunti UI - an open-source UI component library for building Cloud Native web apps
304 lines (303 loc) • 11.7 kB
JavaScript
import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray";
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; }
import { $createCodeNode } from '@lexical/code';
import { INSERT_CHECK_LIST_COMMAND, INSERT_ORDERED_LIST_COMMAND, INSERT_UNORDERED_LIST_COMMAND } from '@lexical/list';
import { $isDecoratorBlockNode } from '@lexical/react/LexicalDecoratorBlockNode';
import { $createHeadingNode, $createQuoteNode, $isHeadingNode, $isQuoteNode } from '@lexical/rich-text';
import { $patchStyleText, $setBlocksType } from '@lexical/selection';
import { $isTableSelection } from '@lexical/table';
import { $findMatchingParent, $getNearestBlockElementAncestorOrThrow } from '@lexical/utils';
import { $createParagraphNode, $getSelection, $isRangeSelection, $isRootOrShadowRoot, $isTextNode } from 'lexical';
import { DEFAULT_FONT_SIZE, MAX_ALLOWED_FONT_SIZE, MIN_ALLOWED_FONT_SIZE } from "../../constants/toolbar";
export var UpdateFontSizeType = /*#__PURE__*/function (UpdateFontSizeType) {
UpdateFontSizeType[UpdateFontSizeType["increment"] = 1] = "increment";
UpdateFontSizeType[UpdateFontSizeType["decrement"] = 2] = "decrement";
return UpdateFontSizeType;
}({});
export var BLOCK_TYPE = /*#__PURE__*/function (BLOCK_TYPE) {
BLOCK_TYPE["PARAGRAPH"] = "paragraph";
BLOCK_TYPE["H1"] = "h1";
BLOCK_TYPE["H2"] = "h2";
BLOCK_TYPE["H3"] = "h3";
BLOCK_TYPE["BULLET"] = "bullet";
BLOCK_TYPE["NUMBER"] = "number";
BLOCK_TYPE["CHECK"] = "check";
BLOCK_TYPE["QUOTE"] = "quote";
BLOCK_TYPE["CODE"] = "code";
return BLOCK_TYPE;
}({});
/**
* Calculates the new font size based on the update type.
* @param currentFontSize - The current font size
* @param updateType - The type of change, either increment or decrement
* @returns the next font size
*/
export var calculateNextFontSize = function calculateNextFontSize(currentFontSize, updateType) {
if (!updateType) {
return currentFontSize;
}
var updatedFontSize = currentFontSize;
switch (updateType) {
case UpdateFontSizeType.decrement:
{
switch (true) {
case currentFontSize > MAX_ALLOWED_FONT_SIZE:
{
updatedFontSize = MAX_ALLOWED_FONT_SIZE;
break;
}
case currentFontSize >= 48:
{
updatedFontSize -= 12;
break;
}
case currentFontSize >= 24:
{
updatedFontSize -= 4;
break;
}
case currentFontSize >= 14:
{
updatedFontSize -= 2;
break;
}
case currentFontSize >= 9:
{
updatedFontSize -= 1;
break;
}
default:
{
updatedFontSize = MIN_ALLOWED_FONT_SIZE;
break;
}
}
break;
}
case UpdateFontSizeType.increment:
{
switch (true) {
case currentFontSize < MIN_ALLOWED_FONT_SIZE:
{
updatedFontSize = MIN_ALLOWED_FONT_SIZE;
break;
}
case currentFontSize < 12:
{
updatedFontSize += 1;
break;
}
case currentFontSize < 20:
{
updatedFontSize += 2;
break;
}
case currentFontSize < 36:
{
updatedFontSize += 4;
break;
}
case currentFontSize <= 60:
{
updatedFontSize += 12;
break;
}
default:
{
updatedFontSize = MAX_ALLOWED_FONT_SIZE;
break;
}
}
break;
}
default:
{
break;
}
}
return updatedFontSize;
};
/**
* Patches the selection with the updated font size.
*/
export var updateFontSizeInSelection = function updateFontSizeInSelection(editor, newFontSize, updateType) {
var getNextFontSize = function getNextFontSize(prevFontSize) {
if (!prevFontSize) {
prevFontSize = "".concat(DEFAULT_FONT_SIZE, "px");
}
prevFontSize = prevFontSize.slice(0, -2);
var nextFontSize = calculateNextFontSize(Number(prevFontSize), updateType);
return "".concat(nextFontSize, "px");
};
editor.update(function () {
if (editor.isEditable()) {
var selection = $getSelection();
if (selection !== null) {
$patchStyleText(selection, {
'font-size': newFontSize || getNextFontSize
});
}
}
});
};
export var updateFontSize = function updateFontSize(editor, updateType, inputValue) {
if (inputValue) {
var nextFontSize = calculateNextFontSize(inputValue, updateType);
updateFontSizeInSelection(editor, String(nextFontSize) + 'px', null);
} else {
updateFontSizeInSelection(editor, null, updateType);
}
};
export var formatParagraph = function formatParagraph(editor) {
editor.update(function () {
var selection = $getSelection();
$setBlocksType(selection, function () {
return $createParagraphNode();
});
});
};
export var formatHeading = function formatHeading(editor, blockType, headingSize) {
if (blockType !== headingSize) {
editor.update(function () {
var selection = $getSelection();
$setBlocksType(selection, function () {
return $createHeadingNode(headingSize);
});
});
}
};
export var formatBulletList = function formatBulletList(editor, blockType) {
if (blockType === 'bullet') {
formatParagraph(editor);
} else {
editor.dispatchCommand(INSERT_UNORDERED_LIST_COMMAND, void 0);
}
};
export var formatCheckList = function formatCheckList(editor, blockType) {
if (blockType === 'check') {
formatParagraph(editor);
} else {
editor.dispatchCommand(INSERT_CHECK_LIST_COMMAND, void 0);
}
};
export var formatNumberedList = function formatNumberedList(editor, blockType) {
if (blockType === 'number') {
formatParagraph(editor);
} else {
editor.dispatchCommand(INSERT_ORDERED_LIST_COMMAND, void 0);
}
};
export var formatQuote = function formatQuote(editor, blockType) {
if (blockType !== 'quote') {
editor.update(function () {
var selection = $getSelection();
$setBlocksType(selection, function () {
return $createQuoteNode();
});
});
}
};
export var formatCode = function formatCode(editor, blockType) {
if (blockType !== 'code') {
editor.update(function () {
var selection = $getSelection();
if (!selection) {
return;
}
if (!$isRangeSelection(selection) || selection.isCollapsed()) {
$setBlocksType(selection, function () {
return $createCodeNode();
});
} else {
var textContent = selection.getTextContent();
var codeNode = $createCodeNode();
selection.insertNodes([codeNode]);
selection = $getSelection();
if ($isRangeSelection(selection)) {
selection.insertRawText(textContent);
}
}
});
}
};
export var clearFormatting = function clearFormatting(editor) {
editor.update(function () {
var selection = $getSelection();
if ($isRangeSelection(selection) || $isTableSelection(selection)) {
var anchor = selection.anchor;
var focus = selection.focus;
var nodes = selection.getNodes();
var extractedNodes = selection.extract();
if (anchor.key === focus.key && anchor.offset === focus.offset) {
return;
}
var _iterator = _createForOfIteratorHelper(nodes.entries()),
_step;
try {
for (_iterator.s(); !(_step = _iterator.n()).done;) {
var _step$value = _slicedToArray(_step.value, 2),
idx = _step$value[0],
node = _step$value[1];
// We split the first and last node by the selection
// So that we don't format unselected text inside those nodes
if ($isTextNode(node)) {
// Use a separate variable to ensure TS does not lose the refinement
var textNode = node;
if (idx === 0 && anchor.offset !== 0) {
textNode = textNode.splitText(anchor.offset)[1] || textNode;
}
if (idx === nodes.length - 1) {
textNode = textNode.splitText(focus.offset)[0] || textNode;
}
/**
* If the selected text has one format applied
* selecting a portion of the text, could
* clear the format to the wrong portion of the text.
*
* The cleared text is based on the length of the selected text.
*/
// We need this in case the selected text only has one format
var extractedTextNode = extractedNodes[0];
if (nodes.length === 1 && $isTextNode(extractedTextNode)) {
textNode = extractedTextNode;
}
if (textNode.__style !== '') {
textNode.setStyle('');
}
if (textNode.__format !== 0) {
textNode.setFormat(0);
}
var nearestBlockElement = $getNearestBlockElementAncestorOrThrow(textNode);
if (nearestBlockElement.__format !== 0) {
nearestBlockElement.setFormat('');
}
if (nearestBlockElement.__indent !== 0) {
nearestBlockElement.setIndent(0);
}
node = textNode;
} else if ($isHeadingNode(node) || $isQuoteNode(node)) {
node.replace($createParagraphNode(), true);
} else if ($isDecoratorBlockNode(node)) {
node.setFormat('');
}
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
}
});
};
export function $findTopLevelElement(node) {
var topLevelElement = node.getKey() === 'root' ? node : $findMatchingParent(node, function (e) {
var parent = e.getParent();
return parent !== null && $isRootOrShadowRoot(parent);
});
if (topLevelElement === null) {
topLevelElement = node.getTopLevelElementOrThrow();
}
return topLevelElement;
}