diff --git a/package-lock.json b/package-lock.json index 43fbf390..ec343e77 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15,15 +15,16 @@ "@codemirror/merge": "^6.4.0", "@codemirror/state": "^6.4.0", "@codemirror/view": "^6.23.0", - "@lexical/clipboard": "^0.35.0", - "@lexical/link": "^0.35.0", - "@lexical/list": "^0.35.0", - "@lexical/markdown": "^0.35.0", - "@lexical/plain-text": "^0.35.0", - "@lexical/react": "^0.35.0", - "@lexical/rich-text": "^0.35.0", - "@lexical/selection": "^0.35.0", - "@lexical/utils": "^0.35.0", + "@lexical/clipboard": "^0.48.0", + "@lexical/extension": "^0.48.0", + "@lexical/link": "^0.48.0", + "@lexical/list": "^0.48.0", + "@lexical/markdown": "^0.48.0", + "@lexical/plain-text": "^0.48.0", + "@lexical/react": "^0.48.0", + "@lexical/rich-text": "^0.48.0", + "@lexical/selection": "^0.48.0", + "@lexical/utils": "^0.48.0", "@mdxeditor/gurx": "^1.2.4", "@radix-ui/colors": "^3.0.0", "@radix-ui/react-dialog": "^1.1.11", @@ -39,7 +40,7 @@ "codemirror": "^6.0.1", "downshift": "^7.6.0", "js-yaml": "4.2.0", - "lexical": "^0.35.0", + "lexical": "^0.48.0", "mdast-util-directive": "^3.0.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-frontmatter": "^2.0.1", @@ -1735,32 +1736,32 @@ } }, "node_modules/@floating-ui/core": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.7.2.tgz", - "integrity": "sha512-wNB5ooIKHQc+Kui96jE/n69rHFWAVoxn5CAzL1Xdd8FG03cgY3MLO+GF9U3W737fYDSgPWA6MReKhBQBop6Pcw==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.8.0.tgz", + "integrity": "sha512-0CIZ5itps/8x7BG8dEIhs53BvCUH2PCoogtakwRTut+Arm58sJooJ0AuZhLw2HJYIR5cMLNPBSS728sPho2khQ==", "license": "MIT", "dependencies": { - "@floating-ui/utils": "^0.2.10" + "@floating-ui/utils": "^0.2.12" } }, "node_modules/@floating-ui/dom": { - "version": "1.7.2", - "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.7.2.tgz", - "integrity": "sha512-7cfaOQuCS27HD7DX+6ib2OrnW+b4ZBwDNnCcT0uTyidcmyWb03FnQqJybDBoCnpdxwBSfA94UAYlRCt7mV+TbA==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.8.0.tgz", + "integrity": "sha512-yXSrzeHZBTZadLOlfyhCkJHNeLJnHRnRInwdZ40L7ZiaAtrBwoYlsDrX3v5zB1Utk7CLfzcOVnVVWoXEky7Ceg==", "license": "MIT", "dependencies": { - "@floating-ui/core": "^1.7.2", - "@floating-ui/utils": "^0.2.10" + "@floating-ui/core": "^1.8.0", + "@floating-ui/utils": "^0.2.12" } }, "node_modules/@floating-ui/react": { - "version": "0.27.14", - "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.27.14.tgz", - "integrity": "sha512-aSf9JXfyXpRQWMbtuW+CJQrnhzHu4Hg1Th9AkvR1o+wSW/vCUVMrtgXaRY5ToV5Fh5w3I7lXJdvlKVvYrQrppw==", + "version": "0.27.20", + "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.27.20.tgz", + "integrity": "sha512-CMqMy7OaXl9W0eq1Uy7L7i2Y/anPvHmFmESd2CEw0t5YvZhcVCeo4MBevAmswRllX7Y2dEidA4ozGPunLSTQpw==", "license": "MIT", "dependencies": { - "@floating-ui/react-dom": "^2.1.4", - "@floating-ui/utils": "^0.2.10", + "@floating-ui/react-dom": "^2.1.9", + "@floating-ui/utils": "^0.2.12", "tabbable": "^6.0.0" }, "peerDependencies": { @@ -1769,12 +1770,12 @@ } }, "node_modules/@floating-ui/react-dom": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.4.tgz", - "integrity": "sha512-JbbpPhp38UmXDDAu60RJmbeme37Jbgsm7NrHGgzYYFKmblzRUh6Pa641dII6LsjwF4XlScDrde2UAzDo/b9KPw==", + "version": "2.1.9", + "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.9.tgz", + "integrity": "sha512-JDjEFGCpImxDCA7JJKviA0M9+RtmJdj0m/NVU5IMgBK+AmZouAQQ7/+2GLH0GXXY0YMw9oXPB8hKdbPYg5QLYg==", "license": "MIT", "dependencies": { - "@floating-ui/dom": "^1.7.2" + "@floating-ui/dom": "^1.8.0" }, "peerDependencies": { "react": ">=16.8.0", @@ -1782,9 +1783,9 @@ } }, "node_modules/@floating-ui/utils": { - "version": "0.2.10", - "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.10.tgz", - "integrity": "sha512-aGTxbpbg8/b5JfU1HXSrbH3wXZuLPJcNEcZQFMxLs3oSzgtVu6nFPkbbGGUvBcUjKV2YyB9Wxxabo+HEH9tcRQ==", + "version": "0.2.12", + "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.12.tgz", + "integrity": "sha512-HpCo8tmWzLVad5s2d19EhAz5zqrrQ6s69qd6moPMQvkOuSwDT1YgRfWSVuc4ennqrgv3OHppiOGMQ7oC13yIww==", "license": "MIT" }, "node_modules/@humanwhocodes/config-array": { @@ -2818,259 +2819,489 @@ } } }, + "node_modules/@lexical/a11y": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@lexical/a11y/-/a11y-0.48.0.tgz", + "integrity": "sha512-18W4ehyipkUim4YVoDZitoH63Om3j6iCN4c84zdqE9RgkWf/PE4rvI/8BHTm6Ni7NkVE14nimXgkpaP5ok15zA==", + "license": "MIT", + "dependencies": { + "@lexical/extension": "0.48.0", + "@lexical/utils": "0.48.0", + "lexical": "0.48.0" + }, + "peerDependencies": { + "typescript": ">=5.2" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, "node_modules/@lexical/clipboard": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@lexical/clipboard/-/clipboard-0.35.0.tgz", - "integrity": "sha512-ko7xSIIiayvDiqjNDX6fgH9RlcM6r9vrrvJYTcfGVBor5httx16lhIi0QJZ4+RNPvGtTjyFv4bwRmsixRRwImg==", + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@lexical/clipboard/-/clipboard-0.48.0.tgz", + "integrity": "sha512-xO2trk6+yBl8XXa/VNe20kXczmPxFoWtUHjidbBLEtlGBj+mo63pJj6H5o/WlZsoMKmIOJxwxsn2ejrS8G0/7A==", "license": "MIT", "dependencies": { - "@lexical/html": "0.35.0", - "@lexical/list": "0.35.0", - "@lexical/selection": "0.35.0", - "@lexical/utils": "0.35.0", - "lexical": "0.35.0" + "@lexical/extension": "0.48.0", + "@lexical/html": "0.48.0", + "@lexical/internal": "0.48.0", + "@lexical/list": "0.48.0", + "@lexical/selection": "0.48.0", + "@lexical/utils": "0.48.0", + "@types/trusted-types": "^2.0.7", + "lexical": "0.48.0" + }, + "peerDependencies": { + "typescript": ">=5.2" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, - "node_modules/@lexical/code": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@lexical/code/-/code-0.35.0.tgz", - "integrity": "sha512-ox4DZwETQ9IA7+DS6PN8RJNwSAF7RMjL7YTVODIqFZ5tUFIf+5xoCHbz7Fll0Bvixlp12hVH90xnLwTLRGpkKw==", + "node_modules/@lexical/code-core": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@lexical/code-core/-/code-core-0.48.0.tgz", + "integrity": "sha512-+O1Ge06AuSo6+r8R2Xk6SkWG07H5/e4K/Scw9aqCM/BRjITxgvFTHTNvgQbaobCsP0uBJiwW1+ZGeWAWcBCY4w==", "license": "MIT", "dependencies": { - "@lexical/utils": "0.35.0", - "lexical": "0.35.0", - "prismjs": "^1.30.0" + "@lexical/extension": "0.48.0", + "@lexical/html": "0.48.0", + "@lexical/internal": "0.48.0", + "@lexical/utils": "0.48.0", + "lexical": "0.48.0" + }, + "peerDependencies": { + "typescript": ">=5.2" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/@lexical/devtools-core": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@lexical/devtools-core/-/devtools-core-0.35.0.tgz", - "integrity": "sha512-C2wwtsMCR6ZTfO0TqpSM17RLJWyfHmifAfCTjFtOJu15p3M6NO/nHYK5Mt7YMQteuS89mOjB4ng8iwoLEZ6QpQ==", + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@lexical/devtools-core/-/devtools-core-0.48.0.tgz", + "integrity": "sha512-4kvKWW6ebgQnJNLXPLmw7dqgSChvzYIBNYtfuR6c48Sw+V/QXQTWqfIUbCIe5X4uG8EEXd5O/udXaJx7GBuP+w==", "license": "MIT", "dependencies": { - "@lexical/html": "0.35.0", - "@lexical/link": "0.35.0", - "@lexical/mark": "0.35.0", - "@lexical/table": "0.35.0", - "@lexical/utils": "0.35.0", - "lexical": "0.35.0" + "@lexical/html": "0.48.0", + "@lexical/link": "0.48.0", + "@lexical/mark": "0.48.0", + "@lexical/table": "0.48.0", + "@lexical/utils": "0.48.0", + "lexical": "0.48.0" }, "peerDependencies": { - "react": ">=17.x", - "react-dom": ">=17.x" + "react": ">=18.x", + "react-dom": ">=18.x", + "typescript": ">=5.2" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/@lexical/dragon": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@lexical/dragon/-/dragon-0.35.0.tgz", - "integrity": "sha512-SL6mT5pcqrt6hEbJ16vWxip5+r3uvMd0bQV5UUxuk+cxIeuP86iTgRh0HFR7SM2dRTYovL6/tM/O+8QLAUGTIg==", + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@lexical/dragon/-/dragon-0.48.0.tgz", + "integrity": "sha512-uPuu7fVca9vmL/Oz30CRZ7FIPIodwMrTgNsRmV8jE6Qd6a7RNiTW7r3+EhbhIdkLb/sjcWsYyOMyUR1TJAB0wQ==", + "license": "MIT", + "dependencies": { + "@lexical/extension": "0.48.0", + "lexical": "0.48.0" + }, + "peerDependencies": { + "typescript": ">=5.2" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@lexical/extension": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@lexical/extension/-/extension-0.48.0.tgz", + "integrity": "sha512-4uBObgz84mVbQWiumndmIhkuJL0ojHiMwFSvSUM/FCo1YMVIZvpI56blI0y+2Vix/oLui9EgVQSJjjWV4NAszw==", "license": "MIT", "dependencies": { - "lexical": "0.35.0" + "@lexical/internal": "0.48.0", + "@lexical/utils": "0.48.0", + "@preact/signals-core": "^1.14.1", + "lexical": "0.48.0" + }, + "peerDependencies": { + "typescript": ">=5.2" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/@lexical/hashtag": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@lexical/hashtag/-/hashtag-0.35.0.tgz", - "integrity": "sha512-LYJWzXuO2ZjKsvQwrLkNZiS2TsjwYkKjlDgtugzejquTBQ/o/nfSn/MmVx6EkYLOYizaJemmZbz3IBh+u732FA==", + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@lexical/hashtag/-/hashtag-0.48.0.tgz", + "integrity": "sha512-hPQtdnbVoNAFsmfnCGfgY7mDbvk6mIznlCRmIR7tLeQKXqz/0Tb6eH3W24EESk9hAF8wFUYNKWE1/Kb3Hl2vEQ==", "license": "MIT", "dependencies": { - "@lexical/utils": "0.35.0", - "lexical": "0.35.0" + "@lexical/text": "0.48.0", + "@lexical/utils": "0.48.0", + "lexical": "0.48.0" + }, + "peerDependencies": { + "typescript": ">=5.2" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/@lexical/history": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@lexical/history/-/history-0.35.0.tgz", - "integrity": "sha512-onjDRLLxGbCfHexSxxrQaDaieIHyV28zCDrbxR5dxTfW8F8PxjuNyuaG0z6o468AXYECmclxkP+P4aT6poHEpQ==", + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@lexical/history/-/history-0.48.0.tgz", + "integrity": "sha512-NllvUfO+u3mfi5uC8k2CodwdzeeopFFVtMZ/NMifzFbZFysdWi9m9mqfO46NrEA1rSFOydyefv6oMzC8ULXInA==", "license": "MIT", "dependencies": { - "@lexical/utils": "0.35.0", - "lexical": "0.35.0" + "@lexical/extension": "0.48.0", + "@lexical/utils": "0.48.0", + "lexical": "0.48.0" + }, + "peerDependencies": { + "typescript": ">=5.2" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/@lexical/html": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@lexical/html/-/html-0.35.0.tgz", - "integrity": "sha512-rXGFE5S5rKsg3tVnr1s4iEgOfCApNXGpIFI3T2jGEShaCZ5HLaBY9NVBXnE9Nb49e9bkDkpZ8FZd1qokCbQXbw==", + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@lexical/html/-/html-0.48.0.tgz", + "integrity": "sha512-uBxlgKl4YgSNEgHJSshdBqtGDzruWdx1ewop+u6faT67qHUdP3P0cUXIrG6NToDWvsL6fzCstAbN76PMER1Pnw==", "license": "MIT", "dependencies": { - "@lexical/selection": "0.35.0", - "@lexical/utils": "0.35.0", - "lexical": "0.35.0" + "@lexical/extension": "0.48.0", + "@lexical/internal": "0.48.0", + "@lexical/selection": "0.48.0", + "@lexical/utils": "0.48.0", + "lexical": "0.48.0" + }, + "peerDependencies": { + "typescript": ">=5.2" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@lexical/internal": { + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@lexical/internal/-/internal-0.48.0.tgz", + "integrity": "sha512-sRwg53K7N0ZQ7KNAvcCY38LSwGizbXP1zlR1lIojZp0GoqHWNvR+vL49t1wYXu1nXx3Osf4ilHHm+aGcwq5hTw==", + "license": "MIT", + "peerDependencies": { + "typescript": ">=5.2" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/@lexical/link": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@lexical/link/-/link-0.35.0.tgz", - "integrity": "sha512-+0Wx6cBwO8TfdMzpkYFacsmgFh8X1rkiYbq3xoLvk3qV8upYxaMzK1s8Q1cpKmWyI0aZrU6z7fiK4vUqB7+69w==", + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@lexical/link/-/link-0.48.0.tgz", + "integrity": "sha512-E0UDmNLUXs/yMCnnE7hbFO0CvhWghmqa+qqPksFfzLkpMHdPpdS1yg59YEbYoNHLi/DXIu4cFRvpHIEuooxwNg==", "license": "MIT", "dependencies": { - "@lexical/utils": "0.35.0", - "lexical": "0.35.0" + "@lexical/extension": "0.48.0", + "@lexical/html": "0.48.0", + "@lexical/internal": "0.48.0", + "@lexical/utils": "0.48.0", + "lexical": "0.48.0" + }, + "peerDependencies": { + "typescript": ">=5.2" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/@lexical/list": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@lexical/list/-/list-0.35.0.tgz", - "integrity": "sha512-owsmc8iwgExBX8sFe8fKTiwJVhYULt9hD1RZ/HwfaiEtRZZkINijqReOBnW2mJfRxBzhFSWc4NG3ISB+fHYzqw==", + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@lexical/list/-/list-0.48.0.tgz", + "integrity": "sha512-9Qe/Vur44v9F9enj55SUzf79FVsijcGOQug7SpiIU8ekLr7JNzcilKYBYcZ6etGEo7bqQHsYMHXeJcSBbCI2zA==", "license": "MIT", "dependencies": { - "@lexical/selection": "0.35.0", - "@lexical/utils": "0.35.0", - "lexical": "0.35.0" + "@lexical/extension": "0.48.0", + "@lexical/html": "0.48.0", + "@lexical/internal": "0.48.0", + "@lexical/utils": "0.48.0", + "lexical": "0.48.0" + }, + "peerDependencies": { + "typescript": ">=5.2" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/@lexical/mark": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@lexical/mark/-/mark-0.35.0.tgz", - "integrity": "sha512-W0hwMTAVeexvpk9/+J6n1G/sNkpI/Meq1yeDazahFLLAwXLHtvhIAq2P/klgFknDy1hr8X7rcsQuN/bqKcKHYg==", + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@lexical/mark/-/mark-0.48.0.tgz", + "integrity": "sha512-DTtypWvnYSXyNUxEmsUnh4y0xXkmdk8Y72EZl8WDHcCwjqaLJlUakH7p/TuSJczs3uVSaoJzu0yh7oGkP1Vsvw==", "license": "MIT", "dependencies": { - "@lexical/utils": "0.35.0", - "lexical": "0.35.0" + "@lexical/utils": "0.48.0", + "lexical": "0.48.0" + }, + "peerDependencies": { + "typescript": ">=5.2" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/@lexical/markdown": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@lexical/markdown/-/markdown-0.35.0.tgz", - "integrity": "sha512-BlNyXZAt4gWidMw0SRWrhBETY1BpPglFBZI7yzfqukFqgXRh7HUQA28OYeI/nsx9pgNob8TiUduUwShqqvOdEA==", - "license": "MIT", - "dependencies": { - "@lexical/code": "0.35.0", - "@lexical/link": "0.35.0", - "@lexical/list": "0.35.0", - "@lexical/rich-text": "0.35.0", - "@lexical/text": "0.35.0", - "@lexical/utils": "0.35.0", - "lexical": "0.35.0" - } - }, - "node_modules/@lexical/offset": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@lexical/offset/-/offset-0.35.0.tgz", - "integrity": "sha512-DRE4Df6qYf2XiV6foh6KpGNmGAv2ANqt3oVXpyS6W8hTx3+cUuAA1APhCZmLNuU107um4zmHym7taCu6uXW5Yg==", + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@lexical/markdown/-/markdown-0.48.0.tgz", + "integrity": "sha512-1WasBenW4bEsa5xtnycVo8G2hcxIqyYLn3/r98yD2Y+54ZyeFuIQfOeJYhIgCh4YkKpfqyrFwkMQwAOsQDqZjA==", "license": "MIT", "dependencies": { - "lexical": "0.35.0" + "@lexical/code-core": "0.48.0", + "@lexical/internal": "0.48.0", + "@lexical/link": "0.48.0", + "@lexical/list": "0.48.0", + "@lexical/rich-text": "0.48.0", + "@lexical/selection": "0.48.0", + "@lexical/text": "0.48.0", + "@lexical/utils": "0.48.0", + "lexical": "0.48.0" + }, + "peerDependencies": { + "typescript": ">=5.2" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/@lexical/overflow": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@lexical/overflow/-/overflow-0.35.0.tgz", - "integrity": "sha512-B25YvnJQTGlZcrNv7b0PJBLWq3tl8sql497OHfYYLem7EOMPKKDGJScJAKM/91D4H/mMAsx5gnA/XgKobriuTg==", + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@lexical/overflow/-/overflow-0.48.0.tgz", + "integrity": "sha512-1YEvMz2tW3EbwrON9mjrkjMVl/vdTcPYSn9P1j6mf5gj0LOoLDNI4TbvSD4SViy+TDghxNdG8YdCISyU2b4YKA==", "license": "MIT", "dependencies": { - "lexical": "0.35.0" + "lexical": "0.48.0" + }, + "peerDependencies": { + "typescript": ">=5.2" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/@lexical/plain-text": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@lexical/plain-text/-/plain-text-0.35.0.tgz", - "integrity": "sha512-lwBCUNMJf7Gujp2syVWMpKRahfbTv5Wq+H3HK1Q1gKH1P2IytPRxssCHvexw9iGwprSyghkKBlbF3fGpEdIJvQ==", + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@lexical/plain-text/-/plain-text-0.48.0.tgz", + "integrity": "sha512-q4f/4VZKVgCrIW2FhDFR2RII1BU0ljedPgEmJ8XQn1zc+JOFPom8Lp0lV5nyEvZaAJYwM/TfoJ9g2V7ESFKznA==", "license": "MIT", "dependencies": { - "@lexical/clipboard": "0.35.0", - "@lexical/selection": "0.35.0", - "@lexical/utils": "0.35.0", - "lexical": "0.35.0" + "@lexical/clipboard": "0.48.0", + "@lexical/dragon": "0.48.0", + "@lexical/extension": "0.48.0", + "@lexical/selection": "0.48.0", + "@lexical/utils": "0.48.0", + "lexical": "0.48.0" + }, + "peerDependencies": { + "typescript": ">=5.2" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/@lexical/react": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@lexical/react/-/react-0.35.0.tgz", - "integrity": "sha512-uYAZSqumH8tRymMef+A0f2hQvMwplKK9DXamcefnk3vSNDHHqRWQXpiUo6kD+rKWuQmMbVa5RW4xRQebXEW+1A==", - "license": "MIT", - "dependencies": { - "@floating-ui/react": "^0.27.8", - "@lexical/devtools-core": "0.35.0", - "@lexical/dragon": "0.35.0", - "@lexical/hashtag": "0.35.0", - "@lexical/history": "0.35.0", - "@lexical/link": "0.35.0", - "@lexical/list": "0.35.0", - "@lexical/mark": "0.35.0", - "@lexical/markdown": "0.35.0", - "@lexical/overflow": "0.35.0", - "@lexical/plain-text": "0.35.0", - "@lexical/rich-text": "0.35.0", - "@lexical/table": "0.35.0", - "@lexical/text": "0.35.0", - "@lexical/utils": "0.35.0", - "@lexical/yjs": "0.35.0", - "lexical": "0.35.0", - "react-error-boundary": "^3.1.4" + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@lexical/react/-/react-0.48.0.tgz", + "integrity": "sha512-uVh9/QSrbtjLjVbxfJ+sfiMyhUq/rv7H6uBEVDDIw1rkZJSDY1fvf/CX+dyKgwcDFjKQZ8/9i5f9UCVPeQ01hA==", + "license": "MIT", + "dependencies": { + "@floating-ui/react": "^0.27.19", + "@lexical/a11y": "0.48.0", + "@lexical/devtools-core": "0.48.0", + "@lexical/dragon": "0.48.0", + "@lexical/extension": "0.48.0", + "@lexical/hashtag": "0.48.0", + "@lexical/history": "0.48.0", + "@lexical/internal": "0.48.0", + "@lexical/link": "0.48.0", + "@lexical/list": "0.48.0", + "@lexical/mark": "0.48.0", + "@lexical/markdown": "0.48.0", + "@lexical/overflow": "0.48.0", + "@lexical/plain-text": "0.48.0", + "@lexical/rich-text": "0.48.0", + "@lexical/table": "0.48.0", + "@lexical/text": "0.48.0", + "@lexical/utils": "0.48.0", + "@lexical/yjs": "0.48.0", + "lexical": "0.48.0" }, "peerDependencies": { - "react": ">=17.x", - "react-dom": ">=17.x" + "react": ">=18.x", + "react-dom": ">=18.x", + "typescript": ">=5.2", + "yjs": ">=13.5.22" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + }, + "yjs": { + "optional": true + } } }, "node_modules/@lexical/rich-text": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@lexical/rich-text/-/rich-text-0.35.0.tgz", - "integrity": "sha512-qEHu8g7vOEzz9GUz1VIUxZBndZRJPh9iJUFI+qTDHj+tQqnd5LCs+G9yz6jgNfiuWWpezTp0i1Vz/udNEuDPKQ==", + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@lexical/rich-text/-/rich-text-0.48.0.tgz", + "integrity": "sha512-QMXFnwCKAQ4yzxvx5FwmANcx3K+NaBkGTxAVD8s8pOKDD/U5rzDS1iIvhH6TLWaFp7VzvLmLB+Sl1Ie/RnkaDQ==", "license": "MIT", "dependencies": { - "@lexical/clipboard": "0.35.0", - "@lexical/selection": "0.35.0", - "@lexical/utils": "0.35.0", - "lexical": "0.35.0" + "@lexical/clipboard": "0.48.0", + "@lexical/dragon": "0.48.0", + "@lexical/extension": "0.48.0", + "@lexical/html": "0.48.0", + "@lexical/selection": "0.48.0", + "@lexical/utils": "0.48.0", + "lexical": "0.48.0" + }, + "peerDependencies": { + "typescript": ">=5.2" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/@lexical/selection": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@lexical/selection/-/selection-0.35.0.tgz", - "integrity": "sha512-mMtDE7Q0nycXdFTTH/+ta6EBrBwxBB4Tg8QwsGntzQ1Cq//d838dpXpFjJOqHEeVHUqXpiuj+cBG8+bvz/rPRw==", + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@lexical/selection/-/selection-0.48.0.tgz", + "integrity": "sha512-Uc0wTrEtHcYK6z/aHHjkgH3vX/R4Bf8mO+qH3VbxfSAKYzNYktM0j+ZGdq5kIEL4frnw/9SulNCXlH7xpjuDgA==", "license": "MIT", "dependencies": { - "lexical": "0.35.0" + "@lexical/internal": "0.48.0", + "lexical": "0.48.0" + }, + "peerDependencies": { + "typescript": ">=5.2" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/@lexical/table": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@lexical/table/-/table-0.35.0.tgz", - "integrity": "sha512-9jlTlkVideBKwsEnEkqkdg7A3mije1SvmfiqoYnkl1kKJCLA5iH90ywx327PU0p+bdnURAytWUeZPXaEuEl2OA==", + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@lexical/table/-/table-0.48.0.tgz", + "integrity": "sha512-t9Mz7q6ODLUz0lG5Xn9EY/5YiVpTHCqlPQP4EtFXlnBQT3DuKeDS3cC0Cn8sGSZc11YY5OLDfWpB64Frs9BL3g==", "license": "MIT", "dependencies": { - "@lexical/clipboard": "0.35.0", - "@lexical/utils": "0.35.0", - "lexical": "0.35.0" + "@lexical/clipboard": "0.48.0", + "@lexical/extension": "0.48.0", + "@lexical/html": "0.48.0", + "@lexical/internal": "0.48.0", + "@lexical/utils": "0.48.0", + "lexical": "0.48.0" + }, + "peerDependencies": { + "typescript": ">=5.2" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/@lexical/text": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@lexical/text/-/text-0.35.0.tgz", - "integrity": "sha512-uaMh46BkysV8hK8wQwp5g/ByZW+2hPDt8ahAErxtf8NuzQem1FHG/f5RTchmFqqUDVHO3qLNTv4AehEGmXv8MA==", + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@lexical/text/-/text-0.48.0.tgz", + "integrity": "sha512-ktTMRbsX4wKxdG2OpZCkrqtt8k9Vg/ZpWdukOQ0r1xPRtCuL1T+q91l7cy2ywIuCfMGYS0aoZGB4LdpUMe/H1g==", "license": "MIT", "dependencies": { - "lexical": "0.35.0" + "@lexical/internal": "0.48.0", + "lexical": "0.48.0" + }, + "peerDependencies": { + "typescript": ">=5.2" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/@lexical/utils": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@lexical/utils/-/utils-0.35.0.tgz", - "integrity": "sha512-2H393EYDnFznYCDFOW3MHiRzwEO5M/UBhtUjvTT+9kc+qhX4U3zc8ixQalo5UmZ5B2nh7L/inXdTFzvSRXtsRA==", + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@lexical/utils/-/utils-0.48.0.tgz", + "integrity": "sha512-W4k4P+y6jmRfna8+ad4X+iMd5h8es5PC3bUw5tbi7MRApxaaFG/0w+uJiZVSwbT2Q6JnA2xhBaqzPgt/Gn6djg==", "license": "MIT", "dependencies": { - "@lexical/list": "0.35.0", - "@lexical/selection": "0.35.0", - "@lexical/table": "0.35.0", - "lexical": "0.35.0" + "@lexical/internal": "0.48.0", + "@lexical/selection": "0.48.0", + "lexical": "0.48.0" + }, + "peerDependencies": { + "typescript": ">=5.2" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/@lexical/yjs": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/@lexical/yjs/-/yjs-0.35.0.tgz", - "integrity": "sha512-3DSP7QpmTGYU9bN/yljP0PIao4tNIQtsR4ycauWNSawxs/GQCZtSmAPcLRnCm6qpqsDDjUtKjO/1Ej8FRp0m0w==", + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/@lexical/yjs/-/yjs-0.48.0.tgz", + "integrity": "sha512-fFsE8EnPM/2KK9rMJ0z6T+Da5UW5V4P+XiAA03LoHTY5YQ/Oy8Q0i7Wcmocv/B/SpsY2o8g07euZEfudl9MVKA==", "license": "MIT", "dependencies": { - "@lexical/offset": "0.35.0", - "@lexical/selection": "0.35.0", - "lexical": "0.35.0" + "@lexical/internal": "0.48.0", + "@lexical/selection": "0.48.0", + "lexical": "0.48.0" }, "peerDependencies": { + "typescript": ">=5.2", "yjs": ">=13.5.22" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } } }, "node_modules/@lezer/common": { @@ -3760,6 +3991,16 @@ "node": ">=12" } }, + "node_modules/@preact/signals-core": { + "version": "1.14.4", + "resolved": "https://registry.npmjs.org/@preact/signals-core/-/signals-core-1.14.4.tgz", + "integrity": "sha512-HNB6HYeYKhQbJ1aKl+YRjrS4+QWHLKX6qKoUsfS/m0vqzsVaEBiZiaKbG/e+NKk2ch5ALQr/ihWaMHxiCuuWHA==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/preact" + } + }, "node_modules/@radix-ui/colors": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/@radix-ui/colors/-/colors-3.0.0.tgz", @@ -6256,6 +6497,12 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/trusted-types": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", + "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==", + "license": "MIT" + }, "node_modules/@types/unist": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.2.tgz", @@ -13581,10 +13828,21 @@ } }, "node_modules/lexical": { - "version": "0.35.0", - "resolved": "https://registry.npmjs.org/lexical/-/lexical-0.35.0.tgz", - "integrity": "sha512-3VuV8xXhh5xJA6tzvfDvE0YBCMkIZUmxtRilJQDDdCgJCc+eut6qAv2qbN+pbqvarqcQqPN1UF+8YvsjmyOZpw==", - "license": "MIT" + "version": "0.48.0", + "resolved": "https://registry.npmjs.org/lexical/-/lexical-0.48.0.tgz", + "integrity": "sha512-KK4Tyr/cPsleoZ7XvhGRiRmcrZidSmoFUdIXK9nPubIifoC+80Dc5THyc4xtGKtsW24S1TsHzk5gmfBU+TxmEg==", + "license": "MIT", + "dependencies": { + "@lexical/internal": "0.48.0" + }, + "peerDependencies": { + "typescript": ">=5.2" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } }, "node_modules/lilconfig": { "version": "2.1.0", @@ -19202,15 +19460,6 @@ "react": ">=16.0.0" } }, - "node_modules/prismjs": { - "version": "1.30.0", - "resolved": "https://registry.npmjs.org/prismjs/-/prismjs-1.30.0.tgz", - "integrity": "sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", @@ -19416,21 +19665,6 @@ "react": "^19.2.1" } }, - "node_modules/react-error-boundary": { - "version": "3.1.4", - "resolved": "https://registry.npmjs.org/react-error-boundary/-/react-error-boundary-3.1.4.tgz", - "integrity": "sha512-uM9uPzZJTF6wRQORmSrvOIgt4lJ9MC1sNgEOj2XGsDTRE4kmpWxg7ENK9EWNKJRMAOY9z0MuF4yIfl6gp4sotA==", - "dependencies": { - "@babel/runtime": "^7.12.5" - }, - "engines": { - "node": ">=10", - "npm": ">=6" - }, - "peerDependencies": { - "react": ">=16.13.1" - } - }, "node_modules/react-hook-form": { "version": "7.56.1", "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.56.1.tgz", @@ -21340,9 +21574,9 @@ } }, "node_modules/tabbable": { - "version": "6.2.0", - "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz", - "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==", + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.5.0.tgz", + "integrity": "sha512-wieBHXygIm7OyQOu5hQlkk62/WyCFYGlWg7L6/ZCUZwx0o398Zkn4pVmMyfYhfMG8kGrj/Krt8eIk6UKC6VzwA==", "license": "MIT" }, "node_modules/tagged-tag": { diff --git a/package.json b/package.json index d8315b18..b146ed28 100644 --- a/package.json +++ b/package.json @@ -44,15 +44,16 @@ "@codemirror/merge": "^6.4.0", "@codemirror/state": "^6.4.0", "@codemirror/view": "^6.23.0", - "@lexical/clipboard": "^0.35.0", - "@lexical/link": "^0.35.0", - "@lexical/list": "^0.35.0", - "@lexical/markdown": "^0.35.0", - "@lexical/plain-text": "^0.35.0", - "@lexical/react": "^0.35.0", - "@lexical/rich-text": "^0.35.0", - "@lexical/selection": "^0.35.0", - "@lexical/utils": "^0.35.0", + "@lexical/clipboard": "^0.48.0", + "@lexical/extension": "^0.48.0", + "@lexical/link": "^0.48.0", + "@lexical/list": "^0.48.0", + "@lexical/markdown": "^0.48.0", + "@lexical/plain-text": "^0.48.0", + "@lexical/react": "^0.48.0", + "@lexical/rich-text": "^0.48.0", + "@lexical/selection": "^0.48.0", + "@lexical/utils": "^0.48.0", "@mdxeditor/gurx": "^1.2.4", "@radix-ui/colors": "^3.0.0", "@radix-ui/react-dialog": "^1.1.11", @@ -68,7 +69,7 @@ "codemirror": "^6.0.1", "downshift": "^7.6.0", "js-yaml": "4.2.0", - "lexical": "^0.35.0", + "lexical": "^0.48.0", "mdast-util-directive": "^3.0.0", "mdast-util-from-markdown": "^2.0.0", "mdast-util-frontmatter": "^2.0.1", diff --git a/src/MDXEditor.tsx b/src/MDXEditor.tsx index 1f07e2a2..82dc221a 100644 --- a/src/MDXEditor.tsx +++ b/src/MDXEditor.tsx @@ -2,6 +2,7 @@ import { useCellValue, useCellValues, usePublisher, useRealm } from '@mdxeditor/ import React, { JSX } from 'react' import { activeEditor$, + activePlugins$, AdditionalLexicalNode, bottomAreaChildren$, composerChildren$, @@ -10,10 +11,7 @@ import { corePlugin, editorRootElementRef$, editorWrappers$, - exportVisitors$, insertMarkdown$, - jsxComponentDescriptors$, - jsxIsAvailable$, markdown$, markdownSourceEditorValue$, placeholder$, @@ -21,8 +19,6 @@ import { contentEditableWrapperElement$, setMarkdown$, spellCheck$, - toMarkdownExtensions$, - toMarkdownOptions$, topAreaChildren$, Translation, useTranslation, @@ -271,20 +267,9 @@ const Methods: React.FC<{ mdxRef: React.ForwardedRef }> = ({ m return '' } - // Get all export parameters from realm - const visitors = realm.getValue(exportVisitors$) - const toMarkdownExtensions = realm.getValue(toMarkdownExtensions$) - const toMarkdownOptions = realm.getValue(toMarkdownOptions$) - const jsxComponentDescriptors = realm.getValue(jsxComponentDescriptors$) - const jsxIsAvailable = realm.getValue(jsxIsAvailable$) + const activePlugins = realm.getValue(activePlugins$) - return getSelectionAsMarkdown(activeEditor, { - visitors, - toMarkdownExtensions, - toMarkdownOptions, - jsxComponentDescriptors, - jsxIsAvailable - }) + return getSelectionAsMarkdown(activeEditor, activePlugins) } } }, diff --git a/src/mdastUtilHtmlComment.ts b/src/mdastUtilHtmlComment.ts index 555c59ba..78f8b1a8 100644 --- a/src/mdastUtilHtmlComment.ts +++ b/src/mdastUtilHtmlComment.ts @@ -3,9 +3,13 @@ import type { Handle, Transform } from 'mdast-util-from-markdown' import { factorySpace } from 'micromark-factory-space' import { markdownLineEnding } from 'micromark-util-character' -import { codes, types } from 'micromark-util-symbol' +import { codes as rawCodes, types as rawTypes } from 'micromark-util-symbol' -import type { Code, Extension, Tokenizer } from 'micromark-util-types' +import type { Code, Extension, Tokenizer, TokenType } from 'micromark-util-types' + +// Type these to avoid moduleResolution issues +const codes = rawCodes as Record +const types = rawTypes as Record declare module 'micromark-util-types' { interface TokenTypeMap { diff --git a/src/plugins/codeblock/CodeBlockNode.tsx b/src/plugins/codeblock/CodeBlockNode.tsx index e4b73201..07d20223 100644 --- a/src/plugins/codeblock/CodeBlockNode.tsx +++ b/src/plugins/codeblock/CodeBlockNode.tsx @@ -68,8 +68,8 @@ export class CodeBlockNode extends DecoratorNode { this.__focusEmitter = voidEmitter() } - static importJSON(serializedNode: SerializedCodeBlockNode): CodeBlockNode { - const { code, meta, language } = serializedNode + static importJSON(serializedNode: SerializedLexicalNode & Record): CodeBlockNode { + const { code, meta, language } = serializedNode as unknown as SerializedCodeBlockNode return $createCodeBlockNode({ code, language, diff --git a/src/plugins/markdown-shortcut/index.tsx b/src/plugins/markdown-shortcut/index.tsx index 5d8b709a..b74a3c1c 100644 --- a/src/plugins/markdown-shortcut/index.tsx +++ b/src/plugins/markdown-shortcut/index.tsx @@ -19,12 +19,12 @@ import { } from '@lexical/markdown' import { MarkdownShortcutPlugin } from '@lexical/react/LexicalMarkdownShortcutPlugin' import { $createHeadingNode, $isHeadingNode, HeadingNode, HeadingTagType } from '@lexical/rich-text' -import { ElementNode, LexicalNode } from 'lexical' +import { ElementNode } from 'lexical' import { realmPlugin } from '../../RealmWithPlugins' import { $createCodeBlockNode, CodeBlockNode } from '../codeblock/CodeBlockNode' import { activePlugins$, addComposerChild$, addNestedEditorChild$, addTableCellEditorChild$ } from '../core' import { HEADING_LEVEL, allowedHeadingLevels$ } from '../headings' -import { $createHorizontalRuleNode, $isHorizontalRuleNode, HorizontalRuleNode } from '@lexical/react/LexicalHorizontalRuleNode' +import { THEMATIC_BREAK_TRANSFORMER } from '../thematic-break/transformer' /** * A plugin that adds markdown shortcuts to the editor. @@ -53,27 +53,6 @@ const createBlockNode = (createNode: (match: string[]) => ElementNode): ElementT } } -const THEMATIC_BREAK: ElementTransformer = { - dependencies: [HorizontalRuleNode], - export: (node: LexicalNode) => { - return $isHorizontalRuleNode(node) ? '***' : null - }, - regExp: /^(---|\*\*\*|___)\s?$/, - replace: (parentNode, _1, _2, isImport) => { - const line = $createHorizontalRuleNode() - - // TODO: Get rid of isImport flag - if (isImport || parentNode.getNextSibling() != null) { - parentNode.replace(line) - } else { - parentNode.insertBefore(line) - } - - line.selectNext() - }, - type: 'element' -} - const LIST_TRANSFORMERS: ReadonlySet = new Set([ORDERED_LIST, UNORDERED_LIST, CHECK_LIST]) function pickTransformersForActivePlugins(pluginIds: string[], allowedHeadingLevels: readonly HEADING_LEVEL[]) { @@ -116,7 +95,7 @@ function pickTransformersForActivePlugins(pluginIds: string[], allowedHeadingLev } if (pluginIds.includes('thematicBreak')) { - transformers.push(THEMATIC_BREAK) + transformers.push(THEMATIC_BREAK_TRANSFORMER) } if (pluginIds.includes('quote')) { diff --git a/src/plugins/table/index.ts b/src/plugins/table/index.ts index 98208d0c..ef911660 100644 --- a/src/plugins/table/index.ts +++ b/src/plugins/table/index.ts @@ -4,17 +4,20 @@ import * as Mdast from 'mdast' import { gfmTableFromMarkdown, gfmTableToMarkdown, Options as GfmTableOptions } from 'mdast-util-gfm-table' import { gfmTable } from 'micromark-extension-gfm-table' import { + addActivePlugin$, addExportVisitor$, addImportVisitor$, addLexicalNode$, addMdastExtension$, addSyntaxExtension$, addToMarkdownExtension$, - insertDecoratorNode$ + insertDecoratorNode$, + toMarkdownExtensions$ } from '../core' import { LexicalTableVisitor } from './LexicalTableVisitor' import { MdastTableVisitor } from './MdastTableVisitor' import { $createTableNode, TableNode } from './TableNode' +import { setTableTransformerExtensions } from './transformer' export * from './TableNode' function seedTable(rows = 1, columns = 1): Mdast.Table { @@ -82,6 +85,7 @@ export const insertTable$ = Signal<{ export const tablePlugin = realmPlugin({ init(realm, params) { realm.pubIn({ + [addActivePlugin$]: 'table', // import [addMdastExtension$]: gfmTableFromMarkdown(), [addSyntaxExtension$]: gfmTable(), @@ -94,5 +98,10 @@ export const tablePlugin = realmPlugin({ tablePipeAlign: params?.tablePipeAlign ?? true }) }) + + // Subscribe to toMarkdownExtensions$ to keep the transformer in sync with active extensions + realm.sub(toMarkdownExtensions$, (extensions) => { + setTableTransformerExtensions(extensions) + }) } }) diff --git a/src/plugins/table/transformer.ts b/src/plugins/table/transformer.ts new file mode 100644 index 00000000..e9a87929 --- /dev/null +++ b/src/plugins/table/transformer.ts @@ -0,0 +1,42 @@ +import { type ElementTransformer } from '@lexical/markdown' +import { type LexicalNode } from 'lexical' +import { $isTableNode, TableNode } from './TableNode' +import { toMarkdown } from 'mdast-util-to-markdown' +import { ToMarkdownExtension } from '../../exportMarkdownFromLexical' + +let cachedExtensions: ToMarkdownExtension[] = [] + +/** + * Update the cached markdown extensions used by the table transformer. + * Called by the table plugin when extensions change. + */ +export function setTableTransformerExtensions(extensions: ToMarkdownExtension[]) { + cachedExtensions = extensions +} + +/** + * Transformer for table nodes. + * Exports TableNode to GFM (GitHub Flavored Markdown) table syntax. + */ +export const TABLE_TRANSFORMER: ElementTransformer = { + dependencies: [TableNode], + export: (node: LexicalNode) => { + if ($isTableNode(node)) { + const mdastTable = node.getMdastNode() + + try { + return toMarkdown(mdastTable, { + // Use cached extensions that are set by the plugin + extensions: cachedExtensions + }) + } catch (e) { + console.error('Failed to export table node:', e) + return null + } + } + return null + }, + regExp: /^\|.+\|.*/, + replace: () => false, + type: 'element' +} diff --git a/src/plugins/thematic-break/LexicalThematicBreakVisitor.ts b/src/plugins/thematic-break/LexicalThematicBreakVisitor.ts index 5e2c1e7a..7b82e51d 100644 --- a/src/plugins/thematic-break/LexicalThematicBreakVisitor.ts +++ b/src/plugins/thematic-break/LexicalThematicBreakVisitor.ts @@ -1,4 +1,4 @@ -import { $isHorizontalRuleNode, HorizontalRuleNode } from '@lexical/react/LexicalHorizontalRuleNode.js' +import { $isHorizontalRuleNode, HorizontalRuleNode } from '@lexical/extension' import * as Mdast from 'mdast' import { LexicalExportVisitor } from '../../exportMarkdownFromLexical' diff --git a/src/plugins/thematic-break/MdastThematicBreakVisitor.ts b/src/plugins/thematic-break/MdastThematicBreakVisitor.ts index b1a36d51..86fffbc9 100644 --- a/src/plugins/thematic-break/MdastThematicBreakVisitor.ts +++ b/src/plugins/thematic-break/MdastThematicBreakVisitor.ts @@ -1,3 +1,4 @@ +// eslint-disable-next-line @typescript-eslint/no-deprecated import { $createHorizontalRuleNode } from '@lexical/react/LexicalHorizontalRuleNode.js' import * as Mdast from 'mdast' import { MdastImportVisitor } from '../../importMarkdownToLexical' @@ -5,6 +6,7 @@ import { MdastImportVisitor } from '../../importMarkdownToLexical' export const MdastThematicBreakVisitor: MdastImportVisitor = { testNode: 'thematicBreak', visitNode({ actions }) { + // eslint-disable-next-line @typescript-eslint/no-deprecated actions.addAndStepInto($createHorizontalRuleNode()) } } diff --git a/src/plugins/thematic-break/index.ts b/src/plugins/thematic-break/index.ts index 038c1872..1adb7d2c 100644 --- a/src/plugins/thematic-break/index.ts +++ b/src/plugins/thematic-break/index.ts @@ -1,6 +1,9 @@ import { realmPlugin } from '../../RealmWithPlugins' -import { HorizontalRuleNode, INSERT_HORIZONTAL_RULE_COMMAND } from '@lexical/react/LexicalHorizontalRuleNode.js' -import { HorizontalRulePlugin } from '@lexical/react/LexicalHorizontalRulePlugin.js' +import { INSERT_HORIZONTAL_RULE_COMMAND } from '@lexical/extension' +// eslint-disable-next-line @typescript-eslint/no-deprecated +import { HorizontalRuleNode } from '@lexical/react/LexicalHorizontalRuleNode' +// eslint-disable-next-line @typescript-eslint/no-deprecated +import { HorizontalRulePlugin } from '@lexical/react/LexicalHorizontalRulePlugin' import { Action, withLatestFrom } from '@mdxeditor/gurx' import { activeEditor$, addActivePlugin$, addComposerChild$, addExportVisitor$, addImportVisitor$, addLexicalNode$ } from '../core' import { LexicalThematicBreakVisitor } from './LexicalThematicBreakVisitor' @@ -25,8 +28,10 @@ export const thematicBreakPlugin = realmPlugin({ realm.pubIn({ [addActivePlugin$]: 'thematicBreak', [addImportVisitor$]: MdastThematicBreakVisitor, + // eslint-disable-next-line @typescript-eslint/no-deprecated [addLexicalNode$]: HorizontalRuleNode, [addExportVisitor$]: LexicalThematicBreakVisitor, + // eslint-disable-next-line @typescript-eslint/no-deprecated [addComposerChild$]: HorizontalRulePlugin }) } diff --git a/src/plugins/thematic-break/transformer.ts b/src/plugins/thematic-break/transformer.ts new file mode 100644 index 00000000..43d88cde --- /dev/null +++ b/src/plugins/thematic-break/transformer.ts @@ -0,0 +1,32 @@ +import { type ElementTransformer } from '@lexical/markdown' +import { $isHorizontalRuleNode } from '@lexical/react/LexicalHorizontalRuleNode' +// eslint-disable-next-line @typescript-eslint/no-deprecated +import { $createHorizontalRuleNode, HorizontalRuleNode } from '@lexical/react/LexicalHorizontalRuleNode' +import { type LexicalNode } from 'lexical' + +/** + * Transformer for thematic break (horizontal rule) nodes. + * Exports HorizontalRuleNode as "***" (thematic break). + */ +export const THEMATIC_BREAK_TRANSFORMER: ElementTransformer = { + // eslint-disable-next-line @typescript-eslint/no-deprecated + dependencies: [HorizontalRuleNode], + export: (node: LexicalNode) => { + return $isHorizontalRuleNode(node) ? '***' : null + }, + regExp: /^(---|\*\*\*|___)\s?$/, + replace: (parentNode, _1, _2, isImport) => { + // eslint-disable-next-line @typescript-eslint/no-deprecated + const line = $createHorizontalRuleNode() + + // TODO: Get rid of isImport flag + if (isImport || parentNode.getNextSibling() != null) { + parentNode.replace(line) + } else { + parentNode.insertBefore(line) + } + + line.selectNext() + }, + type: 'element' +} diff --git a/src/utils/lexicalHelpers.ts b/src/utils/lexicalHelpers.ts index 7412f7cf..02212641 100644 --- a/src/utils/lexicalHelpers.ts +++ b/src/utils/lexicalHelpers.ts @@ -2,20 +2,17 @@ import { $getRoot, $getSelection, $isRangeSelection, - $isTextNode, - $isElementNode, - ElementNode, - LexicalEditor, - LexicalNode, - RangeSelection, - TextNode + type ElementNode, + type LexicalEditor, + type RangeSelection, + type TextNode } from 'lexical' -import { $isLinkNode } from '@lexical/link' -import { $isHeadingNode } from '@lexical/rich-text' -import { $isListNode, $isListItemNode } from '@lexical/list' +import { $convertSelectionToMarkdownString, type Transformer, TRANSFORMERS } from '@lexical/markdown' import { $isAtNodeEnd } from '@lexical/selection' import { tap } from './fp' -import { ExportMarkdownFromLexicalOptions, exportMarkdownFromLexical } from '../exportMarkdownFromLexical' +import { type ExportMarkdownFromLexicalOptions, exportMarkdownFromLexical } from '../exportMarkdownFromLexical' +import { TABLE_TRANSFORMER } from '../plugins/table/transformer' +import { THEMATIC_BREAK_TRANSFORMER } from '../plugins/thematic-break/transformer' /** * Fetches a value from the Lexical editor read cycle. @@ -162,118 +159,32 @@ export function getStateAsMarkdown(editor: LexicalEditor, exportParams: Omit): string { +export function getSelectionAsMarkdown(editor: LexicalEditor, activePlugins: string[]): string { let markdown = '' - editor.getEditorState().read(() => { - const selection = $getSelection() - - // Return empty if no selection or collapsed - if (!selection || !$isRangeSelection(selection) || selection.isCollapsed()) { - return - } - - // Get all nodes in the selection (entire nodes, not partial) - const nodes = selection.getNodes() - - if (nodes.length === 0) { - return - } - - // Get unique block-level parent nodes to preserve structure (headings, lists, paragraphs, etc.) - const parentNodes = new Set() - nodes.forEach((node) => { - let current: LexicalNode | null = node - - // Walk up to find the nearest block-level parent (heading, paragraph, list item, etc.) - while (current) { - // Check if current node is a block-level node - if ($isHeadingNode(current) || $isListItemNode(current) || current.getType() === 'paragraph' || current.getType() === 'quote') { - if ($isElementNode(current)) { - parentNodes.add(current) - } - break - } - - current = current.getParent() + editor.getEditorState().read( + () => { + const selection = $getSelection() + if (!selection || !$isRangeSelection(selection) || selection.isCollapsed()) { + return } - }) - - // If we have parent nodes, use those instead of leaf nodes - const nodesToProcess = parentNodes.size > 0 ? Array.from(parentNodes) : nodes - // Helper function to recursively convert a node to markdown - function nodeToMarkdown(node: LexicalNode): string { - if ($isHeadingNode(node)) { - // Handle heading nodes - const level = parseInt(node.getTag().replace('h', '')) - const children = node.getChildren() - const headingText = children.map((child) => nodeToMarkdown(child)).join('') - return '#'.repeat(level) + ' ' + headingText + '\n\n' - } else if ($isListItemNode(node)) { - // Handle list item nodes - const parent = node.getParent() - const prefix = parent && $isListNode(parent) && parent.getListType() === 'number' ? '1. ' : '- ' - const children = node.getChildren() - const itemText = children.map((child) => nodeToMarkdown(child)).join('') - return prefix + itemText + '\n' - } else if ($isListNode(node)) { - // Handle list nodes - const children = node.getChildren() - return children.map((child) => nodeToMarkdown(child)).join('') + '\n' - } else if ($isTextNode(node)) { - let text = node.getTextContent() - const format = node.getFormat() - - // Apply markdown formatting based on Lexical text format flags - // Bold: 1, Italic: 2, Strikethrough: 4, Underline: 8, Code: 16 - if (format & 16) { - // Code - return `\`${text}\`` - } - // Apply formatting in correct order (innermost to outermost) - if (format & 1) { - // Bold - text = `**${text}**` - } - if (format & 2) { - // Italic - text = `*${text}*` - } - if (format & 4) { - // Strikethrough - text = `~~${text}~~` - } - - return text - } else if ($isLinkNode(node)) { - // Handle link nodes - const url = node.getURL() - const title = node.getTitle() - const children = node.getChildren() - const linkText = children.map((child) => nodeToMarkdown(child)).join('') - - if (title) { - return `[${linkText}](${url} "${title}")` - } - return `[${linkText}](${url})` - } else if ($isElementNode(node)) { - // For other element nodes, process their children - const children = node.getChildren() - return children.map((child) => nodeToMarkdown(child)).join('') + // Determine transformers to use + const transformers: Transformer[] = TRANSFORMERS + if (activePlugins.includes('table')) { + transformers.push(TABLE_TRANSFORMER) + } + if (activePlugins.includes('thematicBreak')) { + transformers.push(THEMATIC_BREAK_TRANSFORMER) } - // Fallback: return text content - return node.getTextContent() - } - - // Convert all selected nodes to markdown and concatenate - markdown = nodesToProcess.map((node) => nodeToMarkdown(node)).join('') - }) + markdown = $convertSelectionToMarkdownString(transformers, selection) + }, + { editor } + ) return markdown.trim() } diff --git a/tsconfig.json b/tsconfig.json index 6a73977b..78e92322 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -4,7 +4,7 @@ "lib": ["dom", "dom.iterable", "esnext"], "jsx": "react-jsx", "module": "esnext", - "moduleResolution": "node", + "moduleResolution": "bundler", "esModuleInterop": true, "forceConsistentCasingInFileNames": true, "strict": true,