From a9a968547adaa49ab10c25cc2ae71e72fe4cb108 Mon Sep 17 00:00:00 2001 From: Anton Tranelis Date: Sat, 14 Jun 2025 00:32:44 +0200 Subject: [PATCH] adapt to monorepo --- lib/package-lock.json | 585 +++++++++++++++++- lib/package.json | 12 + lib/src/Components/AppShell/NavBar.tsx | 13 +- lib/src/Components/Gaming/Modal.tsx | 23 +- lib/src/Components/Input/RichTextEditor.tsx | 97 ++- .../Components/Input/TextAreaInput.spec.tsx | 1 + lib/src/Components/Map/ProfileView.tsx | 0 .../ItemPopupComponents/TextView.tsx | 85 ++- lib/src/Utils/ReplaceURLs.ts | 4 +- lib/src/assets/css/markdown.css | 108 +++- 10 files changed, 873 insertions(+), 55 deletions(-) delete mode 100644 lib/src/Components/Map/ProfileView.tsx diff --git a/lib/package-lock.json b/lib/package-lock.json index d6cd9828..b900ef90 100644 --- a/lib/package-lock.json +++ b/lib/package-lock.json @@ -13,10 +13,18 @@ "@tanstack/react-query": "^5.17.8", "@tiptap/core": "^2.14.0", "@tiptap/extension-bubble-menu": "^2.14.0", + "@tiptap/extension-bullet-list": "^2.14.0", "@tiptap/extension-color": "^2.12.0", "@tiptap/extension-image": "^2.14.0", "@tiptap/extension-link": "^2.14.0", + "@tiptap/extension-list-item": "^2.14.0", "@tiptap/extension-placeholder": "^2.14.0", + "@tiptap/extension-table": "^2.14.0", + "@tiptap/extension-table-cell": "^2.14.0", + "@tiptap/extension-table-header": "^2.14.0", + "@tiptap/extension-table-row": "^2.14.0", + "@tiptap/extension-task-item": "^2.14.0", + "@tiptap/extension-task-list": "^2.14.0", "@tiptap/extension-youtube": "^2.12.0", "@tiptap/pm": "^2.12.0", "@tiptap/react": "^2.12.0", @@ -27,6 +35,7 @@ "date-fns": "^3.3.1", "leaflet": "^1.9.4", "leaflet.locatecontrol": "^0.79.0", + "prosemirror-markdown": "^1.13.2", "radash": "^12.1.0", "react-colorful": "^5.6.1", "react-dropzone": "^14.3.8", @@ -39,7 +48,10 @@ "react-photo-album": "^3.0.2", "react-router-dom": "^6.23.0", "react-toastify": "^9.1.3", + "rehype-raw": "^7.0.0", + "rehype-sanitize": "^6.0.0", "remark-breaks": "^4.0.0", + "remark-gfm": "^4.0.1", "tiptap-markdown": "^0.8.10", "yet-another-react-lightbox": "^3.21.7" }, @@ -2433,9 +2445,9 @@ } }, "node_modules/@tiptap/extension-bullet-list": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-bullet-list/-/extension-bullet-list-2.12.0.tgz", - "integrity": "sha512-YTCjztB8MaIpwyxFYr81H4+LdKCq1VlaSXQyrPdB44mVdhhRqc46BYQb8/B//XE3UIu3X2QWFjwrqRlUq6vUiw==", + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bullet-list/-/extension-bullet-list-2.14.0.tgz", + "integrity": "sha512-SWnL4bP8Mm/mWN42AMQNoqYE0V6LgSBTVsHwwAki2wIUQdr9HyoAnohvHy3IME56NMwoyZyo+Mzl45wOqUxziA==", "license": "MIT", "funding": { "type": "github", @@ -2642,9 +2654,9 @@ } }, "node_modules/@tiptap/extension-list-item": { - "version": "2.12.0", - "resolved": "https://registry.npmjs.org/@tiptap/extension-list-item/-/extension-list-item-2.12.0.tgz", - "integrity": "sha512-4YwZooC8HP+gPxs6YrkB1ayggyYbgVvJx/rWBT6lKSW2MVVg8QXi1zAcSI3MhIhHmqDysXXFPL8JURlbeGjaFA==", + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-list-item/-/extension-list-item-2.14.0.tgz", + "integrity": "sha512-t1jXDPEd82sC6vZVE/12/CB52uuiydCIcRfwdh21xNgBMckToKO9S0K6XEp4ROtrKQdlIH2JDVPfpUBvVrYN8Q==", "license": "MIT", "funding": { "type": "github", @@ -2707,6 +2719,86 @@ "@tiptap/core": "^2.7.0" } }, + "node_modules/@tiptap/extension-table": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-table/-/extension-table-2.14.0.tgz", + "integrity": "sha512-X/wH3XKxi5+G7cB+lHt3fPMWIJ30IBkzrJZYapJ8d4p2JxMNIU1Nyu+8K6204d0hF6SVWY8hvb/Jq/WgHtoCFA==", + "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.14.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-table-cell/-/extension-table-cell-2.14.0.tgz", + "integrity": "sha512-DkSNAAkMI/ymPgO8y8Gv0MDVcbd2gk7xrSyicIDNoDFFXp15VasInGW8mvyM+CgvlurGB2N+PkYncPtfb4XNuQ==", + "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.14.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-table-header/-/extension-table-header-2.14.0.tgz", + "integrity": "sha512-wX6/+t0iCo3KrqK2OjK0vbFeL76Pq+VpobGt+oM8lcxsENnsa6a0s3wdd1QEVLVPlj+WMFQggAG80Rf17+iDxA==", + "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.14.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-table-row/-/extension-table-row-2.14.0.tgz", + "integrity": "sha512-a1GvCIju9xETIQu664lVQNftHqpPdRmwYp+1QzY82v3zHClso+tTLPeBSlbDdUscSmv3yZXgGML20IiOoR2l2Q==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-task-item": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-task-item/-/extension-task-item-2.14.0.tgz", + "integrity": "sha512-MFE928s1J2ACyjOlkx52D/+r6aqz6c516C0tvnP2vzrkijFaSMNY4Xg7L1wTinzIdijh184AYQpyw7LezJa1ug==", + "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-task-list": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-task-list/-/extension-task-list-2.14.0.tgz", + "integrity": "sha512-o2VELXgkDIHS15pnF1W2OFfxZGvo9V6RcwjzCYUS0mqMF9TTbfHwddRcv4t3pifpMO3sWhspVARavJAGaP5zdQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, "node_modules/@tiptap/extension-text": { "version": "2.12.0", "resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-2.12.0.tgz", @@ -7040,6 +7132,89 @@ "node": ">= 0.4" } }, + "node_modules/hast-util-from-parse5": { + "version": "8.0.3", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-8.0.3.tgz", + "integrity": "sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "devlop": "^1.0.0", + "hastscript": "^9.0.0", + "property-information": "^7.0.0", + "vfile": "^6.0.0", + "vfile-location": "^5.0.0", + "web-namespaces": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-from-parse5/node_modules/property-information": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz", + "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/hast-util-parse-selector": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-4.0.0.tgz", + "integrity": "sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-raw": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-9.1.0.tgz", + "integrity": "sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@types/unist": "^3.0.0", + "@ungap/structured-clone": "^1.0.0", + "hast-util-from-parse5": "^8.0.0", + "hast-util-to-parse5": "^8.0.0", + "html-void-elements": "^3.0.0", + "mdast-util-to-hast": "^13.0.0", + "parse5": "^7.0.0", + "unist-util-position": "^5.0.0", + "unist-util-visit": "^5.0.0", + "vfile": "^6.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-sanitize": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/hast-util-sanitize/-/hast-util-sanitize-5.0.2.tgz", + "integrity": "sha512-3yTWghByc50aGS7JlGhk61SPenfE/p1oaFeNwkOOyrscaOkMGrcW9+Cy/QAIOBpZxP1yqDIzFMR0+Np0i0+usg==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "@ungap/structured-clone": "^1.0.0", + "unist-util-position": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/hast-util-to-jsx-runtime": { "version": "2.3.2", "resolved": "https://registry.npmjs.org/hast-util-to-jsx-runtime/-/hast-util-to-jsx-runtime-2.3.2.tgz", @@ -7067,6 +7242,25 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/hast-util-to-parse5": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-8.0.0.tgz", + "integrity": "sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "devlop": "^1.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/hast-util-whitespace": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-3.0.0.tgz", @@ -7080,6 +7274,33 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/hastscript": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-9.0.1.tgz", + "integrity": "sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^4.0.0", + "property-information": "^7.0.0", + "space-separated-tokens": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hastscript/node_modules/property-information": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-7.1.0.tgz", + "integrity": "sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", @@ -7097,6 +7318,16 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/html-void-elements": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-3.0.0.tgz", + "integrity": "sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/http-signature": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.4.0.tgz", @@ -8748,6 +8979,16 @@ "url": "https://github.com/fb55/entities?sponsor=1" } }, + "node_modules/markdown-table": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-3.0.4.tgz", + "integrity": "sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -8809,6 +9050,107 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/mdast-util-gfm": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-3.1.0.tgz", + "integrity": "sha512-0ulfdQOM3ysHhCJ1p06l0b0VKlhU0wuQs3thxZQagjcjPrlFRqY215uZGHHJan9GEAXd9MbfPjFJz+qMkVR6zQ==", + "license": "MIT", + "dependencies": { + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-gfm-autolink-literal": "^2.0.0", + "mdast-util-gfm-footnote": "^2.0.0", + "mdast-util-gfm-strikethrough": "^2.0.0", + "mdast-util-gfm-table": "^2.0.0", + "mdast-util-gfm-task-list-item": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-2.0.1.tgz", + "integrity": "sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "ccount": "^2.0.0", + "devlop": "^1.0.0", + "mdast-util-find-and-replace": "^3.0.0", + "micromark-util-character": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-footnote/-/mdast-util-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-sqpDWlsHn7Ac9GNZQMeUzPQSMzR6Wv0WKRNvQRg0KqHh02fpTz69Qc1QSseNX29bhz1ROIyNyxExfawVKTm1GQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.1.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-strikethrough": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-2.0.0.tgz", + "integrity": "sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-2.0.0.tgz", + "integrity": "sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "markdown-table": "^3.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-task-list-item": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-2.0.0.tgz", + "integrity": "sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "devlop": "^1.0.0", + "mdast-util-from-markdown": "^2.0.0", + "mdast-util-to-markdown": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/mdast-util-mdx-expression": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-2.0.1.tgz", @@ -9051,6 +9393,127 @@ "micromark-util-types": "^2.0.0" } }, + "node_modules/micromark-extension-gfm": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-3.0.0.tgz", + "integrity": "sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==", + "license": "MIT", + "dependencies": { + "micromark-extension-gfm-autolink-literal": "^2.0.0", + "micromark-extension-gfm-footnote": "^2.0.0", + "micromark-extension-gfm-strikethrough": "^2.0.0", + "micromark-extension-gfm-table": "^2.0.0", + "micromark-extension-gfm-tagfilter": "^2.0.0", + "micromark-extension-gfm-task-list-item": "^2.0.0", + "micromark-util-combine-extensions": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-2.1.0.tgz", + "integrity": "sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==", + "license": "MIT", + "dependencies": { + "micromark-util-character": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-footnote": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-footnote/-/micromark-extension-gfm-footnote-2.1.0.tgz", + "integrity": "sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-core-commonmark": "^2.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-normalize-identifier": "^2.0.0", + "micromark-util-sanitize-uri": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-strikethrough": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-2.1.0.tgz", + "integrity": "sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-util-chunked": "^2.0.0", + "micromark-util-classify-character": "^2.0.0", + "micromark-util-resolve-all": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-2.1.1.tgz", + "integrity": "sha512-t2OU/dXXioARrC6yWfJ4hqB7rct14e8f7m0cbI5hUmDyyIlwv5vEtooptH8INkbLzOatzKuVbQmAYcbWoyz6Dg==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-tagfilter": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-2.0.0.tgz", + "integrity": "sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==", + "license": "MIT", + "dependencies": { + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-2.1.0.tgz", + "integrity": "sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==", + "license": "MIT", + "dependencies": { + "devlop": "^1.0.0", + "micromark-factory-space": "^2.0.0", + "micromark-util-character": "^2.0.0", + "micromark-util-symbol": "^2.0.0", + "micromark-util-types": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/micromark-factory-destination": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-2.0.1.tgz", @@ -9969,6 +10432,30 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/parse5": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz", + "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==", + "license": "MIT", + "dependencies": { + "entities": "^6.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5/node_modules/entities": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz", + "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -11449,6 +11936,35 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/rehype-raw": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-7.0.0.tgz", + "integrity": "sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-raw": "^9.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-sanitize": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/rehype-sanitize/-/rehype-sanitize-6.0.0.tgz", + "integrity": "sha512-CsnhKNsyI8Tub6L4sm5ZFsme4puGfc6pYylvXo1AeqaGbjOYyzNv3qZPwvs0oMJ39eryyeOdmxwUIo94IpEhqg==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "hast-util-sanitize": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/remark-breaks": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/remark-breaks/-/remark-breaks-4.0.0.tgz", @@ -11464,6 +11980,24 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/remark-gfm": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-4.0.1.tgz", + "integrity": "sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-gfm": "^3.0.0", + "micromark-extension-gfm": "^3.0.0", + "remark-parse": "^11.0.0", + "remark-stringify": "^11.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/remark-parse": { "version": "11.0.0", "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-11.0.0.tgz", @@ -11497,6 +12031,21 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/remark-stringify": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-11.0.0.tgz", + "integrity": "sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==", + "license": "MIT", + "dependencies": { + "@types/mdast": "^4.0.0", + "mdast-util-to-markdown": "^2.0.0", + "unified": "^11.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/request-progress": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz", @@ -13335,6 +13884,20 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/vfile-location": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-5.0.3.tgz", + "integrity": "sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==", + "license": "MIT", + "dependencies": { + "@types/unist": "^3.0.0", + "vfile": "^6.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/vfile-message": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-4.0.2.tgz", @@ -13580,6 +14143,16 @@ "integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==", "license": "MIT" }, + "node_modules/web-namespaces": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", + "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/webidl-conversions": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", diff --git a/lib/package.json b/lib/package.json index 0601b494..8c050b00 100644 --- a/lib/package.json +++ b/lib/package.json @@ -101,10 +101,18 @@ "@tanstack/react-query": "^5.17.8", "@tiptap/core": "^2.14.0", "@tiptap/extension-bubble-menu": "^2.14.0", + "@tiptap/extension-bullet-list": "^2.14.0", "@tiptap/extension-color": "^2.12.0", "@tiptap/extension-image": "^2.14.0", "@tiptap/extension-link": "^2.14.0", + "@tiptap/extension-list-item": "^2.14.0", "@tiptap/extension-placeholder": "^2.14.0", + "@tiptap/extension-table": "^2.14.0", + "@tiptap/extension-table-cell": "^2.14.0", + "@tiptap/extension-table-header": "^2.14.0", + "@tiptap/extension-table-row": "^2.14.0", + "@tiptap/extension-task-item": "^2.14.0", + "@tiptap/extension-task-list": "^2.14.0", "@tiptap/extension-youtube": "^2.12.0", "@tiptap/pm": "^2.12.0", "@tiptap/react": "^2.12.0", @@ -115,6 +123,7 @@ "date-fns": "^3.3.1", "leaflet": "^1.9.4", "leaflet.locatecontrol": "^0.79.0", + "prosemirror-markdown": "^1.13.2", "radash": "^12.1.0", "react-colorful": "^5.6.1", "react-dropzone": "^14.3.8", @@ -127,7 +136,10 @@ "react-photo-album": "^3.0.2", "react-router-dom": "^6.23.0", "react-toastify": "^9.1.3", + "rehype-raw": "^7.0.0", + "rehype-sanitize": "^6.0.0", "remark-breaks": "^4.0.0", + "remark-gfm": "^4.0.1", "tiptap-markdown": "^0.8.10", "yet-another-react-lightbox": "^3.21.7" }, diff --git a/lib/src/Components/AppShell/NavBar.tsx b/lib/src/Components/AppShell/NavBar.tsx index 51f521b9..86ae6f95 100644 --- a/lib/src/Components/AppShell/NavBar.tsx +++ b/lib/src/Components/AppShell/NavBar.tsx @@ -1,7 +1,7 @@ import Bars3Icon from '@heroicons/react/16/solid/Bars3Icon' import QuestionMarkIcon from '@heroicons/react/24/outline/QuestionMarkCircleIcon' import { useEffect, useRef, useState } from 'react' -import { Link } from 'react-router-dom' +import { Link, useLocation } from 'react-router-dom' import { ThemeControl } from '#components/Templates/ThemeControl' @@ -11,6 +11,8 @@ import { UserControl } from './UserControl' export default function NavBar({ appName }: { appName: string }) { const appState = useAppState() const setAppState = useSetAppState() + const { pathname } = useLocation() + const infoButtonTarget = pathname === '/info' ? '/' : '/info' const toggleSidebar = () => { setAppState({ sideBarOpen: !appState.sideBarOpen }) @@ -48,12 +50,9 @@ export default function NavBar({ appName }: { appName: string }) { {appName} - + @@ -63,4 +62,4 @@ export default function NavBar({ appName }: { appName: string }) { ) } else return <> -} +} \ No newline at end of file diff --git a/lib/src/Components/Gaming/Modal.tsx b/lib/src/Components/Gaming/Modal.tsx index 32f66058..7df9ff59 100644 --- a/lib/src/Components/Gaming/Modal.tsx +++ b/lib/src/Components/Gaming/Modal.tsx @@ -1,5 +1,7 @@ import { useEffect } from 'react' +import { MapOverlayPage } from '#components/Templates' + /** * @category Gaming */ @@ -19,18 +21,13 @@ export function Modal({ return ( <> - {/* You can open the modal using ID.showModal() method */} - -
- - {children} -
-
- -
-
+ + {children} + ) -} +} \ No newline at end of file diff --git a/lib/src/Components/Input/RichTextEditor.tsx b/lib/src/Components/Input/RichTextEditor.tsx index 268cbe04..45d7015f 100644 --- a/lib/src/Components/Input/RichTextEditor.tsx +++ b/lib/src/Components/Input/RichTextEditor.tsx @@ -5,13 +5,24 @@ import { Color } from '@tiptap/extension-color' import { Image } from '@tiptap/extension-image' import { Link } from '@tiptap/extension-link' import { Placeholder } from '@tiptap/extension-placeholder' +import { Table } from '@tiptap/extension-table' +import { TableCell } from '@tiptap/extension-table-cell' +import { TableHeader } from '@tiptap/extension-table-header' +import { TableRow } from '@tiptap/extension-table-row' +import { TaskItem } from '@tiptap/extension-task-item' +import { TaskList } from '@tiptap/extension-task-list' import { EditorContent, useEditor } from '@tiptap/react' import { StarterKit } from '@tiptap/starter-kit' +import { MarkdownSerializer } from 'prosemirror-markdown' import { useEffect } from 'react' import { Markdown } from 'tiptap-markdown' import { TextEditorMenu } from './TextEditorMenu' +import type { Editor } from '@tiptap/react' +import type { MarkdownSerializerState } from 'prosemirror-markdown' +import type { Node as ProseMirrorNode } from 'prosemirror-model' + interface RichTextEditorProps { labelTitle?: string labelStyle?: string @@ -22,6 +33,20 @@ interface RichTextEditorProps { updateFormValue?: (value: string) => void } +interface ImageAttrs { + src: string + alt?: string + title?: string + style?: string +} + +type NodeSerializerFn = ( + state: MarkdownSerializerState, + node: ProseMirrorNode, + parent: ProseMirrorNode, + index: number, +) => void + /** * @category Input */ @@ -35,10 +60,14 @@ export function RichTextEditor({ updateFormValue, }: RichTextEditorProps) { const handleChange = () => { - let newValue: string | undefined = editor?.storage.markdown.getMarkdown() + if (!editor) return + + let newValue = getStyledMarkdown(editor) + // matcht entweder Markdown-Images *oder* HTML-–Tags + const regex = /(!\[.*?\]\(.*?\)|]*?\/?>)/gi + + newValue = newValue.replace(regex, (match) => match + '\n\n') - const regex = /!\[.*?\]\(.*?\)/g - newValue = newValue?.replace(regex, (match: string) => match + '\n\n') if (updateFormValue && newValue) { updateFormValue(newValue) } @@ -58,11 +87,20 @@ export function RichTextEditor({ }, }), Markdown.configure({ + html: true, linkify: true, transformCopiedText: true, transformPastedText: true, }), - Image, + Table.configure({ + resizable: true, + }), + TableCell, + TableHeader, + TableRow, + TaskList, + TaskItem, + CustomImage, Link, Placeholder.configure({ placeholder, @@ -108,3 +146,54 @@ export function RichTextEditor({ ) } + +const CustomImage = Image.extend({ + addAttributes() { + return { + ...this.parent?.(), + style: { + default: null, + parseHTML: (element) => element.getAttribute('style'), + renderHTML: (attributes) => { + if (!attributes.style) { + return {} + } + return { style: attributes.style } + }, + }, + width: { + default: null, + parseHTML: (element) => element.getAttribute('width'), + renderHTML: (attrs) => (attrs.width ? { width: attrs.width } : {}), + }, + height: { + default: null, + parseHTML: (element) => element.getAttribute('height'), + renderHTML: (attrs) => (attrs.height ? { height: attrs.height } : {}), + }, + } + }, +}) + +export function getStyledMarkdown(editor: Editor): string { + const { serializer } = editor.storage.markdown as { serializer: MarkdownSerializer } + + const baseNodes = serializer.nodes as Record + const marks = serializer.marks + + const customImage: NodeSerializerFn = (state, node) => { + const { src, alt, title, style } = node.attrs as ImageAttrs + + let tag = '', () => { }) }) }) + diff --git a/lib/src/Components/Map/ProfileView.tsx b/lib/src/Components/Map/ProfileView.tsx deleted file mode 100644 index e69de29b..00000000 diff --git a/lib/src/Components/Map/Subcomponents/ItemPopupComponents/TextView.tsx b/lib/src/Components/Map/Subcomponents/ItemPopupComponents/TextView.tsx index 93fce564..c9e909f2 100644 --- a/lib/src/Components/Map/Subcomponents/ItemPopupComponents/TextView.tsx +++ b/lib/src/Components/Map/Subcomponents/ItemPopupComponents/TextView.tsx @@ -5,7 +5,11 @@ /* eslint-disable @typescript-eslint/no-unsafe-member-access */ /* eslint-disable @typescript-eslint/no-unsafe-call */ import Markdown from 'react-markdown' +import { Link as RouterLink } from 'react-router-dom' +import rehypeRaw from 'rehype-raw' +import rehypeSanitize, { defaultSchema } from 'rehype-sanitize' import remarkBreaks from 'remark-breaks' +import remarkGfm from 'remark-gfm' import { useAddFilterTag } from '#components/Map/hooks/useFilter' import { useTags } from '#components/Map/hooks/useTags' @@ -39,6 +43,8 @@ export const TextView = ({ const tags = useTags() const addFilterTag = useAddFilterTag() + const origin = window.location.origin + let innerText = '' let replacedText = '' @@ -48,18 +54,10 @@ export const TextView = ({ innerText = text } - if (innerText && truncate) - innerText = truncateText(removeMarkdownKeepLinksAndParagraphs(innerText), 100) + if (innerText && truncate) innerText = truncateText(removeMarkdownKeepParagraphs(innerText), 100) if (innerText) replacedText = fixUrls(innerText) - if (replacedText) { - replacedText = replacedText.replace( - /(?)/g, - (url) => `[${url.replace(/https?:\/\/w{3}\./gi, '')}](${url})`, - ) - } - if (replacedText) { replacedText = replacedText.replace(mailRegex, (url) => { return `[${url}](mailto:${url})` @@ -120,7 +118,16 @@ export const TextView = ({ else return children } - // Default: Link + // 4) Interne Links auf gleiche Base-URL + if (href.startsWith(origin)) { + const to = href.slice(origin.length) || '/' + return {children} + } + + if (href.startsWith('/')) { + return {children} + } + return ( {children} @@ -132,7 +139,8 @@ export const TextView = ({
\s+(.*)/g, '$1') // Remove blockquotes - .replace(/^\s*\n/gm, '\n') // Preserve empty lines - .replace(/(\r\n|\n|\r)/gm, '\n') // Preserve line breaks +function removeMarkdownKeepParagraphs(text: string): string { + return ( + text + // 1) Bilder entfernen + .replace(/!\[.*?\]\(.*?\)/g, '') + // 2) Markdown-Links [Text](URL) → URL + .replace(/\[.*?\]\(\s*(https?:\/\/[^\s)]+)\s*\)/g, '$1') + // 3) Autolinks → http://… + .replace(/<\s*(https?:\/\/[^\s>]+)\s*>/g, '$1') + // 4) Code-Fences und Inline-Code entfernen + .replace(/```[\s\S]*?```/g, '') + .replace(/`([^`]+)`/g, '$1') + // 5) Fett/Italic löschen + .replace(/(\*\*|__)(.*?)\1/g, '$2') + .replace(/(\*|_)(.*?)\1/g, '$2') + // 6) Überschriften-Hashes entfernen + .replace(/^#{1,6}\s+(.*)$/gm, '$1') + // 7) Listen-Marker entfernen (-, *, +, 1., 2., …) + .replace(/^\s*([-+*]|\d+\.)\s+/gm, '') + // 8) Tabellen-Pipes entfernen + .replace(/^\|(.+)\|$/gm, '$1') + .replace(/^\s*\|[-\s|]+\|$/gm, '') + // 9) Blockquotes + .replace(/^>\s+(.*)$/gm, '$1') + // 10) Echte HTML-Tags (außer Absätze) entfernen + .replace(/<(?!\s*\/?\s*p\s*>)[^>]+>/g, '') + // 11) Zeilenumbrüche normalisieren + .replace(/\r\n|\r/g, '\n') + // 12) Mehrfache Leerzeilen auf max. 2 reduzieren + .replace(/\n{3,}/g, '\n\n') + // 13) Trim + .trim() + ) } function truncateText(text, limit) { @@ -178,3 +209,15 @@ function truncateText(text, limit) { return truncated.trim() } + +const sanitizeSchema = { + ...defaultSchema, + attributes: { + ...defaultSchema.attributes, + img: [ + // alle bisherigen Attribute, plus 'style' + ...(defaultSchema.attributes?.img || []), + 'style', + ], + }, +} diff --git a/lib/src/Utils/ReplaceURLs.ts b/lib/src/Utils/ReplaceURLs.ts index 25981922..5e393e24 100644 --- a/lib/src/Utils/ReplaceURLs.ts +++ b/lib/src/Utils/ReplaceURLs.ts @@ -1,6 +1,4 @@ -export const urlRegex = - // eslint-disable-next-line no-useless-escape, security/detect-unsafe-regex - /(^| )(http:\/\/www\.|https:\/\/www\.|http:\/\/|https:\/\/)?[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,10}(:[0-9]{1,10})?(\/.*)?$/gm +export const urlRegex = /(?)/g export const mailRegex = /(? li { + list-style: none !important; + } + + /* Für den Fall, dass ProseMirror ein ::before oder ::marker nutzt */ + ul[data-type="taskList"] > li::before, + ul[data-type="taskList"] > li::marker { + content: "" !important; + display: none !important; + } + /* Ul ohne Marker, ohne Einrückung */ + ul[data-type="taskList"] { + @apply tw:list-none tw:m-0 tw:p-0; + } + + /* Li als Flex-Container, kein Marker */ + ul[data-type="taskList"] > li { + @apply tw:flex tw:items-start tw:gap-2 tw:my-1 tw:list-none; + } + ul[data-type="taskList"] > li::marker { + content: ""; + } + + /* Label hält nur die Checkbox */ + ul[data-type="taskList"] > li > label { + @apply tw:flex tw:items-center tw:m-0 tw:p-0; + } + + /* Checkbox-Größe */ + ul[data-type="taskList"] > li label input[type="checkbox"] { + @apply tw:w-4 tw:h-4 tw:shrink-0; + } + + /* Der Text steht in einem div – mach’s inline und ohne Margin */ + ul[data-type="taskList"] > li > div { + @apply tw:flex-1 tw:m-0; + } + ul[data-type="taskList"] > li > div > p { + @apply tw:inline-block tw:my-0 tw:leading-relaxed; + } + + ul.contains-task-list { + @apply tw:list-none tw:m-0 tw:p-0; + } + + /* Li ebenfalls ohne Marker */ + ul.contains-task-list > li.task-list-item { + @apply tw:list-none; + } + /* Für alle Browser-Marker und ::before-Pseudo-Elemente */ + ul.contains-task-list > li.task-list-item::marker, + ul.contains-task-list > li.task-list-item::before { + content: "" !important; + display: none !important; + } + + /* P als Inline-Flex, damit kein Umbruch und guter Abstand */ + ul.contains-task-list > li.task-list-item > p { + @apply tw:inline-flex tw:items-center tw:gap-2 tw:leading-relaxed; + } + + /* Checkbox-Größe und Abstand */ + ul.contains-task-list > li.task-list-item > p > input[type="checkbox"] { + @apply tw:w-4 tw:h-4 tw:shrink-0; + } + + /* ========== Blockzitate ========== */ + blockquote { + @apply tw:border-l-4 tw:border-gray-300 tw:pl-4 tw:italic tw:text-gray-600 tw:bg-gray-50 tw:my-4 tw:py-2; } } }