@crystallize/design-system 1.24.24 → 1.24.25
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +6 -0
- package/dist/index.js +76 -67
- package/dist/index.mjs +1 -1
- package/dist/{rich-text-editor-A5TU4T3X.mjs → rich-text-editor-7VOY4KHA.mjs} +75 -66
- package/package.json +24 -25
- package/src/rich-text-editor/model/crystallize-to-lexical.ts +6 -6
- package/src/rich-text-editor/model/lexical-to-crystallize.ts +11 -10
- package/src/rich-text-editor/model/parse-initial-state.test.ts +8 -7
- package/src/rich-text-editor/plugins/CodeActionMenuPlugin/index.tsx +63 -53
- package/src/rich-text-editor/plugins/FloatingLinkEditorPlugin/index.tsx +2 -5
- package/src/rich-text-editor/plugins/TableActionMenuPlugin/index.tsx +11 -10
- package/src/rich-text-editor/plugins/ToolbarPlugin/index.tsx +5 -5
package/CHANGELOG.md
CHANGED
package/dist/index.js
CHANGED
|
@@ -8273,7 +8273,6 @@ var init_parse_initial_state = __esm({
|
|
|
8273
8273
|
// src/rich-text-editor/model/crystallize-to-lexical.ts
|
|
8274
8274
|
function composeInitialState({ richText }) {
|
|
8275
8275
|
return function setLexicalState() {
|
|
8276
|
-
const root = (0, import_lexical.$getRoot)();
|
|
8277
8276
|
function handleNode({
|
|
8278
8277
|
crystallizeContentNode,
|
|
8279
8278
|
lexicalParent
|
|
@@ -8419,6 +8418,7 @@ function composeInitialState({ richText }) {
|
|
|
8419
8418
|
lexicalParent.append(lexicalNode);
|
|
8420
8419
|
}
|
|
8421
8420
|
}
|
|
8421
|
+
const root = (0, import_lexical.$getRoot)();
|
|
8422
8422
|
parseInitialState({ richText }).forEach(
|
|
8423
8423
|
(crystallizeContentNode) => handleNode({ crystallizeContentNode, lexicalParent: root })
|
|
8424
8424
|
);
|
|
@@ -37732,7 +37732,7 @@ function CodeActionMenuContainer({ anchorElem }) {
|
|
|
37732
37732
|
const [editor] = (0, import_LexicalComposerContext.useLexicalComposerContext)();
|
|
37733
37733
|
const [lang, setLang] = (0, import_react128.useState)("");
|
|
37734
37734
|
const [isShown, setShown] = (0, import_react128.useState)(false);
|
|
37735
|
-
const [shouldListenMouseMove, setShouldListenMouseMove] = (0, import_react128.useState)(
|
|
37735
|
+
const [shouldListenMouseMove, setShouldListenMouseMove] = (0, import_react128.useState)(false);
|
|
37736
37736
|
const [position, setPosition] = (0, import_react128.useState)({
|
|
37737
37737
|
right: "0",
|
|
37738
37738
|
top: "0"
|
|
@@ -37742,36 +37742,40 @@ function CodeActionMenuContainer({ anchorElem }) {
|
|
|
37742
37742
|
function getCodeDOMNode() {
|
|
37743
37743
|
return codeDOMNodeRef.current;
|
|
37744
37744
|
}
|
|
37745
|
-
const debouncedOnMouseMove = (0, import_use_debounce2.useDebouncedCallback)(
|
|
37746
|
-
|
|
37747
|
-
|
|
37748
|
-
|
|
37749
|
-
|
|
37750
|
-
|
|
37751
|
-
if (!codeDOMNode) {
|
|
37752
|
-
return;
|
|
37753
|
-
}
|
|
37754
|
-
codeDOMNodeRef.current = codeDOMNode;
|
|
37755
|
-
let codeNode = null;
|
|
37756
|
-
let _lang = "";
|
|
37757
|
-
editor.update(() => {
|
|
37758
|
-
const maybeCodeNode = (0, import_lexical6.$getNearestNodeFromDOMNode)(codeDOMNode);
|
|
37759
|
-
if ((0, import_code6.$isCodeNode)(maybeCodeNode)) {
|
|
37760
|
-
codeNode = maybeCodeNode;
|
|
37761
|
-
_lang = codeNode.getLanguage() || "";
|
|
37745
|
+
const debouncedOnMouseMove = (0, import_use_debounce2.useDebouncedCallback)(
|
|
37746
|
+
(event) => {
|
|
37747
|
+
const { codeDOMNode, isOutside } = getMouseInfo(event);
|
|
37748
|
+
if (isOutside) {
|
|
37749
|
+
setShown(false);
|
|
37750
|
+
return;
|
|
37762
37751
|
}
|
|
37763
|
-
|
|
37764
|
-
|
|
37765
|
-
|
|
37766
|
-
|
|
37767
|
-
|
|
37768
|
-
|
|
37769
|
-
|
|
37770
|
-
|
|
37771
|
-
|
|
37752
|
+
if (!codeDOMNode) {
|
|
37753
|
+
return;
|
|
37754
|
+
}
|
|
37755
|
+
codeDOMNodeRef.current = codeDOMNode;
|
|
37756
|
+
let codeNode = null;
|
|
37757
|
+
let _lang = "";
|
|
37758
|
+
editor.update(() => {
|
|
37759
|
+
const maybeCodeNode = (0, import_lexical6.$getNearestNodeFromDOMNode)(codeDOMNode);
|
|
37760
|
+
if ((0, import_code6.$isCodeNode)(maybeCodeNode)) {
|
|
37761
|
+
codeNode = maybeCodeNode;
|
|
37762
|
+
_lang = codeNode.getLanguage() || "";
|
|
37763
|
+
}
|
|
37772
37764
|
});
|
|
37773
|
-
|
|
37774
|
-
|
|
37765
|
+
if (codeNode) {
|
|
37766
|
+
const { y: editorElemY, right: editorElemRight } = anchorElem.getBoundingClientRect();
|
|
37767
|
+
const { y, right } = codeDOMNode.getBoundingClientRect();
|
|
37768
|
+
setLang(_lang);
|
|
37769
|
+
setShown(true);
|
|
37770
|
+
setPosition({
|
|
37771
|
+
right: `${editorElemRight - right + CODE_PADDING}px`,
|
|
37772
|
+
top: `${y - editorElemY}px`
|
|
37773
|
+
});
|
|
37774
|
+
}
|
|
37775
|
+
},
|
|
37776
|
+
50,
|
|
37777
|
+
{ maxWait: 1e3 }
|
|
37778
|
+
);
|
|
37775
37779
|
(0, import_react128.useEffect)(() => {
|
|
37776
37780
|
if (!shouldListenMouseMove) {
|
|
37777
37781
|
return;
|
|
@@ -37783,24 +37787,29 @@ function CodeActionMenuContainer({ anchorElem }) {
|
|
|
37783
37787
|
document.removeEventListener("mousemove", debouncedOnMouseMove);
|
|
37784
37788
|
};
|
|
37785
37789
|
}, [shouldListenMouseMove, debouncedOnMouseMove]);
|
|
37786
|
-
|
|
37787
|
-
editor.
|
|
37788
|
-
|
|
37789
|
-
|
|
37790
|
-
|
|
37791
|
-
|
|
37792
|
-
|
|
37793
|
-
|
|
37794
|
-
|
|
37795
|
-
|
|
37796
|
-
|
|
37797
|
-
|
|
37798
|
-
|
|
37799
|
-
|
|
37800
|
-
|
|
37801
|
-
|
|
37802
|
-
|
|
37803
|
-
|
|
37790
|
+
(0, import_react128.useEffect)(() => {
|
|
37791
|
+
return editor.registerMutationListener(
|
|
37792
|
+
import_code6.CodeNode,
|
|
37793
|
+
(mutations) => {
|
|
37794
|
+
editor.getEditorState().read(() => {
|
|
37795
|
+
for (const [key, type] of mutations) {
|
|
37796
|
+
switch (type) {
|
|
37797
|
+
case "created":
|
|
37798
|
+
codeSetRef.current.add(key);
|
|
37799
|
+
break;
|
|
37800
|
+
case "destroyed":
|
|
37801
|
+
codeSetRef.current.delete(key);
|
|
37802
|
+
break;
|
|
37803
|
+
default:
|
|
37804
|
+
break;
|
|
37805
|
+
}
|
|
37806
|
+
}
|
|
37807
|
+
});
|
|
37808
|
+
setShouldListenMouseMove(codeSetRef.current.size > 0);
|
|
37809
|
+
},
|
|
37810
|
+
{ skipInitialization: false }
|
|
37811
|
+
);
|
|
37812
|
+
}, [editor]);
|
|
37804
37813
|
const normalizedLang = (0, import_code6.normalizeCodeLang)(lang);
|
|
37805
37814
|
const codeFriendlyName = (0, import_code6.getLanguageFriendlyName)(lang);
|
|
37806
37815
|
return /* @__PURE__ */ (0, import_jsx_runtime148.jsx)(import_jsx_runtime148.Fragment, {
|
|
@@ -37827,7 +37836,7 @@ function CodeActionMenuContainer({ anchorElem }) {
|
|
|
37827
37836
|
}
|
|
37828
37837
|
function getMouseInfo(event) {
|
|
37829
37838
|
const target = event.target;
|
|
37830
|
-
if (
|
|
37839
|
+
if ((0, import_lexical6.isHTMLElement)(target)) {
|
|
37831
37840
|
const codeDOMNode = target.closest("code.CrystallizeRTEditorTheme__code");
|
|
37832
37841
|
const isOutside = !(codeDOMNode || target.closest("div.c-rte-code-action-menu-container"));
|
|
37833
37842
|
return { codeDOMNode, isOutside };
|
|
@@ -38369,12 +38378,11 @@ function FloatingLinkEditorPlugin({
|
|
|
38369
38378
|
const [editor] = (0, import_LexicalComposerContext4.useLexicalComposerContext)();
|
|
38370
38379
|
return useFloatingLinkEditorToolbar(editor, anchorElem);
|
|
38371
38380
|
}
|
|
38372
|
-
var import_react131,
|
|
38381
|
+
var import_react131, import_lexical8, import_react_dom3, import_link4, import_LexicalComposerContext4, import_utils, import_jsx_runtime150;
|
|
38373
38382
|
var init_FloatingLinkEditorPlugin = __esm({
|
|
38374
38383
|
"src/rich-text-editor/plugins/FloatingLinkEditorPlugin/index.tsx"() {
|
|
38375
38384
|
"use strict";
|
|
38376
38385
|
import_react131 = require("react");
|
|
38377
|
-
React5 = require("react");
|
|
38378
38386
|
import_lexical8 = require("lexical");
|
|
38379
38387
|
import_react_dom3 = require("react-dom");
|
|
38380
38388
|
import_link4 = require("@lexical/link");
|
|
@@ -38698,13 +38706,13 @@ function FloatingTextFormatToolbarPlugin({
|
|
|
38698
38706
|
const [editor] = (0, import_LexicalComposerContext5.useLexicalComposerContext)();
|
|
38699
38707
|
return useFloatingTextFormatToolbar(editor, anchorElem);
|
|
38700
38708
|
}
|
|
38701
|
-
var import_react132,
|
|
38709
|
+
var import_react132, React5, import_lexical9, import_react_dom4, import_code8, import_link5, import_LexicalComposerContext5, import_utils2, import_jsx_runtime151;
|
|
38702
38710
|
var init_FloatingTextFormatToolbarPlugin = __esm({
|
|
38703
38711
|
"src/rich-text-editor/plugins/FloatingTextFormatToolbarPlugin/index.tsx"() {
|
|
38704
38712
|
"use strict";
|
|
38705
38713
|
init_13();
|
|
38706
38714
|
import_react132 = require("react");
|
|
38707
|
-
|
|
38715
|
+
React5 = require("react");
|
|
38708
38716
|
import_lexical9 = require("lexical");
|
|
38709
38717
|
import_react_dom4 = require("react-dom");
|
|
38710
38718
|
import_code8 = require("@lexical/code");
|
|
@@ -38727,11 +38735,11 @@ function LinkPlugin() {
|
|
|
38727
38735
|
validateUrl
|
|
38728
38736
|
});
|
|
38729
38737
|
}
|
|
38730
|
-
var
|
|
38738
|
+
var React6, import_LexicalLinkPlugin, import_jsx_runtime152;
|
|
38731
38739
|
var init_LinkPlugin = __esm({
|
|
38732
38740
|
"src/rich-text-editor/plugins/LinkPlugin/index.tsx"() {
|
|
38733
38741
|
"use strict";
|
|
38734
|
-
|
|
38742
|
+
React6 = require("react");
|
|
38735
38743
|
import_LexicalLinkPlugin = require("@lexical/react/LexicalLinkPlugin");
|
|
38736
38744
|
init_url();
|
|
38737
38745
|
import_jsx_runtime152 = require("react/jsx-runtime");
|
|
@@ -38942,7 +38950,7 @@ function TableActionMenu({ tableCellNode: _tableCellNode, tableStats }) {
|
|
|
38942
38950
|
(0, import_react136.useEffect)(() => {
|
|
38943
38951
|
editor.getEditorState().read(() => {
|
|
38944
38952
|
const selection = (0, import_lexical13.$getSelection)();
|
|
38945
|
-
if ((0,
|
|
38953
|
+
if ((0, import_table4.$isTableSelection)(selection)) {
|
|
38946
38954
|
const selectionShape = selection.getShape();
|
|
38947
38955
|
updateSelectionCounts({
|
|
38948
38956
|
columns: selectionShape.toX - selectionShape.fromX + 1,
|
|
@@ -38959,9 +38967,9 @@ function TableActionMenu({ tableCellNode: _tableCellNode, tableStats }) {
|
|
|
38959
38967
|
if (!tableElement) {
|
|
38960
38968
|
throw new Error("Expected to find tableElement in DOM");
|
|
38961
38969
|
}
|
|
38962
|
-
const tableSelection = (0, import_table4.
|
|
38970
|
+
const tableSelection = (0, import_table4.getTableObserverFromTableElement)(tableElement);
|
|
38963
38971
|
if (tableSelection !== null) {
|
|
38964
|
-
tableSelection
|
|
38972
|
+
tableSelection.$clearHighlight();
|
|
38965
38973
|
}
|
|
38966
38974
|
tableNode.markDirty();
|
|
38967
38975
|
updateTableCellNode(tableCellNode.getLatest());
|
|
@@ -38976,13 +38984,13 @@ function TableActionMenu({ tableCellNode: _tableCellNode, tableStats }) {
|
|
|
38976
38984
|
const selection = (0, import_lexical13.$getSelection)();
|
|
38977
38985
|
const tableNode = (0, import_table4.$getTableNodeFromLexicalNodeOrThrow)(tableCellNode);
|
|
38978
38986
|
let tableRowIndex;
|
|
38979
|
-
if ((0,
|
|
38987
|
+
if ((0, import_table4.$isTableSelection)(selection)) {
|
|
38980
38988
|
const selectionShape = selection.getShape();
|
|
38981
38989
|
tableRowIndex = shouldInsertAfter ? selectionShape.toY : selectionShape.fromY;
|
|
38982
38990
|
} else {
|
|
38983
38991
|
tableRowIndex = (0, import_table4.$getTableRowIndexFromTableCellNode)(tableCellNode);
|
|
38984
38992
|
}
|
|
38985
|
-
const grid = (0, import_table4.$
|
|
38993
|
+
const grid = (0, import_table4.$getElementForTableNode)(editor, tableNode);
|
|
38986
38994
|
(0, import_table4.$insertTableRow)(tableNode, tableRowIndex, shouldInsertAfter, selectionCounts.rows, grid);
|
|
38987
38995
|
clearTableSelection();
|
|
38988
38996
|
});
|
|
@@ -38995,13 +39003,13 @@ function TableActionMenu({ tableCellNode: _tableCellNode, tableStats }) {
|
|
|
38995
39003
|
const selection = (0, import_lexical13.$getSelection)();
|
|
38996
39004
|
const tableNode = (0, import_table4.$getTableNodeFromLexicalNodeOrThrow)(tableCellNode);
|
|
38997
39005
|
let tableColumnIndex;
|
|
38998
|
-
if ((0,
|
|
39006
|
+
if ((0, import_table4.$isTableSelection)(selection)) {
|
|
38999
39007
|
const selectionShape = selection.getShape();
|
|
39000
39008
|
tableColumnIndex = shouldInsertAfter ? selectionShape.toX : selectionShape.fromX;
|
|
39001
39009
|
} else {
|
|
39002
39010
|
tableColumnIndex = (0, import_table4.$getTableColumnIndexFromTableCellNode)(tableCellNode);
|
|
39003
39011
|
}
|
|
39004
|
-
const grid = (0, import_table4.$
|
|
39012
|
+
const grid = (0, import_table4.$getElementForTableNode)(editor, tableNode);
|
|
39005
39013
|
(0, import_table4.$insertTableColumn)(tableNode, tableColumnIndex, shouldInsertAfter, selectionCounts.columns, grid);
|
|
39006
39014
|
clearTableSelection();
|
|
39007
39015
|
});
|
|
@@ -39390,7 +39398,7 @@ function BlockFormatDropDown({
|
|
|
39390
39398
|
if (blockType !== "paragraph") {
|
|
39391
39399
|
editor.update(() => {
|
|
39392
39400
|
const selection = (0, import_lexical15.$getSelection)();
|
|
39393
|
-
if ((0, import_lexical15.$isRangeSelection)(selection) || (0,
|
|
39401
|
+
if ((0, import_lexical15.$isRangeSelection)(selection) || (0, import_table6.$isTableSelection)(selection))
|
|
39394
39402
|
(0, import_selection4.$setBlocksType)(selection, () => (0, import_lexical15.$createParagraphNode)());
|
|
39395
39403
|
});
|
|
39396
39404
|
}
|
|
@@ -39399,7 +39407,7 @@ function BlockFormatDropDown({
|
|
|
39399
39407
|
if (blockType !== headingSize) {
|
|
39400
39408
|
editor.update(() => {
|
|
39401
39409
|
const selection = (0, import_lexical15.$getSelection)();
|
|
39402
|
-
if ((0, import_lexical15.$isRangeSelection)(selection) || (0,
|
|
39410
|
+
if ((0, import_lexical15.$isRangeSelection)(selection) || (0, import_table6.$isTableSelection)(selection)) {
|
|
39403
39411
|
(0, import_selection4.$setBlocksType)(selection, () => (0, import_rich_text5.$createHeadingNode)(headingSize));
|
|
39404
39412
|
}
|
|
39405
39413
|
});
|
|
@@ -39423,7 +39431,7 @@ function BlockFormatDropDown({
|
|
|
39423
39431
|
if (blockType !== "quote") {
|
|
39424
39432
|
editor.update(() => {
|
|
39425
39433
|
const selection = (0, import_lexical15.$getSelection)();
|
|
39426
|
-
if ((0, import_lexical15.$isRangeSelection)(selection) || (0,
|
|
39434
|
+
if ((0, import_lexical15.$isRangeSelection)(selection) || (0, import_table6.$isTableSelection)(selection)) {
|
|
39427
39435
|
(0, import_selection4.$setBlocksType)(selection, () => (0, import_rich_text5.$createQuoteNode)());
|
|
39428
39436
|
} else {
|
|
39429
39437
|
(0, import_selection4.$setBlocksType)((0, import_lexical15.$getRoot)().select(), () => (0, import_rich_text5.$createQuoteNode)());
|
|
@@ -39435,7 +39443,7 @@ function BlockFormatDropDown({
|
|
|
39435
39443
|
if (blockType !== "code") {
|
|
39436
39444
|
editor.update(() => {
|
|
39437
39445
|
let selection = (0, import_lexical15.$getSelection)();
|
|
39438
|
-
if ((0, import_lexical15.$isRangeSelection)(selection) || (0,
|
|
39446
|
+
if ((0, import_lexical15.$isRangeSelection)(selection) || (0, import_table6.$isTableSelection)(selection)) {
|
|
39439
39447
|
if (selection.isCollapsed()) {
|
|
39440
39448
|
(0, import_selection4.$setBlocksType)(selection, () => (0, import_code9.$createCodeNode)());
|
|
39441
39449
|
} else {
|
|
@@ -39986,7 +39994,7 @@ function ToolbarPlugin({
|
|
|
39986
39994
|
]
|
|
39987
39995
|
});
|
|
39988
39996
|
}
|
|
39989
|
-
var import_react138, import_lexical15, import_code9, import_link6, import_list5, import_LexicalComposerContext11, import_LexicalDecoratorBlockNode, import_LexicalHorizontalRuleNode4, import_rich_text5, import_selection4, import_utils4, import_jsx_runtime156, headingTypeToBlockName, headings, blockTypeToBlockName, CODE_LANGUAGE_OPTIONS;
|
|
39997
|
+
var import_react138, import_lexical15, import_code9, import_link6, import_list5, import_LexicalComposerContext11, import_LexicalDecoratorBlockNode, import_LexicalHorizontalRuleNode4, import_rich_text5, import_selection4, import_table6, import_utils4, import_jsx_runtime156, headingTypeToBlockName, headings, blockTypeToBlockName, CODE_LANGUAGE_OPTIONS;
|
|
39990
39998
|
var init_ToolbarPlugin = __esm({
|
|
39991
39999
|
"src/rich-text-editor/plugins/ToolbarPlugin/index.tsx"() {
|
|
39992
40000
|
"use strict";
|
|
@@ -40000,6 +40008,7 @@ var init_ToolbarPlugin = __esm({
|
|
|
40000
40008
|
import_LexicalHorizontalRuleNode4 = require("@lexical/react/LexicalHorizontalRuleNode");
|
|
40001
40009
|
import_rich_text5 = require("@lexical/rich-text");
|
|
40002
40010
|
import_selection4 = require("@lexical/selection");
|
|
40011
|
+
import_table6 = require("@lexical/table");
|
|
40003
40012
|
import_utils4 = require("@lexical/utils");
|
|
40004
40013
|
init_button2();
|
|
40005
40014
|
init_dialog2();
|
package/dist/index.mjs
CHANGED
|
@@ -486,7 +486,7 @@ function Tag({
|
|
|
486
486
|
// src/rich-text-editor/index.tsx
|
|
487
487
|
import { lazy, Suspense } from "react";
|
|
488
488
|
import { jsx as jsx15 } from "react/jsx-runtime";
|
|
489
|
-
var LazyRichTextEditor = lazy(() => import("./rich-text-editor-
|
|
489
|
+
var LazyRichTextEditor = lazy(() => import("./rich-text-editor-7VOY4KHA.mjs"));
|
|
490
490
|
var RichTextEditor = (props) => {
|
|
491
491
|
return /* @__PURE__ */ jsx15(Suspense, {
|
|
492
492
|
fallback: null,
|
|
@@ -179,7 +179,6 @@ function parseInitialState({ richText }) {
|
|
|
179
179
|
// src/rich-text-editor/model/crystallize-to-lexical.ts
|
|
180
180
|
function composeInitialState({ richText }) {
|
|
181
181
|
return function setLexicalState() {
|
|
182
|
-
const root = $getRoot();
|
|
183
182
|
function handleNode({
|
|
184
183
|
crystallizeContentNode,
|
|
185
184
|
lexicalParent
|
|
@@ -325,6 +324,7 @@ function composeInitialState({ richText }) {
|
|
|
325
324
|
lexicalParent.append(lexicalNode);
|
|
326
325
|
}
|
|
327
326
|
}
|
|
327
|
+
const root = $getRoot();
|
|
328
328
|
parseInitialState({ richText }).forEach(
|
|
329
329
|
(crystallizeContentNode) => handleNode({ crystallizeContentNode, lexicalParent: root })
|
|
330
330
|
);
|
|
@@ -610,7 +610,7 @@ function LexicalAutoLinkPlugin() {
|
|
|
610
610
|
|
|
611
611
|
// src/rich-text-editor/plugins/CodeActionMenuPlugin/index.tsx
|
|
612
612
|
import { useEffect, useRef, useState as useState3 } from "react";
|
|
613
|
-
import { $getNearestNodeFromDOMNode as $getNearestNodeFromDOMNode3 } from "lexical";
|
|
613
|
+
import { $getNearestNodeFromDOMNode as $getNearestNodeFromDOMNode3, isHTMLElement } from "lexical";
|
|
614
614
|
import { createPortal } from "react-dom";
|
|
615
615
|
import { useDebouncedCallback as useDebouncedCallback2 } from "use-debounce";
|
|
616
616
|
import { $isCodeNode as $isCodeNode4, CodeNode as CodeNode2, getLanguageFriendlyName, normalizeCodeLang } from "@lexical/code";
|
|
@@ -784,7 +784,7 @@ function CodeActionMenuContainer({ anchorElem }) {
|
|
|
784
784
|
const [editor] = useLexicalComposerContext();
|
|
785
785
|
const [lang, setLang] = useState3("");
|
|
786
786
|
const [isShown, setShown] = useState3(false);
|
|
787
|
-
const [shouldListenMouseMove, setShouldListenMouseMove] = useState3(
|
|
787
|
+
const [shouldListenMouseMove, setShouldListenMouseMove] = useState3(false);
|
|
788
788
|
const [position, setPosition] = useState3({
|
|
789
789
|
right: "0",
|
|
790
790
|
top: "0"
|
|
@@ -794,36 +794,40 @@ function CodeActionMenuContainer({ anchorElem }) {
|
|
|
794
794
|
function getCodeDOMNode() {
|
|
795
795
|
return codeDOMNodeRef.current;
|
|
796
796
|
}
|
|
797
|
-
const debouncedOnMouseMove = useDebouncedCallback2(
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
if (!codeDOMNode) {
|
|
804
|
-
return;
|
|
805
|
-
}
|
|
806
|
-
codeDOMNodeRef.current = codeDOMNode;
|
|
807
|
-
let codeNode = null;
|
|
808
|
-
let _lang = "";
|
|
809
|
-
editor.update(() => {
|
|
810
|
-
const maybeCodeNode = $getNearestNodeFromDOMNode3(codeDOMNode);
|
|
811
|
-
if ($isCodeNode4(maybeCodeNode)) {
|
|
812
|
-
codeNode = maybeCodeNode;
|
|
813
|
-
_lang = codeNode.getLanguage() || "";
|
|
797
|
+
const debouncedOnMouseMove = useDebouncedCallback2(
|
|
798
|
+
(event) => {
|
|
799
|
+
const { codeDOMNode, isOutside } = getMouseInfo(event);
|
|
800
|
+
if (isOutside) {
|
|
801
|
+
setShown(false);
|
|
802
|
+
return;
|
|
814
803
|
}
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
804
|
+
if (!codeDOMNode) {
|
|
805
|
+
return;
|
|
806
|
+
}
|
|
807
|
+
codeDOMNodeRef.current = codeDOMNode;
|
|
808
|
+
let codeNode = null;
|
|
809
|
+
let _lang = "";
|
|
810
|
+
editor.update(() => {
|
|
811
|
+
const maybeCodeNode = $getNearestNodeFromDOMNode3(codeDOMNode);
|
|
812
|
+
if ($isCodeNode4(maybeCodeNode)) {
|
|
813
|
+
codeNode = maybeCodeNode;
|
|
814
|
+
_lang = codeNode.getLanguage() || "";
|
|
815
|
+
}
|
|
824
816
|
});
|
|
825
|
-
|
|
826
|
-
|
|
817
|
+
if (codeNode) {
|
|
818
|
+
const { y: editorElemY, right: editorElemRight } = anchorElem.getBoundingClientRect();
|
|
819
|
+
const { y, right } = codeDOMNode.getBoundingClientRect();
|
|
820
|
+
setLang(_lang);
|
|
821
|
+
setShown(true);
|
|
822
|
+
setPosition({
|
|
823
|
+
right: `${editorElemRight - right + CODE_PADDING}px`,
|
|
824
|
+
top: `${y - editorElemY}px`
|
|
825
|
+
});
|
|
826
|
+
}
|
|
827
|
+
},
|
|
828
|
+
50,
|
|
829
|
+
{ maxWait: 1e3 }
|
|
830
|
+
);
|
|
827
831
|
useEffect(() => {
|
|
828
832
|
if (!shouldListenMouseMove) {
|
|
829
833
|
return;
|
|
@@ -835,24 +839,29 @@ function CodeActionMenuContainer({ anchorElem }) {
|
|
|
835
839
|
document.removeEventListener("mousemove", debouncedOnMouseMove);
|
|
836
840
|
};
|
|
837
841
|
}, [shouldListenMouseMove, debouncedOnMouseMove]);
|
|
838
|
-
|
|
839
|
-
editor.
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
842
|
+
useEffect(() => {
|
|
843
|
+
return editor.registerMutationListener(
|
|
844
|
+
CodeNode2,
|
|
845
|
+
(mutations) => {
|
|
846
|
+
editor.getEditorState().read(() => {
|
|
847
|
+
for (const [key, type] of mutations) {
|
|
848
|
+
switch (type) {
|
|
849
|
+
case "created":
|
|
850
|
+
codeSetRef.current.add(key);
|
|
851
|
+
break;
|
|
852
|
+
case "destroyed":
|
|
853
|
+
codeSetRef.current.delete(key);
|
|
854
|
+
break;
|
|
855
|
+
default:
|
|
856
|
+
break;
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
});
|
|
860
|
+
setShouldListenMouseMove(codeSetRef.current.size > 0);
|
|
861
|
+
},
|
|
862
|
+
{ skipInitialization: false }
|
|
863
|
+
);
|
|
864
|
+
}, [editor]);
|
|
856
865
|
const normalizedLang = normalizeCodeLang(lang);
|
|
857
866
|
const codeFriendlyName = getLanguageFriendlyName(lang);
|
|
858
867
|
return /* @__PURE__ */ jsx6(Fragment, {
|
|
@@ -879,7 +888,7 @@ function CodeActionMenuContainer({ anchorElem }) {
|
|
|
879
888
|
}
|
|
880
889
|
function getMouseInfo(event) {
|
|
881
890
|
const target = event.target;
|
|
882
|
-
if (target
|
|
891
|
+
if (isHTMLElement(target)) {
|
|
883
892
|
const codeDOMNode = target.closest("code.CrystallizeRTEditorTheme__code");
|
|
884
893
|
const isOutside = !(codeDOMNode || target.closest("div.c-rte-code-action-menu-container"));
|
|
885
894
|
return { codeDOMNode, isOutside };
|
|
@@ -909,7 +918,6 @@ function CodeHighlightPlugin() {
|
|
|
909
918
|
|
|
910
919
|
// src/rich-text-editor/plugins/FloatingLinkEditorPlugin/index.tsx
|
|
911
920
|
import { useCallback, useEffect as useEffect4, useRef as useRef2, useState as useState5 } from "react";
|
|
912
|
-
import "react";
|
|
913
921
|
import {
|
|
914
922
|
$getSelection as $getSelection3,
|
|
915
923
|
$isRangeSelection,
|
|
@@ -1876,13 +1884,13 @@ function TabFocusPlugin() {
|
|
|
1876
1884
|
|
|
1877
1885
|
// src/rich-text-editor/plugins/TableActionMenuPlugin/index.tsx
|
|
1878
1886
|
import { useCallback as useCallback3, useEffect as useEffect9, useRef as useRef4, useState as useState7 } from "react";
|
|
1879
|
-
import { $getRoot as $getRoot3, $getSelection as $getSelection8, $isRangeSelection as $isRangeSelection6
|
|
1887
|
+
import { $getRoot as $getRoot3, $getSelection as $getSelection8, $isRangeSelection as $isRangeSelection6 } from "lexical";
|
|
1880
1888
|
import { createPortal as createPortal4 } from "react-dom";
|
|
1881
1889
|
import { useLexicalComposerContext as useLexicalComposerContext9 } from "@lexical/react/LexicalComposerContext";
|
|
1882
1890
|
import useLexicalEditable from "@lexical/react/useLexicalEditable";
|
|
1883
1891
|
import {
|
|
1884
1892
|
$deleteTableColumn,
|
|
1885
|
-
$
|
|
1893
|
+
$getElementForTableNode,
|
|
1886
1894
|
$getTableCellNodeFromLexicalNode,
|
|
1887
1895
|
$getTableColumnIndexFromTableCellNode,
|
|
1888
1896
|
$getTableNodeFromLexicalNodeOrThrow,
|
|
@@ -1892,8 +1900,9 @@ import {
|
|
|
1892
1900
|
$isTableCellNode as $isTableCellNode2,
|
|
1893
1901
|
$isTableNode as $isTableNode2,
|
|
1894
1902
|
$isTableRowNode as $isTableRowNode2,
|
|
1903
|
+
$isTableSelection,
|
|
1895
1904
|
$removeTableRowAtIndex,
|
|
1896
|
-
|
|
1905
|
+
getTableObserverFromTableElement,
|
|
1897
1906
|
TableCellHeaderStates,
|
|
1898
1907
|
TableCellNode as TableCellNode2
|
|
1899
1908
|
} from "@lexical/table";
|
|
@@ -1919,7 +1928,7 @@ function TableActionMenu({ tableCellNode: _tableCellNode, tableStats }) {
|
|
|
1919
1928
|
useEffect9(() => {
|
|
1920
1929
|
editor.getEditorState().read(() => {
|
|
1921
1930
|
const selection = $getSelection8();
|
|
1922
|
-
if (
|
|
1931
|
+
if ($isTableSelection(selection)) {
|
|
1923
1932
|
const selectionShape = selection.getShape();
|
|
1924
1933
|
updateSelectionCounts({
|
|
1925
1934
|
columns: selectionShape.toX - selectionShape.fromX + 1,
|
|
@@ -1936,9 +1945,9 @@ function TableActionMenu({ tableCellNode: _tableCellNode, tableStats }) {
|
|
|
1936
1945
|
if (!tableElement) {
|
|
1937
1946
|
throw new Error("Expected to find tableElement in DOM");
|
|
1938
1947
|
}
|
|
1939
|
-
const tableSelection =
|
|
1948
|
+
const tableSelection = getTableObserverFromTableElement(tableElement);
|
|
1940
1949
|
if (tableSelection !== null) {
|
|
1941
|
-
tableSelection
|
|
1950
|
+
tableSelection.$clearHighlight();
|
|
1942
1951
|
}
|
|
1943
1952
|
tableNode.markDirty();
|
|
1944
1953
|
updateTableCellNode(tableCellNode.getLatest());
|
|
@@ -1953,13 +1962,13 @@ function TableActionMenu({ tableCellNode: _tableCellNode, tableStats }) {
|
|
|
1953
1962
|
const selection = $getSelection8();
|
|
1954
1963
|
const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
|
|
1955
1964
|
let tableRowIndex;
|
|
1956
|
-
if (
|
|
1965
|
+
if ($isTableSelection(selection)) {
|
|
1957
1966
|
const selectionShape = selection.getShape();
|
|
1958
1967
|
tableRowIndex = shouldInsertAfter ? selectionShape.toY : selectionShape.fromY;
|
|
1959
1968
|
} else {
|
|
1960
1969
|
tableRowIndex = $getTableRowIndexFromTableCellNode(tableCellNode);
|
|
1961
1970
|
}
|
|
1962
|
-
const grid = $
|
|
1971
|
+
const grid = $getElementForTableNode(editor, tableNode);
|
|
1963
1972
|
$insertTableRow(tableNode, tableRowIndex, shouldInsertAfter, selectionCounts.rows, grid);
|
|
1964
1973
|
clearTableSelection();
|
|
1965
1974
|
});
|
|
@@ -1972,13 +1981,13 @@ function TableActionMenu({ tableCellNode: _tableCellNode, tableStats }) {
|
|
|
1972
1981
|
const selection = $getSelection8();
|
|
1973
1982
|
const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
|
|
1974
1983
|
let tableColumnIndex;
|
|
1975
|
-
if (
|
|
1984
|
+
if ($isTableSelection(selection)) {
|
|
1976
1985
|
const selectionShape = selection.getShape();
|
|
1977
1986
|
tableColumnIndex = shouldInsertAfter ? selectionShape.toX : selectionShape.fromX;
|
|
1978
1987
|
} else {
|
|
1979
1988
|
tableColumnIndex = $getTableColumnIndexFromTableCellNode(tableCellNode);
|
|
1980
1989
|
}
|
|
1981
|
-
const grid = $
|
|
1990
|
+
const grid = $getElementForTableNode(editor, tableNode);
|
|
1982
1991
|
$insertTableColumn(tableNode, tableColumnIndex, shouldInsertAfter, selectionCounts.columns, grid);
|
|
1983
1992
|
clearTableSelection();
|
|
1984
1993
|
});
|
|
@@ -2212,7 +2221,6 @@ import {
|
|
|
2212
2221
|
CAN_REDO_COMMAND,
|
|
2213
2222
|
CAN_UNDO_COMMAND,
|
|
2214
2223
|
COMMAND_PRIORITY_CRITICAL as COMMAND_PRIORITY_CRITICAL3,
|
|
2215
|
-
DEPRECATED_$isGridSelection as DEPRECATED_$isGridSelection2,
|
|
2216
2224
|
FORMAT_TEXT_COMMAND as FORMAT_TEXT_COMMAND2,
|
|
2217
2225
|
REDO_COMMAND,
|
|
2218
2226
|
SELECTION_CHANGE_COMMAND as SELECTION_CHANGE_COMMAND3,
|
|
@@ -2238,6 +2246,7 @@ import { $isDecoratorBlockNode } from "@lexical/react/LexicalDecoratorBlockNode"
|
|
|
2238
2246
|
import { INSERT_HORIZONTAL_RULE_COMMAND } from "@lexical/react/LexicalHorizontalRuleNode";
|
|
2239
2247
|
import { $createHeadingNode as $createHeadingNode2, $createQuoteNode as $createQuoteNode2, $isHeadingNode as $isHeadingNode2 } from "@lexical/rich-text";
|
|
2240
2248
|
import { $selectAll, $setBlocksType } from "@lexical/selection";
|
|
2249
|
+
import { $isTableSelection as $isTableSelection2 } from "@lexical/table";
|
|
2241
2250
|
import {
|
|
2242
2251
|
$findMatchingParent as $findMatchingParent2,
|
|
2243
2252
|
$getNearestBlockElementAncestorOrThrow,
|
|
@@ -2397,7 +2406,7 @@ function BlockFormatDropDown({
|
|
|
2397
2406
|
if (blockType !== "paragraph") {
|
|
2398
2407
|
editor.update(() => {
|
|
2399
2408
|
const selection = $getSelection9();
|
|
2400
|
-
if ($isRangeSelection7(selection) ||
|
|
2409
|
+
if ($isRangeSelection7(selection) || $isTableSelection2(selection))
|
|
2401
2410
|
$setBlocksType(selection, () => $createParagraphNode2());
|
|
2402
2411
|
});
|
|
2403
2412
|
}
|
|
@@ -2406,7 +2415,7 @@ function BlockFormatDropDown({
|
|
|
2406
2415
|
if (blockType !== headingSize) {
|
|
2407
2416
|
editor.update(() => {
|
|
2408
2417
|
const selection = $getSelection9();
|
|
2409
|
-
if ($isRangeSelection7(selection) ||
|
|
2418
|
+
if ($isRangeSelection7(selection) || $isTableSelection2(selection)) {
|
|
2410
2419
|
$setBlocksType(selection, () => $createHeadingNode2(headingSize));
|
|
2411
2420
|
}
|
|
2412
2421
|
});
|
|
@@ -2430,7 +2439,7 @@ function BlockFormatDropDown({
|
|
|
2430
2439
|
if (blockType !== "quote") {
|
|
2431
2440
|
editor.update(() => {
|
|
2432
2441
|
const selection = $getSelection9();
|
|
2433
|
-
if ($isRangeSelection7(selection) ||
|
|
2442
|
+
if ($isRangeSelection7(selection) || $isTableSelection2(selection)) {
|
|
2434
2443
|
$setBlocksType(selection, () => $createQuoteNode2());
|
|
2435
2444
|
} else {
|
|
2436
2445
|
$setBlocksType($getRoot4().select(), () => $createQuoteNode2());
|
|
@@ -2442,7 +2451,7 @@ function BlockFormatDropDown({
|
|
|
2442
2451
|
if (blockType !== "code") {
|
|
2443
2452
|
editor.update(() => {
|
|
2444
2453
|
let selection = $getSelection9();
|
|
2445
|
-
if ($isRangeSelection7(selection) ||
|
|
2454
|
+
if ($isRangeSelection7(selection) || $isTableSelection2(selection)) {
|
|
2446
2455
|
if (selection.isCollapsed()) {
|
|
2447
2456
|
$setBlocksType(selection, () => $createCodeNode2());
|
|
2448
2457
|
} else {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@crystallize/design-system",
|
|
3
|
-
"version": "1.24.
|
|
3
|
+
"version": "1.24.25",
|
|
4
4
|
"types": "./dist/index.d.ts",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -20,23 +20,23 @@
|
|
|
20
20
|
}
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@lexical/clipboard": "0.
|
|
24
|
-
"@lexical/code": "0.
|
|
25
|
-
"@lexical/file": "0.
|
|
26
|
-
"@lexical/hashtag": "0.
|
|
27
|
-
"@lexical/html": "0.
|
|
28
|
-
"@lexical/link": "0.
|
|
29
|
-
"@lexical/list": "0.
|
|
30
|
-
"@lexical/mark": "0.
|
|
31
|
-
"@lexical/markdown": "0.
|
|
32
|
-
"@lexical/overflow": "0.
|
|
33
|
-
"@lexical/react": "0.
|
|
34
|
-
"@lexical/rich-text": "0.
|
|
35
|
-
"@lexical/selection": "0.
|
|
36
|
-
"@lexical/table": "0.
|
|
37
|
-
"@lexical/text": "0.
|
|
38
|
-
"@lexical/utils": "0.
|
|
39
|
-
"@lexical/yjs": "0.
|
|
23
|
+
"@lexical/clipboard": "0.21.0",
|
|
24
|
+
"@lexical/code": "0.21.0",
|
|
25
|
+
"@lexical/file": "0.21.0",
|
|
26
|
+
"@lexical/hashtag": "0.21.0",
|
|
27
|
+
"@lexical/html": "0.21.0",
|
|
28
|
+
"@lexical/link": "0.21.0",
|
|
29
|
+
"@lexical/list": "0.21.0",
|
|
30
|
+
"@lexical/mark": "0.21.0",
|
|
31
|
+
"@lexical/markdown": "0.21.0",
|
|
32
|
+
"@lexical/overflow": "0.21.0",
|
|
33
|
+
"@lexical/react": "0.21.0",
|
|
34
|
+
"@lexical/rich-text": "0.21.0",
|
|
35
|
+
"@lexical/selection": "0.21.0",
|
|
36
|
+
"@lexical/table": "0.21.0",
|
|
37
|
+
"@lexical/text": "0.21.0",
|
|
38
|
+
"@lexical/utils": "0.21.0",
|
|
39
|
+
"@lexical/yjs": "0.21.0",
|
|
40
40
|
"@radix-ui/react-checkbox": "1.0.1",
|
|
41
41
|
"@radix-ui/react-collapsible": "1.0.0",
|
|
42
42
|
"@radix-ui/react-dialog": "1.0.5",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
"@radix-ui/react-switch": "^1.0.2",
|
|
50
50
|
"@radix-ui/react-tooltip": "1.0.0",
|
|
51
51
|
"class-variance-authority": "^0.4.0",
|
|
52
|
-
"lexical": "0.
|
|
52
|
+
"lexical": "0.21.0",
|
|
53
53
|
"sonner": "^0.6.2",
|
|
54
54
|
"tailwindcss-radix": "^2.6.1",
|
|
55
55
|
"use-debounce": "8.0.4"
|
|
@@ -75,14 +75,13 @@
|
|
|
75
75
|
"@storybook/react": "7.6.2",
|
|
76
76
|
"@storybook/react-vite": "7.6.2",
|
|
77
77
|
"@storybook/theming": "7.6.2",
|
|
78
|
-
"@testing-library/jest-dom": "
|
|
79
|
-
"@testing-library/react": "
|
|
80
|
-
"@testing-library/user-event": "14.5.
|
|
81
|
-
"@types/testing-library__jest-dom": "^5.14.5",
|
|
78
|
+
"@testing-library/jest-dom": "6.6.3",
|
|
79
|
+
"@testing-library/react": "16.1.0",
|
|
80
|
+
"@testing-library/user-event": "14.5.2",
|
|
82
81
|
"@types/prettier": "2.7.2",
|
|
83
82
|
"@types/react": "17.0.1",
|
|
84
83
|
"@types/react-dom": "17.0.1",
|
|
85
|
-
"@vitejs/plugin-react": "
|
|
84
|
+
"@vitejs/plugin-react": "4.3.4",
|
|
86
85
|
"concurrently": "^7.6.0",
|
|
87
86
|
"hex-rgb": "4.3.0",
|
|
88
87
|
"postcss": "^8.4.21",
|
|
@@ -95,7 +94,7 @@
|
|
|
95
94
|
"tsup": "^6.5.0",
|
|
96
95
|
"typescript": "4.9.4",
|
|
97
96
|
"vite": "5.3.5",
|
|
98
|
-
"vitest": "
|
|
97
|
+
"vitest": "2.1.8",
|
|
99
98
|
"tsconfig": "0.0.0"
|
|
100
99
|
},
|
|
101
100
|
"keywords": [
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
$getRoot,
|
|
6
6
|
$isTextNode,
|
|
7
7
|
LexicalNode,
|
|
8
|
+
ElementNode,
|
|
8
9
|
TextFormatType,
|
|
9
10
|
} from 'lexical';
|
|
10
11
|
import { $createCodeHighlightNode, $createCodeNode } from '@lexical/code';
|
|
@@ -19,8 +20,6 @@ import { parseInitialState } from './parse-initial-state';
|
|
|
19
20
|
|
|
20
21
|
export function composeInitialState({ richText }: { richText: CrystallizeRichText }) {
|
|
21
22
|
return function setLexicalState() {
|
|
22
|
-
const root = $getRoot();
|
|
23
|
-
|
|
24
23
|
function handleNode({
|
|
25
24
|
crystallizeContentNode,
|
|
26
25
|
lexicalParent,
|
|
@@ -74,7 +73,7 @@ export function composeInitialState({ richText }: { richText: CrystallizeRichTex
|
|
|
74
73
|
case 'code': {
|
|
75
74
|
const language = metadata && typeof metadata.language === 'string' ? metadata.language : null;
|
|
76
75
|
lexicalNode = $createCodeNode(language);
|
|
77
|
-
lexicalNode.append($createCodeHighlightNode(textContent ?? ''));
|
|
76
|
+
(lexicalNode as ElementNode).append($createCodeHighlightNode(textContent ?? ''));
|
|
78
77
|
insertedTextContent = true;
|
|
79
78
|
break;
|
|
80
79
|
}
|
|
@@ -144,7 +143,7 @@ export function composeInitialState({ richText }: { richText: CrystallizeRichTex
|
|
|
144
143
|
children.forEach(n => handleNode({ crystallizeContentNode: n, lexicalParent }));
|
|
145
144
|
} else if (typeof textContent === 'string' && kind === 'inline') {
|
|
146
145
|
const textNode = $createTextNode(textContent);
|
|
147
|
-
lexicalNode.append(textNode);
|
|
146
|
+
(lexicalNode as ElementNode).append(textNode);
|
|
148
147
|
}
|
|
149
148
|
return;
|
|
150
149
|
}
|
|
@@ -155,7 +154,7 @@ export function composeInitialState({ richText }: { richText: CrystallizeRichTex
|
|
|
155
154
|
if (!lexicalNode && kind === 'inline') {
|
|
156
155
|
lexicalNode = textNode;
|
|
157
156
|
} else if (lexicalNode) {
|
|
158
|
-
lexicalNode.append(textNode);
|
|
157
|
+
(lexicalNode as ElementNode).append(textNode);
|
|
159
158
|
}
|
|
160
159
|
}
|
|
161
160
|
}
|
|
@@ -192,10 +191,11 @@ export function composeInitialState({ richText }: { richText: CrystallizeRichTex
|
|
|
192
191
|
}
|
|
193
192
|
}
|
|
194
193
|
|
|
195
|
-
lexicalParent.append(lexicalNode);
|
|
194
|
+
(lexicalParent as ElementNode).append(lexicalNode);
|
|
196
195
|
}
|
|
197
196
|
}
|
|
198
197
|
|
|
198
|
+
const root = $getRoot();
|
|
199
199
|
parseInitialState({ richText }).forEach(crystallizeContentNode =>
|
|
200
200
|
handleNode({ crystallizeContentNode, lexicalParent: root }),
|
|
201
201
|
);
|
|
@@ -199,16 +199,17 @@ export function lexicalToCrystallizeRichText({
|
|
|
199
199
|
return crystallizeRichText;
|
|
200
200
|
}
|
|
201
201
|
|
|
202
|
-
const lexicalFormatToCrystallizeType: Record<TextFormatType, CrystallizeRichTextInlineFormattedNodes['type']
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
202
|
+
const lexicalFormatToCrystallizeType: Partial<Record<TextFormatType, CrystallizeRichTextInlineFormattedNodes['type']>> =
|
|
203
|
+
{
|
|
204
|
+
bold: 'strong',
|
|
205
|
+
italic: 'emphasized',
|
|
206
|
+
underline: 'underlined',
|
|
207
|
+
strikethrough: 'deleted',
|
|
208
|
+
subscript: 'subscripted',
|
|
209
|
+
superscript: 'superscripted',
|
|
210
|
+
highlight: 'emphasized',
|
|
211
|
+
code: 'code',
|
|
212
|
+
};
|
|
212
213
|
|
|
213
214
|
/**
|
|
214
215
|
* Creates a rich text node with the ability to have
|
|
@@ -1,17 +1,18 @@
|
|
|
1
1
|
/* eslint-disable no-console */
|
|
2
2
|
|
|
3
|
-
import type { CrystallizeRichText } from '../rich-text-editor';
|
|
4
3
|
import { parseInitialState } from './parse-initial-state';
|
|
5
4
|
|
|
6
5
|
describe('RichTextEditor parseInitialState', () => {
|
|
7
6
|
it('ensures that the initial state is an array', async () => {
|
|
8
7
|
expect(
|
|
9
8
|
parseInitialState({
|
|
10
|
-
richText:
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
9
|
+
richText: [
|
|
10
|
+
{
|
|
11
|
+
kind: 'block',
|
|
12
|
+
type: 'paragraph',
|
|
13
|
+
textContent: 'hello',
|
|
14
|
+
},
|
|
15
|
+
],
|
|
15
16
|
}),
|
|
16
17
|
).toEqual([
|
|
17
18
|
{
|
|
@@ -42,7 +43,7 @@ describe('RichTextEditor parseInitialState', () => {
|
|
|
42
43
|
textContent: 'hello',
|
|
43
44
|
},
|
|
44
45
|
],
|
|
45
|
-
}
|
|
46
|
+
},
|
|
46
47
|
]);
|
|
47
48
|
});
|
|
48
49
|
});
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import { useEffect, useRef, useState } from 'react';
|
|
10
|
-
import { $getNearestNodeFromDOMNode } from 'lexical';
|
|
10
|
+
import { $getNearestNodeFromDOMNode, isHTMLElement } from 'lexical';
|
|
11
11
|
import { createPortal } from 'react-dom';
|
|
12
12
|
import { useDebouncedCallback } from 'use-debounce';
|
|
13
13
|
import { $isCodeNode, CodeNode, getLanguageFriendlyName, normalizeCodeLang } from '@lexical/code';
|
|
@@ -28,7 +28,7 @@ function CodeActionMenuContainer({ anchorElem }: { anchorElem: HTMLElement }): J
|
|
|
28
28
|
|
|
29
29
|
const [lang, setLang] = useState('');
|
|
30
30
|
const [isShown, setShown] = useState<boolean>(false);
|
|
31
|
-
const [shouldListenMouseMove, setShouldListenMouseMove] = useState<boolean>(
|
|
31
|
+
const [shouldListenMouseMove, setShouldListenMouseMove] = useState<boolean>(false);
|
|
32
32
|
const [position, setPosition] = useState<Position>({
|
|
33
33
|
right: '0',
|
|
34
34
|
top: '0',
|
|
@@ -40,43 +40,47 @@ function CodeActionMenuContainer({ anchorElem }: { anchorElem: HTMLElement }): J
|
|
|
40
40
|
return codeDOMNodeRef.current;
|
|
41
41
|
}
|
|
42
42
|
|
|
43
|
-
const debouncedOnMouseMove = useDebouncedCallback(
|
|
44
|
-
|
|
43
|
+
const debouncedOnMouseMove = useDebouncedCallback(
|
|
44
|
+
(event: MouseEvent) => {
|
|
45
|
+
const { codeDOMNode, isOutside } = getMouseInfo(event);
|
|
45
46
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
47
|
+
if (isOutside) {
|
|
48
|
+
setShown(false);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
50
51
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
52
|
+
if (!codeDOMNode) {
|
|
53
|
+
return;
|
|
54
|
+
}
|
|
54
55
|
|
|
55
|
-
|
|
56
|
+
codeDOMNodeRef.current = codeDOMNode;
|
|
56
57
|
|
|
57
|
-
|
|
58
|
-
|
|
58
|
+
let codeNode: CodeNode | null = null;
|
|
59
|
+
let _lang = '';
|
|
59
60
|
|
|
60
|
-
|
|
61
|
-
|
|
61
|
+
editor.update(() => {
|
|
62
|
+
const maybeCodeNode = $getNearestNodeFromDOMNode(codeDOMNode);
|
|
62
63
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
if (codeNode) {
|
|
70
|
-
const { y: editorElemY, right: editorElemRight } = anchorElem.getBoundingClientRect();
|
|
71
|
-
const { y, right } = codeDOMNode.getBoundingClientRect();
|
|
72
|
-
setLang(_lang);
|
|
73
|
-
setShown(true);
|
|
74
|
-
setPosition({
|
|
75
|
-
right: `${editorElemRight - right + CODE_PADDING}px`,
|
|
76
|
-
top: `${y - editorElemY}px`,
|
|
64
|
+
if ($isCodeNode(maybeCodeNode)) {
|
|
65
|
+
codeNode = maybeCodeNode;
|
|
66
|
+
_lang = codeNode.getLanguage() || '';
|
|
67
|
+
}
|
|
77
68
|
});
|
|
78
|
-
|
|
79
|
-
|
|
69
|
+
|
|
70
|
+
if (codeNode) {
|
|
71
|
+
const { y: editorElemY, right: editorElemRight } = anchorElem.getBoundingClientRect();
|
|
72
|
+
const { y, right } = codeDOMNode.getBoundingClientRect();
|
|
73
|
+
setLang(_lang);
|
|
74
|
+
setShown(true);
|
|
75
|
+
setPosition({
|
|
76
|
+
right: `${editorElemRight - right + CODE_PADDING}px`,
|
|
77
|
+
top: `${y - editorElemY}px`,
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
},
|
|
81
|
+
50,
|
|
82
|
+
{ maxWait: 1000 },
|
|
83
|
+
);
|
|
80
84
|
|
|
81
85
|
useEffect(() => {
|
|
82
86
|
if (!shouldListenMouseMove) {
|
|
@@ -92,26 +96,32 @@ function CodeActionMenuContainer({ anchorElem }: { anchorElem: HTMLElement }): J
|
|
|
92
96
|
};
|
|
93
97
|
}, [shouldListenMouseMove, debouncedOnMouseMove]);
|
|
94
98
|
|
|
95
|
-
|
|
96
|
-
editor.
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
99
|
+
useEffect(() => {
|
|
100
|
+
return editor.registerMutationListener(
|
|
101
|
+
CodeNode,
|
|
102
|
+
mutations => {
|
|
103
|
+
editor.getEditorState().read(() => {
|
|
104
|
+
for (const [key, type] of mutations) {
|
|
105
|
+
switch (type) {
|
|
106
|
+
case 'created':
|
|
107
|
+
codeSetRef.current.add(key);
|
|
108
|
+
break;
|
|
109
|
+
|
|
110
|
+
case 'destroyed':
|
|
111
|
+
codeSetRef.current.delete(key);
|
|
112
|
+
break;
|
|
113
|
+
|
|
114
|
+
default:
|
|
115
|
+
break;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
});
|
|
119
|
+
setShouldListenMouseMove(codeSetRef.current.size > 0);
|
|
120
|
+
},
|
|
121
|
+
{ skipInitialization: false },
|
|
122
|
+
);
|
|
123
|
+
}, [editor]);
|
|
124
|
+
|
|
115
125
|
const normalizedLang = normalizeCodeLang(lang);
|
|
116
126
|
const codeFriendlyName = getLanguageFriendlyName(lang);
|
|
117
127
|
|
|
@@ -136,7 +146,7 @@ function getMouseInfo(event: MouseEvent): {
|
|
|
136
146
|
} {
|
|
137
147
|
const target = event.target;
|
|
138
148
|
|
|
139
|
-
if (target
|
|
149
|
+
if (isHTMLElement(target)) {
|
|
140
150
|
const codeDOMNode = target.closest<HTMLElement>('code.CrystallizeRTEditorTheme__code');
|
|
141
151
|
const isOutside = !(codeDOMNode || target.closest<HTMLElement>('div.c-rte-code-action-menu-container'));
|
|
142
152
|
|
|
@@ -7,18 +7,15 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import { Dispatch, useCallback, useEffect, useRef, useState } from 'react';
|
|
10
|
-
import * as React from 'react';
|
|
11
10
|
import {
|
|
12
11
|
$getSelection,
|
|
13
12
|
$isRangeSelection,
|
|
13
|
+
BaseSelection,
|
|
14
14
|
COMMAND_PRIORITY_CRITICAL,
|
|
15
15
|
COMMAND_PRIORITY_HIGH,
|
|
16
16
|
COMMAND_PRIORITY_LOW,
|
|
17
|
-
GridSelection,
|
|
18
17
|
KEY_ESCAPE_COMMAND,
|
|
19
18
|
LexicalEditor,
|
|
20
|
-
NodeSelection,
|
|
21
|
-
RangeSelection,
|
|
22
19
|
SELECTION_CHANGE_COMMAND,
|
|
23
20
|
} from 'lexical';
|
|
24
21
|
import { createPortal } from 'react-dom';
|
|
@@ -53,7 +50,7 @@ function FloatingLinkEditor({
|
|
|
53
50
|
const [rel, setRel] = useState<string | null>(null);
|
|
54
51
|
const [target, setTarget] = useState<string | null>(null);
|
|
55
52
|
const [isEditMode, setEditMode] = useState(false);
|
|
56
|
-
const [lastSelection, setLastSelection] = useState<
|
|
53
|
+
const [lastSelection, setLastSelection] = useState<BaseSelection | null>(null);
|
|
57
54
|
const tr = useTr();
|
|
58
55
|
|
|
59
56
|
const updateLinkEditor = useCallback(() => {
|
|
@@ -7,13 +7,13 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import { ReactPortal, useCallback, useEffect, useRef, useState } from 'react';
|
|
10
|
-
import { $getRoot, $getSelection, $isRangeSelection
|
|
10
|
+
import { $getRoot, $getSelection, $isRangeSelection } from 'lexical';
|
|
11
11
|
import { createPortal } from 'react-dom';
|
|
12
12
|
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext';
|
|
13
13
|
import useLexicalEditable from '@lexical/react/useLexicalEditable';
|
|
14
14
|
import {
|
|
15
15
|
$deleteTableColumn,
|
|
16
|
-
$
|
|
16
|
+
$getElementForTableNode,
|
|
17
17
|
$getTableCellNodeFromLexicalNode,
|
|
18
18
|
$getTableColumnIndexFromTableCellNode,
|
|
19
19
|
$getTableNodeFromLexicalNodeOrThrow,
|
|
@@ -23,8 +23,9 @@ import {
|
|
|
23
23
|
$isTableCellNode,
|
|
24
24
|
$isTableNode,
|
|
25
25
|
$isTableRowNode,
|
|
26
|
+
$isTableSelection,
|
|
26
27
|
$removeTableRowAtIndex,
|
|
27
|
-
|
|
28
|
+
getTableObserverFromTableElement,
|
|
28
29
|
HTMLTableElementWithWithTableSelectionState,
|
|
29
30
|
TableCellHeaderStates,
|
|
30
31
|
TableCellNode,
|
|
@@ -70,7 +71,7 @@ function TableActionMenu({ tableCellNode: _tableCellNode, tableStats }: TableCel
|
|
|
70
71
|
editor.getEditorState().read(() => {
|
|
71
72
|
const selection = $getSelection();
|
|
72
73
|
|
|
73
|
-
if (
|
|
74
|
+
if ($isTableSelection(selection)) {
|
|
74
75
|
const selectionShape = selection.getShape();
|
|
75
76
|
|
|
76
77
|
updateSelectionCounts({
|
|
@@ -91,9 +92,9 @@ function TableActionMenu({ tableCellNode: _tableCellNode, tableStats }: TableCel
|
|
|
91
92
|
throw new Error('Expected to find tableElement in DOM');
|
|
92
93
|
}
|
|
93
94
|
|
|
94
|
-
const tableSelection =
|
|
95
|
+
const tableSelection = getTableObserverFromTableElement(tableElement);
|
|
95
96
|
if (tableSelection !== null) {
|
|
96
|
-
tableSelection
|
|
97
|
+
tableSelection.$clearHighlight();
|
|
97
98
|
}
|
|
98
99
|
|
|
99
100
|
tableNode.markDirty();
|
|
@@ -114,14 +115,14 @@ function TableActionMenu({ tableCellNode: _tableCellNode, tableStats }: TableCel
|
|
|
114
115
|
|
|
115
116
|
let tableRowIndex;
|
|
116
117
|
|
|
117
|
-
if (
|
|
118
|
+
if ($isTableSelection(selection)) {
|
|
118
119
|
const selectionShape = selection.getShape();
|
|
119
120
|
tableRowIndex = shouldInsertAfter ? selectionShape.toY : selectionShape.fromY;
|
|
120
121
|
} else {
|
|
121
122
|
tableRowIndex = $getTableRowIndexFromTableCellNode(tableCellNode);
|
|
122
123
|
}
|
|
123
124
|
|
|
124
|
-
const grid = $
|
|
125
|
+
const grid = $getElementForTableNode(editor, tableNode);
|
|
125
126
|
|
|
126
127
|
$insertTableRow(tableNode, tableRowIndex, shouldInsertAfter, selectionCounts.rows, grid);
|
|
127
128
|
|
|
@@ -140,14 +141,14 @@ function TableActionMenu({ tableCellNode: _tableCellNode, tableStats }: TableCel
|
|
|
140
141
|
|
|
141
142
|
let tableColumnIndex;
|
|
142
143
|
|
|
143
|
-
if (
|
|
144
|
+
if ($isTableSelection(selection)) {
|
|
144
145
|
const selectionShape = selection.getShape();
|
|
145
146
|
tableColumnIndex = shouldInsertAfter ? selectionShape.toX : selectionShape.fromX;
|
|
146
147
|
} else {
|
|
147
148
|
tableColumnIndex = $getTableColumnIndexFromTableCellNode(tableCellNode);
|
|
148
149
|
}
|
|
149
150
|
|
|
150
|
-
const grid = $
|
|
151
|
+
const grid = $getElementForTableNode(editor, tableNode);
|
|
151
152
|
|
|
152
153
|
$insertTableColumn(tableNode, tableColumnIndex, shouldInsertAfter, selectionCounts.columns, grid);
|
|
153
154
|
|
|
@@ -18,7 +18,6 @@ import {
|
|
|
18
18
|
CAN_REDO_COMMAND,
|
|
19
19
|
CAN_UNDO_COMMAND,
|
|
20
20
|
COMMAND_PRIORITY_CRITICAL,
|
|
21
|
-
DEPRECATED_$isGridSelection,
|
|
22
21
|
FORMAT_TEXT_COMMAND,
|
|
23
22
|
REDO_COMMAND,
|
|
24
23
|
SELECTION_CHANGE_COMMAND,
|
|
@@ -46,6 +45,7 @@ import { $isDecoratorBlockNode } from '@lexical/react/LexicalDecoratorBlockNode'
|
|
|
46
45
|
import { INSERT_HORIZONTAL_RULE_COMMAND } from '@lexical/react/LexicalHorizontalRuleNode';
|
|
47
46
|
import { $createHeadingNode, $createQuoteNode, $isHeadingNode, HeadingTagType } from '@lexical/rich-text';
|
|
48
47
|
import { $selectAll, $setBlocksType } from '@lexical/selection';
|
|
48
|
+
import { $isTableSelection } from '@lexical/table';
|
|
49
49
|
import {
|
|
50
50
|
$findMatchingParent,
|
|
51
51
|
$getNearestBlockElementAncestorOrThrow,
|
|
@@ -116,7 +116,7 @@ function BlockFormatDropDown({
|
|
|
116
116
|
if (blockType !== 'paragraph') {
|
|
117
117
|
editor.update(() => {
|
|
118
118
|
const selection = $getSelection();
|
|
119
|
-
if ($isRangeSelection(selection) ||
|
|
119
|
+
if ($isRangeSelection(selection) || $isTableSelection(selection))
|
|
120
120
|
$setBlocksType(selection, () => $createParagraphNode());
|
|
121
121
|
});
|
|
122
122
|
}
|
|
@@ -126,7 +126,7 @@ function BlockFormatDropDown({
|
|
|
126
126
|
if (blockType !== headingSize) {
|
|
127
127
|
editor.update(() => {
|
|
128
128
|
const selection = $getSelection();
|
|
129
|
-
if ($isRangeSelection(selection) ||
|
|
129
|
+
if ($isRangeSelection(selection) || $isTableSelection(selection)) {
|
|
130
130
|
$setBlocksType(selection, () => $createHeadingNode(headingSize));
|
|
131
131
|
}
|
|
132
132
|
});
|
|
@@ -153,7 +153,7 @@ function BlockFormatDropDown({
|
|
|
153
153
|
if (blockType !== 'quote') {
|
|
154
154
|
editor.update(() => {
|
|
155
155
|
const selection = $getSelection();
|
|
156
|
-
if ($isRangeSelection(selection) ||
|
|
156
|
+
if ($isRangeSelection(selection) || $isTableSelection(selection)) {
|
|
157
157
|
$setBlocksType(selection, () => $createQuoteNode());
|
|
158
158
|
} else {
|
|
159
159
|
/**
|
|
@@ -171,7 +171,7 @@ function BlockFormatDropDown({
|
|
|
171
171
|
editor.update(() => {
|
|
172
172
|
let selection = $getSelection();
|
|
173
173
|
|
|
174
|
-
if ($isRangeSelection(selection) ||
|
|
174
|
+
if ($isRangeSelection(selection) || $isTableSelection(selection)) {
|
|
175
175
|
if (selection.isCollapsed()) {
|
|
176
176
|
$setBlocksType(selection, () => $createCodeNode());
|
|
177
177
|
} else {
|