adapt to monorepo

This commit is contained in:
Anton Tranelis 2025-06-14 00:32:44 +02:00
parent f3b6603536
commit a9a968547a
10 changed files with 873 additions and 55 deletions

585
lib/package-lock.json generated
View File

@ -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",

View File

@ -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"
},

View File

@ -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}
</h1>
</Link>
<button
className='tw:btn tw:px-2 tw:btn-ghost'
onClick={() => window.my_modal_3.showModal()}
>
<Link className='tw:btn tw:px-2 tw:btn-ghost' to={infoButtonTarget}>
<QuestionMarkIcon className='tw:h-5 tw:w-5' />
</button>
</Link>
</div>
</div>
@ -63,4 +62,4 @@ export default function NavBar({ appName }: { appName: string }) {
</>
)
} else return <></>
}
}

View File

@ -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 */}
<dialog id='my_modal_3' className='tw:modal tw:transition-all tw:duration-300'>
<form method='dialog' className='tw:modal-box tw:transition-none'>
<button className='tw:btn tw:btn-sm tw:btn-circle tw:btn-ghost tw:absolute tw:right-2 tw:top-2 tw:focus:outline-hidden'>
</button>
{children}
</form>
<form method='dialog' className='tw:modal-backdrop'>
<button>close</button>
</form>
</dialog>
<MapOverlayPage
backdrop
card
className={`tw:absolute tw:h-fit tw:max-h-[calc(100%-2.5em)] tw:top-4 tw:bottom-4 tw:left-1/2 tw:transform tw:-translate-x-1/2 tw:overflow-scroll tw:md:w-[calc(50%-32px)] tw:w-[calc(100%-32px)] tw:min-w-80 tw:max-w-[612px] tw:transition-opacity tw:duration-500 tw:opacity-100 tw:pointer-events-auto`}
>
{children}
</MapOverlayPage>
</>
)
}
}

View File

@ -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-<img>Tags
const regex = /(!\[.*?\]\(.*?\)|<img\b[^>]*?\/?>)/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({
</div>
)
}
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<string, NodeSerializerFn>
const marks = serializer.marks
const customImage: NodeSerializerFn = (state, node) => {
const { src, alt, title, style } = node.attrs as ImageAttrs
let tag = '<img src="' + src + '"'
if (alt) tag += ' alt="' + alt + '"'
if (title) tag += ' title="' + title + '"'
if (style) tag += ' style="' + style + '"'
tag += ' />'
state.write(tag)
}
const customSerializer = new MarkdownSerializer({ ...baseNodes, image: customImage }, marks)
return customSerializer.serialize(editor.state.doc)
}

View File

@ -31,3 +31,4 @@ describe('<TextAreaInput />', () => {
})
})
})

View File

@ -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(
/(?<!\]?\()(?<!<)https?:\/\/[^\s)]+(?!\))(?!>)/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 <RouterLink to={to}>{children}</RouterLink>
}
if (href.startsWith('/')) {
return <RouterLink to={href}>{children}</RouterLink>
}
return (
<a href={href} target='_blank' rel='noreferrer'>
{children}
@ -132,7 +139,8 @@ export const TextView = ({
<div translate='no'>
<Markdown
className={'markdown tw:text-map tw:leading-map tw:text-sm'}
remarkPlugins={[remarkBreaks]}
remarkPlugins={[remarkBreaks, remarkGfm]}
rehypePlugins={[rehypeRaw, [rehypeSanitize, sanitizeSchema]]}
components={{
a: Link,
}}
@ -143,16 +151,39 @@ export const TextView = ({
)
}
function removeMarkdownKeepLinksAndParagraphs(text) {
// Remove Markdown syntax using regular expressions but keep links and paragraphs
return text
.replace(/!\[.*?\]\(.*?\)/g, '') // Remove images
.replace(/(`{1,3})(.*?)\1/g, '$2') // Remove inline code
.replace(/(\*{1,2}|_{1,2})(.*?)\1/g, '$2') // Remove bold and italic
.replace(/(#+)\s+(.*)/g, '$2') // Remove headers
.replace(/>\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://…> → 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',
],
},
}

View File

@ -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 = /(?<!\]?\()(?<!<)https?:\/\/[^\s)]+(?!\))(?!>)/g
export const mailRegex = /(?<![[(])([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6})(?![\])])/gi
export function fixUrls(message: string): string {

View File

@ -43,7 +43,7 @@
}
img {
@apply tw:max-w-full tw:rounded tw:shadow;
@apply tw:max-w-full;
}
a {
@ -58,6 +58,112 @@
@apply tw:font-bold tw:cursor-pointer;
color: #faa;
text-decoration: none;
}
/* Überschriften, Absätze, Listen etc. (deine bisherigen Styles) */
/* … */
/* ========== Tabellen ========== */
table {
@apply tw:w-full tw:table-auto tw:border-collapse tw:my-4;
}
thead {
@apply tw:bg-gray-100;
}
th,
td {
@apply tw:border tw:border-gray-300 tw:px-4 tw:py-2;
}
tr:nth-child(even) {
@apply tw:bg-gray-50;
}
/* ========== Inline-Code & Codeblöcke ========== */
code {
@apply tw:bg-gray-100 tw:text-sm tw:px-1 tw:py-0.5 tw:rounded tw:font-mono;
}
pre {
@apply tw:bg-gray-800 tw:text-white tw:rounded tw:p-4 tw:my-4 tw:overflow-x-auto;
}
pre code {
/* entfernt doppeltes Padding im Code-Tag */
@apply tw:bg-transparent tw:px-0 tw:py-0;
}
/* ========== Task-Lists ========== */
/* ========== Task-Lists: alle Marker entfernen ========== */
/* Stelle sicher, dass UL und LI kein List-Style haben */
ul[data-type="taskList"],
ul[data-type="taskList"] > 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 machs 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;
}
}
}