From c0ec39a7df8bb093ec58b42426115baa504b0e60 Mon Sep 17 00:00:00 2001 From: Deep Chudasama Date: Mon, 16 Dec 2024 11:53:49 +0530 Subject: [PATCH 1/5] feat(editor): adds wysisyng editor --- package-lock.json | 870 +++++++++++++++++- package.json | 13 + .../checkbox-tree-view.stories.tsx | 61 ++ .../checkbox-tree-view/checkbox-tree-view.tsx | 233 +++++ .../color-picker-input.stories.tsx | 0 .../color-picker-input.tsx | 0 .../tiptap-wysiwyg-editor.stories.tsx | 17 + .../tiptap-wysiwyg-editor.tsx | 184 ++++ .../rich-text-editor.stories.tsx | 17 + .../wysiwyg-editor/rich-text-editor.tsx | 48 + src/index.ts | 11 +- 11 files changed, 1444 insertions(+), 10 deletions(-) create mode 100644 src/components/checkbox-tree-view/checkbox-tree-view.stories.tsx create mode 100644 src/components/checkbox-tree-view/checkbox-tree-view.tsx rename src/components/{color-picker => color-picker-input}/color-picker-input.stories.tsx (100%) rename src/components/{color-picker => color-picker-input}/color-picker-input.tsx (100%) create mode 100644 src/components/tiptap-wysiwyg-editor/tiptap-wysiwyg-editor.stories.tsx create mode 100644 src/components/tiptap-wysiwyg-editor/tiptap-wysiwyg-editor.tsx create mode 100644 src/components/wysiwyg-editor/rich-text-editor.stories.tsx create mode 100644 src/components/wysiwyg-editor/rich-text-editor.tsx diff --git a/package-lock.json b/package-lock.json index 0a850fe..1e315fb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "@broadlume/willow-ui", - "version": "0.0.5", + "version": "0.0.8", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@broadlume/willow-ui", - "version": "0.0.5", + "version": "0.0.8", "dependencies": { "@hookform/resolvers": "^3.3.4", "@radix-ui/react-accordion": "^1.1.2", @@ -28,6 +28,19 @@ "@radix-ui/react-toast": "^1.1.4", "@radix-ui/react-toggle": "^1.0.3", "@radix-ui/react-tooltip": "^1.0.6", + "@tiptap/extension-floating-menu": "^2.10.3", + "@tiptap/extension-highlight": "^2.10.3", + "@tiptap/extension-image": "^2.10.3", + "@tiptap/extension-link": "^2.10.3", + "@tiptap/extension-placeholder": "^2.10.3", + "@tiptap/extension-table": "^2.10.3", + "@tiptap/extension-table-cell": "^2.10.3", + "@tiptap/extension-table-header": "^2.10.3", + "@tiptap/extension-table-row": "^2.10.3", + "@tiptap/extension-text-align": "^2.10.3", + "@tiptap/pm": "^2.10.3", + "@tiptap/react": "^2.10.3", + "@tiptap/starter-kit": "^2.10.3", "carloslfu-cmdk-internal": "^0.3.1", "class-variance-authority": "^0.6.1", "clsx": "^1.2.1", @@ -3386,6 +3399,16 @@ "node": ">=14" } }, + "node_modules/@popperjs/core": { + "version": "2.11.8", + "resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz", + "integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/popperjs" + } + }, "node_modules/@radix-ui/number": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.0.1.tgz", @@ -4991,6 +5014,12 @@ "@babel/runtime": "^7.13.10" } }, + "node_modules/@remirror/core-constants": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@remirror/core-constants/-/core-constants-3.0.0.tgz", + "integrity": "sha512-42aWfPrimMfDKDi4YegyS7x+/0tlzaqwPQCULLanv3DMIlu96KTJR0fM5isWX2UViOqlGnX6YFgqWepcX+XMNg==", + "license": "MIT" + }, "node_modules/@rollup/pluginutils": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.0.2.tgz", @@ -6764,6 +6793,514 @@ "@testing-library/dom": ">=7.21.4" } }, + "node_modules/@tiptap/core": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@tiptap/core/-/core-2.10.3.tgz", + "integrity": "sha512-wAG/0/UsLeZLmshWb6rtWNXKJftcmnned91/HLccHVQAuQZ1UWH+wXeQKu/mtodxEO7JcU2mVPR9mLGQkK0McQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/pm": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-blockquote": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-blockquote/-/extension-blockquote-2.10.3.tgz", + "integrity": "sha512-u9Mq4r8KzoeGVT8ms6FQDIMN95dTh3TYcT7fZpwcVM96mIl2Oyt+Bk66mL8z4zuFptfRI57Cu9QdnHEeILd//w==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-bold": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-2.10.3.tgz", + "integrity": "sha512-xnF1tS2BsORenr11qyybW120gHaeHKiKq+ZOP14cGA0MsriKvWDnaCSocXP/xMEYHy7+2uUhJ0MsKkHVj4bPzQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-bubble-menu": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bubble-menu/-/extension-bubble-menu-2.10.3.tgz", + "integrity": "sha512-e9a4yMjQezuKy0rtyyzxbV2IAE1bm1PY3yoZEFrcaY0o47g1CMUn2Hwe+9As2HdntEjQpWR7NO1mZeKxHlBPYA==", + "license": "MIT", + "dependencies": { + "tippy.js": "^6.3.7" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0", + "@tiptap/pm": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-bullet-list": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bullet-list/-/extension-bullet-list-2.10.3.tgz", + "integrity": "sha512-PTkwJOVlHi4RR4Wrs044tKMceweXwNmWA6EoQ93hPUVtQcwQL990Es5Izp+i88twTPLuGD9dH+o9QDyH9SkWdA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-code": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-2.10.3.tgz", + "integrity": "sha512-JyLbfyY3cPctq9sVdpcRWTcoUOoq3/MnGE1eP6eBNyMTHyBPcM9TPhOkgj+xkD1zW/884jfelB+wa70RT/AMxQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-code-block": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-code-block/-/extension-code-block-2.10.3.tgz", + "integrity": "sha512-yiDVNg22fYkzsFk5kBlDSHcjwVJgajvO/M5fDXA+Hfxwo2oNcG6aJyyHXFe+UaXTVjdkPej0J6kcMKrTMCiFug==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0", + "@tiptap/pm": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-document": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-document/-/extension-document-2.10.3.tgz", + "integrity": "sha512-6i8+xbS2zB6t8iFzli1O/QB01MmwyI5Hqiiv4m5lOxqavmJwLss2sRhoMC2hB3CyFg5UmeODy/f/RnI6q5Vixg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-dropcursor": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-dropcursor/-/extension-dropcursor-2.10.3.tgz", + "integrity": "sha512-wzWf82ixWzZQr0hxcf/A0ul8NNxgy1N63O+c56st6OomoLuKUJWOXF+cs9O7V+/5rZKWdbdYYoRB5QLvnDBAlQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0", + "@tiptap/pm": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-floating-menu": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-floating-menu/-/extension-floating-menu-2.10.3.tgz", + "integrity": "sha512-Prg8rYLxeyzHxfzVu1mDkkUWMnD9ZN3y370O/1qy55e+XKVw9jFkTSuz0y0+OhMJG6bulYpDUMtb+N3+2xOWlQ==", + "license": "MIT", + "dependencies": { + "tippy.js": "^6.3.7" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0", + "@tiptap/pm": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-gapcursor": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-gapcursor/-/extension-gapcursor-2.10.3.tgz", + "integrity": "sha512-FskZi2DqDSTH1WkgLF2OLy0xU7qj3AgHsKhVsryeAtld4jAK5EsonneWgaipbz0e/MxuIvc1oyacfZKABpLaNg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0", + "@tiptap/pm": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-hard-break": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-hard-break/-/extension-hard-break-2.10.3.tgz", + "integrity": "sha512-2rFlimUKAgKDwT6nqAMtPBjkrknQY8S7oBNyIcDOUGyFkvbDUl3Jd0PiC929S5F3XStJRppnMqhpNDAlWmvBLA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-heading": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-heading/-/extension-heading-2.10.3.tgz", + "integrity": "sha512-AlxXXPCWIvw8hQUDFRskasj32iMNB8Sb19VgyFWqwvntGs2/UffNu8VdsVqxD2HpZ0g5rLYCYtSW4wigs9R3og==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-highlight": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-highlight/-/extension-highlight-2.10.3.tgz", + "integrity": "sha512-srMOdpUTcp1yPGmUqgKOkbmTpCYOF6Q/8CnquDkhrvK7Gyphj+n8TocrKiloaRYZKcoQWtmb+kcVPaHhHMzsWQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-history": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-history/-/extension-history-2.10.3.tgz", + "integrity": "sha512-HaSiMdx9Im9Pb9qGlVud7W8bweRDRMez33Uzs5a2x0n1RWkelfH7TwYs41Y3wus8Ujs7kw6qh7jyhvPpQBKaSA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0", + "@tiptap/pm": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-horizontal-rule": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-2.10.3.tgz", + "integrity": "sha512-1a2IWhD00tgUNg/91RLnBvfENL7DLCui5L245+smcaLu+OXOOEpoBHawx59/M4hEpsjqvRRM79TzO9YXfopsPw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0", + "@tiptap/pm": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-image": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-image/-/extension-image-2.10.3.tgz", + "integrity": "sha512-YIjAF5CwDkMe28OQ5pvnmdRgbJ9JcGMIHY1kyqNunSf2iwphK+6SWz9UEIkDFiT7AsRZySqxFSq93iK1XyTifw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-italic": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-2.10.3.tgz", + "integrity": "sha512-wAiO6ZxoHx2H90phnKttLWGPjPZXrfKxhOCsqYrK8BpRByhr48godOFRuGwYnKaiwoVjpxc63t+kDJDWvqmgMw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-link": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-link/-/extension-link-2.10.3.tgz", + "integrity": "sha512-8esKlkZBzEiNcpt7I8Cd6l1mWmCc/66pPbUq9LfnIniDXE3U+ahBf4m3TJltYFBGbiiTR/xqMtJyVHOpuLDtAw==", + "license": "MIT", + "dependencies": { + "linkifyjs": "^4.1.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0", + "@tiptap/pm": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-list-item": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-list-item/-/extension-list-item-2.10.3.tgz", + "integrity": "sha512-9sok81gvZfSta2K1Dwrq5/HSz1jk4zHBpFqCx0oydzodGslx6X1bNxdca+eXJpXZmQIWALK7zEr4X8kg3WZsgw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-ordered-list": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-ordered-list/-/extension-ordered-list-2.10.3.tgz", + "integrity": "sha512-/SFuEDnbJxy3jvi72LeyiPHWkV+uFc0LUHTUHSh20vwyy+tLrzncJfXohGbTIv5YxYhzExQYZDRD4VbSghKdlw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-paragraph": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-2.10.3.tgz", + "integrity": "sha512-sNkTX/iN+YoleDiTJsrWSBw9D7c4vsYwnW5y/G5ydfuJMIRQMF78pWSIWZFDRNOMkgK5UHkhu9anrbCFYgBfaA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-placeholder": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-placeholder/-/extension-placeholder-2.10.3.tgz", + "integrity": "sha512-0OkwnDLguZgoiJM85cfnOySuMmPUF7qqw7DHQ+c3zwTAYnvzpvqrvpupc+2Zi9GfC1sDgr+Ajrp8imBHa6PHfA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0", + "@tiptap/pm": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-strike": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-2.10.3.tgz", + "integrity": "sha512-jYoPy6F6njYp3txF3u23bgdRy/S5ATcWDO9LPZLHSeikwQfJ47nqb+EUNo5M8jIOgFBTn4MEbhuZ6OGyhnxopA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-table": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-table/-/extension-table-2.10.3.tgz", + "integrity": "sha512-XAvq0ptpHfuN7lQhTeew4Sqo8aKYHTqroa7cHL8I+gWJqYqKJSTGb4FAqdGIFEzHvnSsMCFbTL//kAHXvTdsHg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0", + "@tiptap/pm": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-table-cell": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-table-cell/-/extension-table-cell-2.10.3.tgz", + "integrity": "sha512-EYzBrnq7KUAcRhshIoTmC4ED8YoF4Ei5m8ZMPOctKX+QMAagKdcrw2UxuOf4tP2xgBYx+qDsKCautepZXQiL2g==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-table-header": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-table-header/-/extension-table-header-2.10.3.tgz", + "integrity": "sha512-zJqzivz+VITYIFXNH09leBbkwAPuvp504rCAFL2PMa1uaME6+oiiRqZvXQrOiRkjNpOWEXH4dqvVLwkSMZoWaw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-table-row": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-table-row/-/extension-table-row-2.10.3.tgz", + "integrity": "sha512-l6P6BAE4SuIFdPmsRd+zGP2Ks9AhLAua7nfDlHFMWDnfOeaJu7g/t4oG++9xTojDcVDHhcIe8TJYUXfhOt2anw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-text": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-2.10.3.tgz", + "integrity": "sha512-7p9XiRprsRZm8y9jvF/sS929FCELJ5N9FQnbzikOiyGNUx5mdI+exVZlfvBr9xOD5s7fBLg6jj9Vs0fXPNRkPg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-text-align": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-text-align/-/extension-text-align-2.10.3.tgz", + "integrity": "sha512-g75sNl73gtgjP3XIcl06kvv1qw3c0rGEUD848rUU1bvlBpU3IxjkcQLgYvHmv3vpuUp9cKUkA2wa7Sv6R3fjvw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-text-style": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@tiptap/extension-text-style/-/extension-text-style-2.10.3.tgz", + "integrity": "sha512-TalYIdlF7vBA4afFhmido7AORdBbu3sV+HCByda0FiNbM6cjng3Nr9oxHOCVJy+ChqrcgF4m54zDfLmamdyu5Q==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/pm": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-2.10.3.tgz", + "integrity": "sha512-771p53aU0KFvujvKpngvq2uAxThlEsjYaXcVVmwrhf0vxSSg+psKQEvqvWvHv/3BwkPVCGwmEKNVJZjaXFKu4g==", + "license": "MIT", + "dependencies": { + "prosemirror-changeset": "^2.2.1", + "prosemirror-collab": "^1.3.1", + "prosemirror-commands": "^1.6.2", + "prosemirror-dropcursor": "^1.8.1", + "prosemirror-gapcursor": "^1.3.2", + "prosemirror-history": "^1.4.1", + "prosemirror-inputrules": "^1.4.0", + "prosemirror-keymap": "^1.2.2", + "prosemirror-markdown": "^1.13.1", + "prosemirror-menu": "^1.2.4", + "prosemirror-model": "^1.23.0", + "prosemirror-schema-basic": "^1.2.3", + "prosemirror-schema-list": "^1.4.1", + "prosemirror-state": "^1.4.3", + "prosemirror-tables": "^1.6.1", + "prosemirror-trailing-node": "^3.0.0", + "prosemirror-transform": "^1.10.2", + "prosemirror-view": "^1.37.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + } + }, + "node_modules/@tiptap/react": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@tiptap/react/-/react-2.10.3.tgz", + "integrity": "sha512-5GBL3arWai8WZuCl1MMA7bT5aWwqDi5AOQhX+hovKjwHvttpKDogRoUBL5k6Eds/eQMBMGTpsfmZlGNiFxSv1g==", + "license": "MIT", + "dependencies": { + "@tiptap/extension-bubble-menu": "^2.10.3", + "@tiptap/extension-floating-menu": "^2.10.3", + "@types/use-sync-external-store": "^0.0.6", + "fast-deep-equal": "^3", + "use-sync-external-store": "^1" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0", + "@tiptap/pm": "^2.7.0", + "react": "^17.0.0 || ^18.0.0 || ^19.0.0", + "react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0" + } + }, + "node_modules/@tiptap/starter-kit": { + "version": "2.10.3", + "resolved": "https://registry.npmjs.org/@tiptap/starter-kit/-/starter-kit-2.10.3.tgz", + "integrity": "sha512-oq8xdVIMqohSs91ofHSr7i5dCp2F56Lb9aYIAI25lZmwNwQJL2geGOYjMSfL0IC4cQHPylIuSKYCg7vRFdZmAA==", + "license": "MIT", + "dependencies": { + "@tiptap/core": "^2.10.3", + "@tiptap/extension-blockquote": "^2.10.3", + "@tiptap/extension-bold": "^2.10.3", + "@tiptap/extension-bullet-list": "^2.10.3", + "@tiptap/extension-code": "^2.10.3", + "@tiptap/extension-code-block": "^2.10.3", + "@tiptap/extension-document": "^2.10.3", + "@tiptap/extension-dropcursor": "^2.10.3", + "@tiptap/extension-gapcursor": "^2.10.3", + "@tiptap/extension-hard-break": "^2.10.3", + "@tiptap/extension-heading": "^2.10.3", + "@tiptap/extension-history": "^2.10.3", + "@tiptap/extension-horizontal-rule": "^2.10.3", + "@tiptap/extension-italic": "^2.10.3", + "@tiptap/extension-list-item": "^2.10.3", + "@tiptap/extension-ordered-list": "^2.10.3", + "@tiptap/extension-paragraph": "^2.10.3", + "@tiptap/extension-strike": "^2.10.3", + "@tiptap/extension-text": "^2.10.3", + "@tiptap/extension-text-style": "^2.10.3", + "@tiptap/pm": "^2.10.3" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + } + }, "node_modules/@ts-morph/common": { "version": "0.19.0", "resolved": "https://registry.npmjs.org/@ts-morph/common/-/common-0.19.0.tgz", @@ -7102,12 +7639,28 @@ "integrity": "sha512-Hr5Jfhc9eYOQNPYO5WLDq/n4jqijdHNlDXjuAQkkt+mWdQR+XJToOHrsD4cPaMXpn6KO7y2+wM8AZEs8VpBLVA==", "dev": true }, + "node_modules/@types/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==", + "license": "MIT" + }, "node_modules/@types/lodash": { "version": "4.14.202", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.202.tgz", "integrity": "sha512-OvlIYQK9tNneDlS0VN54LLd5uiPCBOp7gS5Z0f1mjoJYBrtStzgmJBxONW3U6OZqdtNzZPmn9BS/7WI7BFFcFQ==", "dev": true }, + "node_modules/@types/markdown-it": { + "version": "14.1.2", + "resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz", + "integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==", + "license": "MIT", + "dependencies": { + "@types/linkify-it": "^5", + "@types/mdurl": "^2" + } + }, "node_modules/@types/mdast": { "version": "3.0.15", "resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-3.0.15.tgz", @@ -7117,6 +7670,12 @@ "@types/unist": "^2" } }, + "node_modules/@types/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==", + "license": "MIT" + }, "node_modules/@types/mdx": { "version": "2.0.10", "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.10.tgz", @@ -7269,6 +7828,12 @@ "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==", "dev": true }, + "node_modules/@types/use-sync-external-store": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz", + "integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==", + "license": "MIT" + }, "node_modules/@types/uuid": { "version": "9.0.7", "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.7.tgz", @@ -9535,6 +10100,12 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/crelt": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz", + "integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==", + "license": "MIT" + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -10295,7 +10866,6 @@ "version": "4.5.0", "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", - "dev": true, "engines": { "node": ">=0.12" }, @@ -10438,7 +11008,6 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", - "dev": true, "engines": { "node": ">=10" }, @@ -10918,8 +11487,7 @@ "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "node_modules/fast-equals": { "version": "5.0.1", @@ -12992,6 +13560,21 @@ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==" }, + "node_modules/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", + "license": "MIT", + "dependencies": { + "uc.micro": "^2.0.0" + } + }, + "node_modules/linkifyjs": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/linkifyjs/-/linkifyjs-4.2.0.tgz", + "integrity": "sha512-pCj3PrQyATaoTYKHrgWRF3SJwsm61udVh+vuls/Rl6SptiDhgE7ziUIudAedRY9QEfynmM7/RmLEfPUyw1HPCw==", + "license": "MIT" + }, "node_modules/loader-runner": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", @@ -13183,6 +13766,29 @@ "integrity": "sha512-0aF7ZmVon1igznGI4VS30yugpduQW3y3GkcgGJOp7d8x8QrizhigUxjI/m2UojsXXto+jLAH3KSz+xOJTiORjg==", "dev": true }, + "node_modules/markdown-it": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", + "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1", + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" + }, + "bin": { + "markdown-it": "bin/markdown-it.mjs" + } + }, + "node_modules/markdown-it/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "license": "Python-2.0" + }, "node_modules/markdown-table": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.3.tgz", @@ -13532,6 +14138,12 @@ "integrity": "sha512-GaqWWShW4kv/G9IEucWScBx9G1/vsFZZJUO+tD26M8J8z3Kw5RDQjaoZe03YAClgeS/SWPOcb4nkFBTEi5DUEA==", "dev": true }, + "node_modules/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", + "license": "MIT" + }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -14958,6 +15570,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/orderedmap": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/orderedmap/-/orderedmap-2.1.1.tgz", + "integrity": "sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==", + "license": "MIT" + }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -15696,6 +16314,201 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, + "node_modules/prosemirror-changeset": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/prosemirror-changeset/-/prosemirror-changeset-2.2.1.tgz", + "integrity": "sha512-J7msc6wbxB4ekDFj+n9gTW/jav/p53kdlivvuppHsrZXCaQdVgRghoZbSS3kwrRyAstRVQ4/+u5k7YfLgkkQvQ==", + "license": "MIT", + "dependencies": { + "prosemirror-transform": "^1.0.0" + } + }, + "node_modules/prosemirror-collab": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/prosemirror-collab/-/prosemirror-collab-1.3.1.tgz", + "integrity": "sha512-4SnynYR9TTYaQVXd/ieUvsVV4PDMBzrq2xPUWutHivDuOshZXqQ5rGbZM84HEaXKbLdItse7weMGOUdDVcLKEQ==", + "license": "MIT", + "dependencies": { + "prosemirror-state": "^1.0.0" + } + }, + "node_modules/prosemirror-commands": { + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.6.2.tgz", + "integrity": "sha512-0nDHH++qcf/BuPLYvmqZTUUsPJUCPBUXt0J1ErTcDIS369CTp773itzLGIgIXG4LJXOlwYCr44+Mh4ii6MP1QA==", + "license": "MIT", + "dependencies": { + "prosemirror-model": "^1.0.0", + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.10.2" + } + }, + "node_modules/prosemirror-dropcursor": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/prosemirror-dropcursor/-/prosemirror-dropcursor-1.8.1.tgz", + "integrity": "sha512-M30WJdJZLyXHi3N8vxN6Zh5O8ZBbQCz0gURTfPmTIBNQ5pxrdU7A58QkNqfa98YEjSAL1HUyyU34f6Pm5xBSGw==", + "license": "MIT", + "dependencies": { + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.1.0", + "prosemirror-view": "^1.1.0" + } + }, + "node_modules/prosemirror-gapcursor": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/prosemirror-gapcursor/-/prosemirror-gapcursor-1.3.2.tgz", + "integrity": "sha512-wtjswVBd2vaQRrnYZaBCbyDqr232Ed4p2QPtRIUK5FuqHYKGWkEwl08oQM4Tw7DOR0FsasARV5uJFvMZWxdNxQ==", + "license": "MIT", + "dependencies": { + "prosemirror-keymap": "^1.0.0", + "prosemirror-model": "^1.0.0", + "prosemirror-state": "^1.0.0", + "prosemirror-view": "^1.0.0" + } + }, + "node_modules/prosemirror-history": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/prosemirror-history/-/prosemirror-history-1.4.1.tgz", + "integrity": "sha512-2JZD8z2JviJrboD9cPuX/Sv/1ChFng+xh2tChQ2X4bB2HeK+rra/bmJ3xGntCcjhOqIzSDG6Id7e8RJ9QPXLEQ==", + "license": "MIT", + "dependencies": { + "prosemirror-state": "^1.2.2", + "prosemirror-transform": "^1.0.0", + "prosemirror-view": "^1.31.0", + "rope-sequence": "^1.3.0" + } + }, + "node_modules/prosemirror-inputrules": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/prosemirror-inputrules/-/prosemirror-inputrules-1.4.0.tgz", + "integrity": "sha512-6ygpPRuTJ2lcOXs9JkefieMst63wVJBgHZGl5QOytN7oSZs3Co/BYbc3Yx9zm9H37Bxw8kVzCnDsihsVsL4yEg==", + "license": "MIT", + "dependencies": { + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.0.0" + } + }, + "node_modules/prosemirror-keymap": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/prosemirror-keymap/-/prosemirror-keymap-1.2.2.tgz", + "integrity": "sha512-EAlXoksqC6Vbocqc0GtzCruZEzYgrn+iiGnNjsJsH4mrnIGex4qbLdWWNza3AW5W36ZRrlBID0eM6bdKH4OStQ==", + "license": "MIT", + "dependencies": { + "prosemirror-state": "^1.0.0", + "w3c-keyname": "^2.2.0" + } + }, + "node_modules/prosemirror-markdown": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/prosemirror-markdown/-/prosemirror-markdown-1.13.1.tgz", + "integrity": "sha512-Sl+oMfMtAjWtlcZoj/5L/Q39MpEnVZ840Xo330WJWUvgyhNmLBLN7MsHn07s53nG/KImevWHSE6fEj4q/GihHw==", + "license": "MIT", + "dependencies": { + "@types/markdown-it": "^14.0.0", + "markdown-it": "^14.0.0", + "prosemirror-model": "^1.20.0" + } + }, + "node_modules/prosemirror-menu": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/prosemirror-menu/-/prosemirror-menu-1.2.4.tgz", + "integrity": "sha512-S/bXlc0ODQup6aiBbWVsX/eM+xJgCTAfMq/nLqaO5ID/am4wS0tTCIkzwytmao7ypEtjj39i7YbJjAgO20mIqA==", + "license": "MIT", + "dependencies": { + "crelt": "^1.0.0", + "prosemirror-commands": "^1.0.0", + "prosemirror-history": "^1.0.0", + "prosemirror-state": "^1.0.0" + } + }, + "node_modules/prosemirror-model": { + "version": "1.24.0", + "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.24.0.tgz", + "integrity": "sha512-Ft7epNnycoQSM+2ObF35SBbBX+5WY39v8amVlrtlAcpglhlHs2tCTnWl7RX5tbp/PsMKcRcWV9cXPuoBWq0AIQ==", + "license": "MIT", + "dependencies": { + "orderedmap": "^2.0.0" + } + }, + "node_modules/prosemirror-schema-basic": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/prosemirror-schema-basic/-/prosemirror-schema-basic-1.2.3.tgz", + "integrity": "sha512-h+H0OQwZVqMon1PNn0AG9cTfx513zgIG2DY00eJ00Yvgb3UD+GQ/VlWW5rcaxacpCGT1Yx8nuhwXk4+QbXUfJA==", + "license": "MIT", + "dependencies": { + "prosemirror-model": "^1.19.0" + } + }, + "node_modules/prosemirror-schema-list": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/prosemirror-schema-list/-/prosemirror-schema-list-1.4.1.tgz", + "integrity": "sha512-jbDyaP/6AFfDfu70VzySsD75Om2t3sXTOdl5+31Wlxlg62td1haUpty/ybajSfJ1pkGadlOfwQq9kgW5IMo1Rg==", + "license": "MIT", + "dependencies": { + "prosemirror-model": "^1.0.0", + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.7.3" + } + }, + "node_modules/prosemirror-state": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.4.3.tgz", + "integrity": "sha512-goFKORVbvPuAQaXhpbemJFRKJ2aixr+AZMGiquiqKxaucC6hlpHNZHWgz5R7dS4roHiwq9vDctE//CZ++o0W1Q==", + "license": "MIT", + "dependencies": { + "prosemirror-model": "^1.0.0", + "prosemirror-transform": "^1.0.0", + "prosemirror-view": "^1.27.0" + } + }, + "node_modules/prosemirror-tables": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/prosemirror-tables/-/prosemirror-tables-1.6.1.tgz", + "integrity": "sha512-p8WRJNA96jaNQjhJolmbxTzd6M4huRE5xQ8OxjvMhQUP0Nzpo4zz6TztEiwk6aoqGBhz9lxRWR1yRZLlpQN98w==", + "license": "MIT", + "dependencies": { + "prosemirror-keymap": "^1.1.2", + "prosemirror-model": "^1.8.1", + "prosemirror-state": "^1.3.1", + "prosemirror-transform": "^1.2.1", + "prosemirror-view": "^1.13.3" + } + }, + "node_modules/prosemirror-trailing-node": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/prosemirror-trailing-node/-/prosemirror-trailing-node-3.0.0.tgz", + "integrity": "sha512-xiun5/3q0w5eRnGYfNlW1uU9W6x5MoFKWwq/0TIRgt09lv7Hcser2QYV8t4muXbEr+Fwo0geYn79Xs4GKywrRQ==", + "license": "MIT", + "dependencies": { + "@remirror/core-constants": "3.0.0", + "escape-string-regexp": "^4.0.0" + }, + "peerDependencies": { + "prosemirror-model": "^1.22.1", + "prosemirror-state": "^1.4.2", + "prosemirror-view": "^1.33.8" + } + }, + "node_modules/prosemirror-transform": { + "version": "1.10.2", + "resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.10.2.tgz", + "integrity": "sha512-2iUq0wv2iRoJO/zj5mv8uDUriOHWzXRnOTVgCzSXnktS/2iQRa3UUQwVlkBlYZFtygw6Nh1+X4mGqoYBINn5KQ==", + "license": "MIT", + "dependencies": { + "prosemirror-model": "^1.21.0" + } + }, + "node_modules/prosemirror-view": { + "version": "1.37.0", + "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.37.0.tgz", + "integrity": "sha512-z2nkKI1sJzyi7T47Ji/ewBPuIma1RNvQCCYVdV+MqWBV7o4Sa1n94UJCJJ1aQRF/xRkFfyqLGlGFWitIcCOtbg==", + "license": "MIT", + "dependencies": { + "prosemirror-model": "^1.20.0", + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.1.0" + } + }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -15763,6 +16576,15 @@ "node": ">=6" } }, + "node_modules/punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/puppeteer-core": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-2.1.1.tgz", @@ -16727,6 +17549,12 @@ "fsevents": "~2.3.2" } }, + "node_modules/rope-sequence": { + "version": "1.3.4", + "resolved": "https://registry.npmjs.org/rope-sequence/-/rope-sequence-1.3.4.tgz", + "integrity": "sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==", + "license": "MIT" + }, "node_modules/run-parallel": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz", @@ -18179,6 +19007,15 @@ "integrity": "sha512-AD5ih2NlSssTCwsMznbvwMZpJ1cbhkGd2uueNxzv2jDlEeZdU04JQfRnggJQ8DrcVBGjAsCKwFBbDlVNtEMlzw==", "dev": true }, + "node_modules/tippy.js": { + "version": "6.3.7", + "resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-6.3.7.tgz", + "integrity": "sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==", + "license": "MIT", + "dependencies": { + "@popperjs/core": "^2.9.0" + } + }, "node_modules/tmpl": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", @@ -18383,6 +19220,12 @@ "node": ">=14.17" } }, + "node_modules/uc.micro": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", + "license": "MIT" + }, "node_modules/ufo": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.3.2.tgz", @@ -18687,6 +19530,15 @@ } } }, + "node_modules/use-sync-external-store": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz", + "integrity": "sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/util": { "version": "0.12.5", "resolved": "https://registry.npmjs.org/util/-/util-0.12.5.tgz", @@ -18971,6 +19823,12 @@ } } }, + "node_modules/w3c-keyname": { + "version": "2.2.8", + "resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz", + "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==", + "license": "MIT" + }, "node_modules/walker": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", diff --git a/package.json b/package.json index 0b46718..1568ddd 100644 --- a/package.json +++ b/package.json @@ -114,6 +114,19 @@ "@radix-ui/react-toast": "^1.1.4", "@radix-ui/react-toggle": "^1.0.3", "@radix-ui/react-tooltip": "^1.0.6", + "@tiptap/extension-floating-menu": "^2.10.3", + "@tiptap/extension-highlight": "^2.10.3", + "@tiptap/extension-image": "^2.10.3", + "@tiptap/extension-link": "^2.10.3", + "@tiptap/extension-placeholder": "^2.10.3", + "@tiptap/extension-table": "^2.10.3", + "@tiptap/extension-table-cell": "^2.10.3", + "@tiptap/extension-table-header": "^2.10.3", + "@tiptap/extension-table-row": "^2.10.3", + "@tiptap/extension-text-align": "^2.10.3", + "@tiptap/pm": "^2.10.3", + "@tiptap/react": "^2.10.3", + "@tiptap/starter-kit": "^2.10.3", "carloslfu-cmdk-internal": "^0.3.1", "class-variance-authority": "^0.6.1", "clsx": "^1.2.1", diff --git a/src/components/checkbox-tree-view/checkbox-tree-view.stories.tsx b/src/components/checkbox-tree-view/checkbox-tree-view.stories.tsx new file mode 100644 index 0000000..3a19342 --- /dev/null +++ b/src/components/checkbox-tree-view/checkbox-tree-view.stories.tsx @@ -0,0 +1,61 @@ +import { useState } from 'react'; +import { Meta, StoryObj } from '@storybook/react'; + +import { TreeView } from './checkbox-tree-view'; + +const meta: Meta = { + component: TreeView, + title: 'Components/Checkbox Tree View', +}; + +export default meta; +type Story = StoryObj; + +export const Demo: Story = { + render: (_) => { + const [treeData, setTreeData] = useState([ + { + id: '1', + name: 'Parent 1', + value: 'parent1', + children: [ + { id: '2', name: 'Child 1.1', value: 'child1.1' }, + { id: '3', name: 'Child 1.2', value: 'child1.2' }, + ], + }, + { + id: '4', + name: 'Parent 2', + value: 'parent2', + children: [ + { + id: '5', + name: 'Child 2.1', + value: 'child2.1', + children: [ + { id: '6', name: 'Grandchild 2.1.1', value: 'grandchild2.1.1' }, + ], + }, + ], + }, + ]); + const [selectedValues, setSelectedValues] = useState([]); + + const handleTreeChange = (selectedValues: string[]) => { + setSelectedValues(selectedValues); + console.log('Selected Values:', selectedValues); + }; + + return ( +
+ +
+          

Selected Values:

+ {selectedValues.map((val) => ( +

{val}

+ ))} +
+
+ ); + }, +}; diff --git a/src/components/checkbox-tree-view/checkbox-tree-view.tsx b/src/components/checkbox-tree-view/checkbox-tree-view.tsx new file mode 100644 index 0000000..3ccd121 --- /dev/null +++ b/src/components/checkbox-tree-view/checkbox-tree-view.tsx @@ -0,0 +1,233 @@ +import React, { useState, useEffect } from 'react'; +import { FaChevronDown, FaChevronRight } from 'react-icons/fa'; +import { Checkbox } from '@components/checkbox/checkbox'; +import { Label } from '@components/label/label'; +import { Button } from '@components/button'; + +type TreeNode = { + id: string; + name: string; + value: string; + children?: TreeNode[]; +}; + +type TreeViewProps = { + data: TreeNode[]; + onChange?: (selectedValues: string[]) => void; +}; + +type CheckedState = Record< + string, + { checked: boolean; indeterminate: boolean } +>; + +const TreeView: React.FC = ({ data, onChange }) => { + const [checkedState, setCheckedState] = useState({}); + const [expandedState, setExpandedState] = useState>( + {} + ); // Track expanded state + + const reset = () => { + const newState = Object.keys(checkedState).reduce((acc, key) => { + acc[key] = { checked: false, indeterminate: false }; + return acc; + }, {} as CheckedState); + setCheckedState(newState); + if (onChange) onChange([]); + }; + + useEffect(() => { + const initializeState = (nodes: TreeNode[]): CheckedState => { + const state: CheckedState = {}; + const traverse = (node: TreeNode) => { + state[node.id] = { checked: false, indeterminate: false }; + if (node.children) { + node.children.forEach(traverse); + } + }; + nodes.forEach(traverse); + return state; + }; + + const initializeExpandedState = ( + nodes: TreeNode[] + ): Record => { + const state: Record = {}; + const traverse = (node: TreeNode) => { + state[node.id] = true; // Default to expanded + if (node.children) { + node.children.forEach(traverse); + } + }; + nodes.forEach(traverse); + return state; + }; + + setCheckedState(initializeState(data)); + setExpandedState(initializeExpandedState(data)); + }, [data]); + + const handleCheckboxChange = (id: string) => { + const newState = { ...checkedState }; + + const updateChildren = (nodeId: string, checked: boolean) => { + newState[nodeId].checked = checked; + newState[nodeId].indeterminate = false; + const node = findNodeById(data, nodeId); + if (node?.children) { + node.children.forEach((child) => updateChildren(child.id, checked)); + } + }; + + const updateParents = (nodeId: string) => { + const parentNode = findParentById(data, nodeId, null); + if (parentNode) { + const allChecked = parentNode.children?.every( + (child) => newState[child.id].checked + ); + const anyChecked = parentNode.children?.some( + (child) => + newState[child.id].checked || newState[child.id].indeterminate + ); + + newState[parentNode.id].checked = !!allChecked; + newState[parentNode.id].indeterminate = !!(!allChecked && anyChecked); + updateParents(parentNode.id); + } + }; + + const currentNode = newState[id]; + const isChecked = !currentNode.checked; + updateChildren(id, isChecked); + updateParents(id); + + setCheckedState(newState); + + if (onChange) { + // const selectedValues = Object.keys(newState) + // .filter((key) => newState[key].checked) + // .map((key) => findNodeById(data, key)?.value) + // .filter(Boolean) as string[] + const selectedValues = getSelectedChildrenValues(data); + onChange(selectedValues); + } + }; + + const findNodeById = (nodes: TreeNode[], id: string): TreeNode | null => { + for (const node of nodes) { + if (node.id === id) return node; + if (node.children) { + const found = findNodeById(node.children, id); + if (found) return found; + } + } + return null; + }; + + const findParentById = ( + nodes: TreeNode[], + id: string, + parent: TreeNode | null + ): TreeNode | null => { + for (const node of nodes) { + if (node.id === id) return parent; + if (node.children) { + const found = findParentById(node.children, id, node); + if (found) return found; + } + } + return null; + }; + + const toggleExpand = (id: string) => { + setExpandedState((prevState) => ({ + ...prevState, + [id]: !prevState[id], + })); + }; + + const getSelectedChildrenValues = (nodes: TreeNode[]): string[] => { + let selectedValues: string[] = []; + + nodes.forEach((node) => { + // If the node has children, recursively process them + if (node.children && node.children.length > 0) { + selectedValues = selectedValues.concat( + getSelectedChildrenValues(node.children) + ); + } else if (checkedState[node.id]?.checked) { + // Only add leaf node values if they are checked + selectedValues.push(node.value); + } + }); + + return selectedValues; + }; + + const renderTree = (nodes: TreeNode[]) => ( +
    + {nodes.map((node) => ( +
  • +
    + {/* Space reserved for Chevron, even if the node doesn't have one */} + + {node.children && node.children.length > 0 && ( + toggleExpand(node.id)} + className='~cursor-pointer' + > + {expandedState[node.id] ? ( + + ) : ( + + )} + + )} + + {/* */} + + handleCheckboxChange(node.id)} + /> + + +
    + {/* Children are indented */} + {node.children && expandedState[node.id] && renderTree(node.children)} +
  • + ))} +
+ ); + + return ( +
+ {renderTree(data)} + +
+ ); +}; + +export { TreeView }; diff --git a/src/components/color-picker/color-picker-input.stories.tsx b/src/components/color-picker-input/color-picker-input.stories.tsx similarity index 100% rename from src/components/color-picker/color-picker-input.stories.tsx rename to src/components/color-picker-input/color-picker-input.stories.tsx diff --git a/src/components/color-picker/color-picker-input.tsx b/src/components/color-picker-input/color-picker-input.tsx similarity index 100% rename from src/components/color-picker/color-picker-input.tsx rename to src/components/color-picker-input/color-picker-input.tsx diff --git a/src/components/tiptap-wysiwyg-editor/tiptap-wysiwyg-editor.stories.tsx b/src/components/tiptap-wysiwyg-editor/tiptap-wysiwyg-editor.stories.tsx new file mode 100644 index 0000000..6d801b2 --- /dev/null +++ b/src/components/tiptap-wysiwyg-editor/tiptap-wysiwyg-editor.stories.tsx @@ -0,0 +1,17 @@ +import { Meta, StoryObj } from '@storybook/react'; + +import { TiptapEditor } from './tiptap-wysiwyg-editor'; + +const meta: Meta = { + component: TiptapEditor, + title: 'Components/TipTap Editor', +}; + +export default meta; +type Story = StoryObj; + +export const Demo: Story = { + render: (_) => { + return ; + }, +}; diff --git a/src/components/tiptap-wysiwyg-editor/tiptap-wysiwyg-editor.tsx b/src/components/tiptap-wysiwyg-editor/tiptap-wysiwyg-editor.tsx new file mode 100644 index 0000000..4c73838 --- /dev/null +++ b/src/components/tiptap-wysiwyg-editor/tiptap-wysiwyg-editor.tsx @@ -0,0 +1,184 @@ +import React, { useState } from 'react'; +import { EditorContent, useEditor, FloatingMenu } from '@tiptap/react'; +import StarterKit from '@tiptap/starter-kit'; +import Link from '@tiptap/extension-link'; +import Image from '@tiptap/extension-image'; +import Table from '@tiptap/extension-table'; +import TableRow from '@tiptap/extension-table-row'; +import TableCell from '@tiptap/extension-table-cell'; +import TableHeader from '@tiptap/extension-table-header'; +import TextAlign from '@tiptap/extension-text-align'; +import Highlight from '@tiptap/extension-highlight'; +import BulletList from '@tiptap/extension-bullet-list'; +import CodeBlock from '@tiptap/extension-code-block'; +import Placeholder from '@tiptap/extension-placeholder'; +// import { NodeViewContent, NodeViewWrapper } from '@tiptap/react'; +import { Button } from '@components/button'; + +const TiptapEditor: React.FC = () => { + const [content, setContent] = useState('

Type / to insert blocks...

'); + const [commandMenu, setCommandMenu] = useState(false); + + const editor = useEditor({ + extensions: [ + StarterKit, + Link.configure({ openOnClick: true }), + Image, + Table.configure({ resizable: true }), + TableRow, + TableCell, + TableHeader, + TextAlign.configure({ types: ['heading', 'paragraph'] }), + Highlight, + CodeBlock, + BulletList, + Placeholder.configure({ + placeholder: 'Start typing...', + }), + ], + content: content, + onUpdate: ({ editor }) => { + setContent(editor.getHTML()); + }, + editorProps: { + handleKeyDown: (view, event) => { + if (event.key === '/') { + setCommandMenu(true); + } + if (event.key === 'Escape') { + setCommandMenu(false); + } + }, + }, + }); + + if (!editor) return null; + + return ( +
+ {/* Toolbar */} +
+ + + + + + +
+ + + + + + + + + + {/* Editor */} + + + {/* Command Menu */} + {commandMenu && ( +
+ + + + + +
+ )} + + {/* Debugging Content */} +
+

Editor Content (HTML):

+
{content}
+
+
+ ); +}; + +export { TiptapEditor }; diff --git a/src/components/wysiwyg-editor/rich-text-editor.stories.tsx b/src/components/wysiwyg-editor/rich-text-editor.stories.tsx new file mode 100644 index 0000000..6c57a3c --- /dev/null +++ b/src/components/wysiwyg-editor/rich-text-editor.stories.tsx @@ -0,0 +1,17 @@ +import { Meta, StoryObj } from '@storybook/react'; + +import { RichTextEditor } from './rich-text-editor'; + +const meta: Meta = { + component: RichTextEditor, + title: 'Components/Rich Text Editor', +}; + +export default meta; +type Story = StoryObj; + +export const Demo: Story = { + render: (_) => { + return ; + }, +}; diff --git a/src/components/wysiwyg-editor/rich-text-editor.tsx b/src/components/wysiwyg-editor/rich-text-editor.tsx new file mode 100644 index 0000000..08d7484 --- /dev/null +++ b/src/components/wysiwyg-editor/rich-text-editor.tsx @@ -0,0 +1,48 @@ +import { cn } from '@src/lib/utils'; + +// Require Editor CSS files. +import 'froala-editor/css/froala_style.min.css'; +import 'froala-editor/css/froala_editor.pkgd.min.css'; + +// Import all Froala Editor plugins; +import 'froala-editor/js/plugins.pkgd.min.js'; + +// Import a single Froala Editor plugin. +import 'froala-editor/js/plugins/align.min.js'; + +// Import a language file. +import 'froala-editor/js/languages/de.js'; + +// Import a third-party plugin. +// import 'froala-editor/js/third_party/image_tui.min.js'; +// import 'froala-editor/js/third_party/embedly.min.js'; +// import 'froala-editor/js/third_party/spell_checker.min.js'; + +// Include font-awesome css if required. +// install using "npm install font-awesome --save" +// import 'font-awesome/css/font-awesome.css'; +// import 'froala-editor/js/third_party/font_awesome.min.js'; + +// Include special components if required. +// import FroalaEditorView from 'react-froala-wysiwyg/FroalaEditorView'; +// import FroalaEditorA from 'react-froala-wysiwyg/FroalaEditorA'; +// import FroalaEditorButton from 'react-froala-wysiwyg/FroalaEditorButton'; +// import FroalaEditorImg from 'react-froala-wysiwyg/FroalaEditorImg'; +// import FroalaEditorInput from 'react-froala-wysiwyg/FroalaEditorInput'; + +import FroalaEditor from 'react-froala-wysiwyg'; + +const RichTextEditor = () => { + return ( +
+ +
+ ); +}; + +export { RichTextEditor }; diff --git a/src/index.ts b/src/index.ts index eba9aae..8b2cdba 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,8 +1,7 @@ import './assets/typekit.css'; import './index.scss'; -export * from '@src/lib/icons'; - +// Components export * from '@components/accordion/accordion'; export * from '@components/alert-dialog/alert-dialog'; export * from '@components/avatar/avatar'; @@ -34,7 +33,11 @@ export * from '@components/toast'; export * from '@components/toggle/toggle'; export * from '@components/tooltip/tooltip'; export * from '@components/truncated-text/truncated-text'; -export * from '@src/reports/summary-tile/summary-tile'; +export * from '@components/breadcrumb/breadcrumb'; +export * from '@components/color-picker-input/color-picker-input'; +export * from '@components/drag-n-drop-file-input/drag-n-drop-file-input'; +// Other stuff +export * from '@src/lib/icons'; +export * from '@src/reports/summary-tile/summary-tile'; export * from '@src/misc/custom-data-table/custom-data-table'; -export * from '@components/breadcrumb/breadcrumb'; From 793a372a2ea281b8ed423286b2653187de89c3a1 Mon Sep 17 00:00:00 2001 From: Deep Chudasama Date: Wed, 18 Dec 2024 00:12:27 +0530 Subject: [PATCH 2/5] chore(names): updated names of components and exported from index.ts --- .../tiptap-wysiwyg-editor.stories.tsx | 17 ------- .../rich-text-editor.stories.tsx | 17 ------- .../wysiwyg-editor/rich-text-editor.tsx | 48 ------------------- .../wysiwyg-editor/wysiwyg-editor.stories.tsx | 17 +++++++ .../wysiwyg-editor.tsx} | 4 +- src/index.ts | 2 + 6 files changed, 21 insertions(+), 84 deletions(-) delete mode 100644 src/components/tiptap-wysiwyg-editor/tiptap-wysiwyg-editor.stories.tsx delete mode 100644 src/components/wysiwyg-editor/rich-text-editor.stories.tsx delete mode 100644 src/components/wysiwyg-editor/rich-text-editor.tsx create mode 100644 src/components/wysiwyg-editor/wysiwyg-editor.stories.tsx rename src/components/{tiptap-wysiwyg-editor/tiptap-wysiwyg-editor.tsx => wysiwyg-editor/wysiwyg-editor.tsx} (98%) diff --git a/src/components/tiptap-wysiwyg-editor/tiptap-wysiwyg-editor.stories.tsx b/src/components/tiptap-wysiwyg-editor/tiptap-wysiwyg-editor.stories.tsx deleted file mode 100644 index 6d801b2..0000000 --- a/src/components/tiptap-wysiwyg-editor/tiptap-wysiwyg-editor.stories.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { Meta, StoryObj } from '@storybook/react'; - -import { TiptapEditor } from './tiptap-wysiwyg-editor'; - -const meta: Meta = { - component: TiptapEditor, - title: 'Components/TipTap Editor', -}; - -export default meta; -type Story = StoryObj; - -export const Demo: Story = { - render: (_) => { - return ; - }, -}; diff --git a/src/components/wysiwyg-editor/rich-text-editor.stories.tsx b/src/components/wysiwyg-editor/rich-text-editor.stories.tsx deleted file mode 100644 index 6c57a3c..0000000 --- a/src/components/wysiwyg-editor/rich-text-editor.stories.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { Meta, StoryObj } from '@storybook/react'; - -import { RichTextEditor } from './rich-text-editor'; - -const meta: Meta = { - component: RichTextEditor, - title: 'Components/Rich Text Editor', -}; - -export default meta; -type Story = StoryObj; - -export const Demo: Story = { - render: (_) => { - return ; - }, -}; diff --git a/src/components/wysiwyg-editor/rich-text-editor.tsx b/src/components/wysiwyg-editor/rich-text-editor.tsx deleted file mode 100644 index 08d7484..0000000 --- a/src/components/wysiwyg-editor/rich-text-editor.tsx +++ /dev/null @@ -1,48 +0,0 @@ -import { cn } from '@src/lib/utils'; - -// Require Editor CSS files. -import 'froala-editor/css/froala_style.min.css'; -import 'froala-editor/css/froala_editor.pkgd.min.css'; - -// Import all Froala Editor plugins; -import 'froala-editor/js/plugins.pkgd.min.js'; - -// Import a single Froala Editor plugin. -import 'froala-editor/js/plugins/align.min.js'; - -// Import a language file. -import 'froala-editor/js/languages/de.js'; - -// Import a third-party plugin. -// import 'froala-editor/js/third_party/image_tui.min.js'; -// import 'froala-editor/js/third_party/embedly.min.js'; -// import 'froala-editor/js/third_party/spell_checker.min.js'; - -// Include font-awesome css if required. -// install using "npm install font-awesome --save" -// import 'font-awesome/css/font-awesome.css'; -// import 'froala-editor/js/third_party/font_awesome.min.js'; - -// Include special components if required. -// import FroalaEditorView from 'react-froala-wysiwyg/FroalaEditorView'; -// import FroalaEditorA from 'react-froala-wysiwyg/FroalaEditorA'; -// import FroalaEditorButton from 'react-froala-wysiwyg/FroalaEditorButton'; -// import FroalaEditorImg from 'react-froala-wysiwyg/FroalaEditorImg'; -// import FroalaEditorInput from 'react-froala-wysiwyg/FroalaEditorInput'; - -import FroalaEditor from 'react-froala-wysiwyg'; - -const RichTextEditor = () => { - return ( -
- -
- ); -}; - -export { RichTextEditor }; diff --git a/src/components/wysiwyg-editor/wysiwyg-editor.stories.tsx b/src/components/wysiwyg-editor/wysiwyg-editor.stories.tsx new file mode 100644 index 0000000..2beac34 --- /dev/null +++ b/src/components/wysiwyg-editor/wysiwyg-editor.stories.tsx @@ -0,0 +1,17 @@ +import { Meta, StoryObj } from '@storybook/react'; + +import { WYSIWYGEditor } from './wysiwyg-editor'; + +const meta: Meta = { + component: WYSIWYGEditor, + title: 'Components/WYSIWYG Editor', +}; + +export default meta; +type Story = StoryObj; + +export const Demo: Story = { + render: (_) => { + return ; + }, +}; diff --git a/src/components/tiptap-wysiwyg-editor/tiptap-wysiwyg-editor.tsx b/src/components/wysiwyg-editor/wysiwyg-editor.tsx similarity index 98% rename from src/components/tiptap-wysiwyg-editor/tiptap-wysiwyg-editor.tsx rename to src/components/wysiwyg-editor/wysiwyg-editor.tsx index 4c73838..4396dd0 100644 --- a/src/components/tiptap-wysiwyg-editor/tiptap-wysiwyg-editor.tsx +++ b/src/components/wysiwyg-editor/wysiwyg-editor.tsx @@ -15,7 +15,7 @@ import Placeholder from '@tiptap/extension-placeholder'; // import { NodeViewContent, NodeViewWrapper } from '@tiptap/react'; import { Button } from '@components/button'; -const TiptapEditor: React.FC = () => { +const WYSIWYGEditor: React.FC = () => { const [content, setContent] = useState('

Type / to insert blocks...

'); const [commandMenu, setCommandMenu] = useState(false); @@ -181,4 +181,4 @@ const TiptapEditor: React.FC = () => { ); }; -export { TiptapEditor }; +export { WYSIWYGEditor }; diff --git a/src/index.ts b/src/index.ts index 8b2cdba..ca9a109 100644 --- a/src/index.ts +++ b/src/index.ts @@ -36,6 +36,8 @@ export * from '@components/truncated-text/truncated-text'; export * from '@components/breadcrumb/breadcrumb'; export * from '@components/color-picker-input/color-picker-input'; export * from '@components/drag-n-drop-file-input/drag-n-drop-file-input'; +export * from '@components/checkbox-tree-view/checkbox-tree-view'; +export * from '@components/wysiwyg-editor/wysiwyg-editor'; // Other stuff export * from '@src/lib/icons'; From ac05d3f5306464819b0b7f5af1df873147ab7c19 Mon Sep 17 00:00:00 2001 From: Deep Chudasama Date: Mon, 30 Dec 2024 14:52:57 +0530 Subject: [PATCH 3/5] feat(editor): enhance WYSIWYG editor toolbar with new icons and functionality --- .../wysiwyg-editor/wysiwyg-editor.tsx | 89 +++++++++++-------- 1 file changed, 50 insertions(+), 39 deletions(-) diff --git a/src/components/wysiwyg-editor/wysiwyg-editor.tsx b/src/components/wysiwyg-editor/wysiwyg-editor.tsx index 4396dd0..bd41a78 100644 --- a/src/components/wysiwyg-editor/wysiwyg-editor.tsx +++ b/src/components/wysiwyg-editor/wysiwyg-editor.tsx @@ -1,4 +1,4 @@ -import React, { useState } from 'react'; +import React, { ReactNode, useState } from 'react'; import { EditorContent, useEditor, FloatingMenu } from '@tiptap/react'; import StarterKit from '@tiptap/starter-kit'; import Link from '@tiptap/extension-link'; @@ -14,6 +14,19 @@ import CodeBlock from '@tiptap/extension-code-block'; import Placeholder from '@tiptap/extension-placeholder'; // import { NodeViewContent, NodeViewWrapper } from '@tiptap/react'; import { Button } from '@components/button'; +import { FaBold, FaItalic, FaHighlighter, FaRegFileCode } from "react-icons/fa6"; +import { MdFormatListBulleted, MdOutlineUndo, MdOutlineRedo, MdInsertLink, MdLinkOff, MdFlag, MdOutlineBatteryUnknown } from "react-icons/md"; +import { BsTypeH1, BsTypeH2, BsTable } from "react-icons/bs"; +import { AiOutlinePicture } from "react-icons/ai"; +import { RiOmega } from "react-icons/ri"; + + + +const MenuLink = ({ title, eventHandler }: { title: string | ReactNode, eventHandler: () => void }) => { + return ( + {title} + ) +} const WYSIWYGEditor: React.FC = () => { const [content, setContent] = useState('

Type / to insert blocks...

'); @@ -55,45 +68,43 @@ const WYSIWYGEditor: React.FC = () => { if (!editor) return null; return ( -
+
{/* Toolbar */} -
- - - - - - +
+ } eventHandler={() => editor.chain().undo().run()} /> + } eventHandler={() => editor.chain().redo().run()} /> + | + } eventHandler={() => editor.chain().focus().setLink({ + href: 'https://tiptap.dev', + class: 'link', + target: '_blank', + }).run()} /> + } eventHandler={() => editor.chain().focus().unsetLink().run()} /> + } eventHandler={() => editor.chain().focus().toggleBold().run()} /> + | + } eventHandler={() => editor.chain().focus().toggleBold().run()} /> + } eventHandler={() => editor.chain().focus().toggleBold().run()} /> + } eventHandler={() => editor.chain().focus().toggleBold().run()} /> + } eventHandler={() => editor.chain().focus().toggleBold().run()} /> + | + } eventHandler={() => editor.chain().focus().toggleBold().run()} /> + | + + + Source +
} eventHandler={() => editor.chain().focus().toggleBold().run()} /> + | + } eventHandler={() => editor.chain().focus().toggleBold().run()} /> + } eventHandler={() => editor.chain().focus().toggleItalic().run()} /> + } eventHandler={() => editor.chain().focus().toggleHighlight().run()} /> + } eventHandler={() => editor.chain().focus().setHeading({ level: 1 }).run()} /> + } eventHandler={() => editor.chain().focus().setHeading({ level: 2 }).run()} /> + } eventHandler={() => editor.chain().focus().toggleBulletList().run()} />
{ {/* Editor */} {/* Command Menu */} {commandMenu && ( -
+
@@ -172,11 +183,11 @@ const WYSIWYGEditor: React.FC = () => {
)} - {/* Debugging Content */} + {/* Debugging Content

Editor Content (HTML):

{content}
-
+
*/}
); }; From 59cb1adcb41fa01bf1332d350a44340fd880b923 Mon Sep 17 00:00:00 2001 From: Deep Chudasama Date: Fri, 3 Jan 2025 14:20:09 +0530 Subject: [PATCH 4/5] feat(editor): implement new editor component with menu and bubble functionalities --- .../editor/components/bubble-menu.tsx | 30 +++ .../editor/components/command-menu.tsx | 44 ++++ .../editor/components/menu-link.tsx | 23 +++ src/components/editor/components/menu.tsx | 53 +++++ src/components/editor/editor.stories.tsx | 17 ++ src/components/editor/editor.tsx | 97 +++++++++ .../wysiwyg-editor/wysiwyg-editor.stories.tsx | 17 -- .../wysiwyg-editor/wysiwyg-editor.tsx | 195 ------------------ src/index.ts | 2 +- 9 files changed, 265 insertions(+), 213 deletions(-) create mode 100644 src/components/editor/components/bubble-menu.tsx create mode 100644 src/components/editor/components/command-menu.tsx create mode 100644 src/components/editor/components/menu-link.tsx create mode 100644 src/components/editor/components/menu.tsx create mode 100644 src/components/editor/editor.stories.tsx create mode 100644 src/components/editor/editor.tsx delete mode 100644 src/components/wysiwyg-editor/wysiwyg-editor.stories.tsx delete mode 100644 src/components/wysiwyg-editor/wysiwyg-editor.tsx diff --git a/src/components/editor/components/bubble-menu.tsx b/src/components/editor/components/bubble-menu.tsx new file mode 100644 index 0000000..d848537 --- /dev/null +++ b/src/components/editor/components/bubble-menu.tsx @@ -0,0 +1,30 @@ +import { Editor, BubbleMenu as TipTapBubbleMenu } from '@tiptap/react' + +// Icons +import { FaParagraph, FaBold, FaItalic } from "react-icons/fa"; +import { BsTypeH1, BsTypeH2 } from "react-icons/bs"; + +import { MenuLink } from './menu-link'; + +interface BubbleMenuProps { + editor: Editor +} + +export const BubbleMenu = ({ editor }: BubbleMenuProps) => { + return ( + + } eventHandler={() => editor.chain().focus().setParagraph().run()} /> + } eventHandler={() => editor.chain().focus().setHeading({ level: 1 }).run} /> + } eventHandler={() => editor.chain().focus().setHeading({ level: 2 }).run} /> + } eventHandler={() => editor.chain().focus().toggleBold().run()} /> + } eventHandler={() => editor.chain().focus().toggleItalic().run()} /> + + ) +} diff --git a/src/components/editor/components/command-menu.tsx b/src/components/editor/components/command-menu.tsx new file mode 100644 index 0000000..5b8e5e4 --- /dev/null +++ b/src/components/editor/components/command-menu.tsx @@ -0,0 +1,44 @@ +import { Button } from '@components/button'; +import { Editor } from '@tiptap/react' + +interface CommandMenuProps { + editor: Editor, + showCommandMenu: boolean +} +export const CommandMenu = ({ + editor, + showCommandMenu +}: CommandMenuProps) => { + + return ( + <> + {showCommandMenu && ( +
+ + + + + +
+ )} + + ) +} \ No newline at end of file diff --git a/src/components/editor/components/menu-link.tsx b/src/components/editor/components/menu-link.tsx new file mode 100644 index 0000000..ed134de --- /dev/null +++ b/src/components/editor/components/menu-link.tsx @@ -0,0 +1,23 @@ +import { ReactNode } from "react" + +interface MenuLinkProps { + title: string | ReactNode, + eventHandler: () => void +} + +/** + * MenuLink component renders a styled anchor element. + * + * @param {Object} props - The properties object. + * @param {function} props.eventHandler - The function to be called when the link is clicked. + * @param {string} props.title - The text to be displayed as the link's title. + * @returns {JSX.Element} The rendered anchor element. + */ +export const MenuLink = ({ + eventHandler, + title +}: MenuLinkProps): JSX.Element => { + return ( + {title} + ) +} diff --git a/src/components/editor/components/menu.tsx b/src/components/editor/components/menu.tsx new file mode 100644 index 0000000..2534327 --- /dev/null +++ b/src/components/editor/components/menu.tsx @@ -0,0 +1,53 @@ +import { Editor } from "@tiptap/react" + +// Icons +import { FaBold, FaItalic, FaHighlighter, FaRegFileCode } from "react-icons/fa6"; +import { MdFormatListBulleted, MdOutlineUndo, MdOutlineRedo, MdInsertLink, MdLinkOff, MdFlag, MdOutlineBatteryUnknown } from "react-icons/md"; +import { BsTypeH1, BsTypeH2, BsTable } from "react-icons/bs"; +import { AiOutlinePicture } from "react-icons/ai"; +import { RiOmega } from "react-icons/ri"; + +import { MenuLink } from "./menu-link" + +interface MenuProps { + editor: Editor +} + +export const Menu = ({ + editor +}: MenuProps) => { + + return ( +
+ } eventHandler={() => editor.chain().undo().run()} /> + } eventHandler={() => editor.chain().redo().run()} /> + | + } eventHandler={() => editor.chain().focus().setLink({ + href: 'https://tiptap.dev', + class: 'link', + target: '_blank', + }).run()} /> + } eventHandler={() => editor.chain().focus().unsetLink().run()} /> + } eventHandler={() => editor.chain().focus().toggleBold().run()} /> + | + } eventHandler={() => editor.chain().focus().toggleBold().run()} /> + } eventHandler={() => editor.chain().focus().toggleBold().run()} /> + } eventHandler={() => editor.chain().focus().toggleBold().run()} /> + } eventHandler={() => editor.chain().focus().toggleBold().run()} /> + | + } eventHandler={() => editor.chain().focus().toggleBold().run()} /> + | + + + Source +
} eventHandler={() => editor.chain().focus().toggleBold().run()} /> + | + } eventHandler={() => editor.chain().focus().toggleBold().run()} /> + } eventHandler={() => editor.chain().focus().toggleItalic().run()} /> + } eventHandler={() => editor.chain().focus().toggleHighlight().run()} /> + } eventHandler={() => editor.chain().focus().setHeading({ level: 1 }).run()} /> + } eventHandler={() => editor.chain().focus().setHeading({ level: 2 }).run()} /> + } eventHandler={() => editor.chain().focus().toggleBulletList().run()} /> +
+ ) +} diff --git a/src/components/editor/editor.stories.tsx b/src/components/editor/editor.stories.tsx new file mode 100644 index 0000000..800ed6a --- /dev/null +++ b/src/components/editor/editor.stories.tsx @@ -0,0 +1,17 @@ +import { Meta, StoryObj } from '@storybook/react'; + +import { Editor } from './editor'; + +const meta: Meta = { + component: Editor, + title: 'Components/Editor', +}; + +export default meta; +type Story = StoryObj; + +export const Demo: Story = { + render: (_) => { + return ; + }, +}; diff --git a/src/components/editor/editor.tsx b/src/components/editor/editor.tsx new file mode 100644 index 0000000..e25e6be --- /dev/null +++ b/src/components/editor/editor.tsx @@ -0,0 +1,97 @@ +import React, { useEffect, useState } from 'react'; +import { EditorContent, useEditor } from '@tiptap/react'; + +// Extensions +import StarterKit from '@tiptap/starter-kit'; +import Link from '@tiptap/extension-link'; +import Image from '@tiptap/extension-image'; +import Table from '@tiptap/extension-table'; +import TableRow from '@tiptap/extension-table-row'; +import TableCell from '@tiptap/extension-table-cell'; +import TableHeader from '@tiptap/extension-table-header'; +import TextAlign from '@tiptap/extension-text-align'; +import Highlight from '@tiptap/extension-highlight'; +import BulletList from '@tiptap/extension-bullet-list'; +import CodeBlock from '@tiptap/extension-code-block'; +import Placeholder from '@tiptap/extension-placeholder'; +// import { NodeViewContent, NodeViewWrapper } from '@tiptap/react'; + +// Components +import { Menu } from './components/menu'; +import { BubbleMenu } from './components/bubble-menu'; +import { CommandMenu } from './components/command-menu'; + + +// List of Tiptap Editor Extensions +const TiptapEditorExtensions = [ + StarterKit, + Link.configure({ openOnClick: true }), + Image, + Table.configure({ resizable: true }), + TableRow, + TableCell, + TableHeader, + TextAlign.configure({ types: ['heading', 'paragraph'] }), + Highlight, + CodeBlock, + BulletList, + Placeholder.configure({ + placeholder: 'Start typing...', + }), +] + +const Editor: React.FC = () => { + const [content, setContent] = useState(); + const [commandMenu, setCommandMenu] = useState(false); + + const editor = useEditor({ + extensions: TiptapEditorExtensions, + content: content, + onUpdate: ({ editor }) => { + setContent(editor.getHTML()); + }, + editorProps: { + handleKeyDown: (_, event) => { + switch (event.key) { + case '/': + setCommandMenu(true); + break; + case 'Escape': + case 'Backspace': + setCommandMenu(false); + break; + default: + break; + } + } + }, + }); + + if (!editor) return null; + + return ( +
+ {/* Menu */} + + + {/* Floating Menu */} + + + {/* Command Menu */} + + + {/* Editor */} + + {/* Debugging Content */} + {/*
+

Editor Content (HTML):

+
{content}
+
*/} +
+ ); +}; + +export { Editor }; diff --git a/src/components/wysiwyg-editor/wysiwyg-editor.stories.tsx b/src/components/wysiwyg-editor/wysiwyg-editor.stories.tsx deleted file mode 100644 index 2beac34..0000000 --- a/src/components/wysiwyg-editor/wysiwyg-editor.stories.tsx +++ /dev/null @@ -1,17 +0,0 @@ -import { Meta, StoryObj } from '@storybook/react'; - -import { WYSIWYGEditor } from './wysiwyg-editor'; - -const meta: Meta = { - component: WYSIWYGEditor, - title: 'Components/WYSIWYG Editor', -}; - -export default meta; -type Story = StoryObj; - -export const Demo: Story = { - render: (_) => { - return ; - }, -}; diff --git a/src/components/wysiwyg-editor/wysiwyg-editor.tsx b/src/components/wysiwyg-editor/wysiwyg-editor.tsx deleted file mode 100644 index bd41a78..0000000 --- a/src/components/wysiwyg-editor/wysiwyg-editor.tsx +++ /dev/null @@ -1,195 +0,0 @@ -import React, { ReactNode, useState } from 'react'; -import { EditorContent, useEditor, FloatingMenu } from '@tiptap/react'; -import StarterKit from '@tiptap/starter-kit'; -import Link from '@tiptap/extension-link'; -import Image from '@tiptap/extension-image'; -import Table from '@tiptap/extension-table'; -import TableRow from '@tiptap/extension-table-row'; -import TableCell from '@tiptap/extension-table-cell'; -import TableHeader from '@tiptap/extension-table-header'; -import TextAlign from '@tiptap/extension-text-align'; -import Highlight from '@tiptap/extension-highlight'; -import BulletList from '@tiptap/extension-bullet-list'; -import CodeBlock from '@tiptap/extension-code-block'; -import Placeholder from '@tiptap/extension-placeholder'; -// import { NodeViewContent, NodeViewWrapper } from '@tiptap/react'; -import { Button } from '@components/button'; -import { FaBold, FaItalic, FaHighlighter, FaRegFileCode } from "react-icons/fa6"; -import { MdFormatListBulleted, MdOutlineUndo, MdOutlineRedo, MdInsertLink, MdLinkOff, MdFlag, MdOutlineBatteryUnknown } from "react-icons/md"; -import { BsTypeH1, BsTypeH2, BsTable } from "react-icons/bs"; -import { AiOutlinePicture } from "react-icons/ai"; -import { RiOmega } from "react-icons/ri"; - - - -const MenuLink = ({ title, eventHandler }: { title: string | ReactNode, eventHandler: () => void }) => { - return ( - {title} - ) -} - -const WYSIWYGEditor: React.FC = () => { - const [content, setContent] = useState('

Type / to insert blocks...

'); - const [commandMenu, setCommandMenu] = useState(false); - - const editor = useEditor({ - extensions: [ - StarterKit, - Link.configure({ openOnClick: true }), - Image, - Table.configure({ resizable: true }), - TableRow, - TableCell, - TableHeader, - TextAlign.configure({ types: ['heading', 'paragraph'] }), - Highlight, - CodeBlock, - BulletList, - Placeholder.configure({ - placeholder: 'Start typing...', - }), - ], - content: content, - onUpdate: ({ editor }) => { - setContent(editor.getHTML()); - }, - editorProps: { - handleKeyDown: (view, event) => { - if (event.key === '/') { - setCommandMenu(true); - } - if (event.key === 'Escape') { - setCommandMenu(false); - } - }, - }, - }); - - if (!editor) return null; - - return ( -
- {/* Toolbar */} -
- } eventHandler={() => editor.chain().undo().run()} /> - } eventHandler={() => editor.chain().redo().run()} /> - | - } eventHandler={() => editor.chain().focus().setLink({ - href: 'https://tiptap.dev', - class: 'link', - target: '_blank', - }).run()} /> - } eventHandler={() => editor.chain().focus().unsetLink().run()} /> - } eventHandler={() => editor.chain().focus().toggleBold().run()} /> - | - } eventHandler={() => editor.chain().focus().toggleBold().run()} /> - } eventHandler={() => editor.chain().focus().toggleBold().run()} /> - } eventHandler={() => editor.chain().focus().toggleBold().run()} /> - } eventHandler={() => editor.chain().focus().toggleBold().run()} /> - | - } eventHandler={() => editor.chain().focus().toggleBold().run()} /> - | - - - Source -
} eventHandler={() => editor.chain().focus().toggleBold().run()} /> - | - } eventHandler={() => editor.chain().focus().toggleBold().run()} /> - } eventHandler={() => editor.chain().focus().toggleItalic().run()} /> - } eventHandler={() => editor.chain().focus().toggleHighlight().run()} /> - } eventHandler={() => editor.chain().focus().setHeading({ level: 1 }).run()} /> - } eventHandler={() => editor.chain().focus().setHeading({ level: 2 }).run()} /> - } eventHandler={() => editor.chain().focus().toggleBulletList().run()} /> -
- - - - - - - - - - {/* Editor */} - - - {/* Command Menu */} - {commandMenu && ( -
- - - - - -
- )} - - {/* Debugging Content -
-

Editor Content (HTML):

-
{content}
-
*/} - - ); -}; - -export { WYSIWYGEditor }; diff --git a/src/index.ts b/src/index.ts index ca9a109..87d58a8 100644 --- a/src/index.ts +++ b/src/index.ts @@ -37,7 +37,7 @@ export * from '@components/breadcrumb/breadcrumb'; export * from '@components/color-picker-input/color-picker-input'; export * from '@components/drag-n-drop-file-input/drag-n-drop-file-input'; export * from '@components/checkbox-tree-view/checkbox-tree-view'; -export * from '@components/wysiwyg-editor/wysiwyg-editor'; +export * from '@components/editor/editor'; // Other stuff export * from '@src/lib/icons'; From 3e62b5a5120af557b4d371835a0b236ab1fb4175 Mon Sep 17 00:00:00 2001 From: Deep Chudasama Date: Wed, 8 Jan 2025 19:35:00 +0530 Subject: [PATCH 5/5] chore(version): bump version to 0.0.9 and update editor component styles --- package.json | 2 +- src/components/editor/components/menu.tsx | 2 +- src/components/editor/editor.tsx | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 1568ddd..d684365 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "@broadlume/willow-ui", "main": "./src/index.ts", - "version": "0.0.8", + "version": "0.0.9", "author": { "name": "dreadhalor", "url": "https://scotthetrick.com" diff --git a/src/components/editor/components/menu.tsx b/src/components/editor/components/menu.tsx index 2534327..c63a32a 100644 --- a/src/components/editor/components/menu.tsx +++ b/src/components/editor/components/menu.tsx @@ -18,7 +18,7 @@ export const Menu = ({ }: MenuProps) => { return ( -
+
} eventHandler={() => editor.chain().undo().run()} /> } eventHandler={() => editor.chain().redo().run()} /> | diff --git a/src/components/editor/editor.tsx b/src/components/editor/editor.tsx index e25e6be..76e88c4 100644 --- a/src/components/editor/editor.tsx +++ b/src/components/editor/editor.tsx @@ -41,7 +41,7 @@ const TiptapEditorExtensions = [ ] const Editor: React.FC = () => { - const [content, setContent] = useState(); + const [content, setContent] = useState('

Start typing...

'); const [commandMenu, setCommandMenu] = useState(false); const editor = useEditor({ @@ -70,7 +70,7 @@ const Editor: React.FC = () => { if (!editor) return null; return ( -

+
{/* Menu */} @@ -83,7 +83,7 @@ const Editor: React.FC = () => { {/* Editor */} {/* Debugging Content */} {/*