feat(MarkdownEditor): enhance Markdown rendering with new plugins and components
- Integrated rehype-raw and rehype-slug for improved Markdown processing. - Added remark-toc for automatic table of contents generation. - Refactored Markdown components for better styling and functionality. - Updated package.json to include new dependencies for enhanced Markdown features.
This commit is contained in:
@@ -40,14 +40,17 @@
|
|||||||
"mermaid": "^11.12.0",
|
"mermaid": "^11.12.0",
|
||||||
"next": "15.5.3",
|
"next": "15.5.3",
|
||||||
"next-auth": "^4.24.11",
|
"next-auth": "^4.24.11",
|
||||||
|
"prism-react-renderer": "^2.4.1",
|
||||||
"prisma": "^6.16.1",
|
"prisma": "^6.16.1",
|
||||||
"react": "19.1.0",
|
"react": "19.1.0",
|
||||||
"react-dom": "19.1.0",
|
"react-dom": "19.1.0",
|
||||||
"react-markdown": "^10.1.0",
|
"react-markdown": "^10.1.0",
|
||||||
"recharts": "^3.2.1",
|
"recharts": "^3.2.1",
|
||||||
"rehype-highlight": "^7.0.2",
|
"rehype-raw": "^7.0.0",
|
||||||
"rehype-sanitize": "^6.0.0",
|
"rehype-sanitize": "^6.0.0",
|
||||||
|
"rehype-slug": "^6.0.0",
|
||||||
"remark-gfm": "^4.0.1",
|
"remark-gfm": "^4.0.1",
|
||||||
|
"remark-toc": "^9.0.0",
|
||||||
"tailwind-merge": "^3.3.1",
|
"tailwind-merge": "^3.3.1",
|
||||||
"twemoji": "^14.0.2"
|
"twemoji": "^14.0.2"
|
||||||
},
|
},
|
||||||
|
|||||||
217
pnpm-lock.yaml
generated
217
pnpm-lock.yaml
generated
@@ -53,6 +53,9 @@ importers:
|
|||||||
next-auth:
|
next-auth:
|
||||||
specifier: ^4.24.11
|
specifier: ^4.24.11
|
||||||
version: 4.24.11(next@15.5.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
version: 4.24.11(next@15.5.3(react-dom@19.1.0(react@19.1.0))(react@19.1.0))(react-dom@19.1.0(react@19.1.0))(react@19.1.0)
|
||||||
|
prism-react-renderer:
|
||||||
|
specifier: ^2.4.1
|
||||||
|
version: 2.4.1(react@19.1.0)
|
||||||
prisma:
|
prisma:
|
||||||
specifier: ^6.16.1
|
specifier: ^6.16.1
|
||||||
version: 6.17.1(typescript@5.9.3)
|
version: 6.17.1(typescript@5.9.3)
|
||||||
@@ -68,15 +71,21 @@ importers:
|
|||||||
recharts:
|
recharts:
|
||||||
specifier: ^3.2.1
|
specifier: ^3.2.1
|
||||||
version: 3.2.1(@types/react@19.2.2)(react-dom@19.1.0(react@19.1.0))(react-is@16.13.1)(react@19.1.0)(redux@5.0.1)
|
version: 3.2.1(@types/react@19.2.2)(react-dom@19.1.0(react@19.1.0))(react-is@16.13.1)(react@19.1.0)(redux@5.0.1)
|
||||||
rehype-highlight:
|
rehype-raw:
|
||||||
specifier: ^7.0.2
|
specifier: ^7.0.0
|
||||||
version: 7.0.2
|
version: 7.0.0
|
||||||
rehype-sanitize:
|
rehype-sanitize:
|
||||||
specifier: ^6.0.0
|
specifier: ^6.0.0
|
||||||
version: 6.0.0
|
version: 6.0.0
|
||||||
|
rehype-slug:
|
||||||
|
specifier: ^6.0.0
|
||||||
|
version: 6.0.0
|
||||||
remark-gfm:
|
remark-gfm:
|
||||||
specifier: ^4.0.1
|
specifier: ^4.0.1
|
||||||
version: 4.0.1
|
version: 4.0.1
|
||||||
|
remark-toc:
|
||||||
|
specifier: ^9.0.0
|
||||||
|
version: 9.0.0
|
||||||
tailwind-merge:
|
tailwind-merge:
|
||||||
specifier: ^3.3.1
|
specifier: ^3.3.1
|
||||||
version: 3.3.1
|
version: 3.3.1
|
||||||
@@ -1016,6 +1025,9 @@ packages:
|
|||||||
'@types/node@20.19.21':
|
'@types/node@20.19.21':
|
||||||
resolution: {integrity: sha512-CsGG2P3I5y48RPMfprQGfy4JPRZ6csfC3ltBZSRItG3ngggmNY/qs2uZKp4p9VbrpqNNSMzUZNFZKzgOGnd/VA==}
|
resolution: {integrity: sha512-CsGG2P3I5y48RPMfprQGfy4JPRZ6csfC3ltBZSRItG3ngggmNY/qs2uZKp4p9VbrpqNNSMzUZNFZKzgOGnd/VA==}
|
||||||
|
|
||||||
|
'@types/prismjs@1.26.5':
|
||||||
|
resolution: {integrity: sha512-AUZTa7hQ2KY5L7AmtSiqxlhWxb4ina0yd8hNbl4TWuqnv/pFP0nDMb3YrfSBf4hJVGLh2YEIBfKaBW/9UEl6IQ==}
|
||||||
|
|
||||||
'@types/react-dom@19.2.2':
|
'@types/react-dom@19.2.2':
|
||||||
resolution: {integrity: sha512-9KQPoO6mZCi7jcIStSnlOWn2nEF3mNmyr3rIAsGnAbQKYbRLyqmeSc39EVgtxXVia+LMT8j3knZLAZAh+xLmrw==}
|
resolution: {integrity: sha512-9KQPoO6mZCi7jcIStSnlOWn2nEF3mNmyr3rIAsGnAbQKYbRLyqmeSc39EVgtxXVia+LMT8j3knZLAZAh+xLmrw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@@ -1027,6 +1039,9 @@ packages:
|
|||||||
'@types/trusted-types@2.0.7':
|
'@types/trusted-types@2.0.7':
|
||||||
resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==}
|
resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==}
|
||||||
|
|
||||||
|
'@types/ungap__structured-clone@1.2.0':
|
||||||
|
resolution: {integrity: sha512-ZoaihZNLeZSxESbk9PUAPZOlSpcKx81I1+4emtULDVmBLkYutTcMlCj2K9VNlf9EWODxdO6gkAqEaLorXwZQVA==}
|
||||||
|
|
||||||
'@types/unist@2.0.11':
|
'@types/unist@2.0.11':
|
||||||
resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==}
|
resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==}
|
||||||
|
|
||||||
@@ -1709,6 +1724,10 @@ packages:
|
|||||||
resolution: {integrity: sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==}
|
resolution: {integrity: sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==}
|
||||||
engines: {node: '>=10.13.0'}
|
engines: {node: '>=10.13.0'}
|
||||||
|
|
||||||
|
entities@6.0.1:
|
||||||
|
resolution: {integrity: sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==}
|
||||||
|
engines: {node: '>=0.12'}
|
||||||
|
|
||||||
environment@1.1.0:
|
environment@1.1.0:
|
||||||
resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==}
|
resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==}
|
||||||
engines: {node: '>=18'}
|
engines: {node: '>=18'}
|
||||||
@@ -2007,6 +2026,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==}
|
resolution: {integrity: sha512-L5bGsVkxJbJgdnwyuheIunkGatUF/zssUoxxjACCseZYAVbaqdh9Tsmmlkl8vYan09H7sbvKt4pS8GqKLBrEzA==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
github-slugger@2.0.0:
|
||||||
|
resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==}
|
||||||
|
|
||||||
glob-parent@5.1.2:
|
glob-parent@5.1.2:
|
||||||
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
|
resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
|
||||||
engines: {node: '>= 6'}
|
engines: {node: '>= 6'}
|
||||||
@@ -2067,8 +2089,17 @@ packages:
|
|||||||
resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
|
resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
hast-util-is-element@3.0.0:
|
hast-util-from-parse5@8.0.3:
|
||||||
resolution: {integrity: sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==}
|
resolution: {integrity: sha512-3kxEVkEKt0zvcZ3hCRYI8rqrgwtlIOFMWkbclACvjlDw8Li9S2hk/d51OI0nr/gIpdMHNepwgOKqZ/sy0Clpyg==}
|
||||||
|
|
||||||
|
hast-util-heading-rank@3.0.0:
|
||||||
|
resolution: {integrity: sha512-EJKb8oMUXVHcWZTDepnr+WNbfnXKFNf9duMesmr4S8SXTJBJ9M4Yok08pu9vxdJwdlGRhVumk9mEhkEvKGifwA==}
|
||||||
|
|
||||||
|
hast-util-parse-selector@4.0.0:
|
||||||
|
resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==}
|
||||||
|
|
||||||
|
hast-util-raw@9.1.0:
|
||||||
|
resolution: {integrity: sha512-Y8/SBAHkZGoNkpzqqfCldijcuUKh7/su31kEBp67cFY09Wy0mTRgtsLYsiIxMJxlu0f6AA5SUTbDR8K0rxnbUw==}
|
||||||
|
|
||||||
hast-util-sanitize@5.0.2:
|
hast-util-sanitize@5.0.2:
|
||||||
resolution: {integrity: sha512-3yTWghByc50aGS7JlGhk61SPenfE/p1oaFeNwkOOyrscaOkMGrcW9+Cy/QAIOBpZxP1yqDIzFMR0+Np0i0+usg==}
|
resolution: {integrity: sha512-3yTWghByc50aGS7JlGhk61SPenfE/p1oaFeNwkOOyrscaOkMGrcW9+Cy/QAIOBpZxP1yqDIzFMR0+Np0i0+usg==}
|
||||||
@@ -2076,19 +2107,24 @@ packages:
|
|||||||
hast-util-to-jsx-runtime@2.3.6:
|
hast-util-to-jsx-runtime@2.3.6:
|
||||||
resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==}
|
resolution: {integrity: sha512-zl6s8LwNyo1P9uw+XJGvZtdFF1GdAkOg8ujOw+4Pyb76874fLps4ueHXDhXWdk6YHQ6OgUtinliG7RsYvCbbBg==}
|
||||||
|
|
||||||
hast-util-to-text@4.0.2:
|
hast-util-to-parse5@8.0.0:
|
||||||
resolution: {integrity: sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==}
|
resolution: {integrity: sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==}
|
||||||
|
|
||||||
|
hast-util-to-string@3.0.1:
|
||||||
|
resolution: {integrity: sha512-XelQVTDWvqcl3axRfI0xSeoVKzyIFPwsAGSLIsKdJKQMXDYJS4WYrBNF/8J7RdhIcFI2BOHgAifggsvsxp/3+A==}
|
||||||
|
|
||||||
hast-util-whitespace@3.0.0:
|
hast-util-whitespace@3.0.0:
|
||||||
resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==}
|
resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==}
|
||||||
|
|
||||||
highlight.js@11.11.1:
|
hastscript@9.0.1:
|
||||||
resolution: {integrity: sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==}
|
resolution: {integrity: sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==}
|
||||||
engines: {node: '>=12.0.0'}
|
|
||||||
|
|
||||||
html-url-attributes@3.0.1:
|
html-url-attributes@3.0.1:
|
||||||
resolution: {integrity: sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==}
|
resolution: {integrity: sha512-ol6UPyBWqsrO6EJySPz2O7ZSr856WDrEzM5zMqp+FJJLGMW35cLYmmZnl0vztAZxRUoNZJFTCohfjuIJ8I4QBQ==}
|
||||||
|
|
||||||
|
html-void-elements@3.0.0:
|
||||||
|
resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==}
|
||||||
|
|
||||||
human-signals@5.0.0:
|
human-signals@5.0.0:
|
||||||
resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==}
|
resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==}
|
||||||
engines: {node: '>=16.17.0'}
|
engines: {node: '>=16.17.0'}
|
||||||
@@ -2457,9 +2493,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
|
resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
lowlight@3.3.0:
|
|
||||||
resolution: {integrity: sha512-0JNhgFoPvP6U6lE/UdVsSq99tn6DhjjpAj5MxG49ewd2mOBVtwWYIT8ClyABhq198aXXODMU6Ox8DrGy/CpTZQ==}
|
|
||||||
|
|
||||||
lru-cache@6.0.0:
|
lru-cache@6.0.0:
|
||||||
resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==}
|
resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==}
|
||||||
engines: {node: '>=10'}
|
engines: {node: '>=10'}
|
||||||
@@ -2529,6 +2562,9 @@ packages:
|
|||||||
mdast-util-to-string@4.0.0:
|
mdast-util-to-string@4.0.0:
|
||||||
resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==}
|
resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==}
|
||||||
|
|
||||||
|
mdast-util-toc@7.1.0:
|
||||||
|
resolution: {integrity: sha512-2TVKotOQzqdY7THOdn2gGzS9d1Sdd66bvxUyw3aNpWfcPXCLYSJCCgfPy30sEtuzkDraJgqF35dzgmz6xlvH/w==}
|
||||||
|
|
||||||
merge-stream@2.0.0:
|
merge-stream@2.0.0:
|
||||||
resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==}
|
resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==}
|
||||||
|
|
||||||
@@ -2805,6 +2841,9 @@ packages:
|
|||||||
parse-entities@4.0.2:
|
parse-entities@4.0.2:
|
||||||
resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==}
|
resolution: {integrity: sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==}
|
||||||
|
|
||||||
|
parse5@7.3.0:
|
||||||
|
resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==}
|
||||||
|
|
||||||
path-data-parser@0.1.0:
|
path-data-parser@0.1.0:
|
||||||
resolution: {integrity: sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w==}
|
resolution: {integrity: sha512-NOnmBpt5Y2RWbuv0LMzsayp3lVylAHLPUTut412ZA3l+C4uw4ZVkQbjShYCQ8TCpUMdPapr4YjUqLYD6v68j+w==}
|
||||||
|
|
||||||
@@ -2889,6 +2928,11 @@ packages:
|
|||||||
pretty-format@3.8.0:
|
pretty-format@3.8.0:
|
||||||
resolution: {integrity: sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==}
|
resolution: {integrity: sha512-WuxUnVtlWL1OfZFQFuqvnvs6MiAGk9UNsBostyBOB0Is9wb5uRESevA6rnl/rkksXaGX3GzZhPup5d6Vp1nFew==}
|
||||||
|
|
||||||
|
prism-react-renderer@2.4.1:
|
||||||
|
resolution: {integrity: sha512-ey8Ls/+Di31eqzUxC46h8MksNuGx/n0AAC8uKpwFau4RPDYLuE3EXTp8N8G2vX2N7UC/+IXeNUnlWBGGcAG+Ig==}
|
||||||
|
peerDependencies:
|
||||||
|
react: '>=16.0.0'
|
||||||
|
|
||||||
prisma@6.17.1:
|
prisma@6.17.1:
|
||||||
resolution: {integrity: sha512-ac6h0sM1Tg3zu8NInY+qhP/S9KhENVaw9n1BrGKQVFu05JT5yT5Qqqmb8tMRIE3ZXvVj4xcRA5yfrsy4X7Yy5g==}
|
resolution: {integrity: sha512-ac6h0sM1Tg3zu8NInY+qhP/S9KhENVaw9n1BrGKQVFu05JT5yT5Qqqmb8tMRIE3ZXvVj4xcRA5yfrsy4X7Yy5g==}
|
||||||
engines: {node: '>=18.18'}
|
engines: {node: '>=18.18'}
|
||||||
@@ -2902,6 +2946,9 @@ packages:
|
|||||||
prop-types@15.8.1:
|
prop-types@15.8.1:
|
||||||
resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
|
resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==}
|
||||||
|
|
||||||
|
property-information@6.5.0:
|
||||||
|
resolution: {integrity: sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==}
|
||||||
|
|
||||||
property-information@7.1.0:
|
property-information@7.1.0:
|
||||||
resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==}
|
resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==}
|
||||||
|
|
||||||
@@ -2979,12 +3026,15 @@ packages:
|
|||||||
resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==}
|
resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
|
|
||||||
rehype-highlight@7.0.2:
|
rehype-raw@7.0.0:
|
||||||
resolution: {integrity: sha512-k158pK7wdC2qL3M5NcZROZ2tR/l7zOzjxXd5VGdcfIyoijjQqpHd3JKtYSBDpDZ38UI2WJWuFAtkMDxmx5kstA==}
|
resolution: {integrity: sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==}
|
||||||
|
|
||||||
rehype-sanitize@6.0.0:
|
rehype-sanitize@6.0.0:
|
||||||
resolution: {integrity: sha512-CsnhKNsyI8Tub6L4sm5ZFsme4puGfc6pYylvXo1AeqaGbjOYyzNv3qZPwvs0oMJ39eryyeOdmxwUIo94IpEhqg==}
|
resolution: {integrity: sha512-CsnhKNsyI8Tub6L4sm5ZFsme4puGfc6pYylvXo1AeqaGbjOYyzNv3qZPwvs0oMJ39eryyeOdmxwUIo94IpEhqg==}
|
||||||
|
|
||||||
|
rehype-slug@6.0.0:
|
||||||
|
resolution: {integrity: sha512-lWyvf/jwu+oS5+hL5eClVd3hNdmwM1kAC0BUvEGD19pajQMIzcNUd/k9GsfQ+FfECvX+JE+e9/btsKH0EjJT6A==}
|
||||||
|
|
||||||
remark-gfm@4.0.1:
|
remark-gfm@4.0.1:
|
||||||
resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==}
|
resolution: {integrity: sha512-1quofZ2RQ9EWdeN34S79+KExV1764+wCUGop5CPL1WGdD0ocPpu91lzPGbwWMECpEpd42kJGQwzRfyov9j4yNg==}
|
||||||
|
|
||||||
@@ -2997,6 +3047,9 @@ packages:
|
|||||||
remark-stringify@11.0.0:
|
remark-stringify@11.0.0:
|
||||||
resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==}
|
resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==}
|
||||||
|
|
||||||
|
remark-toc@9.0.0:
|
||||||
|
resolution: {integrity: sha512-KJ9txbo33GjDAV1baHFze7ij4G8c7SGYoY8Kzsm2gzFpbhL/bSoVpMMzGa3vrNDSWASNd/3ppAqL7cP2zD6JIA==}
|
||||||
|
|
||||||
reselect@5.1.1:
|
reselect@5.1.1:
|
||||||
resolution: {integrity: sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==}
|
resolution: {integrity: sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==}
|
||||||
|
|
||||||
@@ -3319,9 +3372,6 @@ packages:
|
|||||||
unified@11.0.5:
|
unified@11.0.5:
|
||||||
resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==}
|
resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==}
|
||||||
|
|
||||||
unist-util-find-after@5.0.0:
|
|
||||||
resolution: {integrity: sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==}
|
|
||||||
|
|
||||||
unist-util-is@6.0.0:
|
unist-util-is@6.0.0:
|
||||||
resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==}
|
resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==}
|
||||||
|
|
||||||
@@ -3360,6 +3410,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==}
|
resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
|
|
||||||
|
vfile-location@5.0.3:
|
||||||
|
resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==}
|
||||||
|
|
||||||
vfile-message@4.0.3:
|
vfile-message@4.0.3:
|
||||||
resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==}
|
resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==}
|
||||||
|
|
||||||
@@ -3393,6 +3446,9 @@ packages:
|
|||||||
resolution: {integrity: sha512-3hu+tD8YzSLGuFYtPRb48vdhKMi0KQV5sn+uWr8+7dMEq/2G/dtLrdDinkLjqq5TIbIBjYJ4Ax/n3YiaW7QM8A==}
|
resolution: {integrity: sha512-3hu+tD8YzSLGuFYtPRb48vdhKMi0KQV5sn+uWr8+7dMEq/2G/dtLrdDinkLjqq5TIbIBjYJ4Ax/n3YiaW7QM8A==}
|
||||||
engines: {node: 20 || >=22}
|
engines: {node: 20 || >=22}
|
||||||
|
|
||||||
|
web-namespaces@2.0.1:
|
||||||
|
resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==}
|
||||||
|
|
||||||
which-boxed-primitive@1.1.1:
|
which-boxed-primitive@1.1.1:
|
||||||
resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==}
|
resolution: {integrity: sha512-TbX3mj8n0odCBFVlY8AxkqcHASw3L60jIuF8jFP78az3C2YhmGvqbHBpAjTRH2/xqYunrJ9g1jSyjCjpoWzIAA==}
|
||||||
engines: {node: '>= 0.4'}
|
engines: {node: '>= 0.4'}
|
||||||
@@ -4194,6 +4250,8 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
undici-types: 6.21.0
|
undici-types: 6.21.0
|
||||||
|
|
||||||
|
'@types/prismjs@1.26.5': {}
|
||||||
|
|
||||||
'@types/react-dom@19.2.2(@types/react@19.2.2)':
|
'@types/react-dom@19.2.2(@types/react@19.2.2)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/react': 19.2.2
|
'@types/react': 19.2.2
|
||||||
@@ -4205,6 +4263,8 @@ snapshots:
|
|||||||
'@types/trusted-types@2.0.7':
|
'@types/trusted-types@2.0.7':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
|
'@types/ungap__structured-clone@1.2.0': {}
|
||||||
|
|
||||||
'@types/unist@2.0.11': {}
|
'@types/unist@2.0.11': {}
|
||||||
|
|
||||||
'@types/unist@3.0.3': {}
|
'@types/unist@3.0.3': {}
|
||||||
@@ -4912,6 +4972,8 @@ snapshots:
|
|||||||
graceful-fs: 4.2.11
|
graceful-fs: 4.2.11
|
||||||
tapable: 2.3.0
|
tapable: 2.3.0
|
||||||
|
|
||||||
|
entities@6.0.1: {}
|
||||||
|
|
||||||
environment@1.1.0: {}
|
environment@1.1.0: {}
|
||||||
|
|
||||||
es-abstract@1.24.0:
|
es-abstract@1.24.0:
|
||||||
@@ -5398,6 +5460,8 @@ snapshots:
|
|||||||
nypm: 0.6.2
|
nypm: 0.6.2
|
||||||
pathe: 2.0.3
|
pathe: 2.0.3
|
||||||
|
|
||||||
|
github-slugger@2.0.0: {}
|
||||||
|
|
||||||
glob-parent@5.1.2:
|
glob-parent@5.1.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
is-glob: 4.0.3
|
is-glob: 4.0.3
|
||||||
@@ -5445,9 +5509,40 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
function-bind: 1.1.2
|
function-bind: 1.1.2
|
||||||
|
|
||||||
hast-util-is-element@3.0.0:
|
hast-util-from-parse5@8.0.3:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/hast': 3.0.4
|
'@types/hast': 3.0.4
|
||||||
|
'@types/unist': 3.0.3
|
||||||
|
devlop: 1.1.0
|
||||||
|
hastscript: 9.0.1
|
||||||
|
property-information: 7.1.0
|
||||||
|
vfile: 6.0.3
|
||||||
|
vfile-location: 5.0.3
|
||||||
|
web-namespaces: 2.0.1
|
||||||
|
|
||||||
|
hast-util-heading-rank@3.0.0:
|
||||||
|
dependencies:
|
||||||
|
'@types/hast': 3.0.4
|
||||||
|
|
||||||
|
hast-util-parse-selector@4.0.0:
|
||||||
|
dependencies:
|
||||||
|
'@types/hast': 3.0.4
|
||||||
|
|
||||||
|
hast-util-raw@9.1.0:
|
||||||
|
dependencies:
|
||||||
|
'@types/hast': 3.0.4
|
||||||
|
'@types/unist': 3.0.3
|
||||||
|
'@ungap/structured-clone': 1.3.0
|
||||||
|
hast-util-from-parse5: 8.0.3
|
||||||
|
hast-util-to-parse5: 8.0.0
|
||||||
|
html-void-elements: 3.0.0
|
||||||
|
mdast-util-to-hast: 13.2.0
|
||||||
|
parse5: 7.3.0
|
||||||
|
unist-util-position: 5.0.0
|
||||||
|
unist-util-visit: 5.0.0
|
||||||
|
vfile: 6.0.3
|
||||||
|
web-namespaces: 2.0.1
|
||||||
|
zwitch: 2.0.4
|
||||||
|
|
||||||
hast-util-sanitize@5.0.2:
|
hast-util-sanitize@5.0.2:
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -5475,21 +5570,36 @@ snapshots:
|
|||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- supports-color
|
- supports-color
|
||||||
|
|
||||||
hast-util-to-text@4.0.2:
|
hast-util-to-parse5@8.0.0:
|
||||||
|
dependencies:
|
||||||
|
'@types/hast': 3.0.4
|
||||||
|
comma-separated-tokens: 2.0.3
|
||||||
|
devlop: 1.1.0
|
||||||
|
property-information: 6.5.0
|
||||||
|
space-separated-tokens: 2.0.2
|
||||||
|
web-namespaces: 2.0.1
|
||||||
|
zwitch: 2.0.4
|
||||||
|
|
||||||
|
hast-util-to-string@3.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/hast': 3.0.4
|
'@types/hast': 3.0.4
|
||||||
'@types/unist': 3.0.3
|
|
||||||
hast-util-is-element: 3.0.0
|
|
||||||
unist-util-find-after: 5.0.0
|
|
||||||
|
|
||||||
hast-util-whitespace@3.0.0:
|
hast-util-whitespace@3.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/hast': 3.0.4
|
'@types/hast': 3.0.4
|
||||||
|
|
||||||
highlight.js@11.11.1: {}
|
hastscript@9.0.1:
|
||||||
|
dependencies:
|
||||||
|
'@types/hast': 3.0.4
|
||||||
|
comma-separated-tokens: 2.0.3
|
||||||
|
hast-util-parse-selector: 4.0.0
|
||||||
|
property-information: 7.1.0
|
||||||
|
space-separated-tokens: 2.0.2
|
||||||
|
|
||||||
html-url-attributes@3.0.1: {}
|
html-url-attributes@3.0.1: {}
|
||||||
|
|
||||||
|
html-void-elements@3.0.0: {}
|
||||||
|
|
||||||
human-signals@5.0.0: {}
|
human-signals@5.0.0: {}
|
||||||
|
|
||||||
husky@9.1.7: {}
|
husky@9.1.7: {}
|
||||||
@@ -5857,12 +5967,6 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
js-tokens: 4.0.0
|
js-tokens: 4.0.0
|
||||||
|
|
||||||
lowlight@3.3.0:
|
|
||||||
dependencies:
|
|
||||||
'@types/hast': 3.0.4
|
|
||||||
devlop: 1.1.0
|
|
||||||
highlight.js: 11.11.1
|
|
||||||
|
|
||||||
lru-cache@6.0.0:
|
lru-cache@6.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
yallist: 4.0.0
|
yallist: 4.0.0
|
||||||
@@ -6034,6 +6138,16 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@types/mdast': 4.0.4
|
'@types/mdast': 4.0.4
|
||||||
|
|
||||||
|
mdast-util-toc@7.1.0:
|
||||||
|
dependencies:
|
||||||
|
'@types/mdast': 4.0.4
|
||||||
|
'@types/ungap__structured-clone': 1.2.0
|
||||||
|
'@ungap/structured-clone': 1.3.0
|
||||||
|
github-slugger: 2.0.0
|
||||||
|
mdast-util-to-string: 4.0.0
|
||||||
|
unist-util-is: 6.0.0
|
||||||
|
unist-util-visit: 5.0.0
|
||||||
|
|
||||||
merge-stream@2.0.0: {}
|
merge-stream@2.0.0: {}
|
||||||
|
|
||||||
merge2@1.4.1: {}
|
merge2@1.4.1: {}
|
||||||
@@ -6472,6 +6586,10 @@ snapshots:
|
|||||||
is-decimal: 2.0.1
|
is-decimal: 2.0.1
|
||||||
is-hexadecimal: 2.0.1
|
is-hexadecimal: 2.0.1
|
||||||
|
|
||||||
|
parse5@7.3.0:
|
||||||
|
dependencies:
|
||||||
|
entities: 6.0.1
|
||||||
|
|
||||||
path-data-parser@0.1.0: {}
|
path-data-parser@0.1.0: {}
|
||||||
|
|
||||||
path-exists@4.0.0: {}
|
path-exists@4.0.0: {}
|
||||||
@@ -6540,6 +6658,12 @@ snapshots:
|
|||||||
|
|
||||||
pretty-format@3.8.0: {}
|
pretty-format@3.8.0: {}
|
||||||
|
|
||||||
|
prism-react-renderer@2.4.1(react@19.1.0):
|
||||||
|
dependencies:
|
||||||
|
'@types/prismjs': 1.26.5
|
||||||
|
clsx: 2.1.1
|
||||||
|
react: 19.1.0
|
||||||
|
|
||||||
prisma@6.17.1(typescript@5.9.3):
|
prisma@6.17.1(typescript@5.9.3):
|
||||||
dependencies:
|
dependencies:
|
||||||
'@prisma/config': 6.17.1
|
'@prisma/config': 6.17.1
|
||||||
@@ -6555,6 +6679,8 @@ snapshots:
|
|||||||
object-assign: 4.1.1
|
object-assign: 4.1.1
|
||||||
react-is: 16.13.1
|
react-is: 16.13.1
|
||||||
|
|
||||||
|
property-information@6.5.0: {}
|
||||||
|
|
||||||
property-information@7.1.0: {}
|
property-information@7.1.0: {}
|
||||||
|
|
||||||
punycode@2.3.1: {}
|
punycode@2.3.1: {}
|
||||||
@@ -6654,12 +6780,10 @@ snapshots:
|
|||||||
gopd: 1.2.0
|
gopd: 1.2.0
|
||||||
set-function-name: 2.0.2
|
set-function-name: 2.0.2
|
||||||
|
|
||||||
rehype-highlight@7.0.2:
|
rehype-raw@7.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/hast': 3.0.4
|
'@types/hast': 3.0.4
|
||||||
hast-util-to-text: 4.0.2
|
hast-util-raw: 9.1.0
|
||||||
lowlight: 3.3.0
|
|
||||||
unist-util-visit: 5.0.0
|
|
||||||
vfile: 6.0.3
|
vfile: 6.0.3
|
||||||
|
|
||||||
rehype-sanitize@6.0.0:
|
rehype-sanitize@6.0.0:
|
||||||
@@ -6667,6 +6791,14 @@ snapshots:
|
|||||||
'@types/hast': 3.0.4
|
'@types/hast': 3.0.4
|
||||||
hast-util-sanitize: 5.0.2
|
hast-util-sanitize: 5.0.2
|
||||||
|
|
||||||
|
rehype-slug@6.0.0:
|
||||||
|
dependencies:
|
||||||
|
'@types/hast': 3.0.4
|
||||||
|
github-slugger: 2.0.0
|
||||||
|
hast-util-heading-rank: 3.0.0
|
||||||
|
hast-util-to-string: 3.0.1
|
||||||
|
unist-util-visit: 5.0.0
|
||||||
|
|
||||||
remark-gfm@4.0.1:
|
remark-gfm@4.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/mdast': 4.0.4
|
'@types/mdast': 4.0.4
|
||||||
@@ -6701,6 +6833,11 @@ snapshots:
|
|||||||
mdast-util-to-markdown: 2.1.2
|
mdast-util-to-markdown: 2.1.2
|
||||||
unified: 11.0.5
|
unified: 11.0.5
|
||||||
|
|
||||||
|
remark-toc@9.0.0:
|
||||||
|
dependencies:
|
||||||
|
'@types/mdast': 4.0.4
|
||||||
|
mdast-util-toc: 7.1.0
|
||||||
|
|
||||||
reselect@5.1.1: {}
|
reselect@5.1.1: {}
|
||||||
|
|
||||||
resolve-from@4.0.0: {}
|
resolve-from@4.0.0: {}
|
||||||
@@ -7099,11 +7236,6 @@ snapshots:
|
|||||||
trough: 2.2.0
|
trough: 2.2.0
|
||||||
vfile: 6.0.3
|
vfile: 6.0.3
|
||||||
|
|
||||||
unist-util-find-after@5.0.0:
|
|
||||||
dependencies:
|
|
||||||
'@types/unist': 3.0.3
|
|
||||||
unist-util-is: 6.0.0
|
|
||||||
|
|
||||||
unist-util-is@6.0.0:
|
unist-util-is@6.0.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/unist': 3.0.3
|
'@types/unist': 3.0.3
|
||||||
@@ -7165,6 +7297,11 @@ snapshots:
|
|||||||
|
|
||||||
uuid@8.3.2: {}
|
uuid@8.3.2: {}
|
||||||
|
|
||||||
|
vfile-location@5.0.3:
|
||||||
|
dependencies:
|
||||||
|
'@types/unist': 3.0.3
|
||||||
|
vfile: 6.0.3
|
||||||
|
|
||||||
vfile-message@4.0.3:
|
vfile-message@4.0.3:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/unist': 3.0.3
|
'@types/unist': 3.0.3
|
||||||
@@ -7211,6 +7348,8 @@ snapshots:
|
|||||||
|
|
||||||
walk-up-path@4.0.0: {}
|
walk-up-path@4.0.0: {}
|
||||||
|
|
||||||
|
web-namespaces@2.0.1: {}
|
||||||
|
|
||||||
which-boxed-primitive@1.1.1:
|
which-boxed-primitive@1.1.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
is-bigint: 1.1.0
|
is-bigint: 1.1.0
|
||||||
|
|||||||
@@ -4,14 +4,274 @@ import { useState, useEffect, useCallback, useRef } from 'react';
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import ReactMarkdown from 'react-markdown';
|
import ReactMarkdown from 'react-markdown';
|
||||||
import remarkGfm from 'remark-gfm';
|
import remarkGfm from 'remark-gfm';
|
||||||
import rehypeHighlight from 'rehype-highlight';
|
import remarkToc from 'remark-toc';
|
||||||
|
import rehypeRaw from 'rehype-raw';
|
||||||
|
import rehypeSlug from 'rehype-slug';
|
||||||
import rehypeSanitize from 'rehype-sanitize';
|
import rehypeSanitize from 'rehype-sanitize';
|
||||||
|
import { Highlight, themes } from 'prism-react-renderer';
|
||||||
import { Eye, EyeOff, Edit3, X, CheckSquare2 } from 'lucide-react';
|
import { Eye, EyeOff, Edit3, X, CheckSquare2 } from 'lucide-react';
|
||||||
import { TagInput } from '@/components/ui/TagInput';
|
import { TagInput } from '@/components/ui/TagInput';
|
||||||
import { TagDisplay } from '@/components/ui/TagDisplay';
|
import { TagDisplay } from '@/components/ui/TagDisplay';
|
||||||
import { TaskSelectorWithData } from '@/components/shared/TaskSelectorWithData';
|
import { TaskSelectorWithData } from '@/components/shared/TaskSelectorWithData';
|
||||||
import { MermaidRenderer } from '@/components/ui/MermaidRenderer';
|
import { MermaidRenderer } from '@/components/ui/MermaidRenderer';
|
||||||
import { Tag, Task } from '@/lib/types';
|
import { Tag, Task } from '@/lib/types';
|
||||||
|
import type { Components } from 'react-markdown';
|
||||||
|
|
||||||
|
// Fonction pour générer les composants Markdown réutilisables
|
||||||
|
const createMarkdownComponents = (
|
||||||
|
isPreviewMode: boolean
|
||||||
|
): Partial<Components> => ({
|
||||||
|
// Titres avec tailles différentes selon le mode
|
||||||
|
h1: ({ children }: { children?: React.ReactNode }) => (
|
||||||
|
<h1
|
||||||
|
className={
|
||||||
|
isPreviewMode
|
||||||
|
? 'text-4xl font-bold text-[var(--foreground)] mb-8 mt-10 first:mt-0 bg-gradient-to-r from-[var(--primary)] to-[var(--accent)] bg-clip-text text-transparent'
|
||||||
|
: 'text-4xl font-bold text-[var(--foreground)] mb-8 mt-10 first:mt-0 bg-gradient-to-r from-[var(--primary)] to-[var(--accent)] bg-clip-text text-transparent'
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</h1>
|
||||||
|
),
|
||||||
|
h2: ({ children }: { children?: React.ReactNode }) => (
|
||||||
|
<h2
|
||||||
|
className={
|
||||||
|
isPreviewMode
|
||||||
|
? 'text-3xl font-bold text-[var(--foreground)] mb-6 mt-8 border-b border-[var(--border)]/30 pb-2'
|
||||||
|
: 'text-3xl font-bold text-[var(--foreground)] mb-6 mt-8 border-b border-[var(--border)]/30 pb-2'
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</h2>
|
||||||
|
),
|
||||||
|
h3: ({ children }: { children?: React.ReactNode }) => (
|
||||||
|
<h3
|
||||||
|
className={
|
||||||
|
isPreviewMode
|
||||||
|
? 'text-2xl font-semibold text-[var(--foreground)] mb-4 mt-6'
|
||||||
|
: 'text-2xl font-semibold text-[var(--foreground)] mb-4 mt-6'
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</h3>
|
||||||
|
),
|
||||||
|
h4: ({ children }: { children?: React.ReactNode }) => (
|
||||||
|
<h4
|
||||||
|
className={
|
||||||
|
isPreviewMode
|
||||||
|
? 'text-xl font-semibold text-[var(--foreground)] mb-3 mt-5'
|
||||||
|
: 'text-xl font-semibold text-[var(--foreground)] mb-3 mt-5'
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</h4>
|
||||||
|
),
|
||||||
|
h5: ({ children }: { children?: React.ReactNode }) => (
|
||||||
|
<h5
|
||||||
|
className={
|
||||||
|
isPreviewMode
|
||||||
|
? 'text-lg font-semibold text-[var(--foreground)] mb-2 mt-4'
|
||||||
|
: 'text-lg font-semibold text-[var(--foreground)] mb-2 mt-4'
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</h5>
|
||||||
|
),
|
||||||
|
h6: ({ children }: { children?: React.ReactNode }) => (
|
||||||
|
<h6
|
||||||
|
className={
|
||||||
|
isPreviewMode
|
||||||
|
? 'text-base font-semibold text-[var(--foreground)] mb-2 mt-3 text-[var(--muted-foreground)]'
|
||||||
|
: 'text-base font-semibold text-[var(--foreground)] mb-2 mt-3 text-[var(--muted-foreground)]'
|
||||||
|
}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</h6>
|
||||||
|
),
|
||||||
|
p: ({ children }: { children?: React.ReactNode }) => (
|
||||||
|
<p className="text-[var(--foreground)] mb-4 leading-relaxed">{children}</p>
|
||||||
|
),
|
||||||
|
// Listes avec le même style partout
|
||||||
|
ul: ({ children }: { children?: React.ReactNode }) => (
|
||||||
|
<ul className="mb-0 pl-4">{children}</ul>
|
||||||
|
),
|
||||||
|
ol: ({ children }: { children?: React.ReactNode }) => (
|
||||||
|
<ol className="mb-0 pl-4 list-decimal list-inside">{children}</ol>
|
||||||
|
),
|
||||||
|
li: ({
|
||||||
|
children,
|
||||||
|
className,
|
||||||
|
}: {
|
||||||
|
children?: React.ReactNode;
|
||||||
|
className?: string;
|
||||||
|
}) => {
|
||||||
|
const isTaskListItem = className?.includes('task-list-item');
|
||||||
|
|
||||||
|
if (isTaskListItem) {
|
||||||
|
return (
|
||||||
|
<li className="!m-0 py-0.5 text-[var(--foreground)]">{children}</li>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<li className="!m-0 py-0.5 text-[var(--foreground)] flex items-start gap-2">
|
||||||
|
<span className="w-1.5 h-1.5 bg-[var(--primary)] rounded-full mt-2 flex-shrink-0"></span>
|
||||||
|
<span>{children}</span>
|
||||||
|
</li>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
blockquote: ({ children }: { children?: React.ReactNode }) => (
|
||||||
|
<blockquote className="border-l-4 border-[var(--primary)] pl-4 py-2 my-4 bg-[var(--card)]/20 backdrop-blur-sm rounded-r-lg">
|
||||||
|
<div className="text-[var(--muted-foreground)] italic">{children}</div>
|
||||||
|
</blockquote>
|
||||||
|
),
|
||||||
|
code: (({
|
||||||
|
inline,
|
||||||
|
className,
|
||||||
|
children,
|
||||||
|
...props
|
||||||
|
}: {
|
||||||
|
inline?: boolean;
|
||||||
|
className?: string;
|
||||||
|
children?: React.ReactNode;
|
||||||
|
} & Record<string, unknown>) => {
|
||||||
|
if (inline) {
|
||||||
|
return (
|
||||||
|
<code className="bg-[var(--card)]/60 px-2 py-1 rounded text-[var(--accent)] font-mono text-sm border border-[var(--border)]/40">
|
||||||
|
{children}
|
||||||
|
</code>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<code className={className} {...props}>
|
||||||
|
{children}
|
||||||
|
</code>
|
||||||
|
);
|
||||||
|
}) as Components['code'],
|
||||||
|
pre: ({ children }: { children?: React.ReactNode }) => {
|
||||||
|
let codeElement: string | null = null;
|
||||||
|
let className = '';
|
||||||
|
|
||||||
|
if (React.isValidElement(children)) {
|
||||||
|
const props = children.props as {
|
||||||
|
children?: string;
|
||||||
|
className?: string;
|
||||||
|
};
|
||||||
|
codeElement = props?.children || null;
|
||||||
|
className = props?.className || '';
|
||||||
|
}
|
||||||
|
|
||||||
|
const isMermaid =
|
||||||
|
className.includes('language-mermaid') ||
|
||||||
|
(typeof codeElement === 'string' &&
|
||||||
|
(codeElement.trim().startsWith('graph') ||
|
||||||
|
codeElement.trim().startsWith('flowchart') ||
|
||||||
|
codeElement.trim().startsWith('sequenceDiagram') ||
|
||||||
|
codeElement.trim().startsWith('gantt') ||
|
||||||
|
codeElement.trim().startsWith('pie') ||
|
||||||
|
codeElement.trim().startsWith('gitgraph') ||
|
||||||
|
codeElement.trim().startsWith('journey') ||
|
||||||
|
codeElement.trim().startsWith('stateDiagram') ||
|
||||||
|
codeElement.trim().startsWith('classDiagram') ||
|
||||||
|
codeElement.trim().startsWith('erDiagram') ||
|
||||||
|
codeElement.trim().startsWith('mindmap') ||
|
||||||
|
codeElement.trim().startsWith('timeline')));
|
||||||
|
|
||||||
|
if (isMermaid && typeof codeElement === 'string') {
|
||||||
|
return (
|
||||||
|
<div className="my-6">
|
||||||
|
<MermaidRenderer chart={codeElement} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const match = /language-(\w+)/.exec(className || '');
|
||||||
|
const language = match ? match[1] : 'javascript';
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Highlight
|
||||||
|
theme={themes.vsDark}
|
||||||
|
code={codeElement || ''}
|
||||||
|
language={language}
|
||||||
|
>
|
||||||
|
{({
|
||||||
|
className: highlightClassName,
|
||||||
|
style,
|
||||||
|
tokens,
|
||||||
|
getLineProps,
|
||||||
|
getTokenProps,
|
||||||
|
}) => {
|
||||||
|
// Supprimer les lignes vides à la fin
|
||||||
|
const filteredTokens = tokens.filter((line, i) => {
|
||||||
|
// Garder toutes les lignes sauf la dernière si elle est vide
|
||||||
|
if (i === tokens.length - 1) {
|
||||||
|
return (
|
||||||
|
line.length > 0 &&
|
||||||
|
line.some((token) => token.content.trim() !== '')
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<pre
|
||||||
|
className="bg-[var(--card)]/60 border border-[var(--border)]/60 rounded-lg p-4 overflow-x-auto backdrop-blur-sm font-mono text-sm mb-6"
|
||||||
|
style={{
|
||||||
|
...style,
|
||||||
|
background: 'color-mix(in srgb, var(--card) 80%, transparent)',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<code className={highlightClassName}>
|
||||||
|
{filteredTokens.map((line, i) => (
|
||||||
|
<div key={i} {...getLineProps({ line })}>
|
||||||
|
{line.map((token, key) => (
|
||||||
|
<span key={key} {...getTokenProps({ token })} />
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</code>
|
||||||
|
</pre>
|
||||||
|
);
|
||||||
|
}}
|
||||||
|
</Highlight>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
a: ({ children, href }: { children?: React.ReactNode; href?: string }) => (
|
||||||
|
<a
|
||||||
|
href={href}
|
||||||
|
className="text-[var(--primary)] hover:text-[var(--primary)]/80 underline decoration-[var(--primary)]/50 hover:decoration-[var(--primary)] transition-colors"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
</a>
|
||||||
|
),
|
||||||
|
table: ({ children }: { children?: React.ReactNode }) => (
|
||||||
|
<div className="overflow-x-auto my-6">
|
||||||
|
<table className="min-w-full border border-[var(--border)]/60 rounded-lg overflow-hidden">
|
||||||
|
{children}
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
|
),
|
||||||
|
thead: ({ children }: { children?: React.ReactNode }) => (
|
||||||
|
<thead className="bg-[var(--card)]/40">{children}</thead>
|
||||||
|
),
|
||||||
|
tbody: ({ children }: { children?: React.ReactNode }) => (
|
||||||
|
<tbody className="divide-y divide-[var(--border)]/60">{children}</tbody>
|
||||||
|
),
|
||||||
|
tr: ({ children }: { children?: React.ReactNode }) => (
|
||||||
|
<tr className="hover:bg-[var(--card)]/20 transition-colors">{children}</tr>
|
||||||
|
),
|
||||||
|
th: ({ children }: { children?: React.ReactNode }) => (
|
||||||
|
<th className="px-4 py-2 text-left text-[var(--foreground)] font-semibold border-b border-[var(--border)]/60">
|
||||||
|
{children}
|
||||||
|
</th>
|
||||||
|
),
|
||||||
|
td: ({ children }: { children?: React.ReactNode }) => (
|
||||||
|
<td className="px-4 py-2 text-[var(--foreground)]">{children}</td>
|
||||||
|
),
|
||||||
|
hr: () => <hr className="my-8 border-t-2 border-[var(--border)]/30" />,
|
||||||
|
});
|
||||||
|
|
||||||
interface MarkdownEditorProps {
|
interface MarkdownEditorProps {
|
||||||
value: string;
|
value: string;
|
||||||
@@ -444,161 +704,18 @@ export function MarkdownEditor({
|
|||||||
<div className="flex-1 overflow-auto p-6 bg-[var(--background)]/50 backdrop-blur-sm">
|
<div className="flex-1 overflow-auto p-6 bg-[var(--background)]/50 backdrop-blur-sm">
|
||||||
<div className="prose prose-sm max-w-none prose-headings:text-[var(--foreground)] prose-p:text-[var(--foreground)] prose-strong:text-[var(--foreground)] prose-strong:font-bold prose-em:text-[var(--muted-foreground)] prose-code:text-[var(--accent)] prose-pre:bg-[var(--card)]/60 prose-pre:border prose-pre:border-[var(--border)]/60 prose-blockquote:border-[var(--primary)] prose-blockquote:text-[var(--muted-foreground)] prose-a:text-[var(--primary)] prose-table:border-[var(--border)]/60 prose-th:bg-[var(--card)]/40 prose-th:text-[var(--foreground)] prose-td:text-[var(--foreground)]">
|
<div className="prose prose-sm max-w-none prose-headings:text-[var(--foreground)] prose-p:text-[var(--foreground)] prose-strong:text-[var(--foreground)] prose-strong:font-bold prose-em:text-[var(--muted-foreground)] prose-code:text-[var(--accent)] prose-pre:bg-[var(--card)]/60 prose-pre:border prose-pre:border-[var(--border)]/60 prose-blockquote:border-[var(--primary)] prose-blockquote:text-[var(--muted-foreground)] prose-a:text-[var(--primary)] prose-table:border-[var(--border)]/60 prose-th:bg-[var(--card)]/40 prose-th:text-[var(--foreground)] prose-td:text-[var(--foreground)]">
|
||||||
<ReactMarkdown
|
<ReactMarkdown
|
||||||
remarkPlugins={[remarkGfm]}
|
remarkPlugins={[
|
||||||
rehypePlugins={[rehypeHighlight, rehypeSanitize]}
|
remarkGfm,
|
||||||
components={{
|
[
|
||||||
// Custom styling for better integration
|
remarkToc,
|
||||||
h1: ({ children }) => (
|
{
|
||||||
<h1 className="text-3xl font-bold text-[var(--foreground)] mb-6 mt-8 first:mt-0 bg-gradient-to-r from-[var(--primary)] to-[var(--accent)] bg-clip-text text-transparent">
|
heading: '(table[ -]of[ -])?contents?|toc|sommaire',
|
||||||
{children}
|
tight: true,
|
||||||
</h1>
|
},
|
||||||
),
|
],
|
||||||
h2: ({ children }) => (
|
]}
|
||||||
<h2 className="text-2xl font-bold text-[var(--foreground)] mb-4 mt-6 border-b border-[var(--border)]/30 pb-2">
|
rehypePlugins={[rehypeRaw, rehypeSlug, rehypeSanitize]}
|
||||||
{children}
|
components={createMarkdownComponents(true)}
|
||||||
</h2>
|
|
||||||
),
|
|
||||||
h3: ({ children }) => (
|
|
||||||
<h3 className="text-xl font-semibold text-[var(--foreground)] mb-3 mt-5 flex items-center gap-2">
|
|
||||||
<span className="w-2 h-2 bg-[var(--primary)] rounded-full"></span>
|
|
||||||
{children}
|
|
||||||
</h3>
|
|
||||||
),
|
|
||||||
h4: ({ children }) => (
|
|
||||||
<h4 className="text-lg font-semibold text-[var(--foreground)] mb-2 mt-4">
|
|
||||||
{children}
|
|
||||||
</h4>
|
|
||||||
),
|
|
||||||
h5: ({ children }) => (
|
|
||||||
<h5 className="text-base font-semibold text-[var(--foreground)] mb-2 mt-3">
|
|
||||||
{children}
|
|
||||||
</h5>
|
|
||||||
),
|
|
||||||
h6: ({ children }) => (
|
|
||||||
<h6 className="text-sm font-semibold text-[var(--foreground)] mb-2 mt-3 text-[var(--muted-foreground)]">
|
|
||||||
{children}
|
|
||||||
</h6>
|
|
||||||
),
|
|
||||||
p: ({ children }) => (
|
|
||||||
<p className="text-[var(--foreground)] mb-4 leading-relaxed">
|
|
||||||
{children}
|
|
||||||
</p>
|
|
||||||
),
|
|
||||||
ul: ({ children }) => (
|
|
||||||
<ul className="mb-4 space-y-2">{children}</ul>
|
|
||||||
),
|
|
||||||
ol: ({ children }) => (
|
|
||||||
<ol className="mb-4 space-y-2 list-decimal list-inside">
|
|
||||||
{children}
|
|
||||||
</ol>
|
|
||||||
),
|
|
||||||
li: ({ children }) => (
|
|
||||||
<li className="text-[var(--foreground)] flex items-start gap-2">
|
|
||||||
<span className="w-1.5 h-1.5 bg-[var(--primary)] rounded-full mt-2 flex-shrink-0"></span>
|
|
||||||
<span>{children}</span>
|
|
||||||
</li>
|
|
||||||
),
|
|
||||||
blockquote: ({ children }) => (
|
|
||||||
<blockquote className="border-l-4 border-[var(--primary)] pl-4 py-2 my-4 bg-[var(--card)]/20 backdrop-blur-sm rounded-r-lg">
|
|
||||||
<div className="text-[var(--muted-foreground)] italic">
|
|
||||||
{children}
|
|
||||||
</div>
|
|
||||||
</blockquote>
|
|
||||||
),
|
|
||||||
code: ({ children, className }) => {
|
|
||||||
const isInline = !className;
|
|
||||||
if (isInline) {
|
|
||||||
return (
|
|
||||||
<code className="bg-[var(--card)]/60 px-2 py-1 rounded text-[var(--accent)] font-mono text-sm border border-[var(--border)]/40">
|
|
||||||
{children}
|
|
||||||
</code>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return <code className={className}>{children}</code>;
|
|
||||||
},
|
|
||||||
pre: ({ children }) => {
|
|
||||||
// Check if this is a mermaid code block
|
|
||||||
let codeElement: string | null = null;
|
|
||||||
let className = '';
|
|
||||||
|
|
||||||
if (React.isValidElement(children)) {
|
|
||||||
const props = children.props as {
|
|
||||||
children?: string;
|
|
||||||
className?: string;
|
|
||||||
};
|
|
||||||
codeElement = props?.children || null;
|
|
||||||
className = props?.className || '';
|
|
||||||
}
|
|
||||||
|
|
||||||
const isMermaid =
|
|
||||||
className.includes('language-mermaid') ||
|
|
||||||
(typeof codeElement === 'string' &&
|
|
||||||
(codeElement.trim().startsWith('graph') ||
|
|
||||||
codeElement.trim().startsWith('flowchart') ||
|
|
||||||
codeElement.trim().startsWith('sequenceDiagram') ||
|
|
||||||
codeElement.trim().startsWith('gantt') ||
|
|
||||||
codeElement.trim().startsWith('pie') ||
|
|
||||||
codeElement.trim().startsWith('gitgraph') ||
|
|
||||||
codeElement.trim().startsWith('journey') ||
|
|
||||||
codeElement.trim().startsWith('stateDiagram') ||
|
|
||||||
codeElement.trim().startsWith('classDiagram') ||
|
|
||||||
codeElement.trim().startsWith('erDiagram') ||
|
|
||||||
codeElement.trim().startsWith('mindmap') ||
|
|
||||||
codeElement.trim().startsWith('timeline')));
|
|
||||||
|
|
||||||
if (isMermaid && typeof codeElement === 'string') {
|
|
||||||
return (
|
|
||||||
<div className="my-6">
|
|
||||||
<MermaidRenderer chart={codeElement} />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<pre className="bg-[var(--card)]/60 border border-[var(--border)]/60 rounded-lg p-4 overflow-x-auto backdrop-blur-sm">
|
|
||||||
{children}
|
|
||||||
</pre>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
a: ({ children, href }) => (
|
|
||||||
<a
|
|
||||||
href={href}
|
|
||||||
className="text-[var(--primary)] hover:text-[var(--primary)]/80 underline decoration-[var(--primary)]/50 hover:decoration-[var(--primary)] transition-colors"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</a>
|
|
||||||
),
|
|
||||||
table: ({ children }) => (
|
|
||||||
<div className="overflow-x-auto mb-6 rounded-lg border border-[var(--border)]/60">
|
|
||||||
<table className="min-w-full">{children}</table>
|
|
||||||
</div>
|
|
||||||
),
|
|
||||||
th: ({ children }) => (
|
|
||||||
<th className="border-b border-[var(--border)]/60 bg-[var(--card)]/40 px-4 py-3 text-left font-semibold text-[var(--foreground)] backdrop-blur-sm">
|
|
||||||
{children}
|
|
||||||
</th>
|
|
||||||
),
|
|
||||||
td: ({ children }) => (
|
|
||||||
<td className="border-b border-[var(--border)]/30 px-4 py-3 text-[var(--foreground)]">
|
|
||||||
{children}
|
|
||||||
</td>
|
|
||||||
),
|
|
||||||
hr: () => (
|
|
||||||
<hr className="my-8 border-0 h-px bg-gradient-to-r from-transparent via-[var(--border)] to-transparent" />
|
|
||||||
),
|
|
||||||
strong: ({ children }) => (
|
|
||||||
<strong className="font-bold text-[var(--foreground)]">
|
|
||||||
{children}
|
|
||||||
</strong>
|
|
||||||
),
|
|
||||||
em: ({ children }) => (
|
|
||||||
<em className="italic text-[var(--muted-foreground)]">
|
|
||||||
{children}
|
|
||||||
</em>
|
|
||||||
),
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{value || "*Commencez à écrire pour voir l'aperçu...*"}
|
{value || "*Commencez à écrire pour voir l'aperçu...*"}
|
||||||
</ReactMarkdown>
|
</ReactMarkdown>
|
||||||
@@ -670,163 +787,18 @@ export function MarkdownEditor({
|
|||||||
<div className="flex-1 overflow-auto p-6 bg-[var(--background)]/50 backdrop-blur-sm">
|
<div className="flex-1 overflow-auto p-6 bg-[var(--background)]/50 backdrop-blur-sm">
|
||||||
<div className="prose prose-sm max-w-none prose-headings:text-[var(--foreground)] prose-p:text-[var(--foreground)] prose-strong:text-[var(--foreground)] prose-strong:font-bold prose-em:text-[var(--muted-foreground)] prose-code:text-[var(--accent)] prose-pre:bg-[var(--card)]/60 prose-pre:border prose-pre:border-[var(--border)]/60 prose-blockquote:border-[var(--primary)] prose-blockquote:text-[var(--muted-foreground)] prose-a:text-[var(--primary)] prose-table:border-[var(--border)]/60 prose-th:bg-[var(--card)]/40 prose-th:text-[var(--foreground)] prose-td:text-[var(--foreground)]">
|
<div className="prose prose-sm max-w-none prose-headings:text-[var(--foreground)] prose-p:text-[var(--foreground)] prose-strong:text-[var(--foreground)] prose-strong:font-bold prose-em:text-[var(--muted-foreground)] prose-code:text-[var(--accent)] prose-pre:bg-[var(--card)]/60 prose-pre:border prose-pre:border-[var(--border)]/60 prose-blockquote:border-[var(--primary)] prose-blockquote:text-[var(--muted-foreground)] prose-a:text-[var(--primary)] prose-table:border-[var(--border)]/60 prose-th:bg-[var(--card)]/40 prose-th:text-[var(--foreground)] prose-td:text-[var(--foreground)]">
|
||||||
<ReactMarkdown
|
<ReactMarkdown
|
||||||
remarkPlugins={[remarkGfm]}
|
remarkPlugins={[
|
||||||
rehypePlugins={[rehypeHighlight, rehypeSanitize]}
|
remarkGfm,
|
||||||
components={{
|
[
|
||||||
// Custom styling for better integration
|
remarkToc,
|
||||||
h1: ({ children }) => (
|
{
|
||||||
<h1 className="text-3xl font-bold text-[var(--foreground)] mb-6 mt-8 first:mt-0 bg-gradient-to-r from-[var(--primary)] to-[var(--accent)] bg-clip-text text-transparent">
|
heading: '(table[ -]of[ -])?contents?|toc|sommaire',
|
||||||
{children}
|
tight: true,
|
||||||
</h1>
|
},
|
||||||
),
|
],
|
||||||
h2: ({ children }) => (
|
]}
|
||||||
<h2 className="text-2xl font-bold text-[var(--foreground)] mb-4 mt-6 border-b border-[var(--border)]/30 pb-2">
|
rehypePlugins={[rehypeRaw, rehypeSlug, rehypeSanitize]}
|
||||||
{children}
|
components={createMarkdownComponents(false)}
|
||||||
</h2>
|
|
||||||
),
|
|
||||||
h3: ({ children }) => (
|
|
||||||
<h3 className="text-xl font-semibold text-[var(--foreground)] mb-3 mt-5 flex items-center gap-2">
|
|
||||||
<span className="w-2 h-2 bg-[var(--primary)] rounded-full"></span>
|
|
||||||
{children}
|
|
||||||
</h3>
|
|
||||||
),
|
|
||||||
h4: ({ children }) => (
|
|
||||||
<h4 className="text-lg font-semibold text-[var(--foreground)] mb-2 mt-4">
|
|
||||||
{children}
|
|
||||||
</h4>
|
|
||||||
),
|
|
||||||
h5: ({ children }) => (
|
|
||||||
<h5 className="text-base font-semibold text-[var(--foreground)] mb-2 mt-3">
|
|
||||||
{children}
|
|
||||||
</h5>
|
|
||||||
),
|
|
||||||
h6: ({ children }) => (
|
|
||||||
<h6 className="text-sm font-semibold text-[var(--foreground)] mb-2 mt-3 text-[var(--muted-foreground)]">
|
|
||||||
{children}
|
|
||||||
</h6>
|
|
||||||
),
|
|
||||||
p: ({ children }) => (
|
|
||||||
<p className="text-[var(--foreground)] mb-4 leading-relaxed">
|
|
||||||
{children}
|
|
||||||
</p>
|
|
||||||
),
|
|
||||||
ul: ({ children }) => (
|
|
||||||
<ul className="mb-4 space-y-2">{children}</ul>
|
|
||||||
),
|
|
||||||
ol: ({ children }) => (
|
|
||||||
<ol className="mb-4 space-y-2 list-decimal list-inside">
|
|
||||||
{children}
|
|
||||||
</ol>
|
|
||||||
),
|
|
||||||
li: ({ children }) => (
|
|
||||||
<li className="text-[var(--foreground)] flex items-start gap-2">
|
|
||||||
<span className="w-1.5 h-1.5 bg-[var(--primary)] rounded-full mt-2 flex-shrink-0"></span>
|
|
||||||
<span>{children}</span>
|
|
||||||
</li>
|
|
||||||
),
|
|
||||||
blockquote: ({ children }) => (
|
|
||||||
<blockquote className="border-l-4 border-[var(--primary)] pl-4 py-2 my-4 bg-[var(--card)]/20 backdrop-blur-sm rounded-r-lg">
|
|
||||||
<div className="text-[var(--muted-foreground)] italic">
|
|
||||||
{children}
|
|
||||||
</div>
|
|
||||||
</blockquote>
|
|
||||||
),
|
|
||||||
code: ({ children, className }) => {
|
|
||||||
const isInline = !className;
|
|
||||||
if (isInline) {
|
|
||||||
return (
|
|
||||||
<code className="bg-[var(--card)]/60 px-2 py-1 rounded text-[var(--accent)] font-mono text-sm border border-[var(--border)]/40">
|
|
||||||
{children}
|
|
||||||
</code>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return <code className={className}>{children}</code>;
|
|
||||||
},
|
|
||||||
pre: ({ children }) => {
|
|
||||||
// Check if this is a mermaid code block
|
|
||||||
let codeElement: string | null = null;
|
|
||||||
let className = '';
|
|
||||||
|
|
||||||
if (React.isValidElement(children)) {
|
|
||||||
const props = children.props as {
|
|
||||||
children?: string;
|
|
||||||
className?: string;
|
|
||||||
};
|
|
||||||
codeElement = props?.children || null;
|
|
||||||
className = props?.className || '';
|
|
||||||
}
|
|
||||||
|
|
||||||
const isMermaid =
|
|
||||||
className.includes('language-mermaid') ||
|
|
||||||
(typeof codeElement === 'string' &&
|
|
||||||
(codeElement.trim().startsWith('graph') ||
|
|
||||||
codeElement.trim().startsWith('flowchart') ||
|
|
||||||
codeElement
|
|
||||||
.trim()
|
|
||||||
.startsWith('sequenceDiagram') ||
|
|
||||||
codeElement.trim().startsWith('gantt') ||
|
|
||||||
codeElement.trim().startsWith('pie') ||
|
|
||||||
codeElement.trim().startsWith('gitgraph') ||
|
|
||||||
codeElement.trim().startsWith('journey') ||
|
|
||||||
codeElement.trim().startsWith('stateDiagram') ||
|
|
||||||
codeElement.trim().startsWith('classDiagram') ||
|
|
||||||
codeElement.trim().startsWith('erDiagram') ||
|
|
||||||
codeElement.trim().startsWith('mindmap') ||
|
|
||||||
codeElement.trim().startsWith('timeline')));
|
|
||||||
|
|
||||||
if (isMermaid && typeof codeElement === 'string') {
|
|
||||||
return (
|
|
||||||
<div className="my-6">
|
|
||||||
<MermaidRenderer chart={codeElement} />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<pre className="bg-[var(--card)]/60 border border-[var(--border)]/60 rounded-lg p-4 overflow-x-auto backdrop-blur-sm">
|
|
||||||
{children}
|
|
||||||
</pre>
|
|
||||||
);
|
|
||||||
},
|
|
||||||
a: ({ children, href }) => (
|
|
||||||
<a
|
|
||||||
href={href}
|
|
||||||
className="text-[var(--primary)] hover:text-[var(--primary)]/80 underline decoration-[var(--primary)]/50 hover:decoration-[var(--primary)] transition-colors"
|
|
||||||
target="_blank"
|
|
||||||
rel="noopener noreferrer"
|
|
||||||
>
|
|
||||||
{children}
|
|
||||||
</a>
|
|
||||||
),
|
|
||||||
table: ({ children }) => (
|
|
||||||
<div className="overflow-x-auto mb-6 rounded-lg border border-[var(--border)]/60">
|
|
||||||
<table className="min-w-full">{children}</table>
|
|
||||||
</div>
|
|
||||||
),
|
|
||||||
th: ({ children }) => (
|
|
||||||
<th className="border-b border-[var(--border)]/60 bg-[var(--card)]/40 px-4 py-3 text-left font-semibold text-[var(--foreground)] backdrop-blur-sm">
|
|
||||||
{children}
|
|
||||||
</th>
|
|
||||||
),
|
|
||||||
td: ({ children }) => (
|
|
||||||
<td className="border-b border-[var(--border)]/30 px-4 py-3 text-[var(--foreground)]">
|
|
||||||
{children}
|
|
||||||
</td>
|
|
||||||
),
|
|
||||||
hr: () => (
|
|
||||||
<hr className="my-8 border-0 h-px bg-gradient-to-r from-transparent via-[var(--border)] to-transparent" />
|
|
||||||
),
|
|
||||||
strong: ({ children }) => (
|
|
||||||
<strong className="font-bold text-[var(--foreground)]">
|
|
||||||
{children}
|
|
||||||
</strong>
|
|
||||||
),
|
|
||||||
em: ({ children }) => (
|
|
||||||
<em className="italic text-[var(--muted-foreground)]">
|
|
||||||
{children}
|
|
||||||
</em>
|
|
||||||
),
|
|
||||||
}}
|
|
||||||
>
|
>
|
||||||
{value || "*Commencez à écrire pour voir l'aperçu...*"}
|
{value || "*Commencez à écrire pour voir l'aperçu...*"}
|
||||||
</ReactMarkdown>
|
</ReactMarkdown>
|
||||||
|
|||||||
Reference in New Issue
Block a user