From 6199bcf3a5d444c8c7c16147a0618bf7c4731796 Mon Sep 17 00:00:00 2001 From: Bartosz Gotowski Date: Mon, 28 Oct 2024 21:40:53 +0100 Subject: [PATCH 1/6] fix: wysiwyg lool --- .eslintrc.json | 3 +- @types/nextjs-routes.d.ts | 2 +- package-lock.json | 2436 ++++++++++++++--- package.json | 19 + src/components/landing/MobileMenu.tsx | 4 +- src/components/landing/Navbar.tsx | 5 +- .../bubble-menu/image-bubble-menu.tsx | 41 + .../bubble-menu/link-bubble-menu.tsx | 118 + .../components/image/image-edit-block.tsx | 94 + .../components/image/image-edit-dialog.tsx | 57 + .../components/image/image-popover-block.tsx | 26 + .../components/link/link-edit-block.tsx | 97 + .../components/link/link-edit-popover.tsx | 75 + .../components/link/link-popover-block.tsx | 84 + .../components/section/five.tsx | 94 + .../components/section/four.tsx | 82 + .../minimal-tiptap/components/section/one.tsx | 154 ++ .../components/section/three.tsx | 220 ++ .../minimal-tiptap/components/section/two.tsx | 116 + .../components/shortcut-key.tsx | 44 + .../components/toolbar-button.tsx | 55 + .../components/toolbar-section.tsx | 124 + .../code-block-lowlight.ts | 16 + .../extensions/code-block-lowlight/index.ts | 1 + .../minimal-tiptap/extensions/color/color.ts | 20 + .../minimal-tiptap/extensions/color/index.ts | 1 + .../horizontal-rule/horizontal-rule.ts | 16 + .../extensions/horizontal-rule/index.ts | 1 + .../minimal-tiptap/extensions/index.ts | 7 + .../minimal-tiptap/extensions/link/index.ts | 1 + .../minimal-tiptap/extensions/link/link.ts | 97 + .../extensions/reset-marks-on-enter/index.ts | 1 + .../reset-marks-on-enter.ts | 25 + .../extensions/selection/index.ts | 1 + .../extensions/selection/selection.ts | 34 + .../extensions/unset-all-marks/index.ts | 1 + .../unset-all-marks/unset-all-marks.ts | 9 + .../hooks/use-minimal-tiptap.ts | 119 + .../minimal-tiptap/hooks/use-theme.ts | 25 + .../minimal-tiptap/hooks/use-throttle.ts | 34 + src/components/minimal-tiptap/index.ts | 1 + .../minimal-tiptap/minimal-tiptap.tsx | 102 + .../minimal-tiptap/styles/index.css | 182 ++ .../minimal-tiptap/styles/partials/code.css | 86 + .../minimal-tiptap/styles/partials/lists.css | 93 + .../styles/partials/placeholder.css | 4 + .../styles/partials/typography.css | 27 + src/components/minimal-tiptap/types.ts | 22 + src/components/minimal-tiptap/utils.ts | 89 + src/components/ui/separator.tsx | 29 + src/components/ui/switch.tsx | 27 + src/components/ui/toggle-group.tsx | 59 + src/components/ui/toggle.tsx | 70 +- src/lib/types.ts | 84 +- src/pages/_app.tsx | 27 +- src/pages/editor.tsx | 24 + src/pages/event/[slug]/settings.tsx | 66 +- src/pages/object.tsx | 151 - .../[blockId]/[reservationId].tsx | 12 +- .../rejestracja/[participationSlug]/index.tsx | 43 +- supabase/.temp/cli-latest | 1 + 61 files changed, 4853 insertions(+), 705 deletions(-) create mode 100644 src/components/minimal-tiptap/components/bubble-menu/image-bubble-menu.tsx create mode 100644 src/components/minimal-tiptap/components/bubble-menu/link-bubble-menu.tsx create mode 100644 src/components/minimal-tiptap/components/image/image-edit-block.tsx create mode 100644 src/components/minimal-tiptap/components/image/image-edit-dialog.tsx create mode 100644 src/components/minimal-tiptap/components/image/image-popover-block.tsx create mode 100644 src/components/minimal-tiptap/components/link/link-edit-block.tsx create mode 100644 src/components/minimal-tiptap/components/link/link-edit-popover.tsx create mode 100644 src/components/minimal-tiptap/components/link/link-popover-block.tsx create mode 100644 src/components/minimal-tiptap/components/section/five.tsx create mode 100644 src/components/minimal-tiptap/components/section/four.tsx create mode 100644 src/components/minimal-tiptap/components/section/one.tsx create mode 100644 src/components/minimal-tiptap/components/section/three.tsx create mode 100644 src/components/minimal-tiptap/components/section/two.tsx create mode 100644 src/components/minimal-tiptap/components/shortcut-key.tsx create mode 100644 src/components/minimal-tiptap/components/toolbar-button.tsx create mode 100644 src/components/minimal-tiptap/components/toolbar-section.tsx create mode 100644 src/components/minimal-tiptap/extensions/code-block-lowlight/code-block-lowlight.ts create mode 100644 src/components/minimal-tiptap/extensions/code-block-lowlight/index.ts create mode 100644 src/components/minimal-tiptap/extensions/color/color.ts create mode 100644 src/components/minimal-tiptap/extensions/color/index.ts create mode 100644 src/components/minimal-tiptap/extensions/horizontal-rule/horizontal-rule.ts create mode 100644 src/components/minimal-tiptap/extensions/horizontal-rule/index.ts create mode 100644 src/components/minimal-tiptap/extensions/index.ts create mode 100644 src/components/minimal-tiptap/extensions/link/index.ts create mode 100644 src/components/minimal-tiptap/extensions/link/link.ts create mode 100644 src/components/minimal-tiptap/extensions/reset-marks-on-enter/index.ts create mode 100644 src/components/minimal-tiptap/extensions/reset-marks-on-enter/reset-marks-on-enter.ts create mode 100644 src/components/minimal-tiptap/extensions/selection/index.ts create mode 100644 src/components/minimal-tiptap/extensions/selection/selection.ts create mode 100644 src/components/minimal-tiptap/extensions/unset-all-marks/index.ts create mode 100644 src/components/minimal-tiptap/extensions/unset-all-marks/unset-all-marks.ts create mode 100644 src/components/minimal-tiptap/hooks/use-minimal-tiptap.ts create mode 100644 src/components/minimal-tiptap/hooks/use-theme.ts create mode 100644 src/components/minimal-tiptap/hooks/use-throttle.ts create mode 100644 src/components/minimal-tiptap/index.ts create mode 100644 src/components/minimal-tiptap/minimal-tiptap.tsx create mode 100644 src/components/minimal-tiptap/styles/index.css create mode 100644 src/components/minimal-tiptap/styles/partials/code.css create mode 100644 src/components/minimal-tiptap/styles/partials/lists.css create mode 100644 src/components/minimal-tiptap/styles/partials/placeholder.css create mode 100644 src/components/minimal-tiptap/styles/partials/typography.css create mode 100644 src/components/minimal-tiptap/types.ts create mode 100644 src/components/minimal-tiptap/utils.ts create mode 100644 src/components/ui/separator.tsx create mode 100644 src/components/ui/switch.tsx create mode 100644 src/components/ui/toggle-group.tsx create mode 100644 src/pages/editor.tsx delete mode 100644 src/pages/object.tsx create mode 100644 supabase/.temp/cli-latest diff --git a/.eslintrc.json b/.eslintrc.json index 4ab735c..65ccb52 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -18,7 +18,8 @@ "rules": { "simple-import-sort/imports": "off", "simple-import-sort/exports": "off", - "@typescript-eslint/no-magic-numbers": "off" + "@typescript-eslint/no-magic-numbers": "off", + "no-extra-boolean-cast": "off" }, "overrides": [ { diff --git a/@types/nextjs-routes.d.ts b/@types/nextjs-routes.d.ts index bb26cc6..6de7ce5 100644 --- a/@types/nextjs-routes.d.ts +++ b/@types/nextjs-routes.d.ts @@ -12,9 +12,9 @@ declare module "nextjs-routes" { export type Route = | StaticRoute<"/"> + | StaticRoute<"/editor"> | DynamicRoute<"/event/[slug]/preview", { "slug": string }> | DynamicRoute<"/event/[slug]/settings", { "slug": string }> - | StaticRoute<"/object"> | DynamicRoute<"/rejestracja/[participationSlug]", { "participationSlug": string }> | DynamicRoute<"/rejestracja/[participationSlug]/[blockId]/[reservationId]", { "participationSlug": string; "blockId": string; "reservationId": string }> | DynamicRoute<"/rejestracja/[participationSlug]/[blockId]/formularz", { "participationSlug": string; "blockId": string }>; diff --git a/package-lock.json b/package-lock.json index 00df3ad..ea0ffc9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -20,9 +20,13 @@ "@radix-ui/react-popover": "^1.0.7", "@radix-ui/react-scroll-area": "^1.0.5", "@radix-ui/react-select": "^2.0.0", + "@radix-ui/react-separator": "^1.1.0", "@radix-ui/react-slot": "^1.0.2", + "@radix-ui/react-switch": "^1.1.1", "@radix-ui/react-tabs": "^1.0.4", "@radix-ui/react-toast": "^1.1.5", + "@radix-ui/react-toggle": "^1.1.0", + "@radix-ui/react-toggle-group": "^1.1.0", "@radix-ui/react-tooltip": "^1.1.2", "@supabase/ssr": "^0.5.1", "@supabase/supabase-js": "^2.43.4", @@ -30,6 +34,19 @@ "@tabler/icons-react": "^3.5.0", "@tanstack/react-query": "^5.40.1", "@tanstack/react-table": "^8.19.2", + "@tiptap/core": "^2.8.0", + "@tiptap/extension-code-block-lowlight": "^2.8.0", + "@tiptap/extension-color": "^2.8.0", + "@tiptap/extension-heading": "^2.8.0", + "@tiptap/extension-horizontal-rule": "^2.8.0", + "@tiptap/extension-image": "^2.8.0", + "@tiptap/extension-link": "^2.8.0", + "@tiptap/extension-placeholder": "^2.8.0", + "@tiptap/extension-text-style": "^2.8.0", + "@tiptap/extension-typography": "^2.8.0", + "@tiptap/pm": "^2.8.0", + "@tiptap/react": "^2.8.0", + "@tiptap/starter-kit": "^2.8.0", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", "cmdk": "^1.0.0", @@ -37,6 +54,7 @@ "framer-motion": "^11.2.9", "i18next": "^23.11.5", "jotai": "^2.10.0", + "lowlight": "^3.1.0", "lucide-react": "^0.379.0", "next": "14.2.3", "next-themes": "^0.3.0", @@ -51,6 +69,7 @@ "sonner": "^1.4.41", "tailwind-merge": "^2.3.0", "tailwindcss-animate": "^1.0.7", + "tiptap-extension-resize-image": "^1.1.9", "uuid": "^10.0.0", "zod": "^3.23.8", "zod-i18n-map": "^2.27.0" @@ -2291,6 +2310,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/@radix-ui/number": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/@radix-ui/number/-/number-1.0.1.tgz", @@ -3237,46 +3266,19 @@ } } }, - "node_modules/@radix-ui/react-slot": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.2.tgz", - "integrity": "sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==", - "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-compose-refs": "1.0.1" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-tabs": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.0.4.tgz", - "integrity": "sha512-egZfYY/+wRNCflXNHx+dePvnz9FbmssDTJBtgRfDY7e8SE5oIo3Py2eCB1ckAbh1Q7cQ/6yJZThJ++sgbxibog==", + "node_modules/@radix-ui/react-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-separator/-/react-separator-1.1.0.tgz", + "integrity": "sha512-3uBAs+egzvJBDZAzvb/n4NxxOYpnspmWxO2u5NbZ8Y6FM/NdrGSF9bop3Cf6F6C71z1rTSn8KV0Fo2ZVd79lGA==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/primitive": "1.0.1", - "@radix-ui/react-context": "1.0.1", - "@radix-ui/react-direction": "1.0.1", - "@radix-ui/react-id": "1.0.1", - "@radix-ui/react-presence": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-roving-focus": "1.0.4", - "@radix-ui/react-use-controllable-state": "1.0.1" + "@radix-ui/react-primitive": "2.0.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -3287,59 +3289,28 @@ } } }, - "node_modules/@radix-ui/react-toast": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/@radix-ui/react-toast/-/react-toast-1.1.5.tgz", - "integrity": "sha512-fRLn227WHIBRSzuRzGJ8W+5YALxofH23y0MlPLddaIpLpCDqdE0NZlS2NRQDRiptfxDeeCjgFIpexB1/zkxDlw==", + "node_modules/@radix-ui/react-separator/node_modules/@radix-ui/react-compose-refs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz", + "integrity": "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==", "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/primitive": "1.0.1", - "@radix-ui/react-collection": "1.0.3", - "@radix-ui/react-compose-refs": "1.0.1", - "@radix-ui/react-context": "1.0.1", - "@radix-ui/react-dismissable-layer": "1.0.5", - "@radix-ui/react-portal": "1.0.4", - "@radix-ui/react-presence": "1.0.1", - "@radix-ui/react-primitive": "1.0.3", - "@radix-ui/react-use-callback-ref": "1.0.1", - "@radix-ui/react-use-controllable-state": "1.0.1", - "@radix-ui/react-use-layout-effect": "1.0.1", - "@radix-ui/react-visually-hidden": "1.0.3" - }, "peerDependencies": { "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { "optional": true - }, - "@types/react-dom": { - "optional": true } } }, - "node_modules/@radix-ui/react-tooltip": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.1.2.tgz", - "integrity": "sha512-9XRsLwe6Yb9B/tlnYCPVUd/TFS4J7HuOZW345DCeC6vKIxQGMZdx21RK4VoZauPD5frgkXTYVS5y90L+3YBn4w==", + "node_modules/@radix-ui/react-separator/node_modules/@radix-ui/react-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz", + "integrity": "sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==", "license": "MIT", "dependencies": { - "@radix-ui/primitive": "1.1.0", - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-context": "1.1.0", - "@radix-ui/react-dismissable-layer": "1.1.0", - "@radix-ui/react-id": "1.1.0", - "@radix-ui/react-popper": "1.2.0", - "@radix-ui/react-portal": "1.1.1", - "@radix-ui/react-presence": "1.1.0", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-slot": "1.1.0", - "@radix-ui/react-use-controllable-state": "1.1.0", - "@radix-ui/react-visually-hidden": "1.1.0" + "@radix-ui/react-slot": "1.1.0" }, "peerDependencies": { "@types/react": "*", @@ -3356,40 +3327,14 @@ } } }, - "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/primitive": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.0.tgz", - "integrity": "sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==", - "license": "MIT" - }, - "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-arrow": { + "node_modules/@radix-ui/react-separator/node_modules/@radix-ui/react-slot": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.0.tgz", - "integrity": "sha512-FmlW1rCg7hBpEBwFbjHwCW6AmWLQM6g/v0Sn8XbP9NvmSZ2San1FpQeyPtufzOMSIx7Y4dzjlHoifhp+7NkZhw==", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz", + "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==", "license": "MIT", "dependencies": { - "@radix-ui/react-primitive": "2.0.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "@radix-ui/react-compose-refs": "1.1.0" }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-compose-refs": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz", - "integrity": "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==", - "license": "MIT", "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" @@ -3400,14 +3345,18 @@ } } }, - "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-context": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz", - "integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==", + "node_modules/@radix-ui/react-slot": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.0.2.tgz", + "integrity": "sha512-YeTpuq4deV+6DusvVUW4ivBgnkHwECUu0BiN43L5UCDFgdhsRUWAghhTF5MbvNTPzmiFOx90asDSUjWuCNapwg==", "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-compose-refs": "1.0.1" + }, "peerDependencies": { "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "react": "^16.8 || ^17.0 || ^18.0" }, "peerDependenciesMeta": { "@types/react": { @@ -3415,17 +3364,19 @@ } } }, - "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-dismissable-layer": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.0.tgz", - "integrity": "sha512-/UovfmmXGptwGcBQawLzvn2jOfM0t4z3/uKffoBlj724+n3FvBbZ7M0aaBOmkp6pqFYpO4yx8tSVJjx3Fl2jig==", + "node_modules/@radix-ui/react-switch": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-switch/-/react-switch-1.1.1.tgz", + "integrity": "sha512-diPqDDoBcZPSicYoMWdWx+bCPuTRH4QSp9J+65IvtdS0Kuzt67bI6n32vCj8q6NZmYW/ah+2orOtMwcX5eQwIg==", "license": "MIT", "dependencies": { "@radix-ui/primitive": "1.1.0", "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.1", "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-use-callback-ref": "1.1.0", - "@radix-ui/react-use-escape-keydown": "1.1.0" + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-use-previous": "1.1.0", + "@radix-ui/react-use-size": "1.1.0" }, "peerDependencies": { "@types/react": "*", @@ -3442,105 +3393,43 @@ } } }, - "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-id": { + "node_modules/@radix-ui/react-switch/node_modules/@radix-ui/primitive": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.0.tgz", - "integrity": "sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-use-layout-effect": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.0.tgz", + "integrity": "sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==", + "license": "MIT" }, - "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-popper": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.0.tgz", - "integrity": "sha512-ZnRMshKF43aBxVWPWvbj21+7TQCvhuULWJ4gNIKYpRlQt5xGRhLx66tMp8pya2UkGHTSlhpXwmjqltDYHhw7Vg==", + "node_modules/@radix-ui/react-switch/node_modules/@radix-ui/react-compose-refs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz", + "integrity": "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==", "license": "MIT", - "dependencies": { - "@floating-ui/react-dom": "^2.0.0", - "@radix-ui/react-arrow": "1.1.0", - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-context": "1.1.0", - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-use-callback-ref": "1.1.0", - "@radix-ui/react-use-layout-effect": "1.1.0", - "@radix-ui/react-use-rect": "1.1.0", - "@radix-ui/react-use-size": "1.1.0", - "@radix-ui/rect": "1.1.0" - }, "peerDependencies": { "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { "optional": true - }, - "@types/react-dom": { - "optional": true } } }, - "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-portal": { + "node_modules/@radix-ui/react-switch/node_modules/@radix-ui/react-context": { "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.1.tgz", - "integrity": "sha512-A3UtLk85UtqhzFqtoC8Q0KvR2GbXF3mtPgACSazajqq6A41mEQgo53iPzY4i6BwDxlIFqWIhiQ2G729n+2aw/g==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-primitive": "2.0.0", - "@radix-ui/react-use-layout-effect": "1.1.0" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-presence": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.0.tgz", - "integrity": "sha512-Gq6wuRN/asf9H/E/VzdKoUtT8GC9PQc9z40/vEr0VCJ4u5XvvhWIrSsCB6vD2/cH7ugTdSfYq9fLJCcM00acrQ==", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.1.tgz", + "integrity": "sha512-UASk9zi+crv9WteK/NU4PLvOoL3OuE6BWVKNF6hPRBtYBDXQ2u5iu3O59zUlJiTVvkyuycnqrztsHVJwcK9K+Q==", "license": "MIT", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.0", - "@radix-ui/react-use-layout-effect": "1.1.0" - }, "peerDependencies": { "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { "optional": true - }, - "@types/react-dom": { - "optional": true } } }, - "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-primitive": { + "node_modules/@radix-ui/react-switch/node_modules/@radix-ui/react-primitive": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz", "integrity": "sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==", @@ -3563,7 +3452,7 @@ } } }, - "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-slot": { + "node_modules/@radix-ui/react-switch/node_modules/@radix-ui/react-slot": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz", "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==", @@ -3581,7 +3470,7 @@ } } }, - "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-use-callback-ref": { + "node_modules/@radix-ui/react-switch/node_modules/@radix-ui/react-use-callback-ref": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz", "integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==", @@ -3596,7 +3485,7 @@ } } }, - "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-use-controllable-state": { + "node_modules/@radix-ui/react-switch/node_modules/@radix-ui/react-use-controllable-state": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz", "integrity": "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==", @@ -3614,14 +3503,11 @@ } } }, - "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-use-escape-keydown": { + "node_modules/@radix-ui/react-switch/node_modules/@radix-ui/react-use-layout-effect": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.0.tgz", - "integrity": "sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz", + "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==", "license": "MIT", - "dependencies": { - "@radix-ui/react-use-callback-ref": "1.1.0" - }, "peerDependencies": { "@types/react": "*", "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" @@ -3632,10 +3518,10 @@ } } }, - "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-use-layout-effect": { + "node_modules/@radix-ui/react-switch/node_modules/@radix-ui/react-use-previous": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz", - "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.1.0.tgz", + "integrity": "sha512-Z/e78qg2YFnnXcW88A4JmTtm4ADckLno6F7OXotmkQfeuCVaKuYzqAATPhVzl3delXE7CxIV8shofPn3jPc5Og==", "license": "MIT", "peerDependencies": { "@types/react": "*", @@ -3647,13 +3533,13 @@ } } }, - "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-use-rect": { + "node_modules/@radix-ui/react-switch/node_modules/@radix-ui/react-use-size": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.0.tgz", - "integrity": "sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.0.tgz", + "integrity": "sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==", "license": "MIT", "dependencies": { - "@radix-ui/rect": "1.1.0" + "@radix-ui/react-use-layout-effect": "1.1.0" }, "peerDependencies": { "@types/react": "*", @@ -3665,37 +3551,62 @@ } } }, - "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-use-size": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.0.tgz", - "integrity": "sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==", + "node_modules/@radix-ui/react-tabs": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.0.4.tgz", + "integrity": "sha512-egZfYY/+wRNCflXNHx+dePvnz9FbmssDTJBtgRfDY7e8SE5oIo3Py2eCB1ckAbh1Q7cQ/6yJZThJ++sgbxibog==", "license": "MIT", "dependencies": { - "@radix-ui/react-use-layout-effect": "1.1.0" + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-direction": "1.0.1", + "@radix-ui/react-id": "1.0.1", + "@radix-ui/react-presence": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-roving-focus": "1.0.4", + "@radix-ui/react-use-controllable-state": "1.0.1" }, "peerDependencies": { "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" }, "peerDependenciesMeta": { "@types/react": { "optional": true + }, + "@types/react-dom": { + "optional": true } } }, - "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-visually-hidden": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.1.0.tgz", - "integrity": "sha512-N8MDZqtgCgG5S3aV60INAB475osJousYpZ4cTJ2cFbMpdHS5Y6loLTH8LPtkj2QN0x93J30HT/M3qJXM0+lyeQ==", + "node_modules/@radix-ui/react-toast": { + "version": "1.1.5", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toast/-/react-toast-1.1.5.tgz", + "integrity": "sha512-fRLn227WHIBRSzuRzGJ8W+5YALxofH23y0MlPLddaIpLpCDqdE0NZlS2NRQDRiptfxDeeCjgFIpexB1/zkxDlw==", "license": "MIT", "dependencies": { - "@radix-ui/react-primitive": "2.0.0" + "@babel/runtime": "^7.13.10", + "@radix-ui/primitive": "1.0.1", + "@radix-ui/react-collection": "1.0.3", + "@radix-ui/react-compose-refs": "1.0.1", + "@radix-ui/react-context": "1.0.1", + "@radix-ui/react-dismissable-layer": "1.0.5", + "@radix-ui/react-portal": "1.0.4", + "@radix-ui/react-presence": "1.0.1", + "@radix-ui/react-primitive": "1.0.3", + "@radix-ui/react-use-callback-ref": "1.0.1", + "@radix-ui/react-use-controllable-state": "1.0.1", + "@radix-ui/react-use-layout-effect": "1.0.1", + "@radix-ui/react-visually-hidden": "1.0.3" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" }, "peerDependenciesMeta": { "@types/react": { @@ -3706,79 +3617,100 @@ } } }, - "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/rect": { + "node_modules/@radix-ui/react-toggle": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.0.tgz", - "integrity": "sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==", - "license": "MIT" - }, - "node_modules/@radix-ui/react-use-callback-ref": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.1.tgz", - "integrity": "sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ==", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle/-/react-toggle-1.1.0.tgz", + "integrity": "sha512-gwoxaKZ0oJ4vIgzsfESBuSgJNdc0rv12VhHgcqN0TEJmmZixXG/2XpsLK8kzNWYcnaoRIEEQc0bEi3dIvdUpjw==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.13.10" + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-controllable-state": "1.1.0" }, "peerDependencies": { "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { "optional": true + }, + "@types/react-dom": { + "optional": true } } }, - "node_modules/@radix-ui/react-use-controllable-state": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.0.1.tgz", - "integrity": "sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA==", + "node_modules/@radix-ui/react-toggle-group": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle-group/-/react-toggle-group-1.1.0.tgz", + "integrity": "sha512-PpTJV68dZU2oqqgq75Uzto5o/XfOVgkrJ9rulVmfTKxWp3HfUjHE6CP/WLRR4AzPX9HWxw7vFow2me85Yu+Naw==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-use-callback-ref": "1.0.1" + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-roving-focus": "1.1.0", + "@radix-ui/react-toggle": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0" }, "peerDependencies": { "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { "optional": true + }, + "@types/react-dom": { + "optional": true } } }, - "node_modules/@radix-ui/react-use-escape-keydown": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.3.tgz", - "integrity": "sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg==", + "node_modules/@radix-ui/react-toggle-group/node_modules/@radix-ui/primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.0.tgz", + "integrity": "sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==", + "license": "MIT" + }, + "node_modules/@radix-ui/react-toggle-group/node_modules/@radix-ui/react-collection": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.0.tgz", + "integrity": "sha512-GZsZslMJEyo1VKm5L1ZJY8tGDxZNPAoUeQUIbKeJfoi7Q4kmig5AsgLMYYuyYbfjd8fBmFORAIwYAkXMnXZgZw==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-use-callback-ref": "1.0.1" + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-slot": "1.1.0" }, "peerDependencies": { "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { "optional": true + }, + "@types/react-dom": { + "optional": true } } }, - "node_modules/@radix-ui/react-use-layout-effect": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.1.tgz", - "integrity": "sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ==", + "node_modules/@radix-ui/react-toggle-group/node_modules/@radix-ui/react-compose-refs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz", + "integrity": "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==", "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.13.10" - }, "peerDependencies": { "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -3786,17 +3718,14 @@ } } }, - "node_modules/@radix-ui/react-use-previous": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.0.1.tgz", - "integrity": "sha512-cV5La9DPwiQ7S0gf/0qiD6YgNqM5Fk97Kdrlc5yBcrF3jyEZQwm7vYFqMo4IfeHgJXsRaMvLABFtd0OVEmZhDw==", + "node_modules/@radix-ui/react-toggle-group/node_modules/@radix-ui/react-context": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz", + "integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==", "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.13.10" - }, "peerDependencies": { "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -3804,18 +3733,14 @@ } } }, - "node_modules/@radix-ui/react-use-rect": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.0.1.tgz", - "integrity": "sha512-Cq5DLuSiuYVKNU8orzJMbl15TXilTnJKUCltMVQg53BQOF1/C5toAaGrowkgksdBQ9H+SRL23g0HDmg9tvmxXw==", + "node_modules/@radix-ui/react-toggle-group/node_modules/@radix-ui/react-direction": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-direction/-/react-direction-1.1.0.tgz", + "integrity": "sha512-BUuBvgThEiAXh2DWu93XsT+a3aWrGqolGlqqw5VU1kG7p/ZH2cuDlM1sRLNnY3QcBS69UIz2mcKhMxDsdewhjg==", "license": "MIT", - "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/rect": "1.0.1" - }, "peerDependencies": { "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -3823,18 +3748,17 @@ } } }, - "node_modules/@radix-ui/react-use-size": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.0.1.tgz", - "integrity": "sha512-ibay+VqrgcaI6veAojjofPATwledXiSmX+C0KrBk/xgpX9rBzPV3OsfwlhQdUOFbh+LKQorLYT+xTXW9V8yd0g==", + "node_modules/@radix-ui/react-toggle-group/node_modules/@radix-ui/react-id": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.0.tgz", + "integrity": "sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-use-layout-effect": "1.0.1" + "@radix-ui/react-use-layout-effect": "1.1.0" }, "peerDependencies": { "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -3842,20 +3766,19 @@ } } }, - "node_modules/@radix-ui/react-visually-hidden": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.0.3.tgz", - "integrity": "sha512-D4w41yN5YRKtu464TLnByKzMDG/JlMPHtfZgQAu9v6mNakUqGUI9vUrfQKz8NK41VMm/xbZbh76NUTVtIYqOMA==", + "node_modules/@radix-ui/react-toggle-group/node_modules/@radix-ui/react-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz", + "integrity": "sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.13.10", - "@radix-ui/react-primitive": "1.0.3" + "@radix-ui/react-slot": "1.1.0" }, "peerDependencies": { "@types/react": "*", "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0", - "react-dom": "^16.8 || ^17.0 || ^18.0" + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { "@types/react": { @@ -3866,258 +3789,1476 @@ } } }, - "node_modules/@radix-ui/rect": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.0.1.tgz", - "integrity": "sha512-fyrgCaedtvMg9NK3en0pnOYJdtfwxUcNolezkNPUsoX57X8oQk+NkqcvzHXD2uKNij6GXmWU9NDru2IWjrO4BQ==", + "node_modules/@radix-ui/react-toggle-group/node_modules/@radix-ui/react-roving-focus": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.0.tgz", + "integrity": "sha512-EA6AMGeq9AEeQDeSH0aZgG198qkfHSbvWTf1HvoDmOB5bBG/qTxjYMWUKMnYiV6J/iP/J8MEFSuB2zRU2n7ODA==", "license": "MIT", "dependencies": { - "@babel/runtime": "^7.13.10" + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-collection": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-direction": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@rushstack/eslint-patch": { - "version": "1.10.3", - "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.10.3.tgz", - "integrity": "sha512-qC/xYId4NMebE6w/V33Fh9gWxLgURiNYgVNObbJl2LZv0GUUItCcCqC5axQSwRaAgaxl2mELq1rMzlswaQ0Zxg==", - "dev": true, - "license": "MIT" - }, - "node_modules/@snyk/github-codeowners": { + "node_modules/@radix-ui/react-toggle-group/node_modules/@radix-ui/react-slot": { "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@snyk/github-codeowners/-/github-codeowners-1.1.0.tgz", - "integrity": "sha512-lGFf08pbkEac0NYgVf4hdANpAgApRjNByLXB+WBip3qj1iendOIyAwP2GKkKbQMNVy2r1xxDf0ssfWscoiC+Vw==", - "dev": true, + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz", + "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==", "license": "MIT", "dependencies": { - "commander": "^4.1.1", - "ignore": "^5.1.8", - "p-map": "^4.0.0" + "@radix-ui/react-compose-refs": "1.1.0" }, - "bin": { - "github-codeowners": "dist/cli.js" + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, - "engines": { - "node": ">=8.10" + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/@supabase/auth-js": { - "version": "2.64.2", - "resolved": "https://registry.npmjs.org/@supabase/auth-js/-/auth-js-2.64.2.tgz", - "integrity": "sha512-s+lkHEdGiczDrzXJ1YWt2y3bxRi+qIUnXcgkpLSrId7yjBeaXBFygNjTaoZLG02KNcYwbuZ9qkEIqmj2hF7svw==", + "node_modules/@radix-ui/react-toggle-group/node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz", + "integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==", "license": "MIT", - "dependencies": { - "@supabase/node-fetch": "^2.6.14" + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/@supabase/functions-js": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/@supabase/functions-js/-/functions-js-2.3.1.tgz", - "integrity": "sha512-QyzNle/rVzlOi4BbVqxLSH828VdGY1RElqGFAj+XeVypj6+PVtMlD21G8SDnsPQDtlqqTtoGRgdMlQZih5hTuw==", + "node_modules/@radix-ui/react-toggle-group/node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz", + "integrity": "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==", "license": "MIT", "dependencies": { - "@supabase/node-fetch": "^2.6.14" - } - }, - "node_modules/@supabase/node-fetch": { - "version": "2.6.15", - "resolved": "https://registry.npmjs.org/@supabase/node-fetch/-/node-fetch-2.6.15.tgz", - "integrity": "sha512-1ibVeYUacxWYi9i0cf5efil6adJ9WRyZBLivgjs+AUpewx1F3xPi7gLgaASI2SmIQxPoCEjAsLAzKPgMJVgOUQ==", + "@radix-ui/react-use-callback-ref": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-toggle-group/node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz", + "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==", "license": "MIT", - "dependencies": { - "whatwg-url": "^5.0.0" + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, - "engines": { - "node": "4.x || >=6.0.0" + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/@supabase/postgrest-js": { - "version": "1.15.2", - "resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-1.15.2.tgz", - "integrity": "sha512-9/7pUmXExvGuEK1yZhVYXPZnLEkDTwxgMQHXLrN5BwPZZm4iUCL1YEyep/Z2lIZah8d8M433mVAUEGsihUj5KQ==", + "node_modules/@radix-ui/react-toggle/node_modules/@radix-ui/primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.0.tgz", + "integrity": "sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==", + "license": "MIT" + }, + "node_modules/@radix-ui/react-toggle/node_modules/@radix-ui/react-compose-refs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz", + "integrity": "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==", "license": "MIT", - "dependencies": { - "@supabase/node-fetch": "^2.6.14" + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/@supabase/realtime-js": { - "version": "2.9.5", - "resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-2.9.5.tgz", - "integrity": "sha512-TEHlGwNGGmKPdeMtca1lFTYCedrhTAv3nZVoSjrKQ+wkMmaERuCe57zkC5KSWFzLYkb5FVHW8Hrr+PX1DDwplQ==", + "node_modules/@radix-ui/react-toggle/node_modules/@radix-ui/react-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz", + "integrity": "sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==", "license": "MIT", "dependencies": { - "@supabase/node-fetch": "^2.6.14", - "@types/phoenix": "^1.5.4", - "@types/ws": "^8.5.10", - "ws": "^8.14.2" + "@radix-ui/react-slot": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@supabase/ssr": { - "version": "0.5.1", - "resolved": "https://registry.npmjs.org/@supabase/ssr/-/ssr-0.5.1.tgz", - "integrity": "sha512-+G94H/GZG0nErZ3FQV9yJmsC5Rj7dmcfCAwOt37hxeR1La+QTl8cE9whzYwPUrTJjMLGNXoO+1BMvVxwBAbz4g==", + "node_modules/@radix-ui/react-toggle/node_modules/@radix-ui/react-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz", + "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==", "license": "MIT", "dependencies": { - "cookie": "^0.6.0" + "@radix-ui/react-compose-refs": "1.1.0" }, "peerDependencies": { - "@supabase/supabase-js": "^2.43.4" + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/@supabase/storage-js": { - "version": "2.5.5", - "resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-2.5.5.tgz", - "integrity": "sha512-OpLoDRjFwClwc2cjTJZG8XviTiQH4Ik8sCiMK5v7et0MDu2QlXjCAW3ljxJB5+z/KazdMOTnySi+hysxWUPu3w==", + "node_modules/@radix-ui/react-toggle/node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz", + "integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-toggle/node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz", + "integrity": "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==", "license": "MIT", "dependencies": { - "@supabase/node-fetch": "^2.6.14" + "@radix-ui/react-use-callback-ref": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/@supabase/supabase-js": { - "version": "2.43.4", - "resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.43.4.tgz", - "integrity": "sha512-/pLPaxiIsn5Vaz3s32HC6O/VNwfeddnzS0bZRpOW0AKcPuXroD8pT9G8mpiBlZfpKsMmq6k7tlhW7Sr1PAQ1lw==", + "node_modules/@radix-ui/react-tooltip": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.1.2.tgz", + "integrity": "sha512-9XRsLwe6Yb9B/tlnYCPVUd/TFS4J7HuOZW345DCeC6vKIxQGMZdx21RK4VoZauPD5frgkXTYVS5y90L+3YBn4w==", "license": "MIT", "dependencies": { - "@supabase/auth-js": "2.64.2", - "@supabase/functions-js": "2.3.1", - "@supabase/node-fetch": "2.6.15", - "@supabase/postgrest-js": "1.15.2", - "@supabase/realtime-js": "2.9.5", - "@supabase/storage-js": "2.5.5" + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-dismissable-layer": "1.1.0", + "@radix-ui/react-id": "1.1.0", + "@radix-ui/react-popper": "1.2.0", + "@radix-ui/react-portal": "1.1.1", + "@radix-ui/react-presence": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-slot": "1.1.0", + "@radix-ui/react-use-controllable-state": "1.1.0", + "@radix-ui/react-visually-hidden": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@swc/counter": { - "version": "0.1.3", - "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", - "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", - "license": "Apache-2.0" + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/primitive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.0.tgz", + "integrity": "sha512-4Z8dn6Upk0qk4P74xBhZ6Hd/w0mPEzOOLxy4xiPXOXqjF7jZS0VAKk7/x/H6FyY2zCkYJqePf1G5KmkmNJ4RBA==", + "license": "MIT" }, - "node_modules/@swc/helpers": { - "version": "0.5.5", - "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.5.tgz", - "integrity": "sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==", - "license": "Apache-2.0", + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-arrow": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-arrow/-/react-arrow-1.1.0.tgz", + "integrity": "sha512-FmlW1rCg7hBpEBwFbjHwCW6AmWLQM6g/v0Sn8XbP9NvmSZ2San1FpQeyPtufzOMSIx7Y4dzjlHoifhp+7NkZhw==", + "license": "MIT", "dependencies": { - "@swc/counter": "^0.1.3", - "tslib": "^2.4.0" + "@radix-ui/react-primitive": "2.0.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } } }, - "node_modules/@t3-oss/env-core": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/@t3-oss/env-core/-/env-core-0.10.1.tgz", - "integrity": "sha512-GcKZiCfWks5CTxhezn9k5zWX3sMDIYf6Kaxy2Gx9YEQftFcz8hDRN56hcbylyAO3t4jQnQ5ifLawINsNgCDpOg==", + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-compose-refs": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-compose-refs/-/react-compose-refs-1.1.0.tgz", + "integrity": "sha512-b4inOtiaOnYf9KWyO3jAeeCG6FeyfY6ldiEPanbUjWd+xIk5wZeHa8yVwmrJ2vderhu/BQvzCrJI0lHd+wIiqw==", "license": "MIT", "peerDependencies": { - "typescript": ">=5.0.0", - "zod": "^3.0.0" + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" }, "peerDependenciesMeta": { - "typescript": { + "@types/react": { "optional": true } } }, - "node_modules/@t3-oss/env-nextjs": { - "version": "0.10.1", - "resolved": "https://registry.npmjs.org/@t3-oss/env-nextjs/-/env-nextjs-0.10.1.tgz", - "integrity": "sha512-iy2qqJLnFh1RjEWno2ZeyTu0ufomkXruUsOZludzDIroUabVvHsrSjtkHqwHp1/pgPUzN3yBRHMILW162X7x2Q==", + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-context": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.0.tgz", + "integrity": "sha512-OKrckBy+sMEgYM/sMmqmErVn0kZqrHPJze+Ql3DzYsDDp0hl0L62nx/2122/Bvps1qz645jlcu2tD9lrRSdf8A==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-dismissable-layer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-dismissable-layer/-/react-dismissable-layer-1.1.0.tgz", + "integrity": "sha512-/UovfmmXGptwGcBQawLzvn2jOfM0t4z3/uKffoBlj724+n3FvBbZ7M0aaBOmkp6pqFYpO4yx8tSVJjx3Fl2jig==", "license": "MIT", "dependencies": { - "@t3-oss/env-core": "0.10.1" + "@radix-ui/primitive": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-escape-keydown": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-id": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-id/-/react-id-1.1.0.tgz", + "integrity": "sha512-EJUrI8yYh7WOjNOqpoJaf1jlFIH2LvtgAl+YcFqNCa+4hj64ZXmPkAKOFs/ukjz3byN6bdb/AVUqHkI8/uWWMA==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-popper": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.0.tgz", + "integrity": "sha512-ZnRMshKF43aBxVWPWvbj21+7TQCvhuULWJ4gNIKYpRlQt5xGRhLx66tMp8pya2UkGHTSlhpXwmjqltDYHhw7Vg==", + "license": "MIT", + "dependencies": { + "@floating-ui/react-dom": "^2.0.0", + "@radix-ui/react-arrow": "1.1.0", + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-context": "1.1.0", + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-callback-ref": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0", + "@radix-ui/react-use-rect": "1.1.0", + "@radix-ui/react-use-size": "1.1.0", + "@radix-ui/rect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-portal": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-portal/-/react-portal-1.1.1.tgz", + "integrity": "sha512-A3UtLk85UtqhzFqtoC8Q0KvR2GbXF3mtPgACSazajqq6A41mEQgo53iPzY4i6BwDxlIFqWIhiQ2G729n+2aw/g==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.0.0", + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-presence": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-presence/-/react-presence-1.1.0.tgz", + "integrity": "sha512-Gq6wuRN/asf9H/E/VzdKoUtT8GC9PQc9z40/vEr0VCJ4u5XvvhWIrSsCB6vD2/cH7ugTdSfYq9fLJCcM00acrQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.0", + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-primitive": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.0.0.tgz", + "integrity": "sha512-ZSpFm0/uHa8zTvKBDjLFWLo8dkr4MBsiDLz0g3gMUwqgLHz9rTaRRGYDgvZPtBJgYCBKXkS9fzmoySgr8CO6Cw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-slot": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-slot": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.1.0.tgz", + "integrity": "sha512-FUCf5XMfmW4dtYl69pdS4DbxKy8nj4M7SafBgPllysxmdachynNflAdp/gCsnYWNDnge6tI9onzMp5ARYc1KNw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-compose-refs": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz", + "integrity": "sha512-CasTfvsy+frcFkbXtSJ2Zu9JHpN8TYKxkgJGWbjiZhFivxaeW7rMeZt7QELGVLaYVfFMsKHjb7Ak0nMEe+2Vfw==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.1.0.tgz", + "integrity": "sha512-MtfMVJiSr2NjzS0Aa90NPTnvTSg6C/JLCV7ma0W6+OMV78vd8OyRpID+Ng9LxzsPbLeuBnWBA1Nq30AtBIDChw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-callback-ref": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-use-escape-keydown": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.1.0.tgz", + "integrity": "sha512-L7vwWlR1kTTQ3oh7g1O0CBF3YCyyTj8NmhLR+phShpyA50HCfBFKVJTpshm9PzLiKmehsrQzTYTpX9HvmC9rhw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-callback-ref": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.1.0.tgz", + "integrity": "sha512-+FPE0rOdziWSrH9athwI1R0HDVbWlEhd+FR+aSDk4uWGmSJ9Z54sdZVDQPZAinJhJXwfT+qnj969mCsT2gfm5w==", + "license": "MIT", + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-use-rect": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.1.0.tgz", + "integrity": "sha512-0Fmkebhr6PiseyZlYAOtLS+nb7jLmpqTrJyv61Pe68MKYW6OWdRE2kI70TaYY27u7H0lajqM3hSMMLFq18Z7nQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/rect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-use-size": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.1.0.tgz", + "integrity": "sha512-XW3/vWuIXHa+2Uwcc2ABSfcCledmXhhQPlGbfcRXbiUQI5Icjcg19BGCZVKKInYbvUCut/ufbbLLPFC5cbb1hw==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-use-layout-effect": "1.1.0" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/react-visually-hidden": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.1.0.tgz", + "integrity": "sha512-N8MDZqtgCgG5S3aV60INAB475osJousYpZ4cTJ2cFbMpdHS5Y6loLTH8LPtkj2QN0x93J30HT/M3qJXM0+lyeQ==", + "license": "MIT", + "dependencies": { + "@radix-ui/react-primitive": "2.0.0" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", + "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-tooltip/node_modules/@radix-ui/rect": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.1.0.tgz", + "integrity": "sha512-A9+lCBZoaMJlVKcRBz2YByCG+Cp2t6nAnMnNba+XiWxnj6r4JUFqfsgwocMBZU9LPtdxC6wB56ySYpc7LQIoJg==", + "license": "MIT" + }, + "node_modules/@radix-ui/react-use-callback-ref": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.0.1.tgz", + "integrity": "sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-controllable-state": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-controllable-state/-/react-use-controllable-state-1.0.1.tgz", + "integrity": "sha512-Svl5GY5FQeN758fWKrjM6Qb7asvXeiZltlT4U2gVfl8Gx5UAv2sMR0LWo8yhsIZh2oQ0eFdZ59aoOOMV7b47VA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-callback-ref": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-escape-keydown": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-escape-keydown/-/react-use-escape-keydown-1.0.3.tgz", + "integrity": "sha512-vyL82j40hcFicA+M4Ex7hVkB9vHgSse1ZWomAqV2Je3RleKGO5iM8KMOEtfoSB0PnIelMd2lATjTGMYqN5ylTg==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-callback-ref": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-layout-effect": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-layout-effect/-/react-use-layout-effect-1.0.1.tgz", + "integrity": "sha512-v/5RegiJWYdoCvMnITBkNNx6bCj20fiaJnWtRkU18yITptraXjffz5Qbn05uOiQnOvi+dbkznkoaMltz1GnszQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-previous": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-previous/-/react-use-previous-1.0.1.tgz", + "integrity": "sha512-cV5La9DPwiQ7S0gf/0qiD6YgNqM5Fk97Kdrlc5yBcrF3jyEZQwm7vYFqMo4IfeHgJXsRaMvLABFtd0OVEmZhDw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.10" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-rect": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-rect/-/react-use-rect-1.0.1.tgz", + "integrity": "sha512-Cq5DLuSiuYVKNU8orzJMbl15TXilTnJKUCltMVQg53BQOF1/C5toAaGrowkgksdBQ9H+SRL23g0HDmg9tvmxXw==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/rect": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-use-size": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/react-use-size/-/react-use-size-1.0.1.tgz", + "integrity": "sha512-ibay+VqrgcaI6veAojjofPATwledXiSmX+C0KrBk/xgpX9rBzPV3OsfwlhQdUOFbh+LKQorLYT+xTXW9V8yd0g==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-use-layout-effect": "1.0.1" + }, + "peerDependencies": { + "@types/react": "*", + "react": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } + } + }, + "node_modules/@radix-ui/react-visually-hidden": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/@radix-ui/react-visually-hidden/-/react-visually-hidden-1.0.3.tgz", + "integrity": "sha512-D4w41yN5YRKtu464TLnByKzMDG/JlMPHtfZgQAu9v6mNakUqGUI9vUrfQKz8NK41VMm/xbZbh76NUTVtIYqOMA==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.10", + "@radix-ui/react-primitive": "1.0.3" + }, + "peerDependencies": { + "@types/react": "*", + "@types/react-dom": "*", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + } + } + }, + "node_modules/@radix-ui/rect": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@radix-ui/rect/-/rect-1.0.1.tgz", + "integrity": "sha512-fyrgCaedtvMg9NK3en0pnOYJdtfwxUcNolezkNPUsoX57X8oQk+NkqcvzHXD2uKNij6GXmWU9NDru2IWjrO4BQ==", + "license": "MIT", + "dependencies": { + "@babel/runtime": "^7.13.10" + } + }, + "node_modules/@remirror/core-constants": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/@remirror/core-constants/-/core-constants-3.0.0.tgz", + "integrity": "sha512-42aWfPrimMfDKDi4YegyS7x+/0tlzaqwPQCULLanv3DMIlu96KTJR0fM5isWX2UViOqlGnX6YFgqWepcX+XMNg==", + "license": "MIT" + }, + "node_modules/@rushstack/eslint-patch": { + "version": "1.10.3", + "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.10.3.tgz", + "integrity": "sha512-qC/xYId4NMebE6w/V33Fh9gWxLgURiNYgVNObbJl2LZv0GUUItCcCqC5axQSwRaAgaxl2mELq1rMzlswaQ0Zxg==", + "dev": true, + "license": "MIT" + }, + "node_modules/@snyk/github-codeowners": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@snyk/github-codeowners/-/github-codeowners-1.1.0.tgz", + "integrity": "sha512-lGFf08pbkEac0NYgVf4hdANpAgApRjNByLXB+WBip3qj1iendOIyAwP2GKkKbQMNVy2r1xxDf0ssfWscoiC+Vw==", + "dev": true, + "license": "MIT", + "dependencies": { + "commander": "^4.1.1", + "ignore": "^5.1.8", + "p-map": "^4.0.0" + }, + "bin": { + "github-codeowners": "dist/cli.js" + }, + "engines": { + "node": ">=8.10" + } + }, + "node_modules/@supabase/auth-js": { + "version": "2.64.2", + "resolved": "https://registry.npmjs.org/@supabase/auth-js/-/auth-js-2.64.2.tgz", + "integrity": "sha512-s+lkHEdGiczDrzXJ1YWt2y3bxRi+qIUnXcgkpLSrId7yjBeaXBFygNjTaoZLG02KNcYwbuZ9qkEIqmj2hF7svw==", + "license": "MIT", + "dependencies": { + "@supabase/node-fetch": "^2.6.14" + } + }, + "node_modules/@supabase/functions-js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/@supabase/functions-js/-/functions-js-2.3.1.tgz", + "integrity": "sha512-QyzNle/rVzlOi4BbVqxLSH828VdGY1RElqGFAj+XeVypj6+PVtMlD21G8SDnsPQDtlqqTtoGRgdMlQZih5hTuw==", + "license": "MIT", + "dependencies": { + "@supabase/node-fetch": "^2.6.14" + } + }, + "node_modules/@supabase/node-fetch": { + "version": "2.6.15", + "resolved": "https://registry.npmjs.org/@supabase/node-fetch/-/node-fetch-2.6.15.tgz", + "integrity": "sha512-1ibVeYUacxWYi9i0cf5efil6adJ9WRyZBLivgjs+AUpewx1F3xPi7gLgaASI2SmIQxPoCEjAsLAzKPgMJVgOUQ==", + "license": "MIT", + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + } + }, + "node_modules/@supabase/postgrest-js": { + "version": "1.15.2", + "resolved": "https://registry.npmjs.org/@supabase/postgrest-js/-/postgrest-js-1.15.2.tgz", + "integrity": "sha512-9/7pUmXExvGuEK1yZhVYXPZnLEkDTwxgMQHXLrN5BwPZZm4iUCL1YEyep/Z2lIZah8d8M433mVAUEGsihUj5KQ==", + "license": "MIT", + "dependencies": { + "@supabase/node-fetch": "^2.6.14" + } + }, + "node_modules/@supabase/realtime-js": { + "version": "2.9.5", + "resolved": "https://registry.npmjs.org/@supabase/realtime-js/-/realtime-js-2.9.5.tgz", + "integrity": "sha512-TEHlGwNGGmKPdeMtca1lFTYCedrhTAv3nZVoSjrKQ+wkMmaERuCe57zkC5KSWFzLYkb5FVHW8Hrr+PX1DDwplQ==", + "license": "MIT", + "dependencies": { + "@supabase/node-fetch": "^2.6.14", + "@types/phoenix": "^1.5.4", + "@types/ws": "^8.5.10", + "ws": "^8.14.2" + } + }, + "node_modules/@supabase/ssr": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@supabase/ssr/-/ssr-0.5.1.tgz", + "integrity": "sha512-+G94H/GZG0nErZ3FQV9yJmsC5Rj7dmcfCAwOt37hxeR1La+QTl8cE9whzYwPUrTJjMLGNXoO+1BMvVxwBAbz4g==", + "license": "MIT", + "dependencies": { + "cookie": "^0.6.0" + }, + "peerDependencies": { + "@supabase/supabase-js": "^2.43.4" + } + }, + "node_modules/@supabase/storage-js": { + "version": "2.5.5", + "resolved": "https://registry.npmjs.org/@supabase/storage-js/-/storage-js-2.5.5.tgz", + "integrity": "sha512-OpLoDRjFwClwc2cjTJZG8XviTiQH4Ik8sCiMK5v7et0MDu2QlXjCAW3ljxJB5+z/KazdMOTnySi+hysxWUPu3w==", + "license": "MIT", + "dependencies": { + "@supabase/node-fetch": "^2.6.14" + } + }, + "node_modules/@supabase/supabase-js": { + "version": "2.43.4", + "resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.43.4.tgz", + "integrity": "sha512-/pLPaxiIsn5Vaz3s32HC6O/VNwfeddnzS0bZRpOW0AKcPuXroD8pT9G8mpiBlZfpKsMmq6k7tlhW7Sr1PAQ1lw==", + "license": "MIT", + "dependencies": { + "@supabase/auth-js": "2.64.2", + "@supabase/functions-js": "2.3.1", + "@supabase/node-fetch": "2.6.15", + "@supabase/postgrest-js": "1.15.2", + "@supabase/realtime-js": "2.9.5", + "@supabase/storage-js": "2.5.5" + } + }, + "node_modules/@swc/counter": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.3.tgz", + "integrity": "sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==", + "license": "Apache-2.0" + }, + "node_modules/@swc/helpers": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.5.tgz", + "integrity": "sha512-KGYxvIOXcceOAbEk4bi/dVLEK9z8sZ0uBB3Il5b1rhfClSpcX0yfRO0KmTkqR2cnQDymwLB+25ZyMzICg/cm/A==", + "license": "Apache-2.0", + "dependencies": { + "@swc/counter": "^0.1.3", + "tslib": "^2.4.0" + } + }, + "node_modules/@t3-oss/env-core": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@t3-oss/env-core/-/env-core-0.10.1.tgz", + "integrity": "sha512-GcKZiCfWks5CTxhezn9k5zWX3sMDIYf6Kaxy2Gx9YEQftFcz8hDRN56hcbylyAO3t4jQnQ5ifLawINsNgCDpOg==", + "license": "MIT", + "peerDependencies": { + "typescript": ">=5.0.0", + "zod": "^3.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@t3-oss/env-nextjs": { + "version": "0.10.1", + "resolved": "https://registry.npmjs.org/@t3-oss/env-nextjs/-/env-nextjs-0.10.1.tgz", + "integrity": "sha512-iy2qqJLnFh1RjEWno2ZeyTu0ufomkXruUsOZludzDIroUabVvHsrSjtkHqwHp1/pgPUzN3yBRHMILW162X7x2Q==", + "license": "MIT", + "dependencies": { + "@t3-oss/env-core": "0.10.1" + }, + "peerDependencies": { + "typescript": ">=5.0.0", + "zod": "^3.0.0" + }, + "peerDependenciesMeta": { + "typescript": { + "optional": true + } + } + }, + "node_modules/@tabler/icons": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@tabler/icons/-/icons-3.5.0.tgz", + "integrity": "sha512-I53dC3ZSHQ2MZFGvDYJelfXm91L2bTTixS4w5jTAulLhHbCZso5Bih4Rk/NYZxlngLQMKHvEYwZQ+6w/WluKiA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/codecalm" + } + }, + "node_modules/@tabler/icons-react": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/@tabler/icons-react/-/icons-react-3.5.0.tgz", + "integrity": "sha512-bn05XKZV3ZfOv5Jr1FCTmVPOQGBVJoA4NefrnR919rqg6WGXAa08NovONHJGSuMxXUMV3b9Cni85diIW/E9yuw==", + "license": "MIT", + "dependencies": { + "@tabler/icons": "3.5.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/codecalm" + }, + "peerDependencies": { + "react": ">= 16" + } + }, + "node_modules/@tanstack/query-core": { + "version": "5.40.0", + "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.40.0.tgz", + "integrity": "sha512-eD8K8jsOIq0Z5u/QbvOmfvKKE/XC39jA7yv4hgpl/1SRiU+J8QCIwgM/mEHuunQsL87dcvnHqSVLmf9pD4CiaA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tanstack/react-query": { + "version": "5.40.1", + "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.40.1.tgz", + "integrity": "sha512-gOcmu+gpFd2taHrrgMM9RemLYYEDYfsCqszxCC0xtx+csDa4R8t7Hr7SfWXQP13S2sF+mOxySo/+FNXJFYBqcA==", + "license": "MIT", + "dependencies": { + "@tanstack/query-core": "5.40.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": "^18.0.0" + } + }, + "node_modules/@tanstack/react-table": { + "version": "8.19.2", + "resolved": "https://registry.npmjs.org/@tanstack/react-table/-/react-table-8.19.2.tgz", + "integrity": "sha512-itoSIAkA/Vsg+bjY23FSemcTyPhc5/1YjYyaMsr9QSH/cdbZnQxHVWrpWn0Sp2BWN71qkzR7e5ye8WuMmwyOjg==", + "license": "MIT", + "dependencies": { + "@tanstack/table-core": "8.19.2" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + }, + "peerDependencies": { + "react": ">=16.8", + "react-dom": ">=16.8" + } + }, + "node_modules/@tanstack/table-core": { + "version": "8.19.2", + "resolved": "https://registry.npmjs.org/@tanstack/table-core/-/table-core-8.19.2.tgz", + "integrity": "sha512-KpRjhgehIhbfH78ARm/GJDXGnpdw4bCg3qas6yjWSi7czJhI/J6pWln7NHtmBkGE9ZbohiiNtLqwGzKmBfixig==", + "license": "MIT", + "engines": { + "node": ">=12" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/tannerlinsley" + } + }, + "node_modules/@tiptap/core": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@tiptap/core/-/core-2.8.0.tgz", + "integrity": "sha512-xsqDI4BNzYRWRtBq7+/38ThhqEr7uG9Njip1x+9/wgR3vWPBFnBkYJTz6jSxS35NRE6BSnERm4/B/vrLuY1Hdw==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/pm": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-blockquote": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-blockquote/-/extension-blockquote-2.8.0.tgz", + "integrity": "sha512-m3CKrOIvV7fY1Ak2gYf5LkKiz6AHxHpg6wxfVaJvdBqXgLyVtHo552N+A4oSHOSRbB4AG9EBQ2NeBM8cdEQ4MA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-bold": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bold/-/extension-bold-2.8.0.tgz", + "integrity": "sha512-U1YkZBxDkSLNvPNiqxB5g42IeJHr27C7zDb/yGQN2xL4UBeg4O9xVhCFfe32f6tLwivSL0dar4ScElpaCJuqow==", + "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.8.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bubble-menu/-/extension-bubble-menu-2.8.0.tgz", + "integrity": "sha512-swg+myJPN60LduQvLMF4hVBqP5LOIN01INZBzBI8egz8QufqtSyRCgXl7Xcma0RT5xIXnZSG9XOqNFf2rtkjKA==", + "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.8.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-bullet-list/-/extension-bullet-list-2.8.0.tgz", + "integrity": "sha512-H4O2X0ozbc/ce9/XF1H98sqWVUdtt7jzy7hMBunwmY8ZxI4dHtcRkeg81CZbpKTqOqRrMCLWjE3M2tgiDXrDkA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0", + "@tiptap/extension-list-item": "^2.7.0", + "@tiptap/extension-text-style": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-code": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-code/-/extension-code-2.8.0.tgz", + "integrity": "sha512-VSFn3sFF6qPpOGkXFhik8oYRH5iByVJpFEFd/duIEftmS0MdPzkbSItOpN3mc9xsJ5dCX80LYaResSj5hr5zkA==", + "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.8.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-code-block/-/extension-code-block-2.8.0.tgz", + "integrity": "sha512-POuA5Igx+Dto0DTazoBFAQTj/M/FCdkqRVD9Uhsxhv49swPyANTJRr05vgbgtHB+NDDsZfCawVh7pI0IAD/O0w==", + "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-code-block-lowlight": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-code-block-lowlight/-/extension-code-block-lowlight-2.8.0.tgz", + "integrity": "sha512-6RRGtzmRXlUrxJXz6cuTIpGTeMe+0Mz3XBQaZ0t7Y7PgbBDFj9tw9+LeO4eHLS/SraX4Y+P73HzKe03AdfQ95A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0", + "@tiptap/extension-code-block": "^2.7.0", + "@tiptap/pm": "^2.7.0", + "highlight.js": "^11", + "lowlight": "^2 || ^3" + } + }, + "node_modules/@tiptap/extension-color": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-color/-/extension-color-2.8.0.tgz", + "integrity": "sha512-b0ZIDaZKTDVdTb0PMgtOiPzgCkYhvDldjzdWyPLsjWup5x9/zPasH5X/2SfMuwtjt+cKj6YBPveJjF7w5ApK7w==", + "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.8.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-document/-/extension-document-2.8.0.tgz", + "integrity": "sha512-mp7Isx1sVc/ifeW4uW/PexGQ9exN3NRUOebSpnLfqXeWYk4y1RS1PA/3+IHkOPVetbnapgPjFx/DswlCP3XLjA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-dropcursor": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-dropcursor/-/extension-dropcursor-2.8.0.tgz", + "integrity": "sha512-rAFvx44YuT6dtS1c+ALw0ROAGI16l5L1HxquL4hR1gtxDcTieST5xhw5bkshXlmrlfotZXPrhokzqA7qjhZtJw==", + "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.8.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-floating-menu/-/extension-floating-menu-2.8.0.tgz", + "integrity": "sha512-H4QT61CrkLqisnGGC7zgiYmsl2jXPHl89yQCbdlkQN7aw11H7PltcJS2PJguL0OrRVJS/Mv/VTTUiMslmsEV5g==", + "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.8.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-gapcursor/-/extension-gapcursor-2.8.0.tgz", + "integrity": "sha512-Be1LWCmvteQInOnNVN+HTqc1XWsj1bCl+Q7et8qqNjtGtTaCbdCp8ppcH1SKJxNTM/RLUtPyJ8FDgOTj51ixCA==", + "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.8.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-hard-break/-/extension-hard-break-2.8.0.tgz", + "integrity": "sha512-vqiIfviNiCmy/pJTHuDSCAGL2O4QDEdDmAvGJu8oRmElUrnlg8DbJUfKvn6DWQHNSQwRb+LDrwWlzAYj1K9u6A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-heading": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-heading/-/extension-heading-2.8.0.tgz", + "integrity": "sha512-4inWgrTPiqlivPmEHFOM5ck2UsmOsbKKPtqga6bALvWPmCv24S6/EBwFp8Jz4YABabXDnkviihmGu0LpP9D69w==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-history": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-history/-/extension-history-2.8.0.tgz", + "integrity": "sha512-u5YS0J5Egsxt8TUWMMAC3QhPZaak+IzQeyHch4gtqxftx96tprItY7AD/A3pGDF2uCSnN+SZrk6yVexm6EncDw==", + "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.8.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-horizontal-rule/-/extension-horizontal-rule-2.8.0.tgz", + "integrity": "sha512-Sn/MI8WVFBoIYSIHA9NJryJIyCEzZdRysau8pC5TFnfifre0QV1ksPz2bgF+DyCD69ozQiRdBBHDEwKe47ZbfQ==", + "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.8.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-image/-/extension-image-2.8.0.tgz", + "integrity": "sha512-5CReomgHGTUgxaX8P3i6qiC9VRWcWQgVoYtds4ZM52LVx/oGwMxQ4ECyzdVYKaRW+6PrNnAe6ew3Qpd5Wk0cIg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-italic": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-italic/-/extension-italic-2.8.0.tgz", + "integrity": "sha512-PwwSE2LTYiHI47NJnsfhBmPiLE8IXZYqaSoNPU6flPrk1KxEzqvRI1joKZBmD9wuqzmHJ93VFIeZcC+kfwi8ZA==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-link": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-link/-/extension-link-2.8.0.tgz", + "integrity": "sha512-p67hCG/pYCiOK/oCTPZnlkw9Ei7KJ7kCKFaluTcAmr5j8IBdYfDqSMDNCT4vGXBvKFh4X6xD7S7QvOqcH0Gn9A==", + "license": "MIT", + "dependencies": { + "linkifyjs": "^4.1.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0", + "@tiptap/pm": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-list-item": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-list-item/-/extension-list-item-2.8.0.tgz", + "integrity": "sha512-o7OGymGxB0B9x3x2prp3KBDYFuBYGc5sW69O672jk8G52DqhzzndgPnkk0qUn8nXAUKuDGbJmpmHVA2kagqnRg==", + "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.8.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-ordered-list/-/extension-ordered-list-2.8.0.tgz", + "integrity": "sha512-sCvNbcTS1+5QTTXwUPFa10vf5I1pr8sGcOTIh0G+a5ZkS5+6FxT12k7VLzPt39QyNbOi+77U2o4Xr4XyaEkfSg==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0", + "@tiptap/extension-list-item": "^2.7.0", + "@tiptap/extension-text-style": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-paragraph": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-paragraph/-/extension-paragraph-2.8.0.tgz", + "integrity": "sha512-XgxxNNbuBF48rAGwv7/s6as92/xjm/lTZIGTq9aG13ClUKFtgdel7C33SpUCcxg3cO2WkEyllXVyKUiauFZw/A==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" + } + }, + "node_modules/@tiptap/extension-placeholder": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-placeholder/-/extension-placeholder-2.8.0.tgz", + "integrity": "sha512-BMqv/C9Tcjd7L1/OphUAJTZhWfpWs0rTQJ0bs3RRGsC8L+K20Fg+li45vw7M0teojpfrw57zwJogJd/m23Zr1Q==", + "license": "MIT", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "typescript": ">=5.0.0", - "zod": "^3.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } + "@tiptap/core": "^2.7.0", + "@tiptap/pm": "^2.7.0" } }, - "node_modules/@tabler/icons": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/@tabler/icons/-/icons-3.5.0.tgz", - "integrity": "sha512-I53dC3ZSHQ2MZFGvDYJelfXm91L2bTTixS4w5jTAulLhHbCZso5Bih4Rk/NYZxlngLQMKHvEYwZQ+6w/WluKiA==", + "node_modules/@tiptap/extension-strike": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-strike/-/extension-strike-2.8.0.tgz", + "integrity": "sha512-ezkDiXxQ3ME/dDMMM7tAMkKRi6UWw7tIu+Mx7Os0z8HCGpVBk1gFhLlhEd8I5rJaPZr4tK1wtSehMA9bscFGQw==", "license": "MIT", "funding": { "type": "github", - "url": "https://github.com/sponsors/codecalm" + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" } }, - "node_modules/@tabler/icons-react": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/@tabler/icons-react/-/icons-react-3.5.0.tgz", - "integrity": "sha512-bn05XKZV3ZfOv5Jr1FCTmVPOQGBVJoA4NefrnR919rqg6WGXAa08NovONHJGSuMxXUMV3b9Cni85diIW/E9yuw==", + "node_modules/@tiptap/extension-text": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-text/-/extension-text-2.8.0.tgz", + "integrity": "sha512-EDAdFFzWOvQfVy7j3qkKhBpOeE5thkJaBemSWfXI93/gMVc0ZCdLi24mDvNNgUHlT+RjlIoQq908jZaaxLKN2A==", "license": "MIT", - "dependencies": { - "@tabler/icons": "3.5.0" - }, "funding": { "type": "github", - "url": "https://github.com/sponsors/codecalm" + "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "react": ">= 16" + "@tiptap/core": "^2.7.0" } }, - "node_modules/@tanstack/query-core": { - "version": "5.40.0", - "resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.40.0.tgz", - "integrity": "sha512-eD8K8jsOIq0Z5u/QbvOmfvKKE/XC39jA7yv4hgpl/1SRiU+J8QCIwgM/mEHuunQsL87dcvnHqSVLmf9pD4CiaA==", + "node_modules/@tiptap/extension-text-style": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-text-style/-/extension-text-style-2.8.0.tgz", + "integrity": "sha512-jJp0vcZ2Ty7RvIL0VU6dm1y+fTfXq1lN2GwtYzYM0ueFuESa+Qo8ticYOImyWZ3wGJGVrjn7OV9r0ReW0/NYkQ==", "license": "MIT", "funding": { "type": "github", - "url": "https://github.com/sponsors/tannerlinsley" + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0" } }, - "node_modules/@tanstack/react-query": { - "version": "5.40.1", - "resolved": "https://registry.npmjs.org/@tanstack/react-query/-/react-query-5.40.1.tgz", - "integrity": "sha512-gOcmu+gpFd2taHrrgMM9RemLYYEDYfsCqszxCC0xtx+csDa4R8t7Hr7SfWXQP13S2sF+mOxySo/+FNXJFYBqcA==", + "node_modules/@tiptap/extension-typography": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@tiptap/extension-typography/-/extension-typography-2.8.0.tgz", + "integrity": "sha512-g+tbUba6cHbz62rLlmAdXw3GqBfZBVnYXtRqnQzTTPgb8a00+vEoUWA3sNyloq8FhfKFYcMWQDiqaVDqmity+w==", "license": "MIT", - "dependencies": { - "@tanstack/query-core": "5.40.0" - }, "funding": { "type": "github", - "url": "https://github.com/sponsors/tannerlinsley" + "url": "https://github.com/sponsors/ueberdosis" }, "peerDependencies": { - "react": "^18.0.0" + "@tiptap/core": "^2.7.0" } }, - "node_modules/@tanstack/react-table": { - "version": "8.19.2", - "resolved": "https://registry.npmjs.org/@tanstack/react-table/-/react-table-8.19.2.tgz", - "integrity": "sha512-itoSIAkA/Vsg+bjY23FSemcTyPhc5/1YjYyaMsr9QSH/cdbZnQxHVWrpWn0Sp2BWN71qkzR7e5ye8WuMmwyOjg==", + "node_modules/@tiptap/pm": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-2.8.0.tgz", + "integrity": "sha512-eMGpRooUMvKz/vOpnKKppApMSoNM325HxTdAJvTlVAmuHp5bOY5kyY1kfUlePRiVx1t1UlFcXs3kecFwkkBD3Q==", "license": "MIT", "dependencies": { - "@tanstack/table-core": "8.19.2" - }, - "engines": { - "node": ">=12" + "prosemirror-changeset": "^2.2.1", + "prosemirror-collab": "^1.3.1", + "prosemirror-commands": "^1.6.0", + "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.0", + "prosemirror-menu": "^1.2.4", + "prosemirror-model": "^1.22.3", + "prosemirror-schema-basic": "^1.2.3", + "prosemirror-schema-list": "^1.4.1", + "prosemirror-state": "^1.4.3", + "prosemirror-tables": "^1.4.0", + "prosemirror-trailing-node": "^3.0.0", + "prosemirror-transform": "^1.10.0", + "prosemirror-view": "^1.33.10" }, "funding": { "type": "github", - "url": "https://github.com/sponsors/tannerlinsley" - }, - "peerDependencies": { - "react": ">=16.8", - "react-dom": ">=16.8" + "url": "https://github.com/sponsors/ueberdosis" } }, - "node_modules/@tanstack/table-core": { - "version": "8.19.2", - "resolved": "https://registry.npmjs.org/@tanstack/table-core/-/table-core-8.19.2.tgz", - "integrity": "sha512-KpRjhgehIhbfH78ARm/GJDXGnpdw4bCg3qas6yjWSi7czJhI/J6pWln7NHtmBkGE9ZbohiiNtLqwGzKmBfixig==", + "node_modules/@tiptap/react": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@tiptap/react/-/react-2.8.0.tgz", + "integrity": "sha512-o/aSCjO5Nu4MsNpTF+N1SzYzVQvvBiclmTOZX2E6usZ8jre5zmKfXHDSZnjGSRTK6z6kw5KW8wpjRQha03f9mg==", "license": "MIT", - "engines": { - "node": ">=12" + "dependencies": { + "@tiptap/extension-bubble-menu": "^2.8.0", + "@tiptap/extension-floating-menu": "^2.8.0", + "@types/use-sync-external-store": "^0.0.6", + "fast-deep-equal": "^3", + "use-sync-external-store": "^1.2.2" }, "funding": { "type": "github", - "url": "https://github.com/sponsors/tannerlinsley" + "url": "https://github.com/sponsors/ueberdosis" + }, + "peerDependencies": { + "@tiptap/core": "^2.7.0", + "@tiptap/pm": "^2.7.0", + "react": "^17.0.0 || ^18.0.0", + "react-dom": "^17.0.0 || ^18.0.0" + } + }, + "node_modules/@tiptap/starter-kit": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/@tiptap/starter-kit/-/starter-kit-2.8.0.tgz", + "integrity": "sha512-r7UwaTrECkQoheWVZKFDqtL5tBx07x7IFT+prfgnsVlYFutGWskVVqzCDvD3BDmrg5PzeCWYZrQGlPaLib7tjg==", + "license": "MIT", + "dependencies": { + "@tiptap/core": "^2.8.0", + "@tiptap/extension-blockquote": "^2.8.0", + "@tiptap/extension-bold": "^2.8.0", + "@tiptap/extension-bullet-list": "^2.8.0", + "@tiptap/extension-code": "^2.8.0", + "@tiptap/extension-code-block": "^2.8.0", + "@tiptap/extension-document": "^2.8.0", + "@tiptap/extension-dropcursor": "^2.8.0", + "@tiptap/extension-gapcursor": "^2.8.0", + "@tiptap/extension-hard-break": "^2.8.0", + "@tiptap/extension-heading": "^2.8.0", + "@tiptap/extension-history": "^2.8.0", + "@tiptap/extension-horizontal-rule": "^2.8.0", + "@tiptap/extension-italic": "^2.8.0", + "@tiptap/extension-list-item": "^2.8.0", + "@tiptap/extension-ordered-list": "^2.8.0", + "@tiptap/extension-paragraph": "^2.8.0", + "@tiptap/extension-strike": "^2.8.0", + "@tiptap/extension-text": "^2.8.0", + "@tiptap/pm": "^2.8.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/ueberdosis" } }, "node_modules/@trivago/prettier-plugin-sort-imports": { @@ -4243,6 +5384,15 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/hast": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/hast/-/hast-3.0.4.tgz", + "integrity": "sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==", + "license": "MIT", + "dependencies": { + "@types/unist": "*" + } + }, "node_modules/@types/json-schema": { "version": "7.0.15", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz", @@ -4257,6 +5407,28 @@ "dev": true, "license": "MIT" }, + "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/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/node": { "version": "20.14.2", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.14.2.tgz", @@ -4307,6 +5479,18 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/unist": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-3.0.3.tgz", + "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/uuid": { "version": "9.0.8", "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-9.0.8.tgz", @@ -4911,7 +6095,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-hidden": { @@ -5655,6 +6838,12 @@ "dev": true, "license": "MIT" }, + "node_modules/crelt": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/crelt/-/crelt-1.0.6.tgz", + "integrity": "sha512-VQ2MBenTq1fWZUH9DJNGti7kKv6EeAuYr3cLwxUWhIu1baTaXh4Ib5W2CqHVqib4/MqbYGJqiL3Zb8GJZr3l4g==", + "license": "MIT" + }, "node_modules/cross-spawn": { "version": "7.0.3", "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", @@ -5982,7 +7171,6 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", - "dev": true, "license": "MIT", "engines": { "node": ">=6" @@ -6003,6 +7191,19 @@ "integrity": "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ==", "license": "MIT" }, + "node_modules/devlop": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/devlop/-/devlop-1.1.0.tgz", + "integrity": "sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==", + "license": "MIT", + "dependencies": { + "dequal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/didyoumean": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/didyoumean/-/didyoumean-1.2.2.tgz", @@ -6087,6 +7288,18 @@ "node": ">=10.13.0" } }, + "node_modules/entities": { + "version": "4.5.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", + "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "license": "BSD-2-Clause", + "engines": { + "node": ">=0.12" + }, + "funding": { + "url": "https://github.com/fb55/entities?sponsor=1" + } + }, "node_modules/env-paths": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-3.0.0.tgz", @@ -6280,7 +7493,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" @@ -7281,7 +8493,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-equals": { @@ -7904,6 +9115,16 @@ "node": ">= 0.4" } }, + "node_modules/highlight.js": { + "version": "11.10.0", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.10.0.tgz", + "integrity": "sha512-SYVnVFswQER+zu1laSya563s+F8VDGt7o35d4utbamowvUNLLMovFqwCLSocpZTz3MgaSRA1IbqRWZv97dtErQ==", + "license": "BSD-3-Clause", + "peer": true, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/https-proxy-agent": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.4.tgz", @@ -8836,6 +10057,21 @@ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==", "license": "MIT" }, + "node_modules/linkify-it": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-5.0.0.tgz", + "integrity": "sha512-5aHCbzQRADcdP+ATqnDuhhJ/MRIqDkZX5pyjFHRRysS8vZ5AbqGEoFIb6pYHPZ+L/OC2Lc+xT8uHVVR5CAK/wQ==", + "license": "MIT", + "dependencies": { + "uc.micro": "^2.0.0" + } + }, + "node_modules/linkifyjs": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/linkifyjs/-/linkifyjs-4.1.3.tgz", + "integrity": "sha512-auMesunaJ8yfkHvK4gfg1K0SaKX/6Wn9g2Aac/NwX+l5VdmFZzo/hdPGxEOETj+ryRa4/fiOPjeeKURSAJx1sg==", + "license": "MIT" + }, "node_modules/locate-path": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", @@ -8885,6 +10121,30 @@ "loose-envify": "cli.js" } }, + "node_modules/lowlight": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/lowlight/-/lowlight-3.1.0.tgz", + "integrity": "sha512-CEbNVoSikAxwDMDPjXlqlFYiZLkDJHwyGu/MfOsJnF3d7f3tds5J3z8s/l9TMXhzfsJCCJEAsD78842mwmg0PQ==", + "license": "MIT", + "dependencies": { + "@types/hast": "^3.0.0", + "devlop": "^1.0.0", + "highlight.js": "~11.9.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/lowlight/node_modules/highlight.js": { + "version": "11.9.0", + "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-11.9.0.tgz", + "integrity": "sha512-fJ7cW7fQGCYAkgv4CPfwFHrfd/cLS4Hau96JuJ+ZTOWhjnhoeN1ub1tFmALm/+lW5z4WCAuAV9bm05AP0mS6Gw==", + "license": "BSD-3-Clause", + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/lru-cache": { "version": "10.2.2", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.2.2.tgz", @@ -8923,6 +10183,29 @@ "node": ">=4" } }, + "node_modules/markdown-it": { + "version": "14.1.0", + "resolved": "https://registry.npmjs.org/markdown-it/-/markdown-it-14.1.0.tgz", + "integrity": "sha512-a54IwgWPaeBCAAsv13YgmALOF1elABB08FxO9i+r4VFk5Vl4pKokRPeX8u5TCgSsPi6ec1otfLjdOpVcgbpshg==", + "license": "MIT", + "dependencies": { + "argparse": "^2.0.1", + "entities": "^4.4.0", + "linkify-it": "^5.0.0", + "mdurl": "^2.0.0", + "punycode.js": "^2.3.1", + "uc.micro": "^2.1.0" + }, + "bin": { + "markdown-it": "bin/markdown-it.mjs" + } + }, + "node_modules/mdurl": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-2.0.0.tgz", + "integrity": "sha512-Lf+9+2r+Tdp5wXDXC4PcIBjTDtq4UKjCPMQhKIuzpJNW0b96kVqSwW0bT7FhRSfmAiFYgP+SCRvdrDozfh0U5w==", + "license": "MIT" + }, "node_modules/merge2": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", @@ -9441,6 +10724,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/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -9900,6 +11189,201 @@ "react-is": "^16.13.1" } }, + "node_modules/prosemirror-changeset": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/prosemirror-changeset/-/prosemirror-changeset-2.2.1.tgz", + "integrity": "sha512-J7msc6wbxB4ekDFj+n9gTW/jav/p53kdlivvuppHsrZXCaQdVgRghoZbSS3kwrRyAstRVQ4/+u5k7YfLgkkQvQ==", + "license": "MIT", + "dependencies": { + "prosemirror-transform": "^1.0.0" + } + }, + "node_modules/prosemirror-collab": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/prosemirror-collab/-/prosemirror-collab-1.3.1.tgz", + "integrity": "sha512-4SnynYR9TTYaQVXd/ieUvsVV4PDMBzrq2xPUWutHivDuOshZXqQ5rGbZM84HEaXKbLdItse7weMGOUdDVcLKEQ==", + "license": "MIT", + "dependencies": { + "prosemirror-state": "^1.0.0" + } + }, + "node_modules/prosemirror-commands": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/prosemirror-commands/-/prosemirror-commands-1.6.0.tgz", + "integrity": "sha512-xn1U/g36OqXn2tn5nGmvnnimAj/g1pUx2ypJJIe8WkVX83WyJVC5LTARaxZa2AtQRwntu9Jc5zXs9gL9svp/mg==", + "license": "MIT", + "dependencies": { + "prosemirror-model": "^1.0.0", + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.0.0" + } + }, + "node_modules/prosemirror-dropcursor": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/prosemirror-dropcursor/-/prosemirror-dropcursor-1.8.1.tgz", + "integrity": "sha512-M30WJdJZLyXHi3N8vxN6Zh5O8ZBbQCz0gURTfPmTIBNQ5pxrdU7A58QkNqfa98YEjSAL1HUyyU34f6Pm5xBSGw==", + "license": "MIT", + "dependencies": { + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.1.0", + "prosemirror-view": "^1.1.0" + } + }, + "node_modules/prosemirror-gapcursor": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/prosemirror-gapcursor/-/prosemirror-gapcursor-1.3.2.tgz", + "integrity": "sha512-wtjswVBd2vaQRrnYZaBCbyDqr232Ed4p2QPtRIUK5FuqHYKGWkEwl08oQM4Tw7DOR0FsasARV5uJFvMZWxdNxQ==", + "license": "MIT", + "dependencies": { + "prosemirror-keymap": "^1.0.0", + "prosemirror-model": "^1.0.0", + "prosemirror-state": "^1.0.0", + "prosemirror-view": "^1.0.0" + } + }, + "node_modules/prosemirror-history": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/prosemirror-history/-/prosemirror-history-1.4.1.tgz", + "integrity": "sha512-2JZD8z2JviJrboD9cPuX/Sv/1ChFng+xh2tChQ2X4bB2HeK+rra/bmJ3xGntCcjhOqIzSDG6Id7e8RJ9QPXLEQ==", + "license": "MIT", + "dependencies": { + "prosemirror-state": "^1.2.2", + "prosemirror-transform": "^1.0.0", + "prosemirror-view": "^1.31.0", + "rope-sequence": "^1.3.0" + } + }, + "node_modules/prosemirror-inputrules": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/prosemirror-inputrules/-/prosemirror-inputrules-1.4.0.tgz", + "integrity": "sha512-6ygpPRuTJ2lcOXs9JkefieMst63wVJBgHZGl5QOytN7oSZs3Co/BYbc3Yx9zm9H37Bxw8kVzCnDsihsVsL4yEg==", + "license": "MIT", + "dependencies": { + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.0.0" + } + }, + "node_modules/prosemirror-keymap": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/prosemirror-keymap/-/prosemirror-keymap-1.2.2.tgz", + "integrity": "sha512-EAlXoksqC6Vbocqc0GtzCruZEzYgrn+iiGnNjsJsH4mrnIGex4qbLdWWNza3AW5W36ZRrlBID0eM6bdKH4OStQ==", + "license": "MIT", + "dependencies": { + "prosemirror-state": "^1.0.0", + "w3c-keyname": "^2.2.0" + } + }, + "node_modules/prosemirror-markdown": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/prosemirror-markdown/-/prosemirror-markdown-1.13.1.tgz", + "integrity": "sha512-Sl+oMfMtAjWtlcZoj/5L/Q39MpEnVZ840Xo330WJWUvgyhNmLBLN7MsHn07s53nG/KImevWHSE6fEj4q/GihHw==", + "license": "MIT", + "dependencies": { + "@types/markdown-it": "^14.0.0", + "markdown-it": "^14.0.0", + "prosemirror-model": "^1.20.0" + } + }, + "node_modules/prosemirror-menu": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/prosemirror-menu/-/prosemirror-menu-1.2.4.tgz", + "integrity": "sha512-S/bXlc0ODQup6aiBbWVsX/eM+xJgCTAfMq/nLqaO5ID/am4wS0tTCIkzwytmao7ypEtjj39i7YbJjAgO20mIqA==", + "license": "MIT", + "dependencies": { + "crelt": "^1.0.0", + "prosemirror-commands": "^1.0.0", + "prosemirror-history": "^1.0.0", + "prosemirror-state": "^1.0.0" + } + }, + "node_modules/prosemirror-model": { + "version": "1.23.0", + "resolved": "https://registry.npmjs.org/prosemirror-model/-/prosemirror-model-1.23.0.tgz", + "integrity": "sha512-Q/fgsgl/dlOAW9ILu4OOhYWQbc7TQd4BwKH/RwmUjyVf8682Be4zj3rOYdLnYEcGzyg8LL9Q5IWYKD8tdToreQ==", + "license": "MIT", + "dependencies": { + "orderedmap": "^2.0.0" + } + }, + "node_modules/prosemirror-schema-basic": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/prosemirror-schema-basic/-/prosemirror-schema-basic-1.2.3.tgz", + "integrity": "sha512-h+H0OQwZVqMon1PNn0AG9cTfx513zgIG2DY00eJ00Yvgb3UD+GQ/VlWW5rcaxacpCGT1Yx8nuhwXk4+QbXUfJA==", + "license": "MIT", + "dependencies": { + "prosemirror-model": "^1.19.0" + } + }, + "node_modules/prosemirror-schema-list": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/prosemirror-schema-list/-/prosemirror-schema-list-1.4.1.tgz", + "integrity": "sha512-jbDyaP/6AFfDfu70VzySsD75Om2t3sXTOdl5+31Wlxlg62td1haUpty/ybajSfJ1pkGadlOfwQq9kgW5IMo1Rg==", + "license": "MIT", + "dependencies": { + "prosemirror-model": "^1.0.0", + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.7.3" + } + }, + "node_modules/prosemirror-state": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/prosemirror-state/-/prosemirror-state-1.4.3.tgz", + "integrity": "sha512-goFKORVbvPuAQaXhpbemJFRKJ2aixr+AZMGiquiqKxaucC6hlpHNZHWgz5R7dS4roHiwq9vDctE//CZ++o0W1Q==", + "license": "MIT", + "dependencies": { + "prosemirror-model": "^1.0.0", + "prosemirror-transform": "^1.0.0", + "prosemirror-view": "^1.27.0" + } + }, + "node_modules/prosemirror-tables": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/prosemirror-tables/-/prosemirror-tables-1.5.0.tgz", + "integrity": "sha512-VMx4zlYWm7aBlZ5xtfJHpqa3Xgu3b7srV54fXYnXgsAcIGRqKSrhiK3f89omzzgaAgAtDOV4ImXnLKhVfheVNQ==", + "license": "MIT", + "dependencies": { + "prosemirror-keymap": "^1.1.2", + "prosemirror-model": "^1.8.1", + "prosemirror-state": "^1.3.1", + "prosemirror-transform": "^1.2.1", + "prosemirror-view": "^1.13.3" + } + }, + "node_modules/prosemirror-trailing-node": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/prosemirror-trailing-node/-/prosemirror-trailing-node-3.0.0.tgz", + "integrity": "sha512-xiun5/3q0w5eRnGYfNlW1uU9W6x5MoFKWwq/0TIRgt09lv7Hcser2QYV8t4muXbEr+Fwo0geYn79Xs4GKywrRQ==", + "license": "MIT", + "dependencies": { + "@remirror/core-constants": "3.0.0", + "escape-string-regexp": "^4.0.0" + }, + "peerDependencies": { + "prosemirror-model": "^1.22.1", + "prosemirror-state": "^1.4.2", + "prosemirror-view": "^1.33.8" + } + }, + "node_modules/prosemirror-transform": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/prosemirror-transform/-/prosemirror-transform-1.10.0.tgz", + "integrity": "sha512-9UOgFSgN6Gj2ekQH5CTDJ8Rp/fnKR2IkYfGdzzp5zQMFsS4zDllLVx/+jGcX86YlACpG7UR5fwAXiWzxqWtBTg==", + "license": "MIT", + "dependencies": { + "prosemirror-model": "^1.21.0" + } + }, + "node_modules/prosemirror-view": { + "version": "1.34.3", + "resolved": "https://registry.npmjs.org/prosemirror-view/-/prosemirror-view-1.34.3.tgz", + "integrity": "sha512-mKZ54PrX19sSaQye+sef+YjBbNu2voNwLS1ivb6aD2IRmxRGW64HU9B644+7OfJStGLyxvOreKqEgfvXa91WIA==", + "license": "MIT", + "dependencies": { + "prosemirror-model": "^1.20.0", + "prosemirror-state": "^1.0.0", + "prosemirror-transform": "^1.1.0" + } + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -9910,6 +11394,15 @@ "node": ">=6" } }, + "node_modules/punycode.js": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/punycode.js/-/punycode.js-2.3.1.tgz", + "integrity": "sha512-uxFIHU0YlHYhDQtV4R9J6a52SLx28BCjT+4ieh7IGbgwVJWO+km431c4yRlREUAsAmt/uMjQUyQHNEPf0M39CA==", + "license": "MIT", + "engines": { + "node": ">=6" + } + }, "node_modules/queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -10260,6 +11753,12 @@ "url": "https://github.com/sponsors/isaacs" } }, + "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", @@ -10977,6 +12476,26 @@ "node": ">=0.8" } }, + "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-extension-resize-image": { + "version": "1.1.9", + "resolved": "https://registry.npmjs.org/tiptap-extension-resize-image/-/tiptap-extension-resize-image-1.1.9.tgz", + "integrity": "sha512-CyApEvMgxCmHx8DxormIbGD6lZ+7fFeq49OOPPquNIWCRigkqgyFQ3KFJeSN446JlwjyuCMVIYdkKY/m5IBu6A==", + "license": "MIT", + "peerDependencies": { + "@tiptap/core": "^2.0.0", + "@tiptap/extension-image": "^2.0.0", + "@tiptap/pm": "^2.0.0" + } + }, "node_modules/to-fast-properties": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", @@ -11210,6 +12729,12 @@ "node": ">=14.17" } }, + "node_modules/uc.micro": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/uc.micro/-/uc.micro-2.1.0.tgz", + "integrity": "sha512-ARDJmphmdvUk6Glw7y9DQ2bFkKBHwQHLi2lsaH6PPmz/Ka9sFOBsBluozhDltWmnv9u/cF6Rt87znRTPV+yp/A==", + "license": "MIT" + }, "node_modules/unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -11326,6 +12851,15 @@ } } }, + "node_modules/use-sync-external-store": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz", + "integrity": "sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==", + "license": "MIT", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -11366,6 +12900,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/wcwidth": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/wcwidth/-/wcwidth-1.0.1.tgz", diff --git a/package.json b/package.json index 77e3e90..d562188 100644 --- a/package.json +++ b/package.json @@ -28,9 +28,13 @@ "@radix-ui/react-popover": "^1.0.7", "@radix-ui/react-scroll-area": "^1.0.5", "@radix-ui/react-select": "^2.0.0", + "@radix-ui/react-separator": "^1.1.0", "@radix-ui/react-slot": "^1.0.2", + "@radix-ui/react-switch": "^1.1.1", "@radix-ui/react-tabs": "^1.0.4", "@radix-ui/react-toast": "^1.1.5", + "@radix-ui/react-toggle": "^1.1.0", + "@radix-ui/react-toggle-group": "^1.1.0", "@radix-ui/react-tooltip": "^1.1.2", "@supabase/ssr": "^0.5.1", "@supabase/supabase-js": "^2.43.4", @@ -38,6 +42,19 @@ "@tabler/icons-react": "^3.5.0", "@tanstack/react-query": "^5.40.1", "@tanstack/react-table": "^8.19.2", + "@tiptap/core": "^2.8.0", + "@tiptap/extension-code-block-lowlight": "^2.8.0", + "@tiptap/extension-color": "^2.8.0", + "@tiptap/extension-heading": "^2.8.0", + "@tiptap/extension-horizontal-rule": "^2.8.0", + "@tiptap/extension-image": "^2.8.0", + "@tiptap/extension-link": "^2.8.0", + "@tiptap/extension-placeholder": "^2.8.0", + "@tiptap/extension-text-style": "^2.8.0", + "@tiptap/extension-typography": "^2.8.0", + "@tiptap/pm": "^2.8.0", + "@tiptap/react": "^2.8.0", + "@tiptap/starter-kit": "^2.8.0", "class-variance-authority": "^0.7.0", "clsx": "^2.1.1", "cmdk": "^1.0.0", @@ -45,6 +62,7 @@ "framer-motion": "^11.2.9", "i18next": "^23.11.5", "jotai": "^2.10.0", + "lowlight": "^3.1.0", "lucide-react": "^0.379.0", "next": "14.2.3", "next-themes": "^0.3.0", @@ -59,6 +77,7 @@ "sonner": "^1.4.41", "tailwind-merge": "^2.3.0", "tailwindcss-animate": "^1.0.7", + "tiptap-extension-resize-image": "^1.1.9", "uuid": "^10.0.0", "zod": "^3.23.8", "zod-i18n-map": "^2.27.0" diff --git a/src/components/landing/MobileMenu.tsx b/src/components/landing/MobileMenu.tsx index 107267b..1dbf48a 100644 --- a/src/components/landing/MobileMenu.tsx +++ b/src/components/landing/MobileMenu.tsx @@ -18,8 +18,8 @@ export const MobileMenu: React.FC = ({ onClose, isOpen }) => { />
diff --git a/src/components/landing/Navbar.tsx b/src/components/landing/Navbar.tsx index 23ca853..76ab734 100644 --- a/src/components/landing/Navbar.tsx +++ b/src/components/landing/Navbar.tsx @@ -69,7 +69,10 @@ export const Navbar = () => {
{!isMobileMenuOpen && (
- +
)} {isMobileMenuOpen ? ( diff --git a/src/components/minimal-tiptap/components/bubble-menu/image-bubble-menu.tsx b/src/components/minimal-tiptap/components/bubble-menu/image-bubble-menu.tsx new file mode 100644 index 0000000..f80c7bb --- /dev/null +++ b/src/components/minimal-tiptap/components/bubble-menu/image-bubble-menu.tsx @@ -0,0 +1,41 @@ +import type { Editor } from "@tiptap/react"; +import { BubbleMenu } from "@tiptap/react"; + +// eslint-disable-next-line no-restricted-imports +import type { ShouldShowProps } from "../../types"; +import { ImagePopoverBlock } from "../image/image-popover-block"; + +const ImageBubbleMenu = ({ editor }: { editor: Editor }) => { + const shouldShow = ({ editor: e, from, to }: ShouldShowProps) => { + if (from === to) { + return false; + } + + const img = e.getAttributes("image"); + + if (Boolean(img.src)) { + return true; + } + + return false; + }; + + const unSetImage = () => { + editor.commands.deleteSelection(); + }; + + return ( + + + + ); +}; + +export { ImageBubbleMenu }; diff --git a/src/components/minimal-tiptap/components/bubble-menu/link-bubble-menu.tsx b/src/components/minimal-tiptap/components/bubble-menu/link-bubble-menu.tsx new file mode 100644 index 0000000..439f651 --- /dev/null +++ b/src/components/minimal-tiptap/components/bubble-menu/link-bubble-menu.tsx @@ -0,0 +1,118 @@ +import type { Editor } from "@tiptap/react"; +import { BubbleMenu } from "@tiptap/react"; +import * as React from "react"; + +// eslint-disable-next-line no-restricted-imports +import type { ShouldShowProps } from "../../types"; +import { LinkEditBlock } from "../link/link-edit-block"; +import { LinkPopoverBlock } from "../link/link-popover-block"; + +interface LinkBubbleMenuProps { + editor: Editor; +} + +interface LinkAttributes { + href: string; + target: string; +} + +export const LinkBubbleMenu: React.FC = ({ editor }) => { + const [showEdit, setShowEdit] = React.useState(false); + const [linkAttrs, setLinkAttrs] = React.useState({ + href: "", + target: "", + }); + const [selectedText, setSelectedText] = React.useState(""); + + const updateLinkState = React.useCallback(() => { + const { from, to } = editor.state.selection; + const { href, target } = editor.getAttributes("link"); + const text = editor.state.doc.textBetween(from, to, " "); + + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment + setLinkAttrs({ href, target }); + setSelectedText(text); + }, [editor]); + + const shouldShow = React.useCallback( + ({ editor: e, from, to }: ShouldShowProps) => { + if (from === to) { + return false; + } + const { href } = e.getAttributes("link"); + + if (Boolean(href)) { + updateLinkState(); + return true; + } + return false; + }, + [updateLinkState], + ); + + const handleEdit = React.useCallback(() => { + setShowEdit(true); + }, []); + + const onSetLink = React.useCallback( + (url: string, text?: string, openInNewTab?: boolean) => { + editor + .chain() + .focus() + .extendMarkRange("link") + .insertContent({ + type: "text", + text: text ?? url, + marks: [ + { + type: "link", + attrs: { + href: url, + target: openInNewTab === true ? "_blank" : "", + }, + }, + ], + }) + .setLink({ href: url, target: openInNewTab === true ? "_blank" : "" }) + .run(); + setShowEdit(false); + updateLinkState(); + }, + [editor, updateLinkState], + ); + + const onUnsetLink = React.useCallback(() => { + editor.chain().focus().extendMarkRange("link").unsetLink().run(); + setShowEdit(false); + updateLinkState(); + }, [editor, updateLinkState]); + + return ( + { + setShowEdit(false); + }, + }} + > + {showEdit ? ( + + ) : ( + + )} + + ); +}; diff --git a/src/components/minimal-tiptap/components/image/image-edit-block.tsx b/src/components/minimal-tiptap/components/image/image-edit-block.tsx new file mode 100644 index 0000000..6a62be8 --- /dev/null +++ b/src/components/minimal-tiptap/components/image/image-edit-block.tsx @@ -0,0 +1,94 @@ +import type { Editor } from "@tiptap/react"; +import * as React from "react"; + +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { Label } from "@/components/ui/label"; +import { cn } from "@/lib/utils"; + +interface ImageEditBlockProps extends React.HTMLAttributes { + editor: Editor; + close: () => void; +} + +const ImageEditBlock = ({ + editor, + className, + close, + ...props +}: ImageEditBlockProps) => { + const fileInputRef = React.useRef(null); + const [link, setLink] = React.useState(""); + + const handleClick = (e: React.MouseEvent) => { + e.preventDefault(); + e.stopPropagation(); + fileInputRef.current?.click(); + }; + + const handleLink = () => { + editor.chain().focus().setImage({ src: link }).run(); + close(); + }; + + const handleFile = (e: React.ChangeEvent) => { + const files = e.target.files; + if (!files) { + return; + } + + const reader = new FileReader(); + reader.onload = (e2) => { + const src = e2.target?.result as string; + editor.chain().focus().setImage({ src }).run(); + }; + + reader.readAsDataURL(files[0]); + + close(); + }; + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + e.stopPropagation(); + handleLink(); + }; + + return ( +
+
+
+ +
+ { + setLink(e.target.value); + }} + /> + +
+
+ + +
+
+ ); +}; + +export { ImageEditBlock }; diff --git a/src/components/minimal-tiptap/components/image/image-edit-dialog.tsx b/src/components/minimal-tiptap/components/image/image-edit-dialog.tsx new file mode 100644 index 0000000..c9b8e66 --- /dev/null +++ b/src/components/minimal-tiptap/components/image/image-edit-dialog.tsx @@ -0,0 +1,57 @@ +import { ImageIcon } from "@radix-ui/react-icons"; +import type { Editor } from "@tiptap/react"; +import type { VariantProps } from "class-variance-authority"; +import { useState } from "react"; + +import { + Dialog, + DialogContent, + DialogDescription, + DialogHeader, + DialogTitle, + DialogTrigger, +} from "@/components/ui/dialog"; +import type { toggleVariants } from "@/components/ui/toggle"; + +import { ToolbarButton } from "../toolbar-button"; +import { ImageEditBlock } from "./image-edit-block"; + +interface ImageEditDialogProps extends VariantProps { + editor: Editor; +} + +const ImageEditDialog = ({ editor, size, variant }: ImageEditDialogProps) => { + const [open, setOpen] = useState(false); + + return ( + + + + + + + + + Select image + + Upload an image from your computer + + + { + setOpen(false); + }} + /> + + + ); +}; + +export { ImageEditDialog }; diff --git a/src/components/minimal-tiptap/components/image/image-popover-block.tsx b/src/components/minimal-tiptap/components/image/image-popover-block.tsx new file mode 100644 index 0000000..1f53479 --- /dev/null +++ b/src/components/minimal-tiptap/components/image/image-popover-block.tsx @@ -0,0 +1,26 @@ +import { TrashIcon } from "@radix-ui/react-icons"; + +import { ToolbarButton } from "../toolbar-button"; + +const ImagePopoverBlock = ({ + onRemove, +}: { + onRemove: (e: React.MouseEvent) => void; +}) => { + const handleRemove = (e: React.MouseEvent) => { + e.preventDefault(); + onRemove(e); + }; + + return ( +
+
+ + + +
+
+ ); +}; + +export { ImagePopoverBlock }; diff --git a/src/components/minimal-tiptap/components/link/link-edit-block.tsx b/src/components/minimal-tiptap/components/link/link-edit-block.tsx new file mode 100644 index 0000000..5943242 --- /dev/null +++ b/src/components/minimal-tiptap/components/link/link-edit-block.tsx @@ -0,0 +1,97 @@ +/* eslint-disable @typescript-eslint/strict-boolean-expressions */ + +/* eslint-disable @typescript-eslint/prefer-nullish-coalescing */ +import * as React from "react"; + +import { Button } from "@/components/ui/button"; +import { Input } from "@/components/ui/input"; +import { Label } from "@/components/ui/label"; +import { Switch } from "@/components/ui/switch"; +import { cn } from "@/lib/utils"; + +interface LinkEditorProps extends React.HTMLAttributes { + defaultUrl?: string; + defaultText?: string; + defaultIsNewTab?: boolean; + onSave: (url: string, text?: string, isNewTab?: boolean) => void; +} + +export const LinkEditBlock = React.forwardRef( + ({ onSave, defaultIsNewTab, defaultUrl, defaultText, className }, ref) => { + const formRef = React.useRef(null); + const [url, setUrl] = React.useState(defaultUrl || ""); + const [text, setText] = React.useState(defaultText || ""); + const [isNewTab, setIsNewTab] = React.useState(defaultIsNewTab || false); + + const handleSave = React.useCallback( + (e: React.FormEvent) => { + e.preventDefault(); + if (formRef.current) { + const isValid = Array.from( + formRef.current.querySelectorAll("input"), + ).every((input) => input.checkValidity()); + + if (isValid) { + onSave(url, text, isNewTab); + } else { + formRef.current.querySelectorAll("input").forEach((input) => { + if (!input.checkValidity()) { + input.reportValidity(); + } + }); + } + } + }, + [onSave, url, text, isNewTab], + ); + + React.useImperativeHandle(ref, () => formRef.current as HTMLDivElement); + + return ( +
+
+
+ + { + setUrl(e.target.value); + }} + /> +
+ +
+ + { + setText(e.target.value); + }} + /> +
+ +
+ + +
+ +
+ +
+
+
+ ); + }, +); + +/* eslint-enable @typescript-eslint/prefer-nullish-coalescing */ +/* eslint-enable @typescript-eslint/strict-boolean-expressions */ + +LinkEditBlock.displayName = "LinkEditBlock"; diff --git a/src/components/minimal-tiptap/components/link/link-edit-popover.tsx b/src/components/minimal-tiptap/components/link/link-edit-popover.tsx new file mode 100644 index 0000000..0fb0ac5 --- /dev/null +++ b/src/components/minimal-tiptap/components/link/link-edit-popover.tsx @@ -0,0 +1,75 @@ +import { Link2Icon } from "@radix-ui/react-icons"; +import type { Editor } from "@tiptap/react"; +import type { VariantProps } from "class-variance-authority"; +import * as React from "react"; + +import { + Popover, + PopoverContent, + PopoverTrigger, +} from "@/components/ui/popover"; +import type { toggleVariants } from "@/components/ui/toggle"; + +import { ToolbarButton } from "../toolbar-button"; +import { LinkEditBlock } from "./link-edit-block"; + +interface LinkEditPopoverProps extends VariantProps { + editor: Editor; +} + +const LinkEditPopover = ({ editor, size, variant }: LinkEditPopoverProps) => { + const [open, setOpen] = React.useState(false); + + const { from, to } = editor.state.selection; + const text = editor.state.doc.textBetween(from, to, " "); + + const onSetLink = React.useCallback( + (url: string, t?: string, openInNewTab?: boolean) => { + editor + .chain() + .focus() + .extendMarkRange("link") + .insertContent({ + type: "text", + // eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing, @typescript-eslint/strict-boolean-expressions + text: t || url, + marks: [ + { + type: "link", + attrs: { + href: url, + target: openInNewTab === true ? "_blank" : "", + }, + }, + ], + }) + .setLink({ href: url }) + .run(); + + editor.commands.enter(); + }, + [editor], + ); + + return ( + + + + + + + + + + + ); +}; + +export { LinkEditPopover }; diff --git a/src/components/minimal-tiptap/components/link/link-popover-block.tsx b/src/components/minimal-tiptap/components/link/link-popover-block.tsx new file mode 100644 index 0000000..09d903d --- /dev/null +++ b/src/components/minimal-tiptap/components/link/link-popover-block.tsx @@ -0,0 +1,84 @@ +import { + CopyIcon, + ExternalLinkIcon, + LinkBreak2Icon, +} from "@radix-ui/react-icons"; +import * as React from "react"; + +import { Separator } from "@/components/ui/separator"; + +import { ToolbarButton } from "../toolbar-button"; + +interface LinkPopoverBlockProps { + url: string; + onClear: () => void; + onEdit: (e: React.MouseEvent) => void; +} + +export const LinkPopoverBlock: React.FC = ({ + url, + onClear, + onEdit, +}) => { + const [copyTitle, setCopyTitle] = React.useState("Copy"); + + const handleCopy = React.useCallback( + (e: React.MouseEvent) => { + e.preventDefault(); + navigator.clipboard + .writeText(url) + .then(() => { + setCopyTitle("Copied!"); + setTimeout(() => { + setCopyTitle("Copy"); + }, 1000); + }) + // eslint-disable-next-line no-console + .catch(console.error); + }, + [url], + ); + + const handleOpenLink = React.useCallback(() => { + window.open(url, "_blank", "noopener,noreferrer"); + }, [url]); + + return ( +
+
+ + Edytuj link + + + + + + + + + + + { + if (e.target === e.currentTarget) { + e.preventDefault(); + } + }, + }} + > + + +
+
+ ); +}; diff --git a/src/components/minimal-tiptap/components/section/five.tsx b/src/components/minimal-tiptap/components/section/five.tsx new file mode 100644 index 0000000..5a13037 --- /dev/null +++ b/src/components/minimal-tiptap/components/section/five.tsx @@ -0,0 +1,94 @@ +import { + CaretDownIcon, + CodeIcon, + DividerHorizontalIcon, + PlusIcon, + QuoteIcon, +} from "@radix-ui/react-icons"; +import type { Editor } from "@tiptap/react"; +import type { VariantProps } from "class-variance-authority"; +import type * as React from "react"; + +import type { toggleVariants } from "@/components/ui/toggle"; + +// eslint-disable-next-line no-restricted-imports +import type { FormatAction } from "../../types"; +import { ImageEditDialog } from "../image/image-edit-dialog"; +import { LinkEditPopover } from "../link/link-edit-popover"; +import { ToolbarSection } from "../toolbar-section"; + +type InsertElementAction = "blockquote" | "codeBlock" | "horizontalRule"; +interface InsertElement extends FormatAction { + value: InsertElementAction; +} + +const formatActions: InsertElement[] = [ + { + value: "codeBlock", + label: "Kodzik", + icon: , + action: (editor) => editor.chain().focus().toggleCodeBlock().run(), + isActive: (editor) => editor.isActive("codeBlock"), + canExecute: (editor) => + editor.can().chain().focus().toggleCodeBlock().run(), + shortcuts: ["mod", "alt", "C"], + }, + { + value: "blockquote", + label: "Cytat", + icon: , + action: (editor) => editor.chain().focus().toggleBlockquote().run(), + isActive: (editor) => editor.isActive("blockquote"), + canExecute: (editor) => + editor.can().chain().focus().toggleBlockquote().run(), + shortcuts: ["mod", "shift", "B"], + }, + { + value: "horizontalRule", + label: "Linia pozioma", + icon: , + action: (editor) => editor.chain().focus().setHorizontalRule().run(), + isActive: () => false, + canExecute: (editor) => + editor.can().chain().focus().setHorizontalRule().run(), + shortcuts: ["mod", "alt", "-"], + }, +]; + +interface SectionFiveProps extends VariantProps { + editor: Editor; + activeActions?: InsertElementAction[]; + mainActionCount?: number; +} + +export const SectionFive: React.FC = ({ + editor, + activeActions = formatActions.map((action) => action.value), + mainActionCount = 0, + size, + variant, +}) => { + return ( + <> + + + + + + + } + dropdownTooltip="Dodaj element" + size={size} + variant={variant} + /> + + ); +}; + +SectionFive.displayName = "SectionFive"; diff --git a/src/components/minimal-tiptap/components/section/four.tsx b/src/components/minimal-tiptap/components/section/four.tsx new file mode 100644 index 0000000..84b8652 --- /dev/null +++ b/src/components/minimal-tiptap/components/section/four.tsx @@ -0,0 +1,82 @@ +import { CaretDownIcon, ListBulletIcon } from "@radix-ui/react-icons"; +import type { Editor } from "@tiptap/react"; +import type { VariantProps } from "class-variance-authority"; +import type * as React from "react"; + +import type { toggleVariants } from "@/components/ui/toggle"; + +// eslint-disable-next-line no-restricted-imports +import type { FormatAction } from "../../types"; +import { ToolbarSection } from "../toolbar-section"; + +type ListItemAction = "bulletList" | "orderedList"; +interface ListItem extends FormatAction { + value: ListItemAction; +} + +const formatActions: ListItem[] = [ + { + value: "orderedList", + label: "Lista numerowana", + icon: ( + + + + ), + isActive: (editor) => editor.isActive("orderedList"), + action: (editor) => editor.chain().focus().toggleOrderedList().run(), + canExecute: (editor) => + editor.can().chain().focus().toggleOrderedList().run(), + shortcuts: ["mod", "shift", "7"], + }, + { + value: "bulletList", + label: "Lista punktowana", + icon: , + isActive: (editor) => editor.isActive("bulletList"), + action: (editor) => editor.chain().focus().toggleBulletList().run(), + canExecute: (editor) => + editor.can().chain().focus().toggleBulletList().run(), + shortcuts: ["mod", "shift", "8"], + }, +]; + +interface SectionFourProps extends VariantProps { + editor: Editor; + activeActions?: ListItemAction[]; + mainActionCount?: number; +} + +export const SectionFour: React.FC = ({ + editor, + activeActions = formatActions.map((action) => action.value), + mainActionCount = 0, + size, + variant, +}) => { + return ( + + + + + } + dropdownTooltip="Lists" + size={size} + variant={variant} + /> + ); +}; + +SectionFour.displayName = "SectionFour"; diff --git a/src/components/minimal-tiptap/components/section/one.tsx b/src/components/minimal-tiptap/components/section/one.tsx new file mode 100644 index 0000000..37cc1df --- /dev/null +++ b/src/components/minimal-tiptap/components/section/one.tsx @@ -0,0 +1,154 @@ +import { CaretDownIcon, LetterCaseCapitalizeIcon } from "@radix-ui/react-icons"; +import type { Level } from "@tiptap/extension-heading"; +import type { Editor } from "@tiptap/react"; +import type { VariantProps } from "class-variance-authority"; +import * as React from "react"; + +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; +import type { toggleVariants } from "@/components/ui/toggle"; +import { cn } from "@/lib/utils"; + +// eslint-disable-next-line no-restricted-imports +import type { FormatAction } from "../../types"; +import { ShortcutKey } from "../shortcut-key"; +import { ToolbarButton } from "../toolbar-button"; + +interface TextStyle + extends Omit< + FormatAction, + "action" | "canExecute" | "icon" | "isActive" | "value" + > { + element: keyof JSX.IntrinsicElements; + level?: Level; + className: string; +} + +const formatActions: TextStyle[] = [ + { + label: "Zwykły tekst", + element: "span", + className: "grow", + shortcuts: ["mod", "alt", "0"], + }, + { + label: "Nagłówek 1", + element: "h1", + level: 1, + className: "m-0 grow text-3xl font-extrabold", + shortcuts: ["mod", "alt", "1"], + }, + { + label: "Nagłówek 2", + element: "h2", + level: 2, + className: "m-0 grow text-xl font-bold", + shortcuts: ["mod", "alt", "2"], + }, + { + label: "Nagłówek 3", + element: "h3", + level: 3, + className: "m-0 grow text-lg font-semibold", + shortcuts: ["mod", "alt", "3"], + }, + { + label: "Nagłówek 4", + element: "h4", + level: 4, + className: "m-0 grow text-base font-semibold", + shortcuts: ["mod", "alt", "4"], + }, + { + label: "Nagłówek 5", + element: "h5", + level: 5, + className: "m-0 grow text-sm font-normal", + shortcuts: ["mod", "alt", "5"], + }, + { + label: "Nagłówek 6", + element: "h6", + level: 6, + className: "m-0 grow text-sm font-normal", + shortcuts: ["mod", "alt", "6"], + }, +]; + +interface SectionOneProps extends VariantProps { + editor: Editor; + activeLevels?: Level[]; +} + +export const SectionOne: React.FC = React.memo( + ({ editor, activeLevels = [1, 2, 3, 4, 5, 6], size, variant }) => { + const filteredActions = React.useMemo( + () => + formatActions.filter( + (action) => !action.level || activeLevels.includes(action.level), + ), + [activeLevels], + ); + + const handleStyleChange = React.useCallback( + (level?: Level) => { + if (level) { + editor.chain().focus().toggleHeading({ level }).run(); + } else { + editor.chain().focus().setParagraph().run(); + } + }, + [editor], + ); + + const renderMenuItem = React.useCallback( + ({ label, element: Element, level, className, shortcuts }: TextStyle) => ( + { + handleStyleChange(level); + }} + className={cn("flex flex-row items-center justify-between gap-4", { + "bg-accent": level + ? editor.isActive("heading", { level }) + : editor.isActive("paragraph"), + })} + aria-label={label} + > + {label} + + + ), + [editor, handleStyleChange], + ); + + return ( + + + + + + + + + {filteredActions.map(renderMenuItem)} + + + ); + }, +); + +SectionOne.displayName = "SectionOne"; diff --git a/src/components/minimal-tiptap/components/section/three.tsx b/src/components/minimal-tiptap/components/section/three.tsx new file mode 100644 index 0000000..4ffc491 --- /dev/null +++ b/src/components/minimal-tiptap/components/section/three.tsx @@ -0,0 +1,220 @@ +import { CaretDownIcon, CheckIcon } from "@radix-ui/react-icons"; +import type { Editor } from "@tiptap/react"; +import type { VariantProps } from "class-variance-authority"; +import * as React from "react"; + +import { + Popover, + PopoverContent, + PopoverTrigger, +} from "@/components/ui/popover"; +import type { toggleVariants } from "@/components/ui/toggle"; +import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group"; +import { + Tooltip, + TooltipContent, + TooltipTrigger, +} from "@/components/ui/tooltip"; + +// eslint-disable-next-line no-restricted-imports +import { useTheme } from "../../hooks/use-theme"; +import { ToolbarButton } from "../toolbar-button"; + +interface ColorItem { + cssVar: string; + label: string; + darkLabel?: string; +} + +interface ColorPalette { + label: string; + colors: ColorItem[]; + inverse: string; +} + +const COLORS: ColorPalette[] = [ + { + label: "Paleta 1", + inverse: "hsl(var(--background))", + colors: [ + { cssVar: "hsl(var(--foreground))", label: "Default" }, + { cssVar: "var(--mt-accent-bold-blue)", label: "Bold blue" }, + { cssVar: "var(--mt-accent-bold-teal)", label: "Bold teal" }, + { cssVar: "var(--mt-accent-bold-green)", label: "Bold green" }, + { cssVar: "var(--mt-accent-bold-orange)", label: "Bold orange" }, + { cssVar: "var(--mt-accent-bold-red)", label: "Bold red" }, + { cssVar: "var(--mt-accent-bold-purple)", label: "Bold purple" }, + ], + }, + { + label: "Paleta 2", + inverse: "hsl(var(--background))", + colors: [ + { cssVar: "var(--mt-accent-gray)", label: "Gray" }, + { cssVar: "var(--mt-accent-blue)", label: "Blue" }, + { cssVar: "var(--mt-accent-teal)", label: "Teal" }, + { cssVar: "var(--mt-accent-green)", label: "Green" }, + { cssVar: "var(--mt-accent-orange)", label: "Orange" }, + { cssVar: "var(--mt-accent-red)", label: "Red" }, + { cssVar: "var(--mt-accent-purple)", label: "Purple" }, + ], + }, + { + label: "Paleta 3", + inverse: "hsl(var(--foreground))", + colors: [ + { cssVar: "hsl(var(--background))", label: "White", darkLabel: "Black" }, + { cssVar: "var(--mt-accent-blue-subtler)", label: "Blue subtle" }, + { cssVar: "var(--mt-accent-teal-subtler)", label: "Teal subtle" }, + { cssVar: "var(--mt-accent-green-subtler)", label: "Green subtle" }, + { cssVar: "var(--mt-accent-yellow-subtler)", label: "Yellow subtle" }, + { cssVar: "var(--mt-accent-red-subtler)", label: "Red subtle" }, + { cssVar: "var(--mt-accent-purple-subtler)", label: "Purple subtle" }, + ], + }, +]; + +const MemoizedColorButton = React.memo<{ + color: ColorItem; + isSelected: boolean; + inverse: string; + onClick: (value: string) => void; +}>(({ color, isSelected, inverse, onClick }) => { + const isDarkMode = useTheme(); + const label = + isDarkMode && Boolean(color.darkLabel) ? color.darkLabel : color.label; + + return ( + + + ) => { + e.preventDefault(); + onClick(color.cssVar); + }} + > + {isSelected ? ( + + ) : null} + + + +

{label}

+
+
+ ); +}); + +MemoizedColorButton.displayName = "MemoizedColorButton"; + +const MemoizedColorPicker = React.memo<{ + palette: ColorPalette; + selectedColor: string; + inverse: string; + onColorChange: (value: string) => void; +}>(({ palette, selectedColor, inverse, onColorChange }) => ( + { + if (value) { + onColorChange(value); + } + }} + className="gap-1.5" + > + {palette.colors.map((color, index) => ( + + ))} + +)); + +MemoizedColorPicker.displayName = "MemoizedColorPicker"; + +interface SectionThreeProps extends VariantProps { + editor: Editor; +} + +export const SectionThree: React.FC = ({ + editor, + size, + variant, +}) => { + const color = + (editor.getAttributes("textStyle").color as string | undefined) ?? + "hsl(var(--foreground))"; + const [selectedColor, setSelectedColor] = React.useState(color); + + const handleColorChange = React.useCallback( + (value: string) => { + setSelectedColor(value); + editor.chain().setColor(value).run(); + }, + [editor], + ); + + React.useEffect(() => { + setSelectedColor(color); + }, [color]); + + return ( + + + + + + + + + + + + +
+ {COLORS.map((palette, index) => ( + + ))} +
+
+
+ ); +}; + +SectionThree.displayName = "SectionThree"; diff --git a/src/components/minimal-tiptap/components/section/two.tsx b/src/components/minimal-tiptap/components/section/two.tsx new file mode 100644 index 0000000..19e838b --- /dev/null +++ b/src/components/minimal-tiptap/components/section/two.tsx @@ -0,0 +1,116 @@ +import { + CodeIcon, + DotsHorizontalIcon, + FontBoldIcon, + FontItalicIcon, + StrikethroughIcon, + TextNoneIcon, +} from "@radix-ui/react-icons"; +import type { Editor } from "@tiptap/react"; +import type { VariantProps } from "class-variance-authority"; +import type * as React from "react"; + +import type { toggleVariants } from "@/components/ui/toggle"; + +// eslint-disable-next-line no-restricted-imports +import type { FormatAction } from "../../types"; +import { ToolbarSection } from "../toolbar-section"; + +type TextStyleAction = + | "bold" + | "clearFormatting" + | "code" + | "italic" + | "strikethrough"; + +interface TextStyle extends FormatAction { + value: TextStyleAction; +} + +const formatActions: TextStyle[] = [ + { + value: "bold", + label: "Pogrubienie", + icon: , + action: (editor) => editor.chain().focus().toggleBold().run(), + isActive: (editor) => editor.isActive("bold"), + canExecute: (editor) => + editor.can().chain().focus().toggleBold().run() && + !editor.isActive("codeBlock"), + shortcuts: ["mod", "B"], + }, + { + value: "italic", + label: "Kursywa", + icon: , + action: (editor) => editor.chain().focus().toggleItalic().run(), + isActive: (editor) => editor.isActive("italic"), + canExecute: (editor) => + editor.can().chain().focus().toggleItalic().run() && + !editor.isActive("codeBlock"), + shortcuts: ["mod", "I"], + }, + { + value: "strikethrough", + label: "Kreska", + icon: , + action: (editor) => editor.chain().focus().toggleStrike().run(), + isActive: (editor) => editor.isActive("strike"), + canExecute: (editor) => + editor.can().chain().focus().toggleStrike().run() && + !editor.isActive("codeBlock"), + shortcuts: ["mod", "shift", "S"], + }, + { + value: "code", + label: "Kodzik", + icon: , + action: (editor) => editor.chain().focus().toggleCode().run(), + isActive: (editor) => editor.isActive("code"), + canExecute: (editor) => + editor.can().chain().focus().toggleCode().run() && + !editor.isActive("codeBlock"), + shortcuts: ["mod", "E"], + }, + { + value: "clearFormatting", + label: "Wyczyść formatowanie", + icon: , + action: (editor) => editor.chain().focus().unsetAllMarks().run(), + isActive: () => false, + canExecute: (editor) => + editor.can().chain().focus().unsetAllMarks().run() && + !editor.isActive("codeBlock"), + shortcuts: ["mod", "\\"], + }, +]; + +interface SectionTwoProps extends VariantProps { + editor: Editor; + activeActions?: TextStyleAction[]; + mainActionCount?: number; +} + +export const SectionTwo: React.FC = ({ + editor, + activeActions = formatActions.map((action) => action.value), + mainActionCount = 2, + size, + variant, +}) => { + return ( + } + dropdownTooltip="Więcej formatowania" + dropdownClassName="w-8" + size={size} + variant={variant} + /> + ); +}; + +SectionTwo.displayName = "SectionTwo"; diff --git a/src/components/minimal-tiptap/components/shortcut-key.tsx b/src/components/minimal-tiptap/components/shortcut-key.tsx new file mode 100644 index 0000000..b418d46 --- /dev/null +++ b/src/components/minimal-tiptap/components/shortcut-key.tsx @@ -0,0 +1,44 @@ +import * as React from "react"; + +import { cn } from "@/lib/utils"; + +import { getShortcutKey } from "../utils"; + +interface ShortcutKeyProps extends React.HTMLAttributes { + keys: string[]; +} + +export const ShortcutKey = React.forwardRef( + ({ className, keys, ...props }, ref) => { + const modifiedKeys = keys.map((key) => getShortcutKey(key)); + const ariaLabel = modifiedKeys + .map((shortcut) => shortcut.readable) + .join(" + "); + + return ( + + {modifiedKeys.map((shortcut) => ( + + {shortcut.symbol} + + ))} + + ); + }, +); + +ShortcutKey.displayName = "ShortcutKey"; diff --git a/src/components/minimal-tiptap/components/toolbar-button.tsx b/src/components/minimal-tiptap/components/toolbar-button.tsx new file mode 100644 index 0000000..6ebcd36 --- /dev/null +++ b/src/components/minimal-tiptap/components/toolbar-button.tsx @@ -0,0 +1,55 @@ +import type { TooltipContentProps } from "@radix-ui/react-tooltip"; +import * as React from "react"; + +import { Toggle } from "@/components/ui/toggle"; +import { + Tooltip, + TooltipContent, + TooltipTrigger, +} from "@/components/ui/tooltip"; +import { cn } from "@/lib/utils"; + +interface ToolbarButtonProps + extends React.ComponentPropsWithoutRef { + isActive?: boolean; + tooltip?: string; + tooltipOptions?: TooltipContentProps; +} + +export const ToolbarButton = React.forwardRef< + HTMLButtonElement, + ToolbarButtonProps +>( + ( + { isActive, children, tooltip, className, tooltipOptions, ...props }, + ref, + ) => { + const toggleButton = ( + + {children} + + ); + + if (!Boolean(tooltip)) { + return toggleButton; + } + + return ( + + {toggleButton} + +
+ {tooltip} +
+
+
+ ); + }, +); + +ToolbarButton.displayName = "ToolbarButton"; diff --git a/src/components/minimal-tiptap/components/toolbar-section.tsx b/src/components/minimal-tiptap/components/toolbar-section.tsx new file mode 100644 index 0000000..c368cbc --- /dev/null +++ b/src/components/minimal-tiptap/components/toolbar-section.tsx @@ -0,0 +1,124 @@ +import { CaretDownIcon } from "@radix-ui/react-icons"; +import type { Editor } from "@tiptap/react"; +import type { VariantProps } from "class-variance-authority"; +import * as React from "react"; + +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; +import type { toggleVariants } from "@/components/ui/toggle"; +import { cn } from "@/lib/utils"; + +import type { FormatAction } from "../types"; +import { getShortcutKey } from "../utils"; +import { ShortcutKey } from "./shortcut-key"; +import { ToolbarButton } from "./toolbar-button"; + +interface ToolbarSectionProps extends VariantProps { + editor: Editor; + actions: FormatAction[]; + activeActions?: string[]; + mainActionCount?: number; + dropdownIcon?: React.ReactNode; + dropdownTooltip?: string; + dropdownClassName?: string; +} + +export const ToolbarSection: React.FC = ({ + editor, + actions, + activeActions = actions.map((action) => action.value), + mainActionCount = 0, + dropdownIcon, + dropdownTooltip = "Więcej opcji", + dropdownClassName = "w-12", + size, + variant, +}) => { + const { mainActions, dropdownActions } = React.useMemo(() => { + const sortedActions = actions + .filter((action) => activeActions.includes(action.value)) + .sort( + (a, b) => + activeActions.indexOf(a.value) - activeActions.indexOf(b.value), + ); + + return { + mainActions: sortedActions.slice(0, mainActionCount), + dropdownActions: sortedActions.slice(mainActionCount), + }; + }, [actions, activeActions, mainActionCount]); + + const renderToolbarButton = React.useCallback( + (action: FormatAction) => ( + { + action.action(editor); + }} + disabled={!action.canExecute(editor)} + isActive={action.isActive(editor)} + tooltip={`${action.label} ${action.shortcuts.map((s) => getShortcutKey(s).symbol).join(" ")}`} + aria-label={action.label} + size={size} + variant={variant} + > + {action.icon} + + ), + [editor, size, variant], + ); + + const renderDropdownMenuItem = React.useCallback( + (action: FormatAction) => ( + { + action.action(editor); + }} + disabled={!action.canExecute(editor)} + className={cn("flex flex-row items-center justify-between gap-4", { + "bg-accent": action.isActive(editor), + })} + aria-label={action.label} + > + {action.label} + + + ), + [editor], + ); + + const isDropdownActive = React.useMemo( + () => dropdownActions.some((action) => action.isActive(editor)), + [dropdownActions, editor], + ); + + return ( + <> + {mainActions.map(renderToolbarButton)} + {dropdownActions.length > 0 && ( + + + + {dropdownIcon ?? } + + + + {dropdownActions.map(renderDropdownMenuItem)} + + + )} + + ); +}; diff --git a/src/components/minimal-tiptap/extensions/code-block-lowlight/code-block-lowlight.ts b/src/components/minimal-tiptap/extensions/code-block-lowlight/code-block-lowlight.ts new file mode 100644 index 0000000..7bed749 --- /dev/null +++ b/src/components/minimal-tiptap/extensions/code-block-lowlight/code-block-lowlight.ts @@ -0,0 +1,16 @@ +import { CodeBlockLowlight as TiptapCodeBlockLowlight } from "@tiptap/extension-code-block-lowlight"; +import { common, createLowlight } from "lowlight"; + +export const CodeBlockLowlight = TiptapCodeBlockLowlight.extend({ + addOptions() { + return { + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + ...this.parent?.(), + lowlight: createLowlight(common), + defaultLanguage: null, + HTMLAttributes: { + class: "block-node", + }, + }; + }, +}); diff --git a/src/components/minimal-tiptap/extensions/code-block-lowlight/index.ts b/src/components/minimal-tiptap/extensions/code-block-lowlight/index.ts new file mode 100644 index 0000000..7464bf5 --- /dev/null +++ b/src/components/minimal-tiptap/extensions/code-block-lowlight/index.ts @@ -0,0 +1 @@ +export * from "./code-block-lowlight"; diff --git a/src/components/minimal-tiptap/extensions/color/color.ts b/src/components/minimal-tiptap/extensions/color/color.ts new file mode 100644 index 0000000..383dfd2 --- /dev/null +++ b/src/components/minimal-tiptap/extensions/color/color.ts @@ -0,0 +1,20 @@ +import { Color as TiptapColor } from "@tiptap/extension-color"; +import { Plugin } from "@tiptap/pm/state"; + +export const Color = TiptapColor.extend({ + addProseMirrorPlugins() { + return [ + ...(this.parent?.() ?? []), + new Plugin({ + props: { + handleKeyDown: (_, event) => { + if (event.key === "Enter") { + this.editor.commands.unsetColor(); + } + return false; + }, + }, + }), + ]; + }, +}); diff --git a/src/components/minimal-tiptap/extensions/color/index.ts b/src/components/minimal-tiptap/extensions/color/index.ts new file mode 100644 index 0000000..60b7091 --- /dev/null +++ b/src/components/minimal-tiptap/extensions/color/index.ts @@ -0,0 +1 @@ +export * from "./color"; diff --git a/src/components/minimal-tiptap/extensions/horizontal-rule/horizontal-rule.ts b/src/components/minimal-tiptap/extensions/horizontal-rule/horizontal-rule.ts new file mode 100644 index 0000000..2a2d3f6 --- /dev/null +++ b/src/components/minimal-tiptap/extensions/horizontal-rule/horizontal-rule.ts @@ -0,0 +1,16 @@ +/* + * Wrap the horizontal rule in a div element. + * Also add a keyboard shortcut to insert a horizontal rule. + */ +import { HorizontalRule as TiptapHorizontalRule } from "@tiptap/extension-horizontal-rule"; + +export const HorizontalRule = TiptapHorizontalRule.extend({ + addKeyboardShortcuts() { + return { + "Mod-Alt--": () => + this.editor.commands.insertContent({ + type: this.name, + }), + }; + }, +}); diff --git a/src/components/minimal-tiptap/extensions/horizontal-rule/index.ts b/src/components/minimal-tiptap/extensions/horizontal-rule/index.ts new file mode 100644 index 0000000..f7a009c --- /dev/null +++ b/src/components/minimal-tiptap/extensions/horizontal-rule/index.ts @@ -0,0 +1 @@ +export * from "./horizontal-rule"; diff --git a/src/components/minimal-tiptap/extensions/index.ts b/src/components/minimal-tiptap/extensions/index.ts new file mode 100644 index 0000000..c0b8a2f --- /dev/null +++ b/src/components/minimal-tiptap/extensions/index.ts @@ -0,0 +1,7 @@ +export * from "./code-block-lowlight"; +export * from "./color"; +export * from "./horizontal-rule"; +export * from "./link"; +export * from "./selection"; +export * from "./unset-all-marks"; +export * from "./reset-marks-on-enter"; diff --git a/src/components/minimal-tiptap/extensions/link/index.ts b/src/components/minimal-tiptap/extensions/link/index.ts new file mode 100644 index 0000000..6fc151a --- /dev/null +++ b/src/components/minimal-tiptap/extensions/link/index.ts @@ -0,0 +1 @@ +export * from "./link"; diff --git a/src/components/minimal-tiptap/extensions/link/link.ts b/src/components/minimal-tiptap/extensions/link/link.ts new file mode 100644 index 0000000..6dad605 --- /dev/null +++ b/src/components/minimal-tiptap/extensions/link/link.ts @@ -0,0 +1,97 @@ +import { getMarkRange, mergeAttributes } from "@tiptap/core"; +import TiptapLink from "@tiptap/extension-link"; +import { Plugin, TextSelection } from "@tiptap/pm/state"; +import type { EditorView } from "@tiptap/pm/view"; + +export const Link = TiptapLink.extend({ + /* + * Determines whether typing next to a link automatically becomes part of the link. + * In this case, we dont want any characters to be included as part of the link. + */ + inclusive: false, + + /* + * Match all elements that have an href attribute, except for: + * - elements with a data-type attribute set to button + * - elements with an href attribute that contains 'javascript:' + */ + parseHTML() { + return [ + { + tag: 'a[href]:not([data-type="button"]):not([href *= "javascript:" i])', + }, + ]; + }, + + renderHTML({ HTMLAttributes }) { + return [ + "a", + mergeAttributes(this.options.HTMLAttributes, HTMLAttributes), + 0, + ]; + }, + + addOptions() { + return { + // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition + ...this.parent?.(), + openOnClick: false, + HTMLAttributes: { + class: "link", + }, + }; + }, + + addProseMirrorPlugins() { + const { editor } = this; + + return [ + ...(this.parent?.() ?? []), + new Plugin({ + props: { + handleKeyDown: (_: EditorView, event: KeyboardEvent) => { + const { selection } = editor.state; + + /* + * Handles the 'Escape' key press when there's a selection within the link. + * This will move the cursor to the end of the link. + */ + if (event.key === "Escape" && !selection.empty) { + editor.commands.focus(selection.to, { scrollIntoView: false }); + } + + return false; + }, + handleClick(view, pos) { + /* + * Marks the entire link when the user clicks on it. + */ + + const { schema, doc, tr } = view.state; + const range = getMarkRange(doc.resolve(pos), schema.marks.link); + + if (!range) { + return; + } + + const { from, to } = range; + const start = Math.min(from, to); + const end = Math.max(from, to); + + if (pos < start || pos > end) { + return; + } + + const $start = doc.resolve(start); + const $end = doc.resolve(end); + const transaction = tr.setSelection( + new TextSelection($start, $end), + ); + + view.dispatch(transaction); + }, + }, + }), + ]; + }, +}); diff --git a/src/components/minimal-tiptap/extensions/reset-marks-on-enter/index.ts b/src/components/minimal-tiptap/extensions/reset-marks-on-enter/index.ts new file mode 100644 index 0000000..67f042f --- /dev/null +++ b/src/components/minimal-tiptap/extensions/reset-marks-on-enter/index.ts @@ -0,0 +1 @@ +export * from "./reset-marks-on-enter"; diff --git a/src/components/minimal-tiptap/extensions/reset-marks-on-enter/reset-marks-on-enter.ts b/src/components/minimal-tiptap/extensions/reset-marks-on-enter/reset-marks-on-enter.ts new file mode 100644 index 0000000..b6b73f0 --- /dev/null +++ b/src/components/minimal-tiptap/extensions/reset-marks-on-enter/reset-marks-on-enter.ts @@ -0,0 +1,25 @@ +import { Extension } from "@tiptap/core"; + +export const ResetMarksOnEnter = Extension.create({ + name: "resetMarksOnEnter", + + addKeyboardShortcuts() { + return { + Enter: ({ editor }) => { + if ( + editor.isActive("bold") || + editor.isActive("italic") || + editor.isActive("strike") || + editor.isActive("underline") || + editor.isActive("code") + ) { + editor.commands.splitBlock({ keepMarks: false }); + + return true; + } + + return false; + }, + }; + }, +}); diff --git a/src/components/minimal-tiptap/extensions/selection/index.ts b/src/components/minimal-tiptap/extensions/selection/index.ts new file mode 100644 index 0000000..267dfa3 --- /dev/null +++ b/src/components/minimal-tiptap/extensions/selection/index.ts @@ -0,0 +1 @@ +export * from "./selection"; diff --git a/src/components/minimal-tiptap/extensions/selection/selection.ts b/src/components/minimal-tiptap/extensions/selection/selection.ts new file mode 100644 index 0000000..08aa496 --- /dev/null +++ b/src/components/minimal-tiptap/extensions/selection/selection.ts @@ -0,0 +1,34 @@ +import { Extension } from "@tiptap/core"; +import { Plugin, PluginKey } from "@tiptap/pm/state"; +import { Decoration, DecorationSet } from "@tiptap/pm/view"; + +export const Selection = Extension.create({ + name: "selection", + + addProseMirrorPlugins() { + const { editor } = this; + + return [ + new Plugin({ + key: new PluginKey("selection"), + props: { + decorations(state) { + if (state.selection.empty) { + return null; + } + + if (editor.isFocused) { + return null; + } + + return DecorationSet.create(state.doc, [ + Decoration.inline(state.selection.from, state.selection.to, { + class: "selection", + }), + ]); + }, + }, + }), + ]; + }, +}); diff --git a/src/components/minimal-tiptap/extensions/unset-all-marks/index.ts b/src/components/minimal-tiptap/extensions/unset-all-marks/index.ts new file mode 100644 index 0000000..99a2de5 --- /dev/null +++ b/src/components/minimal-tiptap/extensions/unset-all-marks/index.ts @@ -0,0 +1 @@ +export * from "./unset-all-marks"; diff --git a/src/components/minimal-tiptap/extensions/unset-all-marks/unset-all-marks.ts b/src/components/minimal-tiptap/extensions/unset-all-marks/unset-all-marks.ts new file mode 100644 index 0000000..40ea7de --- /dev/null +++ b/src/components/minimal-tiptap/extensions/unset-all-marks/unset-all-marks.ts @@ -0,0 +1,9 @@ +import { Extension } from "@tiptap/core"; + +export const UnsetAllMarks = Extension.create({ + addKeyboardShortcuts() { + return { + "Mod-\\": () => this.editor.commands.unsetAllMarks(), + }; + }, +}); diff --git a/src/components/minimal-tiptap/hooks/use-minimal-tiptap.ts b/src/components/minimal-tiptap/hooks/use-minimal-tiptap.ts new file mode 100644 index 0000000..bb7e339 --- /dev/null +++ b/src/components/minimal-tiptap/hooks/use-minimal-tiptap.ts @@ -0,0 +1,119 @@ +import type { Editor } from "@tiptap/core"; +import { Image } from "@tiptap/extension-image"; +import { Placeholder } from "@tiptap/extension-placeholder"; +import { TextStyle } from "@tiptap/extension-text-style"; +import { Typography } from "@tiptap/extension-typography"; +import type { Content, UseEditorOptions } from "@tiptap/react"; +import { useEditor } from "@tiptap/react"; +import { StarterKit } from "@tiptap/starter-kit"; +import * as React from "react"; +import ImageResize from "tiptap-extension-resize-image"; + +import { cn } from "@/lib/utils"; + +import { + CodeBlockLowlight, + Color, + HorizontalRule, + Link, + ResetMarksOnEnter, + Selection, + UnsetAllMarks, +} from "../extensions"; +import { useThrottle } from "../hooks/use-throttle"; +import { getOutput } from "../utils"; + +export interface UseMinimalTiptapEditorProps extends UseEditorOptions { + value?: Content; + output?: "html" | "json" | "text"; + placeholder?: string; + editorClassName?: string; + throttleDelay?: number; + onUpdate?: (content: Content) => void; + onBlur?: (content: Content) => void; +} + +const createExtensions = (placeholder: string) => [ + StarterKit.configure({ + horizontalRule: false, + codeBlock: false, + paragraph: { HTMLAttributes: { class: "text-node" } }, + heading: { HTMLAttributes: { class: "heading-node" } }, + blockquote: { HTMLAttributes: { class: "block-node" } }, + bulletList: { HTMLAttributes: { class: "list-node" } }, + orderedList: { HTMLAttributes: { class: "list-node" } }, + code: { HTMLAttributes: { class: "inline", spellcheck: "false" } }, + dropcursor: { width: 2, class: "ProseMirror-dropcursor border" }, + }), + ImageResize, + Link, + Image, + Color, + TextStyle, + Selection, + Typography, + UnsetAllMarks, + HorizontalRule, + ResetMarksOnEnter, + CodeBlockLowlight, + Placeholder.configure({ placeholder: () => placeholder }), +]; + +export const useMinimalTiptapEditor = ({ + value, + output = "html", + placeholder = "", + editorClassName, + throttleDelay = 0, + onUpdate, + onBlur, + ...props +}: UseMinimalTiptapEditorProps) => { + const throttledSetValue = useThrottle( + (v: Content) => onUpdate?.(v), + throttleDelay, + ); + + const handleUpdate = React.useCallback( + (editor: Editor) => { + throttledSetValue(getOutput(editor, output)); + }, + [output, throttledSetValue], + ); + + const handleCreate = React.useCallback( + (editor: Editor) => { + if (value !== undefined && editor.isEmpty) { + editor.commands.setContent(value); + } + }, + [value], + ); + + const handleBlur = React.useCallback( + (editor: Editor) => onBlur?.(getOutput(editor, output)), + [output, onBlur], + ); + + const editor = useEditor({ + extensions: createExtensions(placeholder), + editorProps: { + attributes: { + autocomplete: "off", + autocorrect: "off", + autocapitalize: "off", + class: cn("focus:outline-none", editorClassName), + }, + }, + onUpdate: ({ editor: e }) => { + handleUpdate(e); + }, + onCreate: ({ editor: e }) => { + handleCreate(e); + }, + onBlur: ({ editor: e }) => handleBlur(e), + ...props, + }); + + return editor; +}; diff --git a/src/components/minimal-tiptap/hooks/use-theme.ts b/src/components/minimal-tiptap/hooks/use-theme.ts new file mode 100644 index 0000000..1112f01 --- /dev/null +++ b/src/components/minimal-tiptap/hooks/use-theme.ts @@ -0,0 +1,25 @@ +import * as React from "react"; + +export const useTheme = () => { + const [isDarkMode, setIsDarkMode] = React.useState(false); + + React.useEffect(() => { + const darkModeMediaQuery = window.matchMedia( + "(prefers-color-scheme: dark)", + ); + setIsDarkMode(darkModeMediaQuery.matches); + + const handleChange = (e: MediaQueryListEvent) => { + const newDarkMode = e.matches; + setIsDarkMode(newDarkMode); + }; + + darkModeMediaQuery.addEventListener("change", handleChange); + + return () => { + darkModeMediaQuery.removeEventListener("change", handleChange); + }; + }, []); + + return isDarkMode; +}; diff --git a/src/components/minimal-tiptap/hooks/use-throttle.ts b/src/components/minimal-tiptap/hooks/use-throttle.ts new file mode 100644 index 0000000..401c0ac --- /dev/null +++ b/src/components/minimal-tiptap/hooks/use-throttle.ts @@ -0,0 +1,34 @@ +import { useCallback, useRef } from "react"; + +export function useThrottle void>( + callback: T, + delay: number, +): (...args: Parameters) => void { + const lastRan = useRef(Date.now()); + const timeoutRef = useRef(null); + + return useCallback( + (...args: Parameters) => { + const handler = () => { + if (Date.now() - lastRan.current >= delay) { + callback(...args); + lastRan.current = Date.now(); + } else { + if (timeoutRef.current) { + clearTimeout(timeoutRef.current); + } + timeoutRef.current = setTimeout( + () => { + callback(...args); + lastRan.current = Date.now(); + }, + delay - (Date.now() - lastRan.current), + ); + } + }; + + handler(); + }, + [callback, delay], + ); +} diff --git a/src/components/minimal-tiptap/index.ts b/src/components/minimal-tiptap/index.ts new file mode 100644 index 0000000..643c206 --- /dev/null +++ b/src/components/minimal-tiptap/index.ts @@ -0,0 +1 @@ +export * from "./minimal-tiptap"; diff --git a/src/components/minimal-tiptap/minimal-tiptap.tsx b/src/components/minimal-tiptap/minimal-tiptap.tsx new file mode 100644 index 0000000..773d4b8 --- /dev/null +++ b/src/components/minimal-tiptap/minimal-tiptap.tsx @@ -0,0 +1,102 @@ +import type { Content, Editor } from "@tiptap/react"; +import { EditorContent } from "@tiptap/react"; +import * as React from "react"; + +import { Separator } from "@/components/ui/separator"; +import { cn } from "@/lib/utils"; + +import { ImageBubbleMenu } from "./components/bubble-menu/image-bubble-menu"; +import { LinkBubbleMenu } from "./components/bubble-menu/link-bubble-menu"; +import { SectionFive } from "./components/section/five"; +import { SectionFour } from "./components/section/four"; +import { SectionOne } from "./components/section/one"; +import { SectionThree } from "./components/section/three"; +import { SectionTwo } from "./components/section/two"; +import type { UseMinimalTiptapEditorProps } from "./hooks/use-minimal-tiptap"; +import { useMinimalTiptapEditor } from "./hooks/use-minimal-tiptap"; + +export interface MinimalTiptapProps + extends Omit { + value?: Content; + onChange?: (value: Content) => void; + className?: string; + editorContentClassName?: string; +} + +const Toolbar = ({ editor }: { editor: Editor }) => ( +
+
+ + + + + + + + + + + + + + + + + +
+
+); + +export const MinimalTiptapEditor = React.forwardRef< + HTMLDivElement, + MinimalTiptapProps +>(({ value, onChange, className, editorContentClassName, ...props }, ref) => { + const editor = useMinimalTiptapEditor({ + value, + immediatelyRender: false, + onUpdate: onChange, + ...props, + }); + + if (!editor) { + return null; + } + + return ( +
+ + + + +
+ ); +}); + +MinimalTiptapEditor.displayName = "MinimalTiptapEditor"; diff --git a/src/components/minimal-tiptap/styles/index.css b/src/components/minimal-tiptap/styles/index.css new file mode 100644 index 0000000..f518b2e --- /dev/null +++ b/src/components/minimal-tiptap/styles/index.css @@ -0,0 +1,182 @@ +@import "./partials/code.css"; +@import "./partials/placeholder.css"; +@import "./partials/lists.css"; +@import "./partials/typography.css"; + +:root { + --mt-font-size-regular: 0.9375rem; + + --mt-code-background: #082b781f; + --mt-code-color: #d4d4d4; + --mt-secondary: #9d9d9f; + --mt-pre-background: #ececec; + --mt-pre-border: #e0e0e0; + --mt-pre-color: #2f2f31; + --mt-hr: #dcdcdc; + --mt-drag-handle-hover: #5c5c5e; + + --mt-accent-bold-blue: #05c; + --mt-accent-bold-teal: #206a83; + --mt-accent-bold-green: #216e4e; + --mt-accent-bold-orange: #a54800; + --mt-accent-bold-red: #ae2e24; + --mt-accent-bold-purple: #5e4db2; + + --mt-accent-gray: #758195; + --mt-accent-blue: #1d7afc; + --mt-accent-teal: #2898bd; + --mt-accent-green: #22a06b; + --mt-accent-orange: #fea362; + --mt-accent-red: #c9372c; + --mt-accent-purple: #8270db; + + --mt-accent-blue-subtler: #cce0ff; + --mt-accent-teal-subtler: #c6edfb; + --mt-accent-green-subtler: #baf3db; + --mt-accent-yellow-subtler: #f8e6a0; + --mt-accent-red-subtler: #ffd5d2; + --mt-accent-purple-subtler: #dfd8fd; + + --hljs-string: #aa430f; + --hljs-title: #b08836; + --hljs-comment: #999999; + --hljs-keyword: #0c5eb1; + --hljs-attr: #3a92bc; + --hljs-literal: #c82b0f; + --hljs-name: #259792; + --hljs-selector-tag: #c8500f; + --hljs-number: #3da067; +} + +.dark { + --mt-font-size-regular: 0.9375rem; + + --mt-code-background: #ffffff13; + --mt-code-color: #2c2e33; + --mt-secondary: #595a5c; + --mt-pre-background: #080808; + --mt-pre-border: #23252a; + --mt-pre-color: #e3e4e6; + --mt-hr: #26282d; + --mt-drag-handle-hover: #969799; + + --mt-accent-bold-blue: #85b8ff; + --mt-accent-bold-teal: #9dd9ee; + --mt-accent-bold-green: #7ee2b8; + --mt-accent-bold-orange: #fec195; + --mt-accent-bold-red: #fd9891; + --mt-accent-bold-purple: #b8acf6; + + --mt-accent-gray: #738496; + --mt-accent-blue: #388bff; + --mt-accent-teal: #42b2d7; + --mt-accent-green: #2abb7f; + --mt-accent-orange: #a54800; + --mt-accent-red: #e2483d; + --mt-accent-purple: #8f7ee7; + + --mt-accent-blue-subtler: #09326c; + --mt-accent-teal-subtler: #164555; + --mt-accent-green-subtler: #164b35; + --mt-accent-yellow-subtler: #533f04; + --mt-accent-red-subtler: #5d1f1a; + --mt-accent-purple-subtler: #352c63; + + --hljs-string: #da936b; + --hljs-title: #f1d59d; + --hljs-comment: #aaaaaa; + --hljs-keyword: #6699cc; + --hljs-attr: #90cae8; + --hljs-literal: #f2777a; + --hljs-name: #5fc0a0; + --hljs-selector-tag: #e8c785; + --hljs-number: #b6e7b6; +} + +.minimal-tiptap-editor .ProseMirror { + @apply flex max-w-full flex-1 cursor-text flex-col; + @apply z-0 outline-0; +} + +.minimal-tiptap-editor .ProseMirror > div.editor { + @apply block flex-1 whitespace-pre-wrap; +} + +.minimal-tiptap-editor .ProseMirror .block-node:not(:last-child), +.minimal-tiptap-editor .ProseMirror .list-node:not(:last-child), +.minimal-tiptap-editor .ProseMirror .text-node:not(:last-child) { + @apply mb-2.5; +} + +.minimal-tiptap-editor .ProseMirror ol, +.minimal-tiptap-editor .ProseMirror ul { + @apply pl-6; +} + +.minimal-tiptap-editor .ProseMirror blockquote, +.minimal-tiptap-editor .ProseMirror dl, +.minimal-tiptap-editor .ProseMirror ol, +.minimal-tiptap-editor .ProseMirror p, +.minimal-tiptap-editor .ProseMirror pre, +.minimal-tiptap-editor .ProseMirror ul { + @apply m-0; +} + +.minimal-tiptap-editor .ProseMirror li { + @apply leading-7; +} + +.minimal-tiptap-editor .ProseMirror p { + @apply break-words; +} + +.minimal-tiptap-editor .ProseMirror li .text-node:has(+ .list-node), +.minimal-tiptap-editor .ProseMirror li > .list-node, +.minimal-tiptap-editor .ProseMirror li > .text-node, +.minimal-tiptap-editor .ProseMirror li p { + @apply mb-0; +} + +.minimal-tiptap-editor .ProseMirror blockquote { + @apply relative pl-3.5; +} + +.minimal-tiptap-editor .ProseMirror blockquote::before, +.minimal-tiptap-editor .ProseMirror blockquote.is-empty::before { + @apply absolute bottom-0 left-0 top-0 h-full w-1 rounded-sm bg-accent-foreground/15 content-['']; +} + +.minimal-tiptap-editor .ProseMirror hr { + @apply my-3 h-0.5 w-full border-none bg-[var(--mt-hr)]; +} + +.minimal-tiptap-editor .ProseMirror-focused hr.ProseMirror-selectednode { + @apply rounded-full outline outline-2 outline-offset-1 outline-muted-foreground; +} + +.minimal-tiptap-editor .ProseMirror .ProseMirror-gapcursor { + @apply pointer-events-none absolute hidden; +} + +.minimal-tiptap-editor .ProseMirror .ProseMirror-hideselection { + @apply caret-transparent; +} + +.minimal-tiptap-editor .ProseMirror.resize-cursor { + @apply cursor-col-resize; +} + +.minimal-tiptap-editor .ProseMirror .selection { + @apply inline-block; +} + +.minimal-tiptap-editor .ProseMirror .selection, +.minimal-tiptap-editor .ProseMirror *::selection, +::selection { + @apply bg-primary/25; +} + +/* Override native selection when custom selection is present */ +.minimal-tiptap-editor .ProseMirror .selection::selection { + background: transparent; +} diff --git a/src/components/minimal-tiptap/styles/partials/code.css b/src/components/minimal-tiptap/styles/partials/code.css new file mode 100644 index 0000000..b1d03ea --- /dev/null +++ b/src/components/minimal-tiptap/styles/partials/code.css @@ -0,0 +1,86 @@ +.minimal-tiptap-editor .ProseMirror code.inline { + @apply rounded border border-[var(--mt-code-color)] bg-[var(--mt-code-background)] px-1 py-0.5 text-sm; +} + +.minimal-tiptap-editor .ProseMirror pre { + @apply relative overflow-auto rounded border font-mono text-sm; + @apply border-[var(--mt-pre-border)] bg-[var(--mt-pre-background)] text-[var(--mt-pre-color)]; + @apply hyphens-none whitespace-pre text-left; +} + +.minimal-tiptap-editor .ProseMirror code { + @apply break-words leading-[1.7em]; +} + +.minimal-tiptap-editor .ProseMirror pre code { + @apply block overflow-x-auto p-3.5; +} + +.minimal-tiptap-editor .ProseMirror pre { + .hljs-keyword, + .hljs-operator, + .hljs-function, + .hljs-built_in, + .hljs-builtin-name { + color: var(--hljs-keyword); + } + + .hljs-attr, + .hljs-symbol, + .hljs-property, + .hljs-attribute, + .hljs-variable, + .hljs-template-variable, + .hljs-params { + color: var(--hljs-attr); + } + + .hljs-name, + .hljs-regexp, + .hljs-link, + .hljs-type, + .hljs-addition { + color: var(--hljs-name); + } + + .hljs-string, + .hljs-bullet { + color: var(--hljs-string); + } + + .hljs-title, + .hljs-subst, + .hljs-section { + color: var(--hljs-title); + } + + .hljs-literal, + .hljs-type, + .hljs-deletion { + color: var(--hljs-literal); + } + + .hljs-selector-tag, + .hljs-selector-id, + .hljs-selector-class { + color: var(--hljs-selector-tag); + } + + .hljs-number { + color: var(--hljs-number); + } + + .hljs-comment, + .hljs-meta, + .hljs-quote { + color: var(--hljs-comment); + } + + .hljs-emphasis { + @apply italic; + } + + .hljs-strong { + @apply font-bold; + } +} diff --git a/src/components/minimal-tiptap/styles/partials/lists.css b/src/components/minimal-tiptap/styles/partials/lists.css new file mode 100644 index 0000000..77ed09d --- /dev/null +++ b/src/components/minimal-tiptap/styles/partials/lists.css @@ -0,0 +1,93 @@ +.minimal-tiptap-editor div.tiptap p { + @apply text-[var(--mt-font-size-regular)]; +} + +.minimal-tiptap-editor .ProseMirror ol { + @apply list-decimal; +} + +.minimal-tiptap-editor .ProseMirror ol ol { + list-style: lower-alpha; +} + +.minimal-tiptap-editor .ProseMirror ol ol ol { + list-style: lower-roman; +} + +.minimal-tiptap-editor .ProseMirror ul { + list-style: disc; +} + +.minimal-tiptap-editor .ProseMirror ul ul { + list-style: circle; +} + +.minimal-tiptap-editor .ProseMirror ul ul ul { + list-style: square; +} + +.minimal-tiptap-editor .ProseMirror ul[data-type="taskList"] { + @apply list-none pl-1; +} + +.minimal-tiptap-editor .ProseMirror ul[data-type="taskList"] p { + @apply m-0; +} + +.minimal-tiptap-editor .ProseMirror ul[data-type="taskList"] li > label { + @apply mr-2 mt-0.5 flex-none select-none; +} + +.minimal-tiptap-editor .ProseMirror li[data-type="taskItem"] { + @apply flex flex-row items-start; +} + +.minimal-tiptap-editor + .ProseMirror + li[data-type="taskItem"] + .taskItem-checkbox-container { + @apply relative pr-2; +} + +.minimal-tiptap-editor .ProseMirror .taskItem-drag-handle { + @apply absolute -left-5 top-1.5 h-[18px] w-[18px] cursor-move pl-0.5 text-[var(--mt-secondary)] opacity-0; +} + +.minimal-tiptap-editor + .ProseMirror + li[data-type="taskItem"]:hover:not(:has(li:hover)) + > .taskItem-checkbox-container + > .taskItem-drag-handle { + @apply opacity-100; +} + +.minimal-tiptap-editor .ProseMirror .taskItem-drag-handle:hover { + @apply text-[var(--mt-drag-handle-hover)]; +} + +.minimal-tiptap-editor .ProseMirror .taskItem-checkbox { + fill-opacity: 0; + @apply h-3.5 w-3.5 flex-shrink-0 cursor-pointer select-none appearance-none rounded border border-solid border-[var(--mt-secondary)] bg-transparent bg-[1px_2px] p-0.5 align-middle transition-colors duration-75 ease-out; +} + +.minimal-tiptap-editor .ProseMirror .taskItem-checkbox:checked { + @apply border-primary bg-primary bg-no-repeat; + background-image: url("data:image/svg+xml;utf8,%3Csvg%20width=%2210%22%20height=%229%22%20viewBox=%220%200%2010%208%22%20xmlns=%22http://www.w3.org/2000/svg%22%20fill=%22%23fbfbfb%22%3E%3Cpath%20d=%22M3.46975%205.70757L1.88358%204.1225C1.65832%203.8974%201.29423%203.8974%201.06897%204.1225C0.843675%204.34765%200.843675%204.7116%201.06897%204.93674L3.0648%206.93117C3.29006%207.15628%203.65414%207.15628%203.8794%206.93117L8.93103%201.88306C9.15633%201.65792%209.15633%201.29397%208.93103%201.06883C8.70578%200.843736%208.34172%200.843724%208.11646%201.06879C8.11645%201.0688%208.11643%201.06882%208.11642%201.06883L3.46975%205.70757Z%22%20stroke-width=%220.2%22%20/%3E%3C/svg%3E"); +} + +.minimal-tiptap-editor .ProseMirror .taskItem-content { + @apply min-w-0 flex-1; +} + +.minimal-tiptap-editor + .ProseMirror + li[data-checked="true"] + .taskItem-content + > :not([data-type="taskList"]), +.minimal-tiptap-editor + .ProseMirror + li[data-checked="true"] + .taskItem-content + .taskItem-checkbox { + @apply opacity-75; +} diff --git a/src/components/minimal-tiptap/styles/partials/placeholder.css b/src/components/minimal-tiptap/styles/partials/placeholder.css new file mode 100644 index 0000000..04bcfdf --- /dev/null +++ b/src/components/minimal-tiptap/styles/partials/placeholder.css @@ -0,0 +1,4 @@ +.minimal-tiptap-editor .ProseMirror > p.is-editor-empty::before { + content: attr(data-placeholder); + @apply pointer-events-none float-left h-0 text-[var(--mt-secondary)]; +} diff --git a/src/components/minimal-tiptap/styles/partials/typography.css b/src/components/minimal-tiptap/styles/partials/typography.css new file mode 100644 index 0000000..a1f753b --- /dev/null +++ b/src/components/minimal-tiptap/styles/partials/typography.css @@ -0,0 +1,27 @@ +.minimal-tiptap-editor .ProseMirror .heading-node { + @apply relative font-semibold; +} + +.minimal-tiptap-editor .ProseMirror .heading-node:first-child { + @apply mt-0; +} + +.minimal-tiptap-editor .ProseMirror h1 { + @apply mb-4 mt-[46px] text-[1.375rem] leading-7 tracking-[-0.004375rem]; +} + +.minimal-tiptap-editor .ProseMirror h2 { + @apply mb-3.5 mt-8 text-[1.1875rem] leading-7 tracking-[0.003125rem]; +} + +.minimal-tiptap-editor .ProseMirror h3 { + @apply mb-3 mt-6 text-[1.0625rem] leading-6 tracking-[0.00625rem]; +} + +.minimal-tiptap-editor .ProseMirror a.link { + @apply cursor-pointer text-primary; +} + +.minimal-tiptap-editor .ProseMirror a.link:hover { + @apply underline; +} diff --git a/src/components/minimal-tiptap/types.ts b/src/components/minimal-tiptap/types.ts new file mode 100644 index 0000000..5d39cc9 --- /dev/null +++ b/src/components/minimal-tiptap/types.ts @@ -0,0 +1,22 @@ +import type { Editor } from "@tiptap/core"; +import type { EditorState } from "@tiptap/pm/state"; +import type { EditorView } from "@tiptap/pm/view"; + +export interface ShouldShowProps { + editor: Editor; + view: EditorView; + state: EditorState; + oldState?: EditorState; + from: number; + to: number; +} + +export interface FormatAction { + label: string; + icon?: React.ReactNode; + action: (editor: Editor) => void; + isActive: (editor: Editor) => boolean; + canExecute: (editor: Editor) => boolean; + shortcuts: string[]; + value: string; +} diff --git a/src/components/minimal-tiptap/utils.ts b/src/components/minimal-tiptap/utils.ts new file mode 100644 index 0000000..90df45c --- /dev/null +++ b/src/components/minimal-tiptap/utils.ts @@ -0,0 +1,89 @@ +import type { Editor } from "@tiptap/core"; + +import type { MinimalTiptapProps } from "./minimal-tiptap"; + +let isMac: boolean | undefined; + +interface Navigator { + userAgentData?: { + brands: Array<{ brand: string; version: string }>; + mobile: boolean; + platform: string; + getHighEntropyValues: (hints: string[]) => Promise<{ + platform: string; + platformVersion: string; + uaFullVersion: string; + }>; + }; +} + +function getPlatform(): string { + const nav = navigator as Navigator; + + if (nav.userAgentData) { + if (nav.userAgentData.platform) { + return nav.userAgentData.platform; + } + + void nav.userAgentData + .getHighEntropyValues(["platform"]) + // eslint-disable-next-line consistent-return + .then((highEntropyValues) => { + if (highEntropyValues.platform) { + return highEntropyValues.platform; + } + }); + } + + if (typeof navigator.platform === "string") { + return navigator.platform; + } + + return ""; +} + +function isMacOS() { + if (isMac === undefined) { + isMac = getPlatform().toLowerCase().includes("mac"); + } + + return isMac; +} + +interface ShortcutKeyResult { + symbol: string; + readable: string; +} + +export function getShortcutKey(key: string): ShortcutKeyResult { + const lowercaseKey = key.toLowerCase(); + if (lowercaseKey === "mod") { + return isMacOS() + ? { symbol: "⌘", readable: "Command" } + : { symbol: "Ctrl", readable: "Control" }; + } else if (lowercaseKey === "alt") { + return isMacOS() + ? { symbol: "⌥", readable: "Option" } + : { symbol: "Alt", readable: "Alt" }; + } else if (lowercaseKey === "shift") { + return isMacOS() + ? { symbol: "⇧", readable: "Shift" } + : { symbol: "Shift", readable: "Shift" }; + } + return { symbol: key, readable: key }; +} + +export function getOutput( + editor: Editor, + format: MinimalTiptapProps["output"], +) { + if (format === "json") { + return editor.getJSON(); + } + + if (format === "html") { + return editor.getText() ? editor.getHTML() : ""; + } + + return editor.getText(); +} diff --git a/src/components/ui/separator.tsx b/src/components/ui/separator.tsx new file mode 100644 index 0000000..29b0d2c --- /dev/null +++ b/src/components/ui/separator.tsx @@ -0,0 +1,29 @@ +import * as SeparatorPrimitive from "@radix-ui/react-separator"; +import * as React from "react"; + +import { cn } from "@/lib/utils"; + +const Separator = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>( + ( + { className, orientation = "horizontal", decorative = true, ...props }, + ref, + ) => ( + + ), +); +Separator.displayName = SeparatorPrimitive.Root.displayName; + +export { Separator }; diff --git a/src/components/ui/switch.tsx b/src/components/ui/switch.tsx new file mode 100644 index 0000000..2d56246 --- /dev/null +++ b/src/components/ui/switch.tsx @@ -0,0 +1,27 @@ +import * as SwitchPrimitives from "@radix-ui/react-switch"; +import * as React from "react"; + +import { cn } from "@/lib/utils"; + +const Switch = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, ...props }, ref) => ( + + + +)); +Switch.displayName = SwitchPrimitives.Root.displayName; + +export { Switch }; diff --git a/src/components/ui/toggle-group.tsx b/src/components/ui/toggle-group.tsx new file mode 100644 index 0000000..907bcb8 --- /dev/null +++ b/src/components/ui/toggle-group.tsx @@ -0,0 +1,59 @@ +import * as ToggleGroupPrimitive from "@radix-ui/react-toggle-group"; +import { type VariantProps } from "class-variance-authority"; +import * as React from "react"; + +import { toggleVariants } from "@/components/ui/toggle"; +import { cn } from "@/lib/utils"; + +const ToggleGroupContext = React.createContext< + VariantProps +>({ + size: "default", + variant: "default", +}); + +const ToggleGroup = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & + VariantProps +>(({ className, variant, size, children, ...props }, ref) => ( + + + {children} + + +)); + +ToggleGroup.displayName = ToggleGroupPrimitive.Root.displayName; + +const ToggleGroupItem = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & + VariantProps +>(({ className, children, variant, size, ...props }, ref) => { + const context = React.useContext(ToggleGroupContext); + + return ( + + {children} + + ); +}); + +ToggleGroupItem.displayName = ToggleGroupPrimitive.Item.displayName; + +export { ToggleGroup, ToggleGroupItem }; diff --git a/src/components/ui/toggle.tsx b/src/components/ui/toggle.tsx index b3c44e7..e3bf2f9 100644 --- a/src/components/ui/toggle.tsx +++ b/src/components/ui/toggle.tsx @@ -1,31 +1,43 @@ -import type React from "react"; +import * as TogglePrimitive from "@radix-ui/react-toggle"; +import { type VariantProps, cva } from "class-variance-authority"; +import * as React from "react"; -interface ToggleProps { - isOpen: boolean; - toggle: () => void; - className?: string; -} +import { cn } from "@/lib/utils"; -export const Toggle: React.FC = ({ - isOpen, - toggle, - className, -}) => { - return ( - - ); -}; +const toggleVariants = cva( + "inline-flex items-center justify-center rounded-md text-sm font-medium ring-offset-background transition-colors hover:bg-muted hover:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=on]:bg-accent data-[state=on]:text-accent-foreground", + { + variants: { + variant: { + default: "bg-transparent", + outline: + "border border-input bg-transparent hover:bg-accent hover:text-accent-foreground", + }, + size: { + default: "h-10 px-3", + sm: "h-9 px-2.5", + lg: "h-11 px-5", + }, + }, + defaultVariants: { + variant: "default", + size: "default", + }, + }, +); + +const Toggle = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef & + VariantProps +>(({ className, variant, size, ...props }, ref) => ( + +)); + +Toggle.displayName = TogglePrimitive.Root.displayName; + +export { Toggle, toggleVariants }; diff --git a/src/lib/types.ts b/src/lib/types.ts index 8e57f30..7ffb37f 100644 --- a/src/lib/types.ts +++ b/src/lib/types.ts @@ -57,12 +57,12 @@ export type Database = { events: { Row: { closingRegistrationAt: string | null; - content: Json | null; createdAt: string; description: string | null; - displayOnEverySection: boolean | null; + displayDescriptionOnEverySection: boolean | null; eventDate: string | null; eventId: string; + messageAfterRegistration: string | null; name: string; openingRegistrationAt: string | null; organizerName: string; @@ -73,12 +73,12 @@ export type Database = { }; Insert: { closingRegistrationAt?: string | null; - content?: Json | null; createdAt?: string; description?: string | null; - displayOnEverySection?: boolean | null; + displayDescriptionOnEverySection?: boolean | null; eventDate?: string | null; eventId?: string; + messageAfterRegistration?: string | null; name: string; openingRegistrationAt?: string | null; organizerName: string; @@ -89,12 +89,12 @@ export type Database = { }; Update: { closingRegistrationAt?: string | null; - content?: Json | null; createdAt?: string; description?: string | null; - displayOnEverySection?: boolean | null; + displayDescriptionOnEverySection?: boolean | null; eventDate?: string | null; eventId?: string; + messageAfterRegistration?: string | null; name?: string; openingRegistrationAt?: string | null; organizerName?: string; @@ -103,15 +103,7 @@ export type Database = { participantsSlug?: string; updatedAt?: string | null; }; - Relationships: [ - { - foreignKeyName: "events_ownerUUID_fkey"; - columns: ["ownerUUID"]; - isOneToOne: false; - referencedRelation: "users"; - referencedColumns: ["id"]; - }, - ]; + Relationships: []; }; reservations: { Row: { @@ -151,6 +143,41 @@ export type Database = { }, ]; }; + user_attributes: { + Row: { + createdAt: string; + eventId: string; + isMandatory: boolean; + name: string; + updatedAt: string; + userAttributeId: string; + }; + Insert: { + createdAt?: string; + eventId: string; + isMandatory: boolean; + name: string; + updatedAt?: string; + userAttributeId?: string; + }; + Update: { + createdAt?: string; + eventId?: string; + isMandatory?: boolean; + name?: string; + updatedAt?: string; + userAttributeId?: string; + }; + Relationships: [ + { + foreignKeyName: "user_attributes_eventId_fkey"; + columns: ["eventId"]; + isOneToOne: false; + referencedRelation: "events"; + referencedColumns: ["eventId"]; + }, + ]; + }; }; Views: { [_ in never]: never; @@ -162,6 +189,18 @@ export type Database = { }; Returns: string; }; + get_reservations_by_event: { + Args: { + event_id: string; + }; + Returns: { + imie: string; + nazwisko: string; + data_dodania: string; + sekcja_koncowa: string; + drzewko_sekcji: string; + }[]; + }; get_section_data: { Args: { section_uuid: string; @@ -266,3 +305,18 @@ export type Enums< : PublicEnumNameOrOptions extends keyof PublicSchema["Enums"] ? PublicSchema["Enums"][PublicEnumNameOrOptions] : never; + +export type CompositeTypes< + PublicCompositeTypeNameOrOptions extends + | keyof PublicSchema["CompositeTypes"] + | { schema: keyof Database }, + CompositeTypeName extends PublicCompositeTypeNameOrOptions extends { + schema: keyof Database; + } + ? keyof Database[PublicCompositeTypeNameOrOptions["schema"]]["CompositeTypes"] + : never = never, +> = PublicCompositeTypeNameOrOptions extends { schema: keyof Database } + ? Database[PublicCompositeTypeNameOrOptions["schema"]]["CompositeTypes"][CompositeTypeName] + : PublicCompositeTypeNameOrOptions extends keyof PublicSchema["CompositeTypes"] + ? PublicSchema["CompositeTypes"][PublicCompositeTypeNameOrOptions] + : never; diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx index de08ab6..07d10b5 100644 --- a/src/pages/_app.tsx +++ b/src/pages/_app.tsx @@ -13,9 +13,12 @@ import translation from "zod-i18n-map/locales/pl/zod.json"; import { Toaster } from "@/components/ui/sonner"; import { ThemeProvider } from "@/components/ui/theme-provider"; +import { TooltipProvider } from "@/components/ui/tooltip"; import { supabase } from "@/lib/supabase"; import "@/styles/globals.css"; +import "../components/minimal-tiptap/styles/index.css"; + setDefaultOptions({ locale: pl }); const spaceGrotesk = Space_Grotesk({ @@ -78,17 +81,19 @@ export default function App({ Component, pageProps }: AppProps) { return ( - - - Eventownik - -
- - - - -
-
+ + + + Eventownik + +
+ + + + +
+
+
); } diff --git a/src/pages/editor.tsx b/src/pages/editor.tsx new file mode 100644 index 0000000..90d48f8 --- /dev/null +++ b/src/pages/editor.tsx @@ -0,0 +1,24 @@ +import type { Content } from "@tiptap/react"; +import React, { useState } from "react"; + +import { MinimalTiptapEditor } from "@/components/minimal-tiptap"; + +const Editor = () => { + const [value, setValue] = useState(""); + + return ( + + ); +}; + +export default Editor; diff --git a/src/pages/event/[slug]/settings.tsx b/src/pages/event/[slug]/settings.tsx index cd0f456..9e7450f 100644 --- a/src/pages/event/[slug]/settings.tsx +++ b/src/pages/event/[slug]/settings.tsx @@ -9,6 +9,7 @@ import { toast } from "sonner"; import { z } from "zod"; import { Layout } from "@/components/Layout"; +import { MinimalTiptapEditor } from "@/components/minimal-tiptap"; import { Button } from "@/components/ui/button"; import { Calendar } from "@/components/ui/calendar"; import { @@ -27,7 +28,6 @@ import { PopoverTrigger, } from "@/components/ui/popover"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; -import { Textarea } from "@/components/ui/textarea"; import { supabase } from "@/lib/supabase"; import { createSSRClient } from "@/lib/supabaseSSR"; import type { TablesUpdate } from "@/lib/types"; @@ -50,6 +50,7 @@ export default function Dashboard({ name: z.string().min(1), eventDate: z.date(), description: z.string(), + messageAfterRegistration: z.string(), organizerName: z.string().min(1), }), reValidateMode: "onChange", @@ -80,6 +81,7 @@ export default function Dashboard({ : undefined, description: event.data?.description ?? "", organizerName: event.data?.organizerName, + messageAfterRegistration: event.data?.messageAfterRegistration ?? "", }); }, [event.data, form]); @@ -108,8 +110,6 @@ export default function Dashboard({ Ogólne Udostępnianie - {/* Personalizacja */} - {/* Inne */}
@@ -156,7 +156,6 @@ export default function Dashboard({ )} /> -
-
Opis -