@crystallize/design-system 1.24.24 → 1.24.26

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 CHANGED
@@ -1,5 +1,17 @@
1
1
  # @crystallize/design-system
2
2
 
3
+ ## 1.24.26
4
+
5
+ ### Patch Changes
6
+
7
+ - 045d05a: It was found that table th and td elements were both rendered as td. To fix it, now we tell lexical that they are different.
8
+
9
+ ## 1.24.25
10
+
11
+ ### Patch Changes
12
+
13
+ - 48ba84c: Upgrade lexical to latest version
14
+
3
15
  ## 1.24.24
4
16
 
5
17
  ### Patch Changes
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
@@ -8364,13 +8363,12 @@ function composeInitialState({ richText }) {
8364
8363
  lexicalNode = (0, import_table.$createTableRowNode)();
8365
8364
  break;
8366
8365
  }
8367
- case "table-cell":
8366
+ case "table-cell": {
8367
+ lexicalNode = (0, import_table.$createTableCellNode)(0, void 0);
8368
+ break;
8369
+ }
8368
8370
  case "table-head-cell": {
8369
- const colSpan = void 0;
8370
- lexicalNode = (0, import_table.$createTableCellNode)(
8371
- 0,
8372
- colSpan
8373
- );
8371
+ lexicalNode = (0, import_table.$createTableCellNode)(2, void 0);
8374
8372
  break;
8375
8373
  }
8376
8374
  case "container":
@@ -8419,6 +8417,7 @@ function composeInitialState({ richText }) {
8419
8417
  lexicalParent.append(lexicalNode);
8420
8418
  }
8421
8419
  }
8420
+ const root = (0, import_lexical.$getRoot)();
8422
8421
  parseInitialState({ richText }).forEach(
8423
8422
  (crystallizeContentNode) => handleNode({ crystallizeContentNode, lexicalParent: root })
8424
8423
  );
@@ -37732,7 +37731,7 @@ function CodeActionMenuContainer({ anchorElem }) {
37732
37731
  const [editor] = (0, import_LexicalComposerContext.useLexicalComposerContext)();
37733
37732
  const [lang, setLang] = (0, import_react128.useState)("");
37734
37733
  const [isShown, setShown] = (0, import_react128.useState)(false);
37735
- const [shouldListenMouseMove, setShouldListenMouseMove] = (0, import_react128.useState)(true);
37734
+ const [shouldListenMouseMove, setShouldListenMouseMove] = (0, import_react128.useState)(false);
37736
37735
  const [position, setPosition] = (0, import_react128.useState)({
37737
37736
  right: "0",
37738
37737
  top: "0"
@@ -37742,36 +37741,40 @@ function CodeActionMenuContainer({ anchorElem }) {
37742
37741
  function getCodeDOMNode() {
37743
37742
  return codeDOMNodeRef.current;
37744
37743
  }
37745
- const debouncedOnMouseMove = (0, import_use_debounce2.useDebouncedCallback)((event) => {
37746
- const { codeDOMNode, isOutside } = getMouseInfo(event);
37747
- if (isOutside) {
37748
- setShown(false);
37749
- return;
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() || "";
37744
+ const debouncedOnMouseMove = (0, import_use_debounce2.useDebouncedCallback)(
37745
+ (event) => {
37746
+ const { codeDOMNode, isOutside } = getMouseInfo(event);
37747
+ if (isOutside) {
37748
+ setShown(false);
37749
+ return;
37762
37750
  }
37763
- });
37764
- if (codeNode) {
37765
- const { y: editorElemY, right: editorElemRight } = anchorElem.getBoundingClientRect();
37766
- const { y, right } = codeDOMNode.getBoundingClientRect();
37767
- setLang(_lang);
37768
- setShown(true);
37769
- setPosition({
37770
- right: `${editorElemRight - right + CODE_PADDING}px`,
37771
- top: `${y - editorElemY}px`
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() || "";
37762
+ }
37772
37763
  });
37773
- }
37774
- }, 50);
37764
+ if (codeNode) {
37765
+ const { y: editorElemY, right: editorElemRight } = anchorElem.getBoundingClientRect();
37766
+ const { y, right } = codeDOMNode.getBoundingClientRect();
37767
+ setLang(_lang);
37768
+ setShown(true);
37769
+ setPosition({
37770
+ right: `${editorElemRight - right + CODE_PADDING}px`,
37771
+ top: `${y - editorElemY}px`
37772
+ });
37773
+ }
37774
+ },
37775
+ 50,
37776
+ { maxWait: 1e3 }
37777
+ );
37775
37778
  (0, import_react128.useEffect)(() => {
37776
37779
  if (!shouldListenMouseMove) {
37777
37780
  return;
@@ -37783,24 +37786,29 @@ function CodeActionMenuContainer({ anchorElem }) {
37783
37786
  document.removeEventListener("mousemove", debouncedOnMouseMove);
37784
37787
  };
37785
37788
  }, [shouldListenMouseMove, debouncedOnMouseMove]);
37786
- editor.registerMutationListener(import_code6.CodeNode, (mutations) => {
37787
- editor.getEditorState().read(() => {
37788
- for (const [key, type] of mutations) {
37789
- switch (type) {
37790
- case "created":
37791
- codeSetRef.current.add(key);
37792
- setShouldListenMouseMove(codeSetRef.current.size > 0);
37793
- break;
37794
- case "destroyed":
37795
- codeSetRef.current.delete(key);
37796
- setShouldListenMouseMove(codeSetRef.current.size > 0);
37797
- break;
37798
- default:
37799
- break;
37800
- }
37801
- }
37802
- });
37803
- });
37789
+ (0, import_react128.useEffect)(() => {
37790
+ return editor.registerMutationListener(
37791
+ import_code6.CodeNode,
37792
+ (mutations) => {
37793
+ editor.getEditorState().read(() => {
37794
+ for (const [key, type] of mutations) {
37795
+ switch (type) {
37796
+ case "created":
37797
+ codeSetRef.current.add(key);
37798
+ break;
37799
+ case "destroyed":
37800
+ codeSetRef.current.delete(key);
37801
+ break;
37802
+ default:
37803
+ break;
37804
+ }
37805
+ }
37806
+ });
37807
+ setShouldListenMouseMove(codeSetRef.current.size > 0);
37808
+ },
37809
+ { skipInitialization: false }
37810
+ );
37811
+ }, [editor]);
37804
37812
  const normalizedLang = (0, import_code6.normalizeCodeLang)(lang);
37805
37813
  const codeFriendlyName = (0, import_code6.getLanguageFriendlyName)(lang);
37806
37814
  return /* @__PURE__ */ (0, import_jsx_runtime148.jsx)(import_jsx_runtime148.Fragment, {
@@ -37827,7 +37835,7 @@ function CodeActionMenuContainer({ anchorElem }) {
37827
37835
  }
37828
37836
  function getMouseInfo(event) {
37829
37837
  const target = event.target;
37830
- if (target && target instanceof HTMLElement) {
37838
+ if ((0, import_lexical6.isHTMLElement)(target)) {
37831
37839
  const codeDOMNode = target.closest("code.CrystallizeRTEditorTheme__code");
37832
37840
  const isOutside = !(codeDOMNode || target.closest("div.c-rte-code-action-menu-container"));
37833
37841
  return { codeDOMNode, isOutside };
@@ -38369,12 +38377,11 @@ function FloatingLinkEditorPlugin({
38369
38377
  const [editor] = (0, import_LexicalComposerContext4.useLexicalComposerContext)();
38370
38378
  return useFloatingLinkEditorToolbar(editor, anchorElem);
38371
38379
  }
38372
- var import_react131, React5, import_lexical8, import_react_dom3, import_link4, import_LexicalComposerContext4, import_utils, import_jsx_runtime150;
38380
+ var import_react131, import_lexical8, import_react_dom3, import_link4, import_LexicalComposerContext4, import_utils, import_jsx_runtime150;
38373
38381
  var init_FloatingLinkEditorPlugin = __esm({
38374
38382
  "src/rich-text-editor/plugins/FloatingLinkEditorPlugin/index.tsx"() {
38375
38383
  "use strict";
38376
38384
  import_react131 = require("react");
38377
- React5 = require("react");
38378
38385
  import_lexical8 = require("lexical");
38379
38386
  import_react_dom3 = require("react-dom");
38380
38387
  import_link4 = require("@lexical/link");
@@ -38698,13 +38705,13 @@ function FloatingTextFormatToolbarPlugin({
38698
38705
  const [editor] = (0, import_LexicalComposerContext5.useLexicalComposerContext)();
38699
38706
  return useFloatingTextFormatToolbar(editor, anchorElem);
38700
38707
  }
38701
- var import_react132, React6, import_lexical9, import_react_dom4, import_code8, import_link5, import_LexicalComposerContext5, import_utils2, import_jsx_runtime151;
38708
+ var import_react132, React5, import_lexical9, import_react_dom4, import_code8, import_link5, import_LexicalComposerContext5, import_utils2, import_jsx_runtime151;
38702
38709
  var init_FloatingTextFormatToolbarPlugin = __esm({
38703
38710
  "src/rich-text-editor/plugins/FloatingTextFormatToolbarPlugin/index.tsx"() {
38704
38711
  "use strict";
38705
38712
  init_13();
38706
38713
  import_react132 = require("react");
38707
- React6 = require("react");
38714
+ React5 = require("react");
38708
38715
  import_lexical9 = require("lexical");
38709
38716
  import_react_dom4 = require("react-dom");
38710
38717
  import_code8 = require("@lexical/code");
@@ -38727,11 +38734,11 @@ function LinkPlugin() {
38727
38734
  validateUrl
38728
38735
  });
38729
38736
  }
38730
- var React7, import_LexicalLinkPlugin, import_jsx_runtime152;
38737
+ var React6, import_LexicalLinkPlugin, import_jsx_runtime152;
38731
38738
  var init_LinkPlugin = __esm({
38732
38739
  "src/rich-text-editor/plugins/LinkPlugin/index.tsx"() {
38733
38740
  "use strict";
38734
- React7 = require("react");
38741
+ React6 = require("react");
38735
38742
  import_LexicalLinkPlugin = require("@lexical/react/LexicalLinkPlugin");
38736
38743
  init_url();
38737
38744
  import_jsx_runtime152 = require("react/jsx-runtime");
@@ -38942,7 +38949,7 @@ function TableActionMenu({ tableCellNode: _tableCellNode, tableStats }) {
38942
38949
  (0, import_react136.useEffect)(() => {
38943
38950
  editor.getEditorState().read(() => {
38944
38951
  const selection = (0, import_lexical13.$getSelection)();
38945
- if ((0, import_lexical13.DEPRECATED_$isGridSelection)(selection)) {
38952
+ if ((0, import_table4.$isTableSelection)(selection)) {
38946
38953
  const selectionShape = selection.getShape();
38947
38954
  updateSelectionCounts({
38948
38955
  columns: selectionShape.toX - selectionShape.fromX + 1,
@@ -38959,9 +38966,9 @@ function TableActionMenu({ tableCellNode: _tableCellNode, tableStats }) {
38959
38966
  if (!tableElement) {
38960
38967
  throw new Error("Expected to find tableElement in DOM");
38961
38968
  }
38962
- const tableSelection = (0, import_table4.getTableSelectionFromTableElement)(tableElement);
38969
+ const tableSelection = (0, import_table4.getTableObserverFromTableElement)(tableElement);
38963
38970
  if (tableSelection !== null) {
38964
- tableSelection.clearHighlight();
38971
+ tableSelection.$clearHighlight();
38965
38972
  }
38966
38973
  tableNode.markDirty();
38967
38974
  updateTableCellNode(tableCellNode.getLatest());
@@ -38976,13 +38983,13 @@ function TableActionMenu({ tableCellNode: _tableCellNode, tableStats }) {
38976
38983
  const selection = (0, import_lexical13.$getSelection)();
38977
38984
  const tableNode = (0, import_table4.$getTableNodeFromLexicalNodeOrThrow)(tableCellNode);
38978
38985
  let tableRowIndex;
38979
- if ((0, import_lexical13.DEPRECATED_$isGridSelection)(selection)) {
38986
+ if ((0, import_table4.$isTableSelection)(selection)) {
38980
38987
  const selectionShape = selection.getShape();
38981
38988
  tableRowIndex = shouldInsertAfter ? selectionShape.toY : selectionShape.fromY;
38982
38989
  } else {
38983
38990
  tableRowIndex = (0, import_table4.$getTableRowIndexFromTableCellNode)(tableCellNode);
38984
38991
  }
38985
- const grid = (0, import_table4.$getElementGridForTableNode)(editor, tableNode);
38992
+ const grid = (0, import_table4.$getElementForTableNode)(editor, tableNode);
38986
38993
  (0, import_table4.$insertTableRow)(tableNode, tableRowIndex, shouldInsertAfter, selectionCounts.rows, grid);
38987
38994
  clearTableSelection();
38988
38995
  });
@@ -38995,13 +39002,13 @@ function TableActionMenu({ tableCellNode: _tableCellNode, tableStats }) {
38995
39002
  const selection = (0, import_lexical13.$getSelection)();
38996
39003
  const tableNode = (0, import_table4.$getTableNodeFromLexicalNodeOrThrow)(tableCellNode);
38997
39004
  let tableColumnIndex;
38998
- if ((0, import_lexical13.DEPRECATED_$isGridSelection)(selection)) {
39005
+ if ((0, import_table4.$isTableSelection)(selection)) {
38999
39006
  const selectionShape = selection.getShape();
39000
39007
  tableColumnIndex = shouldInsertAfter ? selectionShape.toX : selectionShape.fromX;
39001
39008
  } else {
39002
39009
  tableColumnIndex = (0, import_table4.$getTableColumnIndexFromTableCellNode)(tableCellNode);
39003
39010
  }
39004
- const grid = (0, import_table4.$getElementGridForTableNode)(editor, tableNode);
39011
+ const grid = (0, import_table4.$getElementForTableNode)(editor, tableNode);
39005
39012
  (0, import_table4.$insertTableColumn)(tableNode, tableColumnIndex, shouldInsertAfter, selectionCounts.columns, grid);
39006
39013
  clearTableSelection();
39007
39014
  });
@@ -39390,7 +39397,7 @@ function BlockFormatDropDown({
39390
39397
  if (blockType !== "paragraph") {
39391
39398
  editor.update(() => {
39392
39399
  const selection = (0, import_lexical15.$getSelection)();
39393
- if ((0, import_lexical15.$isRangeSelection)(selection) || (0, import_lexical15.DEPRECATED_$isGridSelection)(selection))
39400
+ if ((0, import_lexical15.$isRangeSelection)(selection) || (0, import_table6.$isTableSelection)(selection))
39394
39401
  (0, import_selection4.$setBlocksType)(selection, () => (0, import_lexical15.$createParagraphNode)());
39395
39402
  });
39396
39403
  }
@@ -39399,7 +39406,7 @@ function BlockFormatDropDown({
39399
39406
  if (blockType !== headingSize) {
39400
39407
  editor.update(() => {
39401
39408
  const selection = (0, import_lexical15.$getSelection)();
39402
- if ((0, import_lexical15.$isRangeSelection)(selection) || (0, import_lexical15.DEPRECATED_$isGridSelection)(selection)) {
39409
+ if ((0, import_lexical15.$isRangeSelection)(selection) || (0, import_table6.$isTableSelection)(selection)) {
39403
39410
  (0, import_selection4.$setBlocksType)(selection, () => (0, import_rich_text5.$createHeadingNode)(headingSize));
39404
39411
  }
39405
39412
  });
@@ -39423,7 +39430,7 @@ function BlockFormatDropDown({
39423
39430
  if (blockType !== "quote") {
39424
39431
  editor.update(() => {
39425
39432
  const selection = (0, import_lexical15.$getSelection)();
39426
- if ((0, import_lexical15.$isRangeSelection)(selection) || (0, import_lexical15.DEPRECATED_$isGridSelection)(selection)) {
39433
+ if ((0, import_lexical15.$isRangeSelection)(selection) || (0, import_table6.$isTableSelection)(selection)) {
39427
39434
  (0, import_selection4.$setBlocksType)(selection, () => (0, import_rich_text5.$createQuoteNode)());
39428
39435
  } else {
39429
39436
  (0, import_selection4.$setBlocksType)((0, import_lexical15.$getRoot)().select(), () => (0, import_rich_text5.$createQuoteNode)());
@@ -39435,7 +39442,7 @@ function BlockFormatDropDown({
39435
39442
  if (blockType !== "code") {
39436
39443
  editor.update(() => {
39437
39444
  let selection = (0, import_lexical15.$getSelection)();
39438
- if ((0, import_lexical15.$isRangeSelection)(selection) || (0, import_lexical15.DEPRECATED_$isGridSelection)(selection)) {
39445
+ if ((0, import_lexical15.$isRangeSelection)(selection) || (0, import_table6.$isTableSelection)(selection)) {
39439
39446
  if (selection.isCollapsed()) {
39440
39447
  (0, import_selection4.$setBlocksType)(selection, () => (0, import_code9.$createCodeNode)());
39441
39448
  } else {
@@ -39986,7 +39993,7 @@ function ToolbarPlugin({
39986
39993
  ]
39987
39994
  });
39988
39995
  }
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;
39996
+ 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
39997
  var init_ToolbarPlugin = __esm({
39991
39998
  "src/rich-text-editor/plugins/ToolbarPlugin/index.tsx"() {
39992
39999
  "use strict";
@@ -40000,6 +40007,7 @@ var init_ToolbarPlugin = __esm({
40000
40007
  import_LexicalHorizontalRuleNode4 = require("@lexical/react/LexicalHorizontalRuleNode");
40001
40008
  import_rich_text5 = require("@lexical/rich-text");
40002
40009
  import_selection4 = require("@lexical/selection");
40010
+ import_table6 = require("@lexical/table");
40003
40011
  import_utils4 = require("@lexical/utils");
40004
40012
  init_button2();
40005
40013
  init_dialog2();
@@ -40387,7 +40395,7 @@ var import_jsx_runtime3 = require("react/jsx-runtime");
40387
40395
  var cardStyles = (0, import_class_variance_authority3.cva)("c-card", {
40388
40396
  variants: {
40389
40397
  variant: {
40390
- default: "c-card",
40398
+ default: "",
40391
40399
  elevate: "c-card-elevate"
40392
40400
  }
40393
40401
  },
package/dist/index.mjs CHANGED
@@ -26,7 +26,7 @@ import { jsx } from "react/jsx-runtime";
26
26
  var cardStyles = cva("c-card", {
27
27
  variants: {
28
28
  variant: {
29
- default: "c-card",
29
+ default: "",
30
30
  elevate: "c-card-elevate"
31
31
  }
32
32
  },
@@ -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-A5TU4T3X.mjs"));
489
+ var LazyRichTextEditor = lazy(() => import("./rich-text-editor-QPSSPPTF.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
@@ -270,13 +269,12 @@ function composeInitialState({ richText }) {
270
269
  lexicalNode = $createTableRowNode();
271
270
  break;
272
271
  }
273
- case "table-cell":
272
+ case "table-cell": {
273
+ lexicalNode = $createTableCellNode(0, void 0);
274
+ break;
275
+ }
274
276
  case "table-head-cell": {
275
- const colSpan = void 0;
276
- lexicalNode = $createTableCellNode(
277
- 0,
278
- colSpan
279
- );
277
+ lexicalNode = $createTableCellNode(2, void 0);
280
278
  break;
281
279
  }
282
280
  case "container":
@@ -325,6 +323,7 @@ function composeInitialState({ richText }) {
325
323
  lexicalParent.append(lexicalNode);
326
324
  }
327
325
  }
326
+ const root = $getRoot();
328
327
  parseInitialState({ richText }).forEach(
329
328
  (crystallizeContentNode) => handleNode({ crystallizeContentNode, lexicalParent: root })
330
329
  );
@@ -610,7 +609,7 @@ function LexicalAutoLinkPlugin() {
610
609
 
611
610
  // src/rich-text-editor/plugins/CodeActionMenuPlugin/index.tsx
612
611
  import { useEffect, useRef, useState as useState3 } from "react";
613
- import { $getNearestNodeFromDOMNode as $getNearestNodeFromDOMNode3 } from "lexical";
612
+ import { $getNearestNodeFromDOMNode as $getNearestNodeFromDOMNode3, isHTMLElement } from "lexical";
614
613
  import { createPortal } from "react-dom";
615
614
  import { useDebouncedCallback as useDebouncedCallback2 } from "use-debounce";
616
615
  import { $isCodeNode as $isCodeNode4, CodeNode as CodeNode2, getLanguageFriendlyName, normalizeCodeLang } from "@lexical/code";
@@ -784,7 +783,7 @@ function CodeActionMenuContainer({ anchorElem }) {
784
783
  const [editor] = useLexicalComposerContext();
785
784
  const [lang, setLang] = useState3("");
786
785
  const [isShown, setShown] = useState3(false);
787
- const [shouldListenMouseMove, setShouldListenMouseMove] = useState3(true);
786
+ const [shouldListenMouseMove, setShouldListenMouseMove] = useState3(false);
788
787
  const [position, setPosition] = useState3({
789
788
  right: "0",
790
789
  top: "0"
@@ -794,36 +793,40 @@ function CodeActionMenuContainer({ anchorElem }) {
794
793
  function getCodeDOMNode() {
795
794
  return codeDOMNodeRef.current;
796
795
  }
797
- const debouncedOnMouseMove = useDebouncedCallback2((event) => {
798
- const { codeDOMNode, isOutside } = getMouseInfo(event);
799
- if (isOutside) {
800
- setShown(false);
801
- return;
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() || "";
796
+ const debouncedOnMouseMove = useDebouncedCallback2(
797
+ (event) => {
798
+ const { codeDOMNode, isOutside } = getMouseInfo(event);
799
+ if (isOutside) {
800
+ setShown(false);
801
+ return;
814
802
  }
815
- });
816
- if (codeNode) {
817
- const { y: editorElemY, right: editorElemRight } = anchorElem.getBoundingClientRect();
818
- const { y, right } = codeDOMNode.getBoundingClientRect();
819
- setLang(_lang);
820
- setShown(true);
821
- setPosition({
822
- right: `${editorElemRight - right + CODE_PADDING}px`,
823
- top: `${y - editorElemY}px`
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() || "";
814
+ }
824
815
  });
825
- }
826
- }, 50);
816
+ if (codeNode) {
817
+ const { y: editorElemY, right: editorElemRight } = anchorElem.getBoundingClientRect();
818
+ const { y, right } = codeDOMNode.getBoundingClientRect();
819
+ setLang(_lang);
820
+ setShown(true);
821
+ setPosition({
822
+ right: `${editorElemRight - right + CODE_PADDING}px`,
823
+ top: `${y - editorElemY}px`
824
+ });
825
+ }
826
+ },
827
+ 50,
828
+ { maxWait: 1e3 }
829
+ );
827
830
  useEffect(() => {
828
831
  if (!shouldListenMouseMove) {
829
832
  return;
@@ -835,24 +838,29 @@ function CodeActionMenuContainer({ anchorElem }) {
835
838
  document.removeEventListener("mousemove", debouncedOnMouseMove);
836
839
  };
837
840
  }, [shouldListenMouseMove, debouncedOnMouseMove]);
838
- editor.registerMutationListener(CodeNode2, (mutations) => {
839
- editor.getEditorState().read(() => {
840
- for (const [key, type] of mutations) {
841
- switch (type) {
842
- case "created":
843
- codeSetRef.current.add(key);
844
- setShouldListenMouseMove(codeSetRef.current.size > 0);
845
- break;
846
- case "destroyed":
847
- codeSetRef.current.delete(key);
848
- setShouldListenMouseMove(codeSetRef.current.size > 0);
849
- break;
850
- default:
851
- break;
852
- }
853
- }
854
- });
855
- });
841
+ useEffect(() => {
842
+ return editor.registerMutationListener(
843
+ CodeNode2,
844
+ (mutations) => {
845
+ editor.getEditorState().read(() => {
846
+ for (const [key, type] of mutations) {
847
+ switch (type) {
848
+ case "created":
849
+ codeSetRef.current.add(key);
850
+ break;
851
+ case "destroyed":
852
+ codeSetRef.current.delete(key);
853
+ break;
854
+ default:
855
+ break;
856
+ }
857
+ }
858
+ });
859
+ setShouldListenMouseMove(codeSetRef.current.size > 0);
860
+ },
861
+ { skipInitialization: false }
862
+ );
863
+ }, [editor]);
856
864
  const normalizedLang = normalizeCodeLang(lang);
857
865
  const codeFriendlyName = getLanguageFriendlyName(lang);
858
866
  return /* @__PURE__ */ jsx6(Fragment, {
@@ -879,7 +887,7 @@ function CodeActionMenuContainer({ anchorElem }) {
879
887
  }
880
888
  function getMouseInfo(event) {
881
889
  const target = event.target;
882
- if (target && target instanceof HTMLElement) {
890
+ if (isHTMLElement(target)) {
883
891
  const codeDOMNode = target.closest("code.CrystallizeRTEditorTheme__code");
884
892
  const isOutside = !(codeDOMNode || target.closest("div.c-rte-code-action-menu-container"));
885
893
  return { codeDOMNode, isOutside };
@@ -909,7 +917,6 @@ function CodeHighlightPlugin() {
909
917
 
910
918
  // src/rich-text-editor/plugins/FloatingLinkEditorPlugin/index.tsx
911
919
  import { useCallback, useEffect as useEffect4, useRef as useRef2, useState as useState5 } from "react";
912
- import "react";
913
920
  import {
914
921
  $getSelection as $getSelection3,
915
922
  $isRangeSelection,
@@ -1876,13 +1883,13 @@ function TabFocusPlugin() {
1876
1883
 
1877
1884
  // src/rich-text-editor/plugins/TableActionMenuPlugin/index.tsx
1878
1885
  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, DEPRECATED_$isGridSelection } from "lexical";
1886
+ import { $getRoot as $getRoot3, $getSelection as $getSelection8, $isRangeSelection as $isRangeSelection6 } from "lexical";
1880
1887
  import { createPortal as createPortal4 } from "react-dom";
1881
1888
  import { useLexicalComposerContext as useLexicalComposerContext9 } from "@lexical/react/LexicalComposerContext";
1882
1889
  import useLexicalEditable from "@lexical/react/useLexicalEditable";
1883
1890
  import {
1884
1891
  $deleteTableColumn,
1885
- $getElementGridForTableNode,
1892
+ $getElementForTableNode,
1886
1893
  $getTableCellNodeFromLexicalNode,
1887
1894
  $getTableColumnIndexFromTableCellNode,
1888
1895
  $getTableNodeFromLexicalNodeOrThrow,
@@ -1892,8 +1899,9 @@ import {
1892
1899
  $isTableCellNode as $isTableCellNode2,
1893
1900
  $isTableNode as $isTableNode2,
1894
1901
  $isTableRowNode as $isTableRowNode2,
1902
+ $isTableSelection,
1895
1903
  $removeTableRowAtIndex,
1896
- getTableSelectionFromTableElement,
1904
+ getTableObserverFromTableElement,
1897
1905
  TableCellHeaderStates,
1898
1906
  TableCellNode as TableCellNode2
1899
1907
  } from "@lexical/table";
@@ -1919,7 +1927,7 @@ function TableActionMenu({ tableCellNode: _tableCellNode, tableStats }) {
1919
1927
  useEffect9(() => {
1920
1928
  editor.getEditorState().read(() => {
1921
1929
  const selection = $getSelection8();
1922
- if (DEPRECATED_$isGridSelection(selection)) {
1930
+ if ($isTableSelection(selection)) {
1923
1931
  const selectionShape = selection.getShape();
1924
1932
  updateSelectionCounts({
1925
1933
  columns: selectionShape.toX - selectionShape.fromX + 1,
@@ -1936,9 +1944,9 @@ function TableActionMenu({ tableCellNode: _tableCellNode, tableStats }) {
1936
1944
  if (!tableElement) {
1937
1945
  throw new Error("Expected to find tableElement in DOM");
1938
1946
  }
1939
- const tableSelection = getTableSelectionFromTableElement(tableElement);
1947
+ const tableSelection = getTableObserverFromTableElement(tableElement);
1940
1948
  if (tableSelection !== null) {
1941
- tableSelection.clearHighlight();
1949
+ tableSelection.$clearHighlight();
1942
1950
  }
1943
1951
  tableNode.markDirty();
1944
1952
  updateTableCellNode(tableCellNode.getLatest());
@@ -1953,13 +1961,13 @@ function TableActionMenu({ tableCellNode: _tableCellNode, tableStats }) {
1953
1961
  const selection = $getSelection8();
1954
1962
  const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
1955
1963
  let tableRowIndex;
1956
- if (DEPRECATED_$isGridSelection(selection)) {
1964
+ if ($isTableSelection(selection)) {
1957
1965
  const selectionShape = selection.getShape();
1958
1966
  tableRowIndex = shouldInsertAfter ? selectionShape.toY : selectionShape.fromY;
1959
1967
  } else {
1960
1968
  tableRowIndex = $getTableRowIndexFromTableCellNode(tableCellNode);
1961
1969
  }
1962
- const grid = $getElementGridForTableNode(editor, tableNode);
1970
+ const grid = $getElementForTableNode(editor, tableNode);
1963
1971
  $insertTableRow(tableNode, tableRowIndex, shouldInsertAfter, selectionCounts.rows, grid);
1964
1972
  clearTableSelection();
1965
1973
  });
@@ -1972,13 +1980,13 @@ function TableActionMenu({ tableCellNode: _tableCellNode, tableStats }) {
1972
1980
  const selection = $getSelection8();
1973
1981
  const tableNode = $getTableNodeFromLexicalNodeOrThrow(tableCellNode);
1974
1982
  let tableColumnIndex;
1975
- if (DEPRECATED_$isGridSelection(selection)) {
1983
+ if ($isTableSelection(selection)) {
1976
1984
  const selectionShape = selection.getShape();
1977
1985
  tableColumnIndex = shouldInsertAfter ? selectionShape.toX : selectionShape.fromX;
1978
1986
  } else {
1979
1987
  tableColumnIndex = $getTableColumnIndexFromTableCellNode(tableCellNode);
1980
1988
  }
1981
- const grid = $getElementGridForTableNode(editor, tableNode);
1989
+ const grid = $getElementForTableNode(editor, tableNode);
1982
1990
  $insertTableColumn(tableNode, tableColumnIndex, shouldInsertAfter, selectionCounts.columns, grid);
1983
1991
  clearTableSelection();
1984
1992
  });
@@ -2212,7 +2220,6 @@ import {
2212
2220
  CAN_REDO_COMMAND,
2213
2221
  CAN_UNDO_COMMAND,
2214
2222
  COMMAND_PRIORITY_CRITICAL as COMMAND_PRIORITY_CRITICAL3,
2215
- DEPRECATED_$isGridSelection as DEPRECATED_$isGridSelection2,
2216
2223
  FORMAT_TEXT_COMMAND as FORMAT_TEXT_COMMAND2,
2217
2224
  REDO_COMMAND,
2218
2225
  SELECTION_CHANGE_COMMAND as SELECTION_CHANGE_COMMAND3,
@@ -2238,6 +2245,7 @@ import { $isDecoratorBlockNode } from "@lexical/react/LexicalDecoratorBlockNode"
2238
2245
  import { INSERT_HORIZONTAL_RULE_COMMAND } from "@lexical/react/LexicalHorizontalRuleNode";
2239
2246
  import { $createHeadingNode as $createHeadingNode2, $createQuoteNode as $createQuoteNode2, $isHeadingNode as $isHeadingNode2 } from "@lexical/rich-text";
2240
2247
  import { $selectAll, $setBlocksType } from "@lexical/selection";
2248
+ import { $isTableSelection as $isTableSelection2 } from "@lexical/table";
2241
2249
  import {
2242
2250
  $findMatchingParent as $findMatchingParent2,
2243
2251
  $getNearestBlockElementAncestorOrThrow,
@@ -2397,7 +2405,7 @@ function BlockFormatDropDown({
2397
2405
  if (blockType !== "paragraph") {
2398
2406
  editor.update(() => {
2399
2407
  const selection = $getSelection9();
2400
- if ($isRangeSelection7(selection) || DEPRECATED_$isGridSelection2(selection))
2408
+ if ($isRangeSelection7(selection) || $isTableSelection2(selection))
2401
2409
  $setBlocksType(selection, () => $createParagraphNode2());
2402
2410
  });
2403
2411
  }
@@ -2406,7 +2414,7 @@ function BlockFormatDropDown({
2406
2414
  if (blockType !== headingSize) {
2407
2415
  editor.update(() => {
2408
2416
  const selection = $getSelection9();
2409
- if ($isRangeSelection7(selection) || DEPRECATED_$isGridSelection2(selection)) {
2417
+ if ($isRangeSelection7(selection) || $isTableSelection2(selection)) {
2410
2418
  $setBlocksType(selection, () => $createHeadingNode2(headingSize));
2411
2419
  }
2412
2420
  });
@@ -2430,7 +2438,7 @@ function BlockFormatDropDown({
2430
2438
  if (blockType !== "quote") {
2431
2439
  editor.update(() => {
2432
2440
  const selection = $getSelection9();
2433
- if ($isRangeSelection7(selection) || DEPRECATED_$isGridSelection2(selection)) {
2441
+ if ($isRangeSelection7(selection) || $isTableSelection2(selection)) {
2434
2442
  $setBlocksType(selection, () => $createQuoteNode2());
2435
2443
  } else {
2436
2444
  $setBlocksType($getRoot4().select(), () => $createQuoteNode2());
@@ -2442,7 +2450,7 @@ function BlockFormatDropDown({
2442
2450
  if (blockType !== "code") {
2443
2451
  editor.update(() => {
2444
2452
  let selection = $getSelection9();
2445
- if ($isRangeSelection7(selection) || DEPRECATED_$isGridSelection2(selection)) {
2453
+ if ($isRangeSelection7(selection) || $isTableSelection2(selection)) {
2446
2454
  if (selection.isCollapsed()) {
2447
2455
  $setBlocksType(selection, () => $createCodeNode2());
2448
2456
  } else {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@crystallize/design-system",
3
- "version": "1.24.24",
3
+ "version": "1.24.26",
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.12.4",
24
- "@lexical/code": "0.12.4",
25
- "@lexical/file": "0.12.4",
26
- "@lexical/hashtag": "0.12.4",
27
- "@lexical/html": "0.12.4",
28
- "@lexical/link": "0.12.4",
29
- "@lexical/list": "0.12.4",
30
- "@lexical/mark": "0.12.4",
31
- "@lexical/markdown": "0.12.4",
32
- "@lexical/overflow": "0.12.4",
33
- "@lexical/react": "0.12.4",
34
- "@lexical/rich-text": "0.12.4",
35
- "@lexical/selection": "0.12.4",
36
- "@lexical/table": "0.12.4",
37
- "@lexical/text": "0.12.4",
38
- "@lexical/utils": "0.12.4",
39
- "@lexical/yjs": "0.12.4",
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.12.4",
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": "^5.16.4",
79
- "@testing-library/react": "^12.1.2",
80
- "@testing-library/user-event": "14.5.1",
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": "^3.0.1",
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": "0.30.1",
97
+ "vitest": "2.1.8",
99
98
  "tsconfig": "0.0.0"
100
99
  },
101
100
  "keywords": [
package/src/card/card.tsx CHANGED
@@ -7,7 +7,7 @@ type CardStylesProps = VariantProps<typeof cardStyles>;
7
7
  const cardStyles = cva('c-card', {
8
8
  variants: {
9
9
  variant: {
10
- default: 'c-card',
10
+ default: '',
11
11
  elevate: 'c-card-elevate',
12
12
  },
13
13
  },
@@ -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
  }
@@ -117,23 +116,12 @@ export function composeInitialState({ richText }: { richText: CrystallizeRichTex
117
116
  lexicalNode = $createTableRowNode();
118
117
  break;
119
118
  }
120
- case 'table-cell':
119
+ case 'table-cell': {
120
+ lexicalNode = $createTableCellNode(0, undefined);
121
+ break;
122
+ }
121
123
  case 'table-head-cell': {
122
- // ** colSpan / rowSpan has not yet been implemented **
123
- // const colSpanFromMeta = metadata?.colSpan;
124
- // const colSpanParsed =
125
- // typeof colSpanFromMeta === 'number'
126
- // ? colSpanFromMeta
127
- // : parseInt(colSpanFromMeta as unknown as string, 10);
128
- // const colSpan = !isNaN(colSpanParsed) ? colSpanParsed : undefined;
129
- const colSpan = undefined;
130
-
131
- lexicalNode = $createTableCellNode(
132
- // 2 indicates NO_HEADER_STATUS
133
- // See TableCellHeaderStates in @lexical/table/LexicalTableCellNode for details
134
- 0,
135
- colSpan,
136
- );
124
+ lexicalNode = $createTableCellNode(2, undefined);
137
125
  break;
138
126
  }
139
127
  // We do not deal with these tags. They should just be skipped.
@@ -144,7 +132,7 @@ export function composeInitialState({ richText }: { richText: CrystallizeRichTex
144
132
  children.forEach(n => handleNode({ crystallizeContentNode: n, lexicalParent }));
145
133
  } else if (typeof textContent === 'string' && kind === 'inline') {
146
134
  const textNode = $createTextNode(textContent);
147
- lexicalNode.append(textNode);
135
+ (lexicalNode as ElementNode).append(textNode);
148
136
  }
149
137
  return;
150
138
  }
@@ -155,7 +143,7 @@ export function composeInitialState({ richText }: { richText: CrystallizeRichTex
155
143
  if (!lexicalNode && kind === 'inline') {
156
144
  lexicalNode = textNode;
157
145
  } else if (lexicalNode) {
158
- lexicalNode.append(textNode);
146
+ (lexicalNode as ElementNode).append(textNode);
159
147
  }
160
148
  }
161
149
  }
@@ -192,10 +180,11 @@ export function composeInitialState({ richText }: { richText: CrystallizeRichTex
192
180
  }
193
181
  }
194
182
 
195
- lexicalParent.append(lexicalNode);
183
+ (lexicalParent as ElementNode).append(lexicalNode);
196
184
  }
197
185
  }
198
186
 
187
+ const root = $getRoot();
199
188
  parseInitialState({ richText }).forEach(crystallizeContentNode =>
200
189
  handleNode({ crystallizeContentNode, lexicalParent: root }),
201
190
  );
@@ -199,16 +199,17 @@ export function lexicalToCrystallizeRichText({
199
199
  return crystallizeRichText;
200
200
  }
201
201
 
202
- const lexicalFormatToCrystallizeType: Record<TextFormatType, CrystallizeRichTextInlineFormattedNodes['type']> = {
203
- bold: 'strong',
204
- italic: 'emphasized',
205
- underline: 'underlined',
206
- strikethrough: 'deleted',
207
- subscript: 'subscripted',
208
- superscript: 'superscripted',
209
- highlight: 'emphasized',
210
- code: 'code',
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
- kind: 'block',
12
- type: 'paragraph',
13
- textContent: 'hello',
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
- } as CrystallizeRichText,
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>(true);
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((event: MouseEvent) => {
44
- const { codeDOMNode, isOutside } = getMouseInfo(event);
43
+ const debouncedOnMouseMove = useDebouncedCallback(
44
+ (event: MouseEvent) => {
45
+ const { codeDOMNode, isOutside } = getMouseInfo(event);
45
46
 
46
- if (isOutside) {
47
- setShown(false);
48
- return;
49
- }
47
+ if (isOutside) {
48
+ setShown(false);
49
+ return;
50
+ }
50
51
 
51
- if (!codeDOMNode) {
52
- return;
53
- }
52
+ if (!codeDOMNode) {
53
+ return;
54
+ }
54
55
 
55
- codeDOMNodeRef.current = codeDOMNode;
56
+ codeDOMNodeRef.current = codeDOMNode;
56
57
 
57
- let codeNode: CodeNode | null = null;
58
- let _lang = '';
58
+ let codeNode: CodeNode | null = null;
59
+ let _lang = '';
59
60
 
60
- editor.update(() => {
61
- const maybeCodeNode = $getNearestNodeFromDOMNode(codeDOMNode);
61
+ editor.update(() => {
62
+ const maybeCodeNode = $getNearestNodeFromDOMNode(codeDOMNode);
62
63
 
63
- if ($isCodeNode(maybeCodeNode)) {
64
- codeNode = maybeCodeNode;
65
- _lang = codeNode.getLanguage() || '';
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
- }, 50);
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
- editor.registerMutationListener(CodeNode, mutations => {
96
- editor.getEditorState().read(() => {
97
- for (const [key, type] of mutations) {
98
- switch (type) {
99
- case 'created':
100
- codeSetRef.current.add(key);
101
- setShouldListenMouseMove(codeSetRef.current.size > 0);
102
- break;
103
-
104
- case 'destroyed':
105
- codeSetRef.current.delete(key);
106
- setShouldListenMouseMove(codeSetRef.current.size > 0);
107
- break;
108
-
109
- default:
110
- break;
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 && target instanceof HTMLElement) {
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<RangeSelection | GridSelection | NodeSelection | null>(null);
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, DEPRECATED_$isGridSelection } from 'lexical';
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
- $getElementGridForTableNode,
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
- getTableSelectionFromTableElement,
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 (DEPRECATED_$isGridSelection(selection)) {
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 = getTableSelectionFromTableElement(tableElement);
95
+ const tableSelection = getTableObserverFromTableElement(tableElement);
95
96
  if (tableSelection !== null) {
96
- tableSelection.clearHighlight();
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 (DEPRECATED_$isGridSelection(selection)) {
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 = $getElementGridForTableNode(editor, tableNode);
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 (DEPRECATED_$isGridSelection(selection)) {
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 = $getElementGridForTableNode(editor, tableNode);
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) || DEPRECATED_$isGridSelection(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) || DEPRECATED_$isGridSelection(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) || DEPRECATED_$isGridSelection(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) || DEPRECATED_$isGridSelection(selection)) {
174
+ if ($isRangeSelection(selection) || $isTableSelection(selection)) {
175
175
  if (selection.isCollapsed()) {
176
176
  $setBlocksType(selection, () => $createCodeNode());
177
177
  } else {