mirror of
https://github.com/utopia-os/utopia-ui.git
synced 2026-03-01 12:44:17 +00:00
Merge main
This commit is contained in:
commit
0a81f710d2
809
package-lock.json
generated
809
package-lock.json
generated
@ -11,6 +11,16 @@
|
||||
"dependencies": {
|
||||
"@heroicons/react": "^2.0.17",
|
||||
"@tanstack/react-query": "^5.17.8",
|
||||
"@tiptap/core": "^2.14.0",
|
||||
"@tiptap/extension-bubble-menu": "^2.14.0",
|
||||
"@tiptap/extension-color": "^2.12.0",
|
||||
"@tiptap/extension-image": "^2.14.0",
|
||||
"@tiptap/extension-link": "^2.14.0",
|
||||
"@tiptap/extension-placeholder": "^2.14.0",
|
||||
"@tiptap/extension-youtube": "^2.12.0",
|
||||
"@tiptap/pm": "^2.12.0",
|
||||
"@tiptap/react": "^2.12.0",
|
||||
"@tiptap/starter-kit": "^2.12.0",
|
||||
"axios": "^1.6.5",
|
||||
"browser-image-compression": "^2.0.2",
|
||||
"classnames": "^2.5.1",
|
||||
@ -30,6 +40,7 @@
|
||||
"react-router-dom": "^6.16.0",
|
||||
"react-toastify": "^9.1.3",
|
||||
"remark-breaks": "^4.0.0",
|
||||
"tiptap-markdown": "^0.8.10",
|
||||
"yet-another-react-lightbox": "^3.21.7"
|
||||
},
|
||||
"devDependencies": {
|
||||
@ -1291,6 +1302,16 @@
|
||||
"url": "https://opencollective.com/unts"
|
||||
}
|
||||
},
|
||||
"node_modules/@popperjs/core": {
|
||||
"version": "2.11.8",
|
||||
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
|
||||
"integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "opencollective",
|
||||
"url": "https://opencollective.com/popperjs"
|
||||
}
|
||||
},
|
||||
"node_modules/@react-leaflet/core": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@react-leaflet/core/-/core-2.1.0.tgz",
|
||||
@ -1302,6 +1323,12 @@
|
||||
"react-dom": "^18.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@remirror/core-constants": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@remirror/core-constants/-/core-constants-3.0.0.tgz",
|
||||
"integrity": "sha512-42aWfPrimMfDKDi4YegyS7x+/0tlzaqwPQCULLanv3DMIlu96KTJR0fM5isWX2UViOqlGnX6YFgqWepcX+XMNg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@remix-run/router": {
|
||||
"version": "1.22.0",
|
||||
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.22.0.tgz",
|
||||
@ -2349,6 +2376,462 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/core": {
|
||||
"version": "2.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/core/-/core-2.14.0.tgz",
|
||||
"integrity": "sha512-MBSMzGYRFlwYCocvx3dU7zpCBSDQ0qWByNtStaEzuBUgzCJ6wn2DP/xG0cMcLmE3Ia0VLM4nwbLOAAvBXOtylA==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/pm": "^2.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-blockquote": {
|
||||
"version": "2.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-blockquote/-/extension-blockquote-2.12.0.tgz",
|
||||
"integrity": "sha512-XUC2A77YAPMJS2SqZ2S62IGcUH8gZ7cdhoWlYQb1pR4ZzXFByeKDJPxfYeAePSiuI01YGrlzgY2c6Ncx/DtO0A==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "^2.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-bold": {
|
||||
"version": "2.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-2.12.0.tgz",
|
||||
"integrity": "sha512-lAUtoLDLRc5ofD2I9MFY6MQ7d1qBLLqS1rvpwaPjOaoQb/GPVnaHj9qXYG0SY9K3erMtto48bMFpAcscjZHzZQ==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "^2.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-bubble-menu": {
|
||||
"version": "2.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-bubble-menu/-/extension-bubble-menu-2.14.0.tgz",
|
||||
"integrity": "sha512-sN15n0RjPh+2Asvxs7l47hVEvX6c0aPempU8QQWcPUlHoGf1D/XkyHXy6GWVPSxZ5Rj5uAwgKvhHsG/FJ/YGKQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"tippy.js": "^6.3.7"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "^2.7.0",
|
||||
"@tiptap/pm": "^2.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-bullet-list": {
|
||||
"version": "2.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-bullet-list/-/extension-bullet-list-2.12.0.tgz",
|
||||
"integrity": "sha512-YTCjztB8MaIpwyxFYr81H4+LdKCq1VlaSXQyrPdB44mVdhhRqc46BYQb8/B//XE3UIu3X2QWFjwrqRlUq6vUiw==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "^2.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-code": {
|
||||
"version": "2.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-2.12.0.tgz",
|
||||
"integrity": "sha512-R7RaS+hJeHFim7alImQ9L9CSWSMjWXvz0Ote568x9ea5gdBGUYW8PcH+5a91lh8e1XGYWBM12a8oJZRyxg/tQA==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "^2.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-code-block": {
|
||||
"version": "2.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-code-block/-/extension-code-block-2.12.0.tgz",
|
||||
"integrity": "sha512-1D7cYAjgxEFHdfC/35Ooi4GqWKB5sszbW8iI7N16XILNln26xb0d5KflXqYrwr9CN/ZnZoCl2o6YsP7xEObcZA==",
|
||||
"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-color": {
|
||||
"version": "2.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-color/-/extension-color-2.12.0.tgz",
|
||||
"integrity": "sha512-tb3KDhH2Hf3Pwm7pIEH80TKBOLmHU+T/0seR3R+6flamPC7t9S4mcehDX35qvTQTqDU9v429Rw5SL40FRW7AMg==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "^2.7.0",
|
||||
"@tiptap/extension-text-style": "^2.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-document": {
|
||||
"version": "2.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-document/-/extension-document-2.12.0.tgz",
|
||||
"integrity": "sha512-sA1Q+mxDIv0Y3qQTBkYGwknNbDcGFiJ/fyAFholXpqbrcRx3GavwR/o0chBdsJZlFht0x7AWGwUYWvIo7wYilA==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "^2.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-dropcursor": {
|
||||
"version": "2.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-dropcursor/-/extension-dropcursor-2.12.0.tgz",
|
||||
"integrity": "sha512-zcZSOXFj+7LVnmdPWTfKr5AoxYIzFPFlLJe35AdTQC5IhkljLn1Exct8I30ZREojX/00hKYsO7JJmePS6TEVlQ==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "^2.7.0",
|
||||
"@tiptap/pm": "^2.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-floating-menu": {
|
||||
"version": "2.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-floating-menu/-/extension-floating-menu-2.12.0.tgz",
|
||||
"integrity": "sha512-BYpyZx/56KCDksWuJJbhki/uNgt9sACuSSZFH5AN1yS1ISD+EzIxqf6Pzzv8QCoNJ+KcRNVaZsOlOFaJGoyzag==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"tippy.js": "^6.3.7"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "^2.7.0",
|
||||
"@tiptap/pm": "^2.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-gapcursor": {
|
||||
"version": "2.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-gapcursor/-/extension-gapcursor-2.12.0.tgz",
|
||||
"integrity": "sha512-k8ji5v9YKn7bNjo8UtI9hEfXfl4tKUp1hpJOEmUxGJQa3LIwrwSbReupUTnHszGQelzxikS/l1xO9P0TIGwRoA==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "^2.7.0",
|
||||
"@tiptap/pm": "^2.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-hard-break": {
|
||||
"version": "2.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-hard-break/-/extension-hard-break-2.12.0.tgz",
|
||||
"integrity": "sha512-08MNS2PK5DzdnAfqXn4krmJ/xebKmWpRpYqqN5EM8AvetYKlAJyTVSpo0ZUeGbZ3EZiPm9djgSnrLqpFUDjRCg==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "^2.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-heading": {
|
||||
"version": "2.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-heading/-/extension-heading-2.12.0.tgz",
|
||||
"integrity": "sha512-9DfES4Wd5TX1foI70N9sAL+35NN1UHrtzDYN2+dTHupnmKir9RaMXyZcbkUb4aDVzYrGxIqxJzHBVkquKIlTrw==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "^2.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-history": {
|
||||
"version": "2.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-history/-/extension-history-2.12.0.tgz",
|
||||
"integrity": "sha512-+B9CAf2BFURC6mQiM1OQtahVTzdEOEgT/UUNlRZkeeBc0K5of3dr6UdBqaoaMAefja3jx5PqiQ7mhUBAjSt6AA==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "^2.7.0",
|
||||
"@tiptap/pm": "^2.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-horizontal-rule": {
|
||||
"version": "2.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-2.12.0.tgz",
|
||||
"integrity": "sha512-Vi2+6RIehDSpoJn/7PDuOieUj7W7WrEb4wBxK9TG8PDscihR0mehhhzm/K2xhH4TN48iPJGRsjDFrFjTbXmcnw==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "^2.7.0",
|
||||
"@tiptap/pm": "^2.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-image": {
|
||||
"version": "2.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-image/-/extension-image-2.14.0.tgz",
|
||||
"integrity": "sha512-pYCUzZBgsxIvVGTzuW03cPz6PIrAo26xpoxqq4W090uMVoK0SgY5W5y0IqCdw4QyLkJ2/oNSFNc2EP9jVi1CcQ==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "^2.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-italic": {
|
||||
"version": "2.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-2.12.0.tgz",
|
||||
"integrity": "sha512-JKcXK3LmEsmxNzEq5e06rPUGMRLUxmJ2mYtBY4NlJ6yLM9XMDljtgeTnWT0ySLYmfINSFTkX4S7WIRbpl9l4pw==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "^2.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-link": {
|
||||
"version": "2.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-link/-/extension-link-2.14.0.tgz",
|
||||
"integrity": "sha512-fsqW7eRD2xoD6xy7eFrNPAdIuZ3eicA4jKC45Vcft/Xky0DJoIehlVBLxsPbfmv3f27EBrtPkg5+msLXkLyzJA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"linkifyjs": "^4.2.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "^2.7.0",
|
||||
"@tiptap/pm": "^2.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-list-item": {
|
||||
"version": "2.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-list-item/-/extension-list-item-2.12.0.tgz",
|
||||
"integrity": "sha512-4YwZooC8HP+gPxs6YrkB1ayggyYbgVvJx/rWBT6lKSW2MVVg8QXi1zAcSI3MhIhHmqDysXXFPL8JURlbeGjaFA==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "^2.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-ordered-list": {
|
||||
"version": "2.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-ordered-list/-/extension-ordered-list-2.12.0.tgz",
|
||||
"integrity": "sha512-1ys0e/oqk09oXxrB1WzAx5EntK/QreObG/V1yhgihGm429fxHMsxzIYN6dKAYxx0YOPQG7qEZRrrPuWU70Ms7g==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "^2.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-paragraph": {
|
||||
"version": "2.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-2.12.0.tgz",
|
||||
"integrity": "sha512-QNK5cgewCunWFxpLlbvvoO1rrLgEtNKxiY79fctP9toV+e59R+1i1Q9lXC1O5mOfDgVxCb6uFDMsqmKhFjpPog==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "^2.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-placeholder": {
|
||||
"version": "2.14.0",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-placeholder/-/extension-placeholder-2.14.0.tgz",
|
||||
"integrity": "sha512-xzfjHvuukbch4i5O/5uyS2K2QgNEaMKi6e6GExTTgVwnFjKfJmgTqee33tt5JCqSItBvtSZlU3SX/vpiaIof+w==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "^2.7.0",
|
||||
"@tiptap/pm": "^2.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-strike": {
|
||||
"version": "2.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-2.12.0.tgz",
|
||||
"integrity": "sha512-nBaa5YtBsLJPZFfSs36sBz4Zgi/c8b3MsmS/Az8uXaHb0R9yPewOVUMDIQbxMct8SXUlIo9VtKlOL+mVJ3Nkpw==",
|
||||
"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",
|
||||
"integrity": "sha512-0ytN9V1tZYTXdiYDQg4FB2SQ56JAJC9r/65snefb9ztl+gZzDrIvih7CflHs1ic9PgyjexfMLeH+VzuMccNyZw==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "^2.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-text-style": {
|
||||
"version": "2.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-text-style/-/extension-text-style-2.12.0.tgz",
|
||||
"integrity": "sha512-Pxwt23ZlvbQUahV0PvHy8Ej6IAuKR1FvHobUvwP3T8AiY7hob66fWRe7tQbESzSAzm5Vv2xkvyHeU8vekMTezA==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "^2.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-youtube": {
|
||||
"version": "2.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-youtube/-/extension-youtube-2.12.0.tgz",
|
||||
"integrity": "sha512-3EGLBRnKZIw+IiViPeX0bgnBZ4ifIbMawTTV4fVULAteMaEfmGZ9s0ows3MY4KZjWpoxNStH6rH8DhYVn+AfuQ==",
|
||||
"license": "MIT",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "^2.7.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/pm": {
|
||||
"version": "2.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-2.12.0.tgz",
|
||||
"integrity": "sha512-TNzVwpeNzFfHAcYTOKqX9iU4fRxliyoZrCnERR+RRzeg7gWrXrCLubQt1WEx0sojMAfznshSL3M5HGsYjEbYwA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"prosemirror-changeset": "^2.3.0",
|
||||
"prosemirror-collab": "^1.3.1",
|
||||
"prosemirror-commands": "^1.6.2",
|
||||
"prosemirror-dropcursor": "^1.8.1",
|
||||
"prosemirror-gapcursor": "^1.3.2",
|
||||
"prosemirror-history": "^1.4.1",
|
||||
"prosemirror-inputrules": "^1.4.0",
|
||||
"prosemirror-keymap": "^1.2.2",
|
||||
"prosemirror-markdown": "^1.13.1",
|
||||
"prosemirror-menu": "^1.2.4",
|
||||
"prosemirror-model": "^1.23.0",
|
||||
"prosemirror-schema-basic": "^1.2.3",
|
||||
"prosemirror-schema-list": "^1.4.1",
|
||||
"prosemirror-state": "^1.4.3",
|
||||
"prosemirror-tables": "^1.6.4",
|
||||
"prosemirror-trailing-node": "^3.0.0",
|
||||
"prosemirror-transform": "^1.10.2",
|
||||
"prosemirror-view": "^1.37.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/react": {
|
||||
"version": "2.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/react/-/react-2.12.0.tgz",
|
||||
"integrity": "sha512-D+PR+4kJO9h8AB/7XyQ/Anw8tqeS2ecv5QemBOCHi9JlMAjytauUrj6IfFBO9RbsCowlBjW5GnSpFhzpk2Gghg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@tiptap/extension-bubble-menu": "^2.12.0",
|
||||
"@tiptap/extension-floating-menu": "^2.12.0",
|
||||
"@types/use-sync-external-store": "^0.0.6",
|
||||
"fast-deep-equal": "^3",
|
||||
"use-sync-external-store": "^1"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "^2.7.0",
|
||||
"@tiptap/pm": "^2.7.0",
|
||||
"react": "^17.0.0 || ^18.0.0 || ^19.0.0",
|
||||
"react-dom": "^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/starter-kit": {
|
||||
"version": "2.12.0",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/starter-kit/-/starter-kit-2.12.0.tgz",
|
||||
"integrity": "sha512-wlcEEtexd6u0gbR311/OFZnbtRWU97DUsY6/GsSQzN4rqZ7Ra6YbfHEN5Lutu+I/anomK8vKy8k9NyvfY5Hllg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@tiptap/core": "^2.12.0",
|
||||
"@tiptap/extension-blockquote": "^2.12.0",
|
||||
"@tiptap/extension-bold": "^2.12.0",
|
||||
"@tiptap/extension-bullet-list": "^2.12.0",
|
||||
"@tiptap/extension-code": "^2.12.0",
|
||||
"@tiptap/extension-code-block": "^2.12.0",
|
||||
"@tiptap/extension-document": "^2.12.0",
|
||||
"@tiptap/extension-dropcursor": "^2.12.0",
|
||||
"@tiptap/extension-gapcursor": "^2.12.0",
|
||||
"@tiptap/extension-hard-break": "^2.12.0",
|
||||
"@tiptap/extension-heading": "^2.12.0",
|
||||
"@tiptap/extension-history": "^2.12.0",
|
||||
"@tiptap/extension-horizontal-rule": "^2.12.0",
|
||||
"@tiptap/extension-italic": "^2.12.0",
|
||||
"@tiptap/extension-list-item": "^2.12.0",
|
||||
"@tiptap/extension-ordered-list": "^2.12.0",
|
||||
"@tiptap/extension-paragraph": "^2.12.0",
|
||||
"@tiptap/extension-strike": "^2.12.0",
|
||||
"@tiptap/extension-text": "^2.12.0",
|
||||
"@tiptap/extension-text-style": "^2.12.0",
|
||||
"@tiptap/pm": "^2.12.0"
|
||||
},
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
}
|
||||
},
|
||||
"node_modules/@trysound/sax": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz",
|
||||
@ -2486,6 +2969,22 @@
|
||||
"@types/leaflet": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/linkify-it": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-5.0.0.tgz",
|
||||
"integrity": "sha512-sVDA58zAw4eWAffKOaQH5/5j3XeayukzDk+ewSsnv3p4yJEZHCCzMDiZM8e0OUrRvmpGZ85jf4yDHkHsgBNr9Q==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/markdown-it": {
|
||||
"version": "14.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-14.1.2.tgz",
|
||||
"integrity": "sha512-promo4eFwuiW+TfGxhi+0x3czqTYJkG8qB17ZUJiVF10Xm7NLVRSLUsfRTU/6h1e24VvRnXCx+hG7li58lkzog==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/linkify-it": "^5",
|
||||
"@types/mdurl": "^2"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/mdast": {
|
||||
"version": "4.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/mdast/-/mdast-4.0.4.tgz",
|
||||
@ -2495,6 +2994,12 @@
|
||||
"@types/unist": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/mdurl": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-2.0.0.tgz",
|
||||
"integrity": "sha512-RGdgjQUZba5p6QEFAVx2OGb8rQDL/cPRG7GiedRzMcJ1tYnUANBncjbSB1NRGwbvjcPeikRABz2nshyPk1bhWg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/ms": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz",
|
||||
@ -2572,6 +3077,12 @@
|
||||
"integrity": "sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/use-sync-external-store": {
|
||||
"version": "0.0.6",
|
||||
"resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz",
|
||||
"integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/yauzl": {
|
||||
"version": "2.10.3",
|
||||
"resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz",
|
||||
@ -3092,7 +3603,6 @@
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
|
||||
"dev": true,
|
||||
"license": "Python-2.0"
|
||||
},
|
||||
"node_modules/aria-query": {
|
||||
@ -4056,6 +4566,12 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/crelt": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz",
|
||||
"integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/cross-spawn": {
|
||||
"version": "7.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||
@ -5004,7 +5520,6 @@
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
|
||||
"integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
@ -5792,7 +6307,6 @@
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/fast-diff": {
|
||||
@ -7918,12 +8432,17 @@
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz",
|
||||
"integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"uc.micro": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/linkifyjs": {
|
||||
"version": "4.3.1",
|
||||
"resolved": "https://registry.npmjs.org/linkifyjs/-/linkifyjs-4.3.1.tgz",
|
||||
"integrity": "sha512-DRSlB9DKVW04c4SUdGvKK5FR6be45lTU9M76JnngqPeeGDqPwYc0zdUErtsNVMtxPXgUWV4HbXbnC4sNyBxkYg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/listr2": {
|
||||
"version": "3.14.0",
|
||||
"resolved": "https://registry.npmjs.org/listr2/-/listr2-3.14.0.tgz",
|
||||
@ -8198,7 +8717,6 @@
|
||||
"version": "14.1.0",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz",
|
||||
"integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"argparse": "^2.0.1",
|
||||
@ -8212,11 +8730,16 @@
|
||||
"markdown-it": "bin/markdown-it.mjs"
|
||||
}
|
||||
},
|
||||
"node_modules/markdown-it-task-lists": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/markdown-it-task-lists/-/markdown-it-task-lists-2.1.1.tgz",
|
||||
"integrity": "sha512-TxFAc76Jnhb2OUu+n3yz9RMu4CwGfaT788br6HhEDlvWfdeJcLUsxk1Hgw2yJio0OXsxv7pyIPmvECY7bMbluA==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/markdown-it/node_modules/entities": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
|
||||
"integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
|
||||
"dev": true,
|
||||
"license": "BSD-2-Clause",
|
||||
"engines": {
|
||||
"node": ">=0.12"
|
||||
@ -8440,7 +8963,6 @@
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz",
|
||||
"integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/merge-stream": {
|
||||
@ -9264,6 +9786,12 @@
|
||||
"node": ">= 0.8.0"
|
||||
}
|
||||
},
|
||||
"node_modules/orderedmap": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/orderedmap/-/orderedmap-2.1.1.tgz",
|
||||
"integrity": "sha512-TvAWxi0nDe1j/rtMcWcIj94+Ffe6n7zhow33h40SKxmsmozs6dz/e+EajymfoFcHd7sxNn8yHM8839uixMOV6g==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/ospath": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/ospath/-/ospath-1.2.2.tgz",
|
||||
@ -10344,6 +10872,201 @@
|
||||
"url": "https://github.com/sponsors/wooorm"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-changeset": {
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-changeset/-/prosemirror-changeset-2.3.1.tgz",
|
||||
"integrity": "sha512-j0kORIBm8ayJNl3zQvD1TTPHJX3g042et6y/KQhZhnPrruO8exkTgG8X+NRpj7kIyMMEx74Xb3DyMIBtO0IKkQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"prosemirror-transform": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-collab": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-collab/-/prosemirror-collab-1.3.1.tgz",
|
||||
"integrity": "sha512-4SnynYR9TTYaQVXd/ieUvsVV4PDMBzrq2xPUWutHivDuOshZXqQ5rGbZM84HEaXKbLdItse7weMGOUdDVcLKEQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"prosemirror-state": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-commands": {
|
||||
"version": "1.7.1",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.7.1.tgz",
|
||||
"integrity": "sha512-rT7qZnQtx5c0/y/KlYaGvtG411S97UaL6gdp6RIZ23DLHanMYLyfGBV5DtSnZdthQql7W+lEVbpSfwtO8T+L2w==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"prosemirror-model": "^1.0.0",
|
||||
"prosemirror-state": "^1.0.0",
|
||||
"prosemirror-transform": "^1.10.2"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-dropcursor": {
|
||||
"version": "1.8.2",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-dropcursor/-/prosemirror-dropcursor-1.8.2.tgz",
|
||||
"integrity": "sha512-CCk6Gyx9+Tt2sbYk5NK0nB1ukHi2ryaRgadV/LvyNuO3ena1payM2z6Cg0vO1ebK8cxbzo41ku2DE5Axj1Zuiw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"prosemirror-state": "^1.0.0",
|
||||
"prosemirror-transform": "^1.1.0",
|
||||
"prosemirror-view": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-gapcursor": {
|
||||
"version": "1.3.2",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-gapcursor/-/prosemirror-gapcursor-1.3.2.tgz",
|
||||
"integrity": "sha512-wtjswVBd2vaQRrnYZaBCbyDqr232Ed4p2QPtRIUK5FuqHYKGWkEwl08oQM4Tw7DOR0FsasARV5uJFvMZWxdNxQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"prosemirror-keymap": "^1.0.0",
|
||||
"prosemirror-model": "^1.0.0",
|
||||
"prosemirror-state": "^1.0.0",
|
||||
"prosemirror-view": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-history": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-history/-/prosemirror-history-1.4.1.tgz",
|
||||
"integrity": "sha512-2JZD8z2JviJrboD9cPuX/Sv/1ChFng+xh2tChQ2X4bB2HeK+rra/bmJ3xGntCcjhOqIzSDG6Id7e8RJ9QPXLEQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"prosemirror-state": "^1.2.2",
|
||||
"prosemirror-transform": "^1.0.0",
|
||||
"prosemirror-view": "^1.31.0",
|
||||
"rope-sequence": "^1.3.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-inputrules": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-inputrules/-/prosemirror-inputrules-1.5.0.tgz",
|
||||
"integrity": "sha512-K0xJRCmt+uSw7xesnHmcn72yBGTbY45vm8gXI4LZXbx2Z0jwh5aF9xrGQgrVPu0WbyFVFF3E/o9VhJYz6SQWnA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"prosemirror-state": "^1.0.0",
|
||||
"prosemirror-transform": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-keymap": {
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-keymap/-/prosemirror-keymap-1.2.3.tgz",
|
||||
"integrity": "sha512-4HucRlpiLd1IPQQXNqeo81BGtkY8Ai5smHhKW9jjPKRc2wQIxksg7Hl1tTI2IfT2B/LgX6bfYvXxEpJl7aKYKw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"prosemirror-state": "^1.0.0",
|
||||
"w3c-keyname": "^2.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-markdown": {
|
||||
"version": "1.13.2",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-markdown/-/prosemirror-markdown-1.13.2.tgz",
|
||||
"integrity": "sha512-FPD9rHPdA9fqzNmIIDhhnYQ6WgNoSWX9StUZ8LEKapaXU9i6XgykaHKhp6XMyXlOWetmaFgGDS/nu/w9/vUc5g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/markdown-it": "^14.0.0",
|
||||
"markdown-it": "^14.0.0",
|
||||
"prosemirror-model": "^1.25.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-menu": {
|
||||
"version": "1.2.5",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-menu/-/prosemirror-menu-1.2.5.tgz",
|
||||
"integrity": "sha512-qwXzynnpBIeg1D7BAtjOusR+81xCp53j7iWu/IargiRZqRjGIlQuu1f3jFi+ehrHhWMLoyOQTSRx/IWZJqOYtQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"crelt": "^1.0.0",
|
||||
"prosemirror-commands": "^1.0.0",
|
||||
"prosemirror-history": "^1.0.0",
|
||||
"prosemirror-state": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-model": {
|
||||
"version": "1.25.1",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.25.1.tgz",
|
||||
"integrity": "sha512-AUvbm7qqmpZa5d9fPKMvH1Q5bqYQvAZWOGRvxsB6iFLyycvC9MwNemNVjHVrWgjaoxAfY8XVg7DbvQ/qxvI9Eg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"orderedmap": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-schema-basic": {
|
||||
"version": "1.2.4",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-schema-basic/-/prosemirror-schema-basic-1.2.4.tgz",
|
||||
"integrity": "sha512-ELxP4TlX3yr2v5rM7Sb70SqStq5NvI15c0j9j/gjsrO5vaw+fnnpovCLEGIcpeGfifkuqJwl4fon6b+KdrODYQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"prosemirror-model": "^1.25.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-schema-list": {
|
||||
"version": "1.5.1",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-schema-list/-/prosemirror-schema-list-1.5.1.tgz",
|
||||
"integrity": "sha512-927lFx/uwyQaGwJxLWCZRkjXG0p48KpMj6ueoYiu4JX05GGuGcgzAy62dfiV8eFZftgyBUvLx76RsMe20fJl+Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"prosemirror-model": "^1.0.0",
|
||||
"prosemirror-state": "^1.0.0",
|
||||
"prosemirror-transform": "^1.7.3"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-state": {
|
||||
"version": "1.4.3",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.4.3.tgz",
|
||||
"integrity": "sha512-goFKORVbvPuAQaXhpbemJFRKJ2aixr+AZMGiquiqKxaucC6hlpHNZHWgz5R7dS4roHiwq9vDctE//CZ++o0W1Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"prosemirror-model": "^1.0.0",
|
||||
"prosemirror-transform": "^1.0.0",
|
||||
"prosemirror-view": "^1.27.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-tables": {
|
||||
"version": "1.7.1",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-tables/-/prosemirror-tables-1.7.1.tgz",
|
||||
"integrity": "sha512-eRQ97Bf+i9Eby99QbyAiyov43iOKgWa7QCGly+lrDt7efZ1v8NWolhXiB43hSDGIXT1UXgbs4KJN3a06FGpr1Q==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"prosemirror-keymap": "^1.2.2",
|
||||
"prosemirror-model": "^1.25.0",
|
||||
"prosemirror-state": "^1.4.3",
|
||||
"prosemirror-transform": "^1.10.3",
|
||||
"prosemirror-view": "^1.39.1"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-trailing-node": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-trailing-node/-/prosemirror-trailing-node-3.0.0.tgz",
|
||||
"integrity": "sha512-xiun5/3q0w5eRnGYfNlW1uU9W6x5MoFKWwq/0TIRgt09lv7Hcser2QYV8t4muXbEr+Fwo0geYn79Xs4GKywrRQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@remirror/core-constants": "3.0.0",
|
||||
"escape-string-regexp": "^4.0.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"prosemirror-model": "^1.22.1",
|
||||
"prosemirror-state": "^1.4.2",
|
||||
"prosemirror-view": "^1.33.8"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-transform": {
|
||||
"version": "1.10.4",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.10.4.tgz",
|
||||
"integrity": "sha512-pwDy22nAnGqNR1feOQKHxoFkkUtepoFAd3r2hbEDsnf4wp57kKA36hXsB3njA9FtONBEwSDnDeCiJe+ItD+ykw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"prosemirror-model": "^1.21.0"
|
||||
}
|
||||
},
|
||||
"node_modules/prosemirror-view": {
|
||||
"version": "1.40.0",
|
||||
"resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.40.0.tgz",
|
||||
"integrity": "sha512-2G3svX0Cr1sJjkD/DYWSe3cfV5VPVTBOxI9XQEGWJDFEpsZb/gh4MV29ctv+OJx2RFX4BLt09i+6zaGM/ldkCw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"prosemirror-model": "^1.20.0",
|
||||
"prosemirror-state": "^1.0.0",
|
||||
"prosemirror-transform": "^1.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/proxy-from-env": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
||||
@ -10375,7 +11098,6 @@
|
||||
"version": "2.3.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz",
|
||||
"integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
@ -11024,6 +11746,12 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/rope-sequence": {
|
||||
"version": "1.3.4",
|
||||
"resolved": "https://registry.npmjs.org/rope-sequence/-/rope-sequence-1.3.4.tgz",
|
||||
"integrity": "sha512-UT5EDe2cu2E/6O4igUr5PSFs23nvvukicWHx6GnOPlHAiiYbzNuCRQCuiUdHJQcqKalLKlrYJnjY0ySGsXNQXQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/run-parallel": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
|
||||
@ -11965,6 +12693,55 @@
|
||||
"node": ">=14.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/tippy.js": {
|
||||
"version": "6.3.7",
|
||||
"resolved": "https://registry.npmjs.org/tippy.js/-/tippy.js-6.3.7.tgz",
|
||||
"integrity": "sha512-E1d3oP2emgJ9dRQZdf3Kkn0qJgI6ZLpyS5z6ZkY1DF3kaQaBsGZsndEpHwx+eC+tYM41HaSNvNtLx8tU57FzTQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@popperjs/core": "^2.9.0"
|
||||
}
|
||||
},
|
||||
"node_modules/tiptap-markdown": {
|
||||
"version": "0.8.10",
|
||||
"resolved": "https://registry.npmjs.org/tiptap-markdown/-/tiptap-markdown-0.8.10.tgz",
|
||||
"integrity": "sha512-iDVkR2BjAqkTDtFX0h94yVvE2AihCXlF0Q7RIXSJPRSR5I0PA1TMuAg6FHFpmqTn4tPxJ0by0CK7PUMlnFLGEQ==",
|
||||
"license": "MIT",
|
||||
"workspaces": [
|
||||
"example"
|
||||
],
|
||||
"dependencies": {
|
||||
"@types/markdown-it": "^13.0.7",
|
||||
"markdown-it": "^14.1.0",
|
||||
"markdown-it-task-lists": "^2.1.1",
|
||||
"prosemirror-markdown": "^1.11.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "^2.0.3"
|
||||
}
|
||||
},
|
||||
"node_modules/tiptap-markdown/node_modules/@types/linkify-it": {
|
||||
"version": "3.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/linkify-it/-/linkify-it-3.0.5.tgz",
|
||||
"integrity": "sha512-yg6E+u0/+Zjva+buc3EIb+29XEg4wltq7cSmd4Uc2EE/1nUVmxyzpX6gUXD0V8jIrG0r7YeOGVIbYRkxeooCtw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/tiptap-markdown/node_modules/@types/markdown-it": {
|
||||
"version": "13.0.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/markdown-it/-/markdown-it-13.0.9.tgz",
|
||||
"integrity": "sha512-1XPwR0+MgXLWfTn9gCsZ55AHOKW1WN+P9vr0PaQh5aerR9LLQXUbjfEAFhjmEmyoYFWAyuN2Mqkn40MZ4ukjBw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/linkify-it": "^3",
|
||||
"@types/mdurl": "^1"
|
||||
}
|
||||
},
|
||||
"node_modules/tiptap-markdown/node_modules/@types/mdurl": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@types/mdurl/-/mdurl-1.0.5.tgz",
|
||||
"integrity": "sha512-6L6VymKTzYSrEf4Nev4Xa1LCHKrlTlYCBMTlQKFuddo1CvQcE52I0mwfOJayueUC7MJuXOeHTcIU683lzd0cUA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/tldts": {
|
||||
"version": "6.1.77",
|
||||
"resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.77.tgz",
|
||||
@ -12320,7 +13097,6 @@
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz",
|
||||
"integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==",
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/unbox-primitive": {
|
||||
@ -12498,6 +13274,15 @@
|
||||
"punycode": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/use-sync-external-store": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz",
|
||||
"integrity": "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==",
|
||||
"license": "MIT",
|
||||
"peerDependencies": {
|
||||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/util-deprecate": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz",
|
||||
@ -12789,6 +13574,12 @@
|
||||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/w3c-keyname": {
|
||||
"version": "2.2.8",
|
||||
"resolved": "https://registry.npmjs.org/w3c-keyname/-/w3c-keyname-2.2.8.tgz",
|
||||
"integrity": "sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/webidl-conversions": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz",
|
||||
|
||||
11
package.json
11
package.json
@ -99,6 +99,16 @@
|
||||
"dependencies": {
|
||||
"@heroicons/react": "^2.0.17",
|
||||
"@tanstack/react-query": "^5.17.8",
|
||||
"@tiptap/core": "^2.14.0",
|
||||
"@tiptap/extension-bubble-menu": "^2.14.0",
|
||||
"@tiptap/extension-color": "^2.12.0",
|
||||
"@tiptap/extension-image": "^2.14.0",
|
||||
"@tiptap/extension-link": "^2.14.0",
|
||||
"@tiptap/extension-placeholder": "^2.14.0",
|
||||
"@tiptap/extension-youtube": "^2.12.0",
|
||||
"@tiptap/pm": "^2.12.0",
|
||||
"@tiptap/react": "^2.12.0",
|
||||
"@tiptap/starter-kit": "^2.12.0",
|
||||
"axios": "^1.6.5",
|
||||
"browser-image-compression": "^2.0.2",
|
||||
"classnames": "^2.5.1",
|
||||
@ -118,6 +128,7 @@
|
||||
"react-router-dom": "^6.16.0",
|
||||
"react-toastify": "^9.1.3",
|
||||
"remark-breaks": "^4.0.0",
|
||||
"tiptap-markdown": "^0.8.10",
|
||||
"yet-another-react-lightbox": "^3.21.7"
|
||||
},
|
||||
"imports": {
|
||||
|
||||
@ -49,6 +49,10 @@ export default [
|
||||
resolve({
|
||||
extensions: ['.ts', '.tsx'],
|
||||
}),
|
||||
commonjs({
|
||||
include: /node_modules/,
|
||||
requireReturnsDefault: 'auto',
|
||||
}),
|
||||
postcss({
|
||||
plugins: [],
|
||||
}),
|
||||
|
||||
@ -38,7 +38,7 @@ export default function NavBar({ appName }: { appName: string }) {
|
||||
<div className='tw:flex-1 tw:mr-2'>
|
||||
<div
|
||||
className={'tw:flex-1 tw:truncate tw:grid tw:grid-flow-col'}
|
||||
style={{ maxWidth: nameWidth + 60 }}
|
||||
style={{ maxWidth: nameWidth + 62 }}
|
||||
>
|
||||
<Link
|
||||
className='tw:btn tw:btn-ghost tw:px-2 tw:normal-case tw:text-xl tw:flex-1 tw:truncate'
|
||||
|
||||
@ -22,7 +22,7 @@ export const UserControl = () => {
|
||||
user && items.find((i) => i.user_created?.id === user.id && i.layer?.userProfileLayer)
|
||||
profile
|
||||
? setUserProfile(profile)
|
||||
: setUserProfile({ id: crypto.randomUUID(), name: user?.first_name ?? '', text: '' })
|
||||
: setUserProfile({ id: 'new', name: user?.first_name ?? '', text: '' })
|
||||
}, [user, items])
|
||||
|
||||
const onLogout = async () => {
|
||||
|
||||
@ -13,7 +13,7 @@ const ComboBoxInput = ({ id, options, value, onValueChange }: ComboBoxProps) =>
|
||||
return (
|
||||
<select
|
||||
id={id}
|
||||
className='tw:form-select tw:block tw:w-full tw:py-2 tw:px-4 tw:border tw:border-gray-300 rounded-md tw:shadow-sm tw:text-sm tw:focus:outline-hidden tw:focus:ring-indigo-500 tw:focus:border-indigo-500 tw:sm:text-sm'
|
||||
className='tw:select tw:w-full'
|
||||
onChange={handleChange}
|
||||
value={value} // ← hier controlled statt defaultValue
|
||||
>
|
||||
|
||||
@ -1,15 +1,24 @@
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-call */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-member-access */
|
||||
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 { EditorContent, useEditor } from '@tiptap/react'
|
||||
import { StarterKit } from '@tiptap/starter-kit'
|
||||
import { useEffect } from 'react'
|
||||
import { Markdown } from 'tiptap-markdown'
|
||||
|
||||
interface TextAreaProps {
|
||||
import { TextEditorMenu } from './TextEditorMenu'
|
||||
|
||||
interface RichTextEditorProps {
|
||||
labelTitle?: string
|
||||
labelStyle?: string
|
||||
containerStyle?: string
|
||||
dataField?: string
|
||||
inputStyle?: string
|
||||
defaultValue: string
|
||||
placeholder?: string
|
||||
required?: boolean
|
||||
size?: string
|
||||
showMenu?: boolean
|
||||
updateFormValue?: (value: string) => void
|
||||
}
|
||||
|
||||
@ -18,48 +27,84 @@ interface TextAreaProps {
|
||||
*/
|
||||
export function RichTextEditor({
|
||||
labelTitle,
|
||||
dataField,
|
||||
labelStyle,
|
||||
containerStyle,
|
||||
inputStyle,
|
||||
defaultValue,
|
||||
placeholder,
|
||||
required = true,
|
||||
showMenu = true,
|
||||
updateFormValue,
|
||||
}: TextAreaProps) {
|
||||
const ref = useRef<HTMLTextAreaElement>(null)
|
||||
const [inputValue, setInputValue] = useState<string>(defaultValue)
|
||||
}: RichTextEditorProps) {
|
||||
const handleChange = () => {
|
||||
let newValue: string | undefined = editor?.storage.markdown.getMarkdown()
|
||||
|
||||
useEffect(() => {
|
||||
setInputValue(defaultValue)
|
||||
}, [defaultValue])
|
||||
|
||||
const handleChange = (e: React.ChangeEvent<HTMLTextAreaElement>) => {
|
||||
const newValue = e.target.value
|
||||
setInputValue(newValue)
|
||||
if (updateFormValue) {
|
||||
const regex = /!\[.*?\]\(.*?\)/g
|
||||
newValue = newValue?.replace(regex, (match: string) => match + '\n\n')
|
||||
if (updateFormValue && newValue) {
|
||||
updateFormValue(newValue)
|
||||
}
|
||||
}
|
||||
|
||||
const editor = useEditor({
|
||||
extensions: [
|
||||
Color.configure({ types: ['textStyle', 'listItem'] }),
|
||||
StarterKit.configure({
|
||||
bulletList: {
|
||||
keepMarks: true,
|
||||
keepAttributes: false,
|
||||
},
|
||||
orderedList: {
|
||||
keepMarks: true,
|
||||
keepAttributes: false,
|
||||
},
|
||||
}),
|
||||
Markdown.configure({
|
||||
linkify: true,
|
||||
transformCopiedText: true,
|
||||
transformPastedText: true,
|
||||
}),
|
||||
Image,
|
||||
Link,
|
||||
Placeholder.configure({
|
||||
placeholder,
|
||||
emptyEditorClass: 'is-editor-empty',
|
||||
}),
|
||||
],
|
||||
content: defaultValue,
|
||||
onUpdate: handleChange,
|
||||
editorProps: {
|
||||
attributes: {
|
||||
class: `tw:h-full markdown tw:max-h-full tw:p-2 tw:overflow-y-auto`,
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
if (editor?.storage.markdown.getMarkdown() === '' || !editor?.storage.markdown.getMarkdown()) {
|
||||
editor?.commands.setContent(defaultValue)
|
||||
}
|
||||
}, [defaultValue, editor])
|
||||
|
||||
return (
|
||||
<div className={`tw:form-control tw:w-full ${containerStyle ?? ''}`}>
|
||||
<div
|
||||
className={`tw:form-control tw:w-full tw:flex tw:flex-col tw:min-h-0 ${containerStyle ?? ''}`}
|
||||
>
|
||||
{labelTitle ? (
|
||||
<label className='tw:label'>
|
||||
<label className='tw:label tw:pb-1'>
|
||||
<span className={`tw:label-text tw:text-base-content ${labelStyle ?? ''}`}>
|
||||
{labelTitle}
|
||||
</span>
|
||||
</label>
|
||||
) : null}
|
||||
<textarea
|
||||
required={required}
|
||||
ref={ref}
|
||||
value={inputValue}
|
||||
name={dataField}
|
||||
className={`tw:textarea tw:textarea-bordered tw:w-full tw:leading-5 ${inputStyle ?? ''}`}
|
||||
placeholder={placeholder ?? ''}
|
||||
onChange={handleChange}
|
||||
></textarea>
|
||||
<div
|
||||
className={`editor-wrapper tw:border-base-content/20 tw:rounded-box tw:border tw:flex tw:flex-col tw:flex-1 tw:min-h-0`}
|
||||
>
|
||||
{editor ? (
|
||||
<>
|
||||
{showMenu ? <TextEditorMenu editor={editor} /> : null}
|
||||
<EditorContent editor={editor} />
|
||||
</>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
160
src/Components/Input/TextEditorMenu.tsx
Normal file
160
src/Components/Input/TextEditorMenu.tsx
Normal file
@ -0,0 +1,160 @@
|
||||
import BoldIcon from '@heroicons/react/24/solid/BoldIcon'
|
||||
import H1Icon from '@heroicons/react/24/solid/H1Icon'
|
||||
import H2Icon from '@heroicons/react/24/solid/H2Icon'
|
||||
import H3Icon from '@heroicons/react/24/solid/H3Icon'
|
||||
import ItalicIcon from '@heroicons/react/24/solid/ItalicIcon'
|
||||
import ListBulletIcon from '@heroicons/react/24/solid/ListBulletIcon'
|
||||
import NumberedListIcon from '@heroicons/react/24/solid/NumberedListIcon'
|
||||
import { useEditorState } from '@tiptap/react'
|
||||
import { MdUndo, MdRedo, MdHorizontalRule } from 'react-icons/md'
|
||||
|
||||
import type { Editor } from '@tiptap/react'
|
||||
|
||||
export const TextEditorMenu = ({ editor }: { editor: Editor }) => {
|
||||
const editorState = useEditorState({
|
||||
editor,
|
||||
selector: (ctx) => {
|
||||
return {
|
||||
isBold: ctx.editor.isActive('bold'),
|
||||
canBold: ctx.editor.can().chain().focus().toggleBold().run(),
|
||||
isItalic: ctx.editor.isActive('italic'),
|
||||
canItalic: ctx.editor.can().chain().focus().toggleItalic().run(),
|
||||
isStrike: ctx.editor.isActive('strike'),
|
||||
canStrike: ctx.editor.can().chain().focus().toggleStrike().run(),
|
||||
isCode: ctx.editor.isActive('code'),
|
||||
canCode: ctx.editor.can().chain().focus().toggleCode().run(),
|
||||
canClearMarks: ctx.editor.can().chain().focus().unsetAllMarks().run(),
|
||||
isParagraph: ctx.editor.isActive('paragraph'),
|
||||
isHeading1: ctx.editor.isActive('heading', { level: 1 }),
|
||||
isHeading2: ctx.editor.isActive('heading', { level: 2 }),
|
||||
isHeading3: ctx.editor.isActive('heading', { level: 3 }),
|
||||
isHeading4: ctx.editor.isActive('heading', { level: 4 }),
|
||||
isHeading5: ctx.editor.isActive('heading', { level: 5 }),
|
||||
isHeading6: ctx.editor.isActive('heading', { level: 6 }),
|
||||
isHeading: ctx.editor.isActive('heading'),
|
||||
isBulletList: ctx.editor.isActive('bulletList'),
|
||||
isOrderedList: ctx.editor.isActive('orderedList'),
|
||||
isCodeBlock: ctx.editor.isActive('codeBlock'),
|
||||
isBlockquote: ctx.editor.isActive('blockquote'),
|
||||
canUndo: ctx.editor.can().chain().focus().undo().run(),
|
||||
canRedo: ctx.editor.can().chain().focus().redo().run(),
|
||||
}
|
||||
},
|
||||
})
|
||||
|
||||
return (
|
||||
<>
|
||||
<ul
|
||||
className={
|
||||
'tw:menu tw:overflow-x-hidden tw:@sm:overflow-visible tw:menu-horizontal tw:flex-nowrap tw:flex-none tw:bg-base-200 tw:rounded-box tw:w-full tw:rounded-b-none'
|
||||
}
|
||||
>
|
||||
<li>
|
||||
<div
|
||||
className={`tw:@sm:tooltip tw:px-1.5 tw:mx-0.5 ${editorState.isHeading1 ? 'tw:bg-base-content/10' : ''}`}
|
||||
data-tip='Heading 1'
|
||||
onClick={() => editor.chain().focus().toggleHeading({ level: 1 }).run()}
|
||||
>
|
||||
<H1Icon className='tw:w-5 tw:h-5' />
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div
|
||||
className={`tw:@sm:tooltip tw:px-1.5 tw:mx-0.5 ${editorState.isHeading2 ? 'tw:bg-base-content/10' : ''}`}
|
||||
data-tip='Heading 2'
|
||||
onClick={() => editor.chain().focus().toggleHeading({ level: 2 }).run()}
|
||||
>
|
||||
<H2Icon className='tw:w-5 tw:h-5' />
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div
|
||||
className={`tw:@sm:tooltip tw:px-1.5 tw:mx-0.5 ${editorState.isHeading3 ? 'tw:bg-base-content/10' : ''}`}
|
||||
data-tip='Heading 3'
|
||||
onClick={() => editor.chain().focus().toggleHeading({ level: 3 }).run()}
|
||||
>
|
||||
<H3Icon className='tw:w-5 tw:h-5' />
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div className='tw:w-[1px] tw:p-0 tw:mx-1 tw:bg-base-content/10 tw:my-1' />
|
||||
</li>
|
||||
<li>
|
||||
<div
|
||||
className={`tw:@sm:tooltip tw:px-1.5 tw:mx-0.5 ${editorState.isBold ? 'tw:bg-base-content/10' : ''}`}
|
||||
data-tip='Bold'
|
||||
onClick={() => editor.chain().focus().toggleBold().run()}
|
||||
>
|
||||
<BoldIcon className='tw:w-5 tw:h-5' />
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div
|
||||
className={`tw:@sm:tooltip tw:px-1.5 tw:mx-0.5 ${editorState.isItalic ? 'tw:bg-base-content/10' : ''}`}
|
||||
data-tip='Italic'
|
||||
onClick={() => editor.chain().focus().toggleItalic().run()}
|
||||
>
|
||||
<ItalicIcon className='tw:w-5 tw:h-5' />
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div className='tw:w-[1px] tw:p-0 tw:mx-1 tw:bg-base-content/10 tw:my-1' />
|
||||
</li>
|
||||
<li>
|
||||
<div
|
||||
className={`tw:@sm:tooltip tw:px-1.5 tw:mx-0.5 ${editorState.isBulletList ? 'tw:bg-base-content/10' : ''}`}
|
||||
data-tip='List'
|
||||
onClick={() => editor.chain().focus().toggleBulletList().run()}
|
||||
>
|
||||
<ListBulletIcon className='tw:w-5 tw:h-5' />
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div
|
||||
className={`tw:@sm:tooltip tw:px-1.5 tw:mx-0.5 ${editorState.isOrderedList ? 'tw:bg-base-content/10' : ''}`}
|
||||
data-tip='List'
|
||||
onClick={() => editor.chain().focus().toggleOrderedList().run()}
|
||||
>
|
||||
<NumberedListIcon className='tw:w-5 tw:h-5' />
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div className='tw:w-[1px] tw:p-0 tw:mx-1 tw:bg-base-content/10 tw:my-1' />
|
||||
</li>
|
||||
{/* <li>
|
||||
<div className='tw:@sm:tooltip tw:px-1.5 tw:mx-0.5' data-tip='Image' onClick={addImage}>
|
||||
<PhotoIcon className='tw:w-5 tw:h-5' />
|
||||
</div>
|
||||
</li> */}
|
||||
<li>
|
||||
<div
|
||||
className='tw:@sm:tooltip tw:px-1'
|
||||
data-tip='Horizontal Line'
|
||||
onClick={() => editor.chain().focus().setHorizontalRule().run()}
|
||||
>
|
||||
<MdHorizontalRule className='tw:w-5 tw:h-5' />
|
||||
</div>
|
||||
</li>
|
||||
<div className='tw:flex-grow'></div>
|
||||
<li>
|
||||
<div
|
||||
className={`tw:@sm:tooltip tw:px-1.5 tw:mx-0.5 tw:hidden tw:@sm:block ${editorState.canUndo ? '' : 'tw:opacity-50'}`}
|
||||
data-tip='Undo'
|
||||
onClick={() => editor.chain().focus().undo().run()}
|
||||
>
|
||||
<MdUndo className='tw:w-5 tw:h-5' />
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
<div
|
||||
className={`tw:@sm:tooltip tw:px-1.5 tw:mx-0.5 tw:hidden tw:@sm:block ${editorState.canRedo ? '' : 'tw:opacity-50'}`}
|
||||
data-tip='Redo'
|
||||
onClick={() => editor.chain().focus().redo().run()}
|
||||
>
|
||||
<MdRedo className='tw:w-5 tw:h-5' />
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</>
|
||||
)
|
||||
}
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
exports[`<ComboBoxInput /> > renders properly 1`] = `
|
||||
<select
|
||||
class="tw:form-select tw:block tw:w-full tw:py-2 tw:px-4 tw:border tw:border-gray-300 rounded-md tw:shadow-sm tw:text-sm tw:focus:outline-hidden tw:focus:ring-indigo-500 tw:focus:border-indigo-500 tw:sm:text-sm"
|
||||
class="tw:select tw:w-full"
|
||||
>
|
||||
<option
|
||||
value="Option 1"
|
||||
|
||||
@ -6,6 +6,7 @@ import type { Item } from '#types/Item'
|
||||
export interface StartEndInputProps {
|
||||
item?: Item
|
||||
showLabels?: boolean
|
||||
labelStyle?: string
|
||||
updateStartValue?: (value: string) => void
|
||||
updateEndValue?: (value: string) => void
|
||||
}
|
||||
@ -16,6 +17,7 @@ export interface StartEndInputProps {
|
||||
export const PopupStartEndInput = ({
|
||||
item,
|
||||
showLabels = true,
|
||||
labelStyle,
|
||||
updateStartValue,
|
||||
updateEndValue,
|
||||
}: StartEndInputProps) => {
|
||||
@ -26,7 +28,8 @@ export const PopupStartEndInput = ({
|
||||
placeholder='start'
|
||||
dataField='start'
|
||||
inputStyle='tw:text-sm tw:px-2'
|
||||
labelTitle={showLabels ? 'start' : ''}
|
||||
labelTitle={showLabels ? 'Start' : ''}
|
||||
labelStyle={labelStyle}
|
||||
defaultValue={item && item.start ? item.start.substring(0, 10) : ''}
|
||||
autocomplete='one-time-code'
|
||||
updateFormValue={updateStartValue}
|
||||
@ -36,7 +39,8 @@ export const PopupStartEndInput = ({
|
||||
placeholder='end'
|
||||
dataField='end'
|
||||
inputStyle='tw:text-sm tw:px-2'
|
||||
labelTitle={showLabels ? 'end' : ''}
|
||||
labelTitle={showLabels ? 'End' : ''}
|
||||
labelStyle={labelStyle}
|
||||
defaultValue={item && item.end ? item.end.substring(0, 10) : ''}
|
||||
autocomplete='one-time-code'
|
||||
updateFormValue={updateEndValue}
|
||||
|
||||
@ -23,7 +23,7 @@ export const PopupTextInput = ({
|
||||
placeholder={placeholder}
|
||||
inputStyle={style}
|
||||
type='text'
|
||||
containerStyle={'tw:mt-4'}
|
||||
containerStyle={'tw:mt-4 tw:mb-2'}
|
||||
></TextInput>
|
||||
)
|
||||
}
|
||||
|
||||
@ -53,22 +53,6 @@ export const TextView = ({
|
||||
|
||||
if (innerText) replacedText = fixUrls(innerText)
|
||||
|
||||
if (replacedText) {
|
||||
replacedText = replacedText.replace(/(?<!\]?\()https?:\/\/[^\s)]+(?!\))/g, (url) => {
|
||||
let shortUrl = url
|
||||
|
||||
if (url.match('^https://')) {
|
||||
shortUrl = url.split('https://')[1]
|
||||
}
|
||||
|
||||
if (url.match('^http://')) {
|
||||
shortUrl = url.split('http://')[1]
|
||||
}
|
||||
|
||||
return `[${shortUrl}](${url})`
|
||||
})
|
||||
}
|
||||
|
||||
if (replacedText) {
|
||||
replacedText = replacedText.replace(mailRegex, (url) => {
|
||||
return `[${url}](mailto:${url})`
|
||||
|
||||
@ -3,7 +3,6 @@
|
||||
import classNames from 'classnames'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
import { toast } from 'react-toastify'
|
||||
|
||||
import { useAuth } from '#components/Auth/useAuth'
|
||||
import { useItems, useUpdateItem, useAddItem } from '#components/Map/hooks/useItems'
|
||||
@ -53,7 +52,7 @@ export function ProfileForm() {
|
||||
|
||||
const [updatePermission, setUpdatePermission] = useState<boolean>(false)
|
||||
const [loading, setLoading] = useState<boolean>(false)
|
||||
const [item, setItem] = useState<Item>({} as Item)
|
||||
const [item, setItem] = useState<Item>()
|
||||
const { user } = useAuth()
|
||||
const updateItem = useUpdateItem()
|
||||
const addItem = useAddItem()
|
||||
@ -74,30 +73,23 @@ export function ProfileForm() {
|
||||
|
||||
useEffect(() => {
|
||||
const itemId = location.pathname.split('/')[2]
|
||||
|
||||
const item = items.find((i) => i.id === itemId)
|
||||
item && setItem(item)
|
||||
|
||||
if (!item) {
|
||||
if (items.some((i) => i.user_created?.id === user?.id && i.layer?.userProfileLayer)) {
|
||||
navigate('/')
|
||||
toast.error('Item does not exist')
|
||||
} else {
|
||||
const layer = layers.find((l) => l.userProfileLayer)
|
||||
setItem({
|
||||
id: crypto.randomUUID(),
|
||||
name: user?.first_name ?? '',
|
||||
text: '',
|
||||
layer,
|
||||
new: true,
|
||||
})
|
||||
}
|
||||
if (itemId === 'new') {
|
||||
const layer = layers.find((l) => l.userProfileLayer)
|
||||
setItem({
|
||||
id: crypto.randomUUID(),
|
||||
name: user?.first_name ?? '',
|
||||
text: '',
|
||||
layer,
|
||||
new: true,
|
||||
})
|
||||
} else {
|
||||
const item = items.find((i) => i.id === itemId)
|
||||
if (item) setItem(item)
|
||||
}
|
||||
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [items])
|
||||
}, [items, location.pathname, layers, user?.first_name])
|
||||
|
||||
useEffect(() => {
|
||||
if (!item) return
|
||||
const newColor =
|
||||
item.color ??
|
||||
(getItemTags(item) && getItemTags(item)[0]?.color
|
||||
@ -151,6 +143,7 @@ export function ProfileForm() {
|
||||
const [template, setTemplate] = useState<string>('')
|
||||
|
||||
useEffect(() => {
|
||||
if (!item) return
|
||||
if (item.layer?.itemType.template) setTemplate(item.layer?.itemType.template)
|
||||
else {
|
||||
const userLayer = layers.find((l) => l.userProfileLayer === true)
|
||||
@ -164,73 +157,78 @@ export function ProfileForm() {
|
||||
<>
|
||||
<MapOverlayPage
|
||||
backdrop
|
||||
className='tw:mx-4 tw:mt-4 tw:mb-4 tw:@container tw:overflow-x-hidden tw:w-[calc(100%-32px)] tw:md:w-[calc(50%-32px)] tw:max-w-3xl tw:left-auto! tw:top-0 tw:bottom-0'
|
||||
className='tw:mx-4 tw:mt-4 tw:mb-4 tw:@container tw:overflow-x-hidden tw:w-[calc(100%-32px)] tw:md:w-[calc(50%-32px)] tw:max-w-3xl tw:left-auto! tw:top-0 tw:bottom-0 tw:flex tw:flex-col'
|
||||
>
|
||||
<form
|
||||
className='tw:h-full'
|
||||
onSubmit={(e) => {
|
||||
e.preventDefault()
|
||||
void onUpdateItem(
|
||||
state,
|
||||
item,
|
||||
tags,
|
||||
addTag,
|
||||
setLoading,
|
||||
navigate,
|
||||
updateItem,
|
||||
addItem,
|
||||
user,
|
||||
urlParams,
|
||||
)
|
||||
}}
|
||||
>
|
||||
<div className='tw:flex tw:flex-col tw:h-full'>
|
||||
<FormHeader item={item} state={state} setState={setState} />
|
||||
{item ? (
|
||||
<form
|
||||
className='tw:flex tw:flex-col tw:flex-1 tw:min-h-0'
|
||||
onSubmit={(e) => {
|
||||
e.preventDefault()
|
||||
void onUpdateItem(
|
||||
state,
|
||||
item,
|
||||
tags,
|
||||
addTag,
|
||||
setLoading,
|
||||
navigate,
|
||||
updateItem,
|
||||
addItem,
|
||||
user,
|
||||
urlParams,
|
||||
)
|
||||
}}
|
||||
>
|
||||
<div className='tw:flex tw:flex-col tw:flex-1 pb-4'>
|
||||
<FormHeader item={item} state={state} setState={setState} />
|
||||
|
||||
{template === 'onepager' && (
|
||||
<OnepagerForm item={item} state={state} setState={setState}></OnepagerForm>
|
||||
)}
|
||||
{template === 'onepager' && (
|
||||
<OnepagerForm item={item} state={state} setState={setState}></OnepagerForm>
|
||||
)}
|
||||
|
||||
{template === 'simple' && <SimpleForm state={state} setState={setState}></SimpleForm>}
|
||||
{template === 'simple' && <SimpleForm state={state} setState={setState}></SimpleForm>}
|
||||
|
||||
{template === 'flex' && (
|
||||
<FlexForm item={item} state={state} setState={setState}></FlexForm>
|
||||
)}
|
||||
{template === 'flex' && (
|
||||
<FlexForm item={item} state={state} setState={setState}></FlexForm>
|
||||
)}
|
||||
|
||||
{template === 'tabs' && (
|
||||
<TabsForm
|
||||
loading={loading}
|
||||
item={item}
|
||||
state={state}
|
||||
setState={setState}
|
||||
updatePermission={updatePermission}
|
||||
linkItem={(id: string) => linkItem(id, item, updateItem)}
|
||||
unlinkItem={(id: string) => unlinkItem(id, item, updateItem)}
|
||||
setUrlParams={setUrlParams}
|
||||
></TabsForm>
|
||||
)}
|
||||
{template === 'tabs' && (
|
||||
<TabsForm
|
||||
loading={loading}
|
||||
item={item}
|
||||
state={state}
|
||||
setState={setState}
|
||||
updatePermission={updatePermission}
|
||||
linkItem={(id: string) => linkItem(id, item, updateItem)}
|
||||
unlinkItem={(id: string) => unlinkItem(id, item, updateItem)}
|
||||
setUrlParams={setUrlParams}
|
||||
></TabsForm>
|
||||
)}
|
||||
|
||||
<div className='tw:mt-4 tw:flex-none'>
|
||||
<button
|
||||
className={classNames(
|
||||
'tw:btn',
|
||||
'tw:float-right',
|
||||
{ 'tw:loading': loading },
|
||||
{ 'tw:cursor-not-allowed tw:opacity-50': loading || isUpdatingGallery },
|
||||
)}
|
||||
type='submit'
|
||||
style={{
|
||||
// We could refactor this, it is used several times at different locations
|
||||
backgroundColor: `${item.color ?? (getItemTags(item) && getItemTags(item)[0] && getItemTags(item)[0].color ? getItemTags(item)[0].color : item?.layer?.markerDefaultColor)}`,
|
||||
color: '#fff',
|
||||
}}
|
||||
disabled={loading || isUpdatingGallery}
|
||||
>
|
||||
Update
|
||||
</button>
|
||||
<div className='tw:mb-4 tw:mt-6 tw:flex-none'>
|
||||
<button
|
||||
className={classNames(
|
||||
'tw:btn',
|
||||
'tw:float-right',
|
||||
{ 'tw:loading': loading },
|
||||
{ 'tw:cursor-not-allowed tw:opacity-50': loading || isUpdatingGallery },
|
||||
)}
|
||||
type='submit'
|
||||
style={{
|
||||
// We could refactor this, it is used several times at different locations
|
||||
backgroundColor: `${item.color ?? (getItemTags(item) && getItemTags(item)[0] && getItemTags(item)[0].color ? getItemTags(item)[0].color : item?.layer?.markerDefaultColor)}`,
|
||||
color: '#fff',
|
||||
}}
|
||||
>
|
||||
Update
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
) : (
|
||||
<div className='tw:h-full tw:flex tw:flex-col tw:items-center tw:justify-center'>
|
||||
<div className='tw:loading tw:loading-spinner'></div>
|
||||
</div>
|
||||
</form>
|
||||
)}
|
||||
</MapOverlayPage>
|
||||
</>
|
||||
)
|
||||
|
||||
@ -174,7 +174,7 @@ export function ProfileView({ attestationApi }: { attestationApi?: ItemsApi<any>
|
||||
{item && (
|
||||
<MapOverlayPage
|
||||
key={item.id}
|
||||
className={`tw:p-0! tw:overflow-scroll tw:m-4! tw:md:w-[calc(50%-32px)] tw:w-[calc(100%-32px)] tw:min-w-80 tw:max-w-3xl tw:left-0! tw:sm:left-auto! tw:top-0 tw:bottom-0 tw:transition-opacity tw:duration-500 ${!selectPosition ? 'tw:opacity-100 tw:pointer-events-auto' : 'tw:opacity-0 tw:pointer-events-none'}`}
|
||||
className={`tw:p-0! tw:overflow-scroll tw:m-4! tw:md:w-[calc(50%-32px)] tw:w-[calc(100%-32px)] tw:min-w-80 tw:max-w-3xl tw:left-0! tw:sm:left-auto! tw:top-0 tw:bottom-0 tw:transition-opacity tw:duration-500 ${!selectPosition ? 'tw:opacity-100 tw:pointer-events-auto' : 'tw:opacity-0 tw:pointer-events-none'} tw:max-h-[1000px]`}
|
||||
>
|
||||
<>
|
||||
<div className={'tw:px-6 tw:pt-6'}>
|
||||
|
||||
@ -10,7 +10,7 @@ export const ContactInfoForm = ({
|
||||
setState: React.Dispatch<React.SetStateAction<FormState>>
|
||||
}) => {
|
||||
return (
|
||||
<div className='tw:mt-4 tw:space-y-4'>
|
||||
<div className='tw:mt-2 tw:space-y-2'>
|
||||
<div>
|
||||
<label
|
||||
htmlFor='email'
|
||||
|
||||
@ -49,7 +49,7 @@ export const GroupSubheaderForm = ({
|
||||
}, [state.group_type, groupTypes])
|
||||
|
||||
return (
|
||||
<div className='tw:grid tw:grid-cols-1 tw:md:grid-cols-2 tw:gap-6'>
|
||||
<div className='tw:grid tw:grid-cols-1 tw:@sm:grid-cols-2 tw:gap-2'>
|
||||
<div>
|
||||
<label
|
||||
htmlFor='status'
|
||||
|
||||
@ -18,7 +18,6 @@ export const ProfileTextForm = ({
|
||||
heading,
|
||||
size,
|
||||
hideInputLabel,
|
||||
required,
|
||||
}: {
|
||||
state: FormState
|
||||
setState: React.Dispatch<React.SetStateAction<FormState>>
|
||||
@ -26,7 +25,6 @@ export const ProfileTextForm = ({
|
||||
heading: string
|
||||
size: string
|
||||
hideInputLabel: boolean
|
||||
required?: boolean
|
||||
}) => {
|
||||
const [field, setField] = useState<string>(dataField || 'text')
|
||||
|
||||
@ -37,11 +35,13 @@ export const ProfileTextForm = ({
|
||||
}, [dataField])
|
||||
|
||||
return (
|
||||
<div className='tw:h-full tw:flex tw:flex-col tw:mt-4'>
|
||||
<div
|
||||
className={`tw:max-h-124 tw:md:max-h-full tw:flex tw:flex-col tw:mt-2 ${size === 'full' ? 'tw:flex-1 tw:min-h-42' : 'tw:h-28 tw:flex-none'}`}
|
||||
>
|
||||
<div className='tw:flex tw:justify-between tw:items-center'>
|
||||
<label
|
||||
htmlFor='nextAppointment'
|
||||
className='tw:block tw:text-sm tw:font-medium tw:text-gray-500 tw:mb-1'
|
||||
className='tw:block tw:text-sm tw:font-medium tw:text-base-content/50 tw:mb-1'
|
||||
>
|
||||
{heading || 'Text'}:
|
||||
</label>
|
||||
@ -57,10 +57,9 @@ export const ProfileTextForm = ({
|
||||
[field]: v,
|
||||
}))
|
||||
}
|
||||
showMenu={size === 'full'}
|
||||
labelStyle={hideInputLabel ? 'tw:hidden' : ''}
|
||||
containerStyle={size === 'full' ? 'tw:grow tw:h-full' : ''}
|
||||
inputStyle={size === 'full' ? 'tw:h-full' : 'tw:h-24'}
|
||||
required={required}
|
||||
containerStyle={size === 'full' ? 'tw:flex-1' : 'tw:h-24 tw:flex-none'}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
|
||||
@ -33,6 +33,9 @@ export const TagsWidget = ({ placeholder, containerStyle, defaultTags, onUpdate
|
||||
}
|
||||
|
||||
const onKeyDown = (e) => {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault()
|
||||
}
|
||||
const { key } = e
|
||||
const trimmedInput = input.trim()
|
||||
|
||||
@ -42,7 +45,6 @@ export const TagsWidget = ({ placeholder, containerStyle, defaultTags, onUpdate
|
||||
// eslint-disable-next-line react/prop-types
|
||||
!defaultTags.some((tag) => tag.name.toLocaleLowerCase() === trimmedInput.toLocaleLowerCase())
|
||||
) {
|
||||
e.preventDefault()
|
||||
const newTag = tags.find((t) => t.name === trimmedInput.toLocaleLowerCase())
|
||||
newTag && onUpdate([...currentTags, newTag])
|
||||
!newTag &&
|
||||
|
||||
@ -30,7 +30,7 @@ export const FlexForm = ({
|
||||
item: Item
|
||||
}) => {
|
||||
return (
|
||||
<div className='tw:mt-6 tw:flex tw:flex-col tw:h-full'>
|
||||
<div className='tw:mt-6 tw:flex tw:flex-col tw:flex-1 tw:min-h-0'>
|
||||
{item.layer?.itemType.profileTemplate.map((templateItem) => {
|
||||
const TemplateComponent = componentMap[templateItem.collection]
|
||||
return TemplateComponent ? (
|
||||
@ -42,7 +42,7 @@ export const FlexForm = ({
|
||||
{...templateItem.item}
|
||||
/>
|
||||
) : (
|
||||
<div className='tw:mt-2' key={templateItem.id}>
|
||||
<div className='tw:mt-2 tw:flex-none' key={templateItem.id}>
|
||||
{templateItem.collection} form not found
|
||||
</div>
|
||||
)
|
||||
|
||||
@ -6,7 +6,6 @@
|
||||
/* eslint-disable @typescript-eslint/restrict-plus-operands */
|
||||
/* eslint-disable @typescript-eslint/no-unsafe-return */
|
||||
/* eslint-disable react/prop-types */
|
||||
import { useCallback, useEffect, useState } from 'react'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
|
||||
import { RichTextEditor } from '#components/Input/RichTextEditor'
|
||||
@ -15,6 +14,7 @@ import { PopupStartEndInput, TextView } from '#components/Map/Subcomponents/Item
|
||||
import { ActionButton } from '#components/Profile/Subcomponents/ActionsButton'
|
||||
import { LinkedItemsHeaderView } from '#components/Profile/Subcomponents/LinkedItemsHeaderView'
|
||||
import { TagsWidget } from '#components/Profile/Subcomponents/TagsWidget'
|
||||
import { Tabs } from '#components/Templates/Tabs'
|
||||
|
||||
export const TabsForm = ({
|
||||
item,
|
||||
@ -26,114 +26,73 @@ export const TabsForm = ({
|
||||
loading,
|
||||
setUrlParams,
|
||||
}) => {
|
||||
const [activeTab, setActiveTab] = useState<number>(1)
|
||||
const navigate = useNavigate()
|
||||
const updateItem = useUpdateItem()
|
||||
|
||||
const updateActiveTab = useCallback(
|
||||
(id: number) => {
|
||||
setActiveTab(id)
|
||||
|
||||
const params = new URLSearchParams(window.location.search)
|
||||
|
||||
params.set('tab', `${id}`)
|
||||
const newUrl = location.pathname + '?' + params.toString()
|
||||
window.history.pushState({}, '', newUrl)
|
||||
setUrlParams(params)
|
||||
},
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[location.pathname],
|
||||
)
|
||||
|
||||
useEffect(() => {
|
||||
const params = new URLSearchParams(location.search)
|
||||
const urlTab = params.get('tab')
|
||||
setActiveTab(urlTab ? Number(urlTab) : 1)
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [location.search])
|
||||
const navigate = useNavigate()
|
||||
|
||||
return (
|
||||
<div className='tw:grow'>
|
||||
<div role='tablist' className='tw:tabs tw:h-full tw:tabs-lift tw:mt-3'>
|
||||
<input
|
||||
type='radio'
|
||||
name='my_tabs_2'
|
||||
role='tab'
|
||||
className={'tw:tab '}
|
||||
aria-label='Info'
|
||||
checked={activeTab === 1 && true}
|
||||
onChange={() => updateActiveTab(1)}
|
||||
/>
|
||||
<div
|
||||
role='tabpanel'
|
||||
className='tw:tab-content tw:bg-base-100 tw:border-(--fallback-bc,oklch(var(--bc)/0.2)) tw:rounded-box tw:!h-[calc(100%-48px)] tw:min-h-56 tw:border-none'
|
||||
>
|
||||
<div
|
||||
className={`tw:flex tw:flex-col tw:h-full ${item.layer.itemType.show_start_end_input && 'tw:pt-4'}`}
|
||||
>
|
||||
{item.layer.itemType.show_start_end_input && (
|
||||
<PopupStartEndInput
|
||||
item={item}
|
||||
showLabels={false}
|
||||
updateEndValue={(e) =>
|
||||
setState((prevState) => ({
|
||||
...prevState,
|
||||
end: e,
|
||||
}))
|
||||
}
|
||||
updateStartValue={(s) =>
|
||||
setState((prevState) => ({
|
||||
...prevState,
|
||||
start: s,
|
||||
}))
|
||||
}
|
||||
></PopupStartEndInput>
|
||||
)}
|
||||
<div className='tw:flex tw:flex-col tw:flex-1 tw:min-h-0 tw:mt-4'>
|
||||
<Tabs
|
||||
setUrlParams={setUrlParams}
|
||||
items={[
|
||||
{
|
||||
title: 'Info',
|
||||
component: (
|
||||
<div
|
||||
className={`tw:flex tw:flex-col tw:flex-1 tw:min-h-0 ${item.layer.itemType.show_start_end_input && 'tw:pt-4'}`}
|
||||
>
|
||||
{item.layer.itemType.show_start_end_input && (
|
||||
<PopupStartEndInput
|
||||
item={item}
|
||||
showLabels={true}
|
||||
labelStyle={'tw:text-base-content/50'}
|
||||
updateEndValue={(e) =>
|
||||
setState((prevState) => ({
|
||||
...prevState,
|
||||
end: e,
|
||||
}))
|
||||
}
|
||||
updateStartValue={(s) =>
|
||||
setState((prevState) => ({
|
||||
...prevState,
|
||||
start: s,
|
||||
}))
|
||||
}
|
||||
></PopupStartEndInput>
|
||||
)}
|
||||
|
||||
<RichTextEditor
|
||||
labelTitle='About me'
|
||||
placeholder='about ...'
|
||||
defaultValue={item?.text ? item.text : ''}
|
||||
updateFormValue={(v) =>
|
||||
setState((prevState) => ({
|
||||
...prevState,
|
||||
text: v,
|
||||
}))
|
||||
}
|
||||
containerStyle='tw:grow'
|
||||
inputStyle={`tw:h-full ${!item.layer.itemType.show_start_end_input && 'tw:border-t-0 tw:rounded-tl-none'}`}
|
||||
/>
|
||||
<RichTextEditor
|
||||
labelTitle='Contact Info'
|
||||
placeholder='contact info ...'
|
||||
defaultValue={state.contact || ''}
|
||||
updateFormValue={(c) =>
|
||||
setState((prevState) => ({
|
||||
...prevState,
|
||||
contact: c,
|
||||
}))
|
||||
}
|
||||
inputStyle=''
|
||||
containerStyle='tw:pt-4 tw:h-24 tw:flex-none'
|
||||
required={false}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
{item.layer?.itemType.offers_and_needs && (
|
||||
<>
|
||||
<input
|
||||
type='radio'
|
||||
name='my_tabs_2'
|
||||
role='tab'
|
||||
className={'tw:tab tw:min-w-[10em] '}
|
||||
aria-label='Offers & Needs'
|
||||
checked={activeTab === 3 && true}
|
||||
onChange={() => updateActiveTab(3)}
|
||||
/>
|
||||
<div
|
||||
role='tabpanel'
|
||||
className='tw:tab-content tw:bg-base-100 tw:border-(--fallback-bc,oklch(var(--bc)/0.2)) tw:rounded-box tw:!h-[calc(100%-48px)] tw:min-h-56 tw:border-none'
|
||||
>
|
||||
<RichTextEditor
|
||||
labelTitle='About'
|
||||
labelStyle={'tw:text-base-content/50'}
|
||||
placeholder='about ...'
|
||||
defaultValue={item?.text ? item.text : ''}
|
||||
updateFormValue={(v) =>
|
||||
setState((prevState) => ({
|
||||
...prevState,
|
||||
text: v,
|
||||
}))
|
||||
}
|
||||
containerStyle='tw:pt-2 tw:flex-1 tw:min-h-36 tw:max-h-136'
|
||||
/>
|
||||
<RichTextEditor
|
||||
labelTitle='Contact Info'
|
||||
labelStyle={'tw:text-base-content/50'}
|
||||
placeholder='contact info ...'
|
||||
defaultValue={state.contact || ''}
|
||||
updateFormValue={(c) =>
|
||||
setState((prevState) => ({
|
||||
...prevState,
|
||||
contact: c,
|
||||
}))
|
||||
}
|
||||
containerStyle='tw:pt-2 tw:h-36 tw:flex-none'
|
||||
showMenu={false}
|
||||
/>
|
||||
</div>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: 'Offers & Needs',
|
||||
component: (
|
||||
<div className='tw:h-full'>
|
||||
<div className='tw:w-full tw:h-[calc(50%-0.75em)] tw:mb-4'>
|
||||
<TagsWidget
|
||||
@ -162,24 +121,11 @@ export const TabsForm = ({
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
{item.layer?.itemType.relations && (
|
||||
<>
|
||||
<input
|
||||
type='radio'
|
||||
name='my_tabs_2'
|
||||
role='tab'
|
||||
className='tw:tab '
|
||||
aria-label='Links'
|
||||
checked={activeTab === 7 && true}
|
||||
onChange={() => updateActiveTab(7)}
|
||||
/>
|
||||
<div
|
||||
role='tabpanel'
|
||||
className='tw:tab-content tw:rounded-box tw:!h-[calc(100%-48px)] tw:overflow-y-auto tw:pt-4 tw:overflow-x-hidden fade'
|
||||
>
|
||||
),
|
||||
},
|
||||
{
|
||||
title: 'Links',
|
||||
component: (
|
||||
<div className='tw:h-full'>
|
||||
<div className='tw:grid tw:grid-cols-1 tw:sm:grid-cols-2 tw:md:grid-cols-1 tw:lg:grid-cols-1 tw:xl:grid-cols-1 tw:2xl:grid-cols-2 tw:mb-4'>
|
||||
{state.relations &&
|
||||
@ -211,10 +157,10 @@ export const TabsForm = ({
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
),
|
||||
},
|
||||
]}
|
||||
></Tabs>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@ -43,7 +43,7 @@ export const TabsView = ({
|
||||
unlinkItem: (id: string) => Promise<void>
|
||||
}) => {
|
||||
const addFilterTag = useAddFilterTag()
|
||||
const [activeTab, setActiveTab] = useState<number>()
|
||||
const [activeTab, setActiveTab] = useState<number>(0)
|
||||
const navigate = useNavigate()
|
||||
|
||||
const [addItemPopupType] = useState<string>('')
|
||||
@ -80,7 +80,7 @@ export const TabsView = ({
|
||||
useEffect(() => {
|
||||
const params = new URLSearchParams(location.search)
|
||||
const urlTab = params.get('tab')
|
||||
setActiveTab(urlTab ? Number(urlTab) : 1)
|
||||
setActiveTab(urlTab ? Number(urlTab) : 0)
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [location.search])
|
||||
|
||||
@ -91,9 +91,9 @@ export const TabsView = ({
|
||||
name='my_tabs_2'
|
||||
role='tab'
|
||||
className={'tw:tab tw:font-bold tw:ps-2! tw:pe-2! '}
|
||||
aria-label={`${item.layer?.itemType.icon_as_labels && activeTab !== 1 ? '📝' : '📝\u00A0Info'}`}
|
||||
checked={activeTab === 1 && true}
|
||||
onChange={() => updateActiveTab(1)}
|
||||
aria-label={`${item.layer?.itemType.icon_as_labels && activeTab !== 0 ? '📝' : '📝\u00A0Info'}`}
|
||||
checked={activeTab === 0 && true}
|
||||
onChange={() => updateActiveTab(0)}
|
||||
/>
|
||||
<div
|
||||
role='tabpanel'
|
||||
@ -115,9 +115,9 @@ export const TabsView = ({
|
||||
name='my_tabs_2'
|
||||
role='tab'
|
||||
className={'tw:tab tw:font-bold tw:ps-2! tw:pe-2!'}
|
||||
aria-label={`${item.layer.itemType.icon_as_labels && activeTab !== 2 ? '❤️' : '❤️\u00A0Trust'}`}
|
||||
checked={activeTab === 2 && true}
|
||||
onChange={() => updateActiveTab(2)}
|
||||
aria-label={`${item.layer.itemType.icon_as_labels && activeTab !== 3 ? '❤️' : '❤️\u00A0Trust'}`}
|
||||
checked={activeTab === 3 && true}
|
||||
onChange={() => updateActiveTab(3)}
|
||||
/>
|
||||
<div
|
||||
role='tabpanel'
|
||||
@ -197,10 +197,10 @@ export const TabsView = ({
|
||||
type='radio'
|
||||
name='my_tabs_2'
|
||||
role='tab'
|
||||
className={`tw:tab tw:font-bold tw:ps-2! tw:pe-2! ${!(item.layer.itemType.icon_as_labels && activeTab !== 3) && 'tw:min-w-[10.4em]'} `}
|
||||
aria-label={`${item.layer.itemType.icon_as_labels && activeTab !== 3 ? '♻️' : '♻️\u00A0Offers & Needs'}`}
|
||||
checked={activeTab === 3 && true}
|
||||
onChange={() => updateActiveTab(3)}
|
||||
className={`tw:tab tw:font-bold tw:ps-2! tw:pe-2! ${!(item.layer.itemType.icon_as_labels && activeTab !== 1) && 'tw:min-w-[10.4em]'} `}
|
||||
aria-label={`${item.layer.itemType.icon_as_labels && activeTab !== 1 ? '♻️' : '♻️\u00A0Offers & Needs'}`}
|
||||
checked={activeTab === 1 && true}
|
||||
onChange={() => updateActiveTab(1)}
|
||||
/>
|
||||
<div
|
||||
role='tabpanel'
|
||||
@ -251,9 +251,9 @@ export const TabsView = ({
|
||||
name='my_tabs_2'
|
||||
role='tab'
|
||||
className='tw:tab tw:font-bold tw:ps-2! tw:pe-2! '
|
||||
aria-label={`${item.layer.itemType.icon_as_labels && activeTab !== 7 ? '🔗' : '🔗\u00A0Links'}`}
|
||||
checked={activeTab === 7 && true}
|
||||
onChange={() => updateActiveTab(7)}
|
||||
aria-label={`${item.layer.itemType.icon_as_labels && activeTab !== 2 ? '🔗' : '🔗\u00A0Links'}`}
|
||||
checked={activeTab === 2 && true}
|
||||
onChange={() => updateActiveTab(2)}
|
||||
/>
|
||||
<div
|
||||
role='tabpanel'
|
||||
|
||||
65
src/Components/Templates/Tabs.tsx
Normal file
65
src/Components/Templates/Tabs.tsx
Normal file
@ -0,0 +1,65 @@
|
||||
/* eslint-disable security/detect-object-injection */
|
||||
import { useState, useEffect, useCallback } from 'react'
|
||||
import { useLocation, useNavigate } from 'react-router-dom'
|
||||
|
||||
interface TabItem {
|
||||
title: string
|
||||
component: React.ReactNode
|
||||
}
|
||||
|
||||
interface TabsProps {
|
||||
items: TabItem[]
|
||||
setUrlParams: (params: URLSearchParams) => void
|
||||
}
|
||||
|
||||
export const Tabs: React.FC<TabsProps> = ({ items, setUrlParams }: TabsProps) => {
|
||||
const location = useLocation()
|
||||
const navigate = useNavigate()
|
||||
|
||||
const [activeIndex, setActiveIndex] = useState<number>(0)
|
||||
|
||||
useEffect(() => {
|
||||
const params = new URLSearchParams(location.search)
|
||||
const urlTab = params.get('tab')
|
||||
if (urlTab !== null && !isNaN(Number(urlTab))) {
|
||||
const index = Number(urlTab)
|
||||
if (index >= 0 && index < items.length) {
|
||||
setActiveIndex(index)
|
||||
}
|
||||
}
|
||||
}, [items.length, location.search])
|
||||
|
||||
const updateActiveTab = useCallback(
|
||||
(index: number) => {
|
||||
setActiveIndex(index)
|
||||
|
||||
const params = new URLSearchParams(location.search)
|
||||
params.set('tab', `${index}`)
|
||||
setUrlParams(params)
|
||||
const newUrl = location.pathname + '?' + params.toString()
|
||||
|
||||
navigate(newUrl, { replace: false })
|
||||
},
|
||||
[location.pathname, location.search, navigate, setUrlParams],
|
||||
)
|
||||
|
||||
return (
|
||||
<div className='tw:flex tw:flex-col tw:flex-1 tw:min-h-0'>
|
||||
<div role='tablist' className='tw:tabs tw:tabs-lift tw:flex-none'>
|
||||
{items.map((item, index) => (
|
||||
<div
|
||||
key={index}
|
||||
role='tab'
|
||||
className={`tw:tab ${index === activeIndex ? 'tw:tab-active' : ''}`}
|
||||
onClick={() => updateActiveTab(index)}
|
||||
>
|
||||
{item.title}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className='tw:flex-1 tw:flex tw:flex-col tw:min-h-0'>
|
||||
{items[activeIndex]?.component}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@ -1,63 +1,63 @@
|
||||
@import 'tailwindcss' prefix(tw);
|
||||
|
||||
@layer markdown {
|
||||
.markdown h1 {
|
||||
@apply tw:text-xl;
|
||||
@apply tw:font-bold;
|
||||
}
|
||||
.markdown {
|
||||
h1 {
|
||||
@apply tw:my-4 tw:text-2xl tw:font-bold;
|
||||
}
|
||||
|
||||
.markdown h2 {
|
||||
@apply tw:text-lg;
|
||||
@apply tw:font-bold;
|
||||
}
|
||||
h2 {
|
||||
@apply tw:my-3 tw:text-xl tw:font-bold;
|
||||
}
|
||||
|
||||
.markdown h3, .markdown h4 {
|
||||
@apply tw:text-base;
|
||||
@apply tw:font-bold;
|
||||
}
|
||||
h3, h4 {
|
||||
@apply tw:my-2 tw:text-lg tw:font-bold;
|
||||
}
|
||||
|
||||
.markdown h5, .markdown h6 {
|
||||
@apply tw:text-sm;
|
||||
@apply tw:font-bold;
|
||||
}
|
||||
h5, h6 {
|
||||
@apply tw:my-2 tw:text-base tw:font-bold;
|
||||
}
|
||||
|
||||
.markdown p {
|
||||
@apply tw:my-2!;
|
||||
}
|
||||
p {
|
||||
@apply tw:my-1 tw:leading-relaxed;
|
||||
}
|
||||
|
||||
.markdown ul {
|
||||
@apply tw:list-disc;
|
||||
@apply tw:list-inside;
|
||||
}
|
||||
ul, ol {
|
||||
@apply tw:pl-6 tw:my-2;
|
||||
}
|
||||
|
||||
.markdown ol {
|
||||
@apply tw:list-decimal;
|
||||
@apply tw:list-inside;
|
||||
}
|
||||
ul li {
|
||||
@apply tw:list-disc tw:list-outside;
|
||||
}
|
||||
|
||||
.markdown hl {
|
||||
@apply tw:border-current;
|
||||
}
|
||||
ol li {
|
||||
@apply tw:list-decimal tw:list-outside;
|
||||
}
|
||||
|
||||
.markdown img {
|
||||
@apply tw:max-w-full;
|
||||
@apply tw:rounded;
|
||||
@apply tw:shadow;
|
||||
}
|
||||
li > p {
|
||||
@apply tw:inline-block tw:my-0;
|
||||
}
|
||||
|
||||
.markdown a {
|
||||
@apply tw:font-bold;
|
||||
@apply tw:underline;
|
||||
}
|
||||
hr {
|
||||
@apply tw:my-4 tw:border-current;
|
||||
}
|
||||
|
||||
.markdown .hashtag {
|
||||
color: #faa;
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
img {
|
||||
@apply tw:max-w-full tw:rounded tw:shadow;
|
||||
}
|
||||
|
||||
.markdown iframe {
|
||||
@apply tw:w-full;
|
||||
a {
|
||||
@apply tw:font-bold tw:underline;
|
||||
}
|
||||
|
||||
iframe {
|
||||
@apply tw:w-full tw:aspect-video;
|
||||
}
|
||||
|
||||
.hashtag {
|
||||
@apply tw:font-bold tw:cursor-pointer;
|
||||
color: #faa;
|
||||
text-decoration: none;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
43
src/assets/css/tiptap.css
Normal file
43
src/assets/css/tiptap.css
Normal file
@ -0,0 +1,43 @@
|
||||
|
||||
|
||||
.editor-wrapper div {
|
||||
min-height: 0;
|
||||
flex: 1;
|
||||
outline: none;
|
||||
}
|
||||
|
||||
.tiptap p.is-editor-empty:first-child::before {
|
||||
color: var(--color-base-content);
|
||||
opacity: 0.5;
|
||||
content: attr(data-placeholder);
|
||||
float: left;
|
||||
height: 0;
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
/* Bubble menu */
|
||||
.bubble-menu {
|
||||
background-color: var(--color-base-100);
|
||||
border: 1px solid var(--color-base-200);
|
||||
border-radius: 0.7rem;
|
||||
box-shadow: var(--shadow);
|
||||
display: flex;
|
||||
padding: 0.2rem;
|
||||
|
||||
button {
|
||||
background-color: unset;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--color-base-300);
|
||||
}
|
||||
|
||||
&.is-active {
|
||||
background-color: var(--color-base-200);
|
||||
|
||||
&:hover {
|
||||
background-color: var(--color-base-300);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,3 +14,4 @@ import '#assets/css/marker-icons.css'
|
||||
import '#assets/css/leaflet.css'
|
||||
import '#assets/css/color-picker.css'
|
||||
import '#assets/css/markdown.css'
|
||||
import '#assets/css/tiptap.css'
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user