From fd3288cb5b075318df7666c2b28b12cf9ca08b48 Mon Sep 17 00:00:00 2001 From: abearxiong Date: Tue, 4 Mar 2025 01:20:55 +0800 Subject: [PATCH] feat: update new feature temp for panel --- .gitignore | 4 +- index.html | 32 +- package.json | 32 +- pnpm-lock.yaml | 1249 +++++------------ src/App.tsx | 29 +- src/main.tsx | 87 +- src/modules/basename.ts | 2 +- src/modules/panels/Example.tsx | 33 + src/modules/panels/components/WindowIcons.tsx | 60 + .../panels/components/WindowManager.tsx | 420 ++++++ src/modules/panels/demo/DemoWindows.tsx | 120 ++ src/modules/panels/hooks/use-listen-b.ts | 17 + src/modules/panels/index.tsx | 2 + src/modules/panels/store/index.ts | 119 ++ src/modules/panels/style.css | 132 ++ src/modules/panels/types.ts | 51 + src/modules/panels/utils/document-width.ts | 14 + .../tiptap/components/CommandsList.tsx | 112 ++ .../tiptap/components/ReactRenderer.tsx | 42 + src/modules/tiptap/editor.css | 11 + src/modules/tiptap/editor.ts | 12 + .../tiptap/extensions/suggestions/commands.ts | 41 + .../tiptap/extensions/suggestions/index.ts | 3 + .../suggestions/suggestionConfig.ts | 121 ++ .../extensions/suggestions/suggestionItems.ts | 203 +++ .../extensions/suggestions/suggestions.ts | 203 +++ src/pages/wall/docs.ts | 13 +- src/pages/wall/index.tsx | 9 +- src/pages/wall/modules/ContextMenu.tsx | 2 +- src/pages/wall/modules/FormDialog.tsx | 6 +- src/pages/wall/modules/toolbar/Toolbar.tsx | 10 +- src/pages/wall/utils/db.ts | 8 +- template/ai-app/AiApp.tsx | 5 + template/ai-app/main.tsx | 28 + template/app.ts | 36 + template/index.ts | 39 + template/tailwind.css | 32 + template/user/route.ts | 6 + template/user/store/index.ts | 50 + template/wallnote/entry.ts | 25 + template/workspace/entry.ts | 29 + tsconfig.app.json | 3 +- tsconfig.node.json | 2 +- vite.config.prompt.ts | 35 + vite.config.ts | 24 +- 45 files changed, 2559 insertions(+), 954 deletions(-) create mode 100644 src/modules/panels/Example.tsx create mode 100644 src/modules/panels/components/WindowIcons.tsx create mode 100644 src/modules/panels/components/WindowManager.tsx create mode 100644 src/modules/panels/demo/DemoWindows.tsx create mode 100644 src/modules/panels/hooks/use-listen-b.ts create mode 100644 src/modules/panels/index.tsx create mode 100644 src/modules/panels/store/index.ts create mode 100644 src/modules/panels/style.css create mode 100644 src/modules/panels/types.ts create mode 100644 src/modules/panels/utils/document-width.ts create mode 100644 src/modules/tiptap/components/CommandsList.tsx create mode 100644 src/modules/tiptap/components/ReactRenderer.tsx create mode 100644 src/modules/tiptap/editor.css create mode 100644 src/modules/tiptap/extensions/suggestions/commands.ts create mode 100644 src/modules/tiptap/extensions/suggestions/index.ts create mode 100644 src/modules/tiptap/extensions/suggestions/suggestionConfig.ts create mode 100644 src/modules/tiptap/extensions/suggestions/suggestionItems.ts create mode 100644 src/modules/tiptap/extensions/suggestions/suggestions.ts create mode 100644 template/ai-app/AiApp.tsx create mode 100644 template/ai-app/main.tsx create mode 100644 template/index.ts create mode 100644 template/tailwind.css create mode 100644 template/user/route.ts create mode 100644 template/user/store/index.ts create mode 100644 template/wallnote/entry.ts create mode 100644 template/workspace/entry.ts create mode 100644 vite.config.prompt.ts diff --git a/.gitignore b/.gitignore index e03f1d7..8cf0bce 100644 --- a/.gitignore +++ b/.gitignore @@ -25,4 +25,6 @@ dist-ssr *.sw? tsconfig.app.tsbuildinfo -tsconfig.node.tsbuildinfo \ No newline at end of file +tsconfig.node.tsbuildinfo + +aidist \ No newline at end of file diff --git a/index.html b/index.html index a7cd346..52e0b6c 100644 --- a/index.html +++ b/index.html @@ -1,13 +1,23 @@ - - - - - Wall Note - - -
- - - + + + + + + Workspace Wall Note + + + + + + +
+ + + + + + \ No newline at end of file diff --git a/package.json b/package.json index 053c800..1b90d06 100644 --- a/package.json +++ b/package.json @@ -1,44 +1,50 @@ { "name": "wallnote", "private": true, - "version": "0.0.7", + "version": "0.1.0", "type": "module", - "user": "apps", + "user": "workspace", "scripts": { "dev": "vite", "dev:web": "cross-env WEB_DEV=true vite --mode web", + "dev:prompt": "vite build -c vite.config.prompt.ts -w", "build": "vite build", + "build:prompt": "vite build --config vite.config.prompt.ts", "lint": "eslint .", - "deploy": "rsync -avz --delete dist/ light:~/apps/ai/dist", "preview": "vite preview", - "prepub": "pnpm build && envision switch apps", - "pub": "envision deploy ./dist -k wallnote -v 0.0.7 -y y", + "prepub": "pnpm build && envision switch workspace", + "pub": "envision deploy ./dist -k wallnote -v 0.1.0 -y y", "ev": "npm run build && npm run deploy" }, - "stackblitz": { - "startCommand": "npm dev:web" - }, "author": "abearxiong ", "license": "MIT", "dependencies": { "@ant-design/icons": "^5.6.1", + "@blueprintjs/core": "^5.17.2", + "@blueprintjs/icons": "^5.19.1", "@emotion/react": "^11.14.0", "@emotion/styled": "^11.14.0", "@kevisual/cache": "^0.0.1", "@kevisual/query": "0.0.9-alpha.2", - "@kevisual/router": "0.0.7", + "@kevisual/router": "0.0.8", + "@kevisual/system-lib": "0.0.21-beta.2", "@kevisual/system-ui": "^0.0.3", "@kevisual/ui": "^0.0.4-alpha-1", "@mui/material": "^6.4.6", "@tiptap/core": "^2.11.5", "@tiptap/extension-code-block-lowlight": "^2.11.5", + "@tiptap/extension-document": "^2.11.5", "@tiptap/extension-highlight": "^2.11.5", + "@tiptap/extension-paragraph": "^2.11.5", + "@tiptap/extension-placeholder": "^2.11.5", + "@tiptap/extension-text": "^2.11.5", "@tiptap/extension-typography": "^2.11.5", + "@tiptap/pm": "^2.11.5", "@tiptap/starter-kit": "^2.11.5", + "@tiptap/suggestion": "^2.11.5", "@types/lodash-es": "^4.17.12", "@types/turndown": "^5.0.5", "@xyflow/react": "^12.4.4", - "antd": "^5.24.2", "clsx": "^2.1.1", "dayjs": "^1.11.13", "github-markdown-css": "^5.8.1", @@ -53,6 +59,9 @@ "nanoid": "^5.1.2", "react": "^19.0.0", "react-dom": "^19.0.0", + "react-draggable": "^4.4.6", + "react-resizable": "^3.0.5", + "react-resizable-panels": "^2.1.7", "react-router": "^7.2.0", "react-router-dom": "^7.2.0", "react-toastify": "^11.0.5", @@ -67,7 +76,8 @@ "@types/node": "^22.13.8", "@types/react": "^19.0.10", "@types/react-dom": "^19.0.4", - "@vitejs/plugin-basic-ssl": "^1.2.0", + "@types/react-resizable": "^3.0.8", + "@vitejs/plugin-basic-ssl": "^2.0.0", "@vitejs/plugin-react": "^4.3.4", "eslint": "^9.21.0", "eslint-plugin-react-hooks": "^5.2.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index aa59df3..e788d6a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -11,6 +11,12 @@ importers: '@ant-design/icons': specifier: ^5.6.1 version: 5.6.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + '@blueprintjs/core': + specifier: ^5.17.2 + version: 5.17.2(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + '@blueprintjs/icons': + specifier: ^5.19.1 + version: 5.19.1(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) '@emotion/react': specifier: ^11.14.0 version: 11.14.0(@types/react@19.0.10)(react@19.0.0) @@ -19,13 +25,16 @@ importers: version: 11.14.0(@emotion/react@11.14.0(@types/react@19.0.10)(react@19.0.0))(@types/react@19.0.10)(react@19.0.0) '@kevisual/cache': specifier: ^0.0.1 - version: 0.0.1(rollup@4.34.8)(typescript@5.8.2) + version: 0.0.1(rollup@4.34.8)(tslib@2.6.3)(typescript@5.8.2) '@kevisual/query': specifier: 0.0.9-alpha.2 version: 0.0.9-alpha.2(ws@8.18.0) '@kevisual/router': - specifier: 0.0.7 - version: 0.0.7 + specifier: 0.0.8 + version: 0.0.8 + '@kevisual/system-lib': + specifier: 0.0.21-beta.2 + version: 0.0.21-beta.2 '@kevisual/system-ui': specifier: ^0.0.3 version: 0.0.3 @@ -41,15 +50,33 @@ importers: '@tiptap/extension-code-block-lowlight': specifier: ^2.11.5 version: 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))(@tiptap/extension-code-block@2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))(@tiptap/pm@2.11.5))(@tiptap/pm@2.11.5)(highlight.js@11.11.1)(lowlight@3.3.0) + '@tiptap/extension-document': + specifier: ^2.11.5 + version: 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5)) '@tiptap/extension-highlight': specifier: ^2.11.5 version: 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5)) + '@tiptap/extension-paragraph': + specifier: ^2.11.5 + version: 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5)) + '@tiptap/extension-placeholder': + specifier: ^2.11.5 + version: 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))(@tiptap/pm@2.11.5) + '@tiptap/extension-text': + specifier: ^2.11.5 + version: 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5)) '@tiptap/extension-typography': specifier: ^2.11.5 version: 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5)) + '@tiptap/pm': + specifier: ^2.11.5 + version: 2.11.5 '@tiptap/starter-kit': specifier: ^2.11.5 version: 2.11.5 + '@tiptap/suggestion': + specifier: ^2.11.5 + version: 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))(@tiptap/pm@2.11.5) '@types/lodash-es': specifier: ^4.17.12 version: 4.17.12 @@ -59,9 +86,6 @@ importers: '@xyflow/react': specifier: ^12.4.4 version: 12.4.4(@types/react@19.0.10)(immer@10.1.1)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - antd: - specifier: ^5.24.2 - version: 5.24.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) clsx: specifier: ^2.1.1 version: 2.1.1 @@ -104,6 +128,15 @@ importers: react-dom: specifier: ^19.0.0 version: 19.0.0(react@19.0.0) + react-draggable: + specifier: ^4.4.6 + version: 4.4.6(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + react-resizable: + specifier: ^3.0.5 + version: 3.0.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + react-resizable-panels: + specifier: ^2.1.7 + version: 2.1.7(react-dom@19.0.0(react@19.0.0))(react@19.0.0) react-router: specifier: ^7.2.0 version: 7.2.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0) @@ -141,9 +174,12 @@ importers: '@types/react-dom': specifier: ^19.0.4 version: 19.0.4(@types/react@19.0.10) + '@types/react-resizable': + specifier: ^3.0.8 + version: 3.0.8 '@vitejs/plugin-basic-ssl': - specifier: ^1.2.0 - version: 1.2.0(vite@6.2.0(@types/node@22.13.8)(jiti@2.4.2)(lightningcss@1.29.1)(yaml@2.5.1)) + specifier: ^2.0.0 + version: 2.0.0(vite@6.2.0(@types/node@22.13.8)(jiti@2.4.2)(lightningcss@1.29.1)(yaml@2.5.1)) '@vitejs/plugin-react': specifier: ^4.3.4 version: 4.3.4(vite@6.2.0(@types/node@22.13.8)(jiti@2.4.2)(lightningcss@1.29.1)(yaml@2.5.1)) @@ -187,25 +223,6 @@ packages: '@ant-design/colors@7.1.0': resolution: {integrity: sha512-MMoDGWn1y9LdQJQSHiCC20x3uZ3CwQnv9QMz6pCmJOrqdgM9YxsoVVY0wtrdXbmfSgnV0KNk6zi09NAhMR2jvg==} - '@ant-design/colors@7.2.0': - resolution: {integrity: sha512-bjTObSnZ9C/O8MB/B4OUtd/q9COomuJAR2SYfhxLyHvCKn4EKwCN3e+fWGMo7H5InAyV0wL17jdE9ALrdOW/6A==} - - '@ant-design/cssinjs-utils@1.1.3': - resolution: {integrity: sha512-nOoQMLW1l+xR1Co8NFVYiP8pZp3VjIIzqV6D6ShYF2ljtdwWJn5WSsH+7kvCktXL/yhEtWURKOfH5Xz/gzlwsg==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - '@ant-design/cssinjs@1.23.0': - resolution: {integrity: sha512-7GAg9bD/iC9ikWatU9ym+P9ugJhi/WbsTWzcKN6T4gU0aehsprtke1UAaaSxxkjjmkJb3llet/rbUSLPgwlY4w==} - peerDependencies: - react: '>=16.0.0' - react-dom: '>=16.0.0' - - '@ant-design/fast-color@2.0.6': - resolution: {integrity: sha512-y2217gk4NqL35giHl72o6Zzqji9O7vHh9YmhUVkPtAOpoTCH4uWxo/pr4VE8t0+ChEPs0qo4eJRC5Q1eXWo3vA==} - engines: {node: '>=8.x'} - '@ant-design/icons-svg@4.4.2': resolution: {integrity: sha512-vHbT+zJEVzllwP+CM+ul7reTEfBR0vgxFe7+lREAsAA7YGsYpboiq2sQNeQeRvh09GfQgs/GyFEvZpJ9cLXpXA==} @@ -216,11 +233,6 @@ packages: react: '>=16.0.0' react-dom: '>=16.0.0' - '@ant-design/react-slick@1.1.2': - resolution: {integrity: sha512-EzlvzE6xQUBrZuuhSAFTdsr4P2bBBHGZwKFemEfq8gIGyIQCxalYfZW/T2ORbtQx5rU69o+WycP3exY/7T1hGA==} - peerDependencies: - react: '>=16.9.0' - '@babel/code-frame@7.26.2': resolution: {integrity: sha512-RJlIHRueQgwWitWgF8OdFYGZX328Ax5BCemNGlqHfplnRT9ESi8JkFlvaVYbS+UubVY6dpv87Fs2u5M29iNFVQ==} engines: {node: '>=6.9.0'} @@ -321,6 +333,30 @@ packages: resolution: {integrity: sha512-Z/yiTPj+lDVnF7lWeKCIJzaIkI0vYO87dMpZ4bg4TDrFe4XXLFWL1TbXU27gBP3QccxV9mZICCrnjnYlJjXHOA==} engines: {node: '>=6.9.0'} + '@blueprintjs/colors@5.1.8': + resolution: {integrity: sha512-rCl+NZwR6xjJeCB6yWglbqWU2zOdVgeI5unBASalzMXWpRO0UXIjx0pA/Vtii4cB2kIdk8PaHTlGmZnLTu/MSg==} + + '@blueprintjs/core@5.17.2': + resolution: {integrity: sha512-6jLZAdwwmIQHJqX7XxGw32EZrYIQcOwZAhDuyzsWDD+vUzWkciogn/LYD4S4hr3tU5MRX5nVWbUHrHhgrd8RKQ==} + hasBin: true + peerDependencies: + '@types/react': ^16.14.41 || 17 || 18 + react: ^16.8 || 17 || 18 + react-dom: ^16.8 || 17 || 18 + peerDependenciesMeta: + '@types/react': + optional: true + + '@blueprintjs/icons@5.19.1': + resolution: {integrity: sha512-BRHIkoM0gXGYIA48xGjyegGE78L+9wrkhBGEGnnU436YRO2cznHEb/pl9AqCsw+2CEfYy5ubieWM30OiX2hpMw==} + peerDependencies: + '@types/react': ^16.14.41 || 17 || 18 + react: ^16.8 || 17 || 18 + react-dom: ^16.8 || 17 || 18 + peerDependenciesMeta: + '@types/react': + optional: true + '@ctrl/tinycolor@3.6.1': resolution: {integrity: sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==} engines: {node: '>=10'} @@ -331,9 +367,6 @@ packages: '@emotion/cache@11.14.0': resolution: {integrity: sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA==} - '@emotion/hash@0.8.0': - resolution: {integrity: sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==} - '@emotion/hash@0.9.2': resolution: {integrity: sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==} @@ -371,9 +404,6 @@ packages: '@emotion/unitless@0.10.0': resolution: {integrity: sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==} - '@emotion/unitless@0.7.5': - resolution: {integrity: sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==} - '@emotion/use-insertion-effect-with-fallbacks@1.2.0': resolution: {integrity: sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg==} peerDependencies: @@ -613,8 +643,11 @@ packages: '@kevisual/query@0.0.9-alpha.2': resolution: {integrity: sha512-bpMHngIB5et7s83b6gCty9PzvU2JMEe41LhdE+9IHUj8iD0Jg6gD0RlX1t3SFW1Thgc6DoCFcTEPAOCYXqoE5w==} - '@kevisual/router@0.0.7': - resolution: {integrity: sha512-4n1Tp4YLoraJv7jtfy7jbuLGyAj0B2QkTlnlEDHCUTlEUOvOkjtf7DHAe2SL92fTgXhSbod0I/0vUcDF85oj/w==} + '@kevisual/router@0.0.8': + resolution: {integrity: sha512-/Y8u7sJBNDcrTPirIT7vujwBT9GVWeJYquaf1M29fsyftqBv7jLxNlLzRNnWmBsHrTDYO1onrewgzGTBxzPH1g==} + + '@kevisual/system-lib@0.0.21-beta.2': + resolution: {integrity: sha512-oqUQFQp1GD7AM8VmGa0aBLkAO6xHzyuL2gr+dG7ag5CZj0GFNaNr5klTLm6O8ngMHaziMFLD2B0rQfu9/k+/7Q==} '@kevisual/system-ui@0.0.3': resolution: {integrity: sha512-zRtUnL6wNe6R1W7X6eirDADZWeTmxZCNpLwxCLu30yeNuIhpFJdxHyOg0nX9aOZn6F0Kb6lB3Li2fZpKwdpk0w==} @@ -723,61 +756,6 @@ packages: '@popperjs/core@2.11.8': resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} - '@rc-component/async-validator@5.0.4': - resolution: {integrity: sha512-qgGdcVIF604M9EqjNF0hbUTz42bz/RDtxWdWuU5EQe3hi7M8ob54B6B35rOsvX5eSvIHIzT9iH1R3n+hk3CGfg==} - engines: {node: '>=14.x'} - - '@rc-component/color-picker@2.0.1': - resolution: {integrity: sha512-WcZYwAThV/b2GISQ8F+7650r5ZZJ043E57aVBFkQ+kSY4C6wdofXgB0hBx+GPGpIU0Z81eETNoDUJMr7oy/P8Q==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - '@rc-component/context@1.4.0': - resolution: {integrity: sha512-kFcNxg9oLRMoL3qki0OMxK+7g5mypjgaaJp/pkOis/6rVxma9nJBF/8kCIuTYHUQNr0ii7MxqE33wirPZLJQ2w==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - '@rc-component/mini-decimal@1.1.0': - resolution: {integrity: sha512-jS4E7T9Li2GuYwI6PyiVXmxTiM6b07rlD9Ge8uGZSCz3WlzcG5ZK7g5bbuKNeZ9pgUuPK/5guV781ujdVpm4HQ==} - engines: {node: '>=8.x'} - - '@rc-component/mutate-observer@1.1.0': - resolution: {integrity: sha512-QjrOsDXQusNwGZPf4/qRQasg7UFEj06XiCJ8iuiq/Io7CrHrgVi6Uuetw60WAMG1799v+aM8kyc+1L/GBbHSlw==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - '@rc-component/portal@1.1.2': - resolution: {integrity: sha512-6f813C0IsasTZms08kfA8kPAGxbbkYToa8ALaiDIGGECU4i9hj8Plgbx0sNJDrey3EtHO30hmdaxtT0138xZcg==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - '@rc-component/qrcode@1.0.0': - resolution: {integrity: sha512-L+rZ4HXP2sJ1gHMGHjsg9jlYBX/SLN2D6OxP9Zn3qgtpMWtO2vUfxVFwiogHpAIqs54FnALxraUy/BCO1yRIgg==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - '@rc-component/tour@1.15.1': - resolution: {integrity: sha512-Tr2t7J1DKZUpfJuDZWHxyxWpfmj8EZrqSgyMZ+BCdvKZ6r1UDsfU46M/iWAAFBy961Ssfom2kv5f3UcjIL2CmQ==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - '@rc-component/trigger@2.2.6': - resolution: {integrity: sha512-/9zuTnWwhQ3S3WT1T8BubuFTT46kvnXgaERR9f4BTKyn61/wpf/BvbImzYBubzJibU707FxwbKszLlHjcLiv1Q==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - '@remirror/core-constants@3.0.0': resolution: {integrity: sha512-42aWfPrimMfDKDi4YegyS7x+/0tlzaqwPQCULLanv3DMIlu96KTJR0fM5isWX2UViOqlGnX6YFgqWepcX+XMNg==} @@ -1098,6 +1076,12 @@ packages: peerDependencies: '@tiptap/core': ^2.7.0 + '@tiptap/extension-placeholder@2.11.5': + resolution: {integrity: sha512-Pr+0Ju/l2ZvXMd9VQxtaoSZbs0BBp1jbBDqwms88ctpyvQFRfLSfSkqudQcSHyw2ROOz2E31p/7I7fpI8Y0CLA==} + peerDependencies: + '@tiptap/core': ^2.7.0 + '@tiptap/pm': ^2.7.0 + '@tiptap/extension-strike@2.11.5': resolution: {integrity: sha512-PVfUiCqrjvsLpbIoVlegSY8RlkR64F1Rr2RYmiybQfGbg+AkSZXDeO0eIrc03//4gua7D9DfIozHmAKv1KN3ow==} peerDependencies: @@ -1124,6 +1108,12 @@ packages: '@tiptap/starter-kit@2.11.5': resolution: {integrity: sha512-SLI7Aj2ruU1t//6Mk8f+fqW+18uTqpdfLUJYgwu0CkqBckrkRZYZh6GVLk/02k3H2ki7QkFxiFbZrdbZdng0JA==} + '@tiptap/suggestion@2.11.5': + resolution: {integrity: sha512-uafwGgB5YuKX/xLRjnt2H5eA21I8HcNXpdbH4Du2gg3KM71RpUbkyjaV7KEMA/5qwCEo+sddlpuErj4wBycZ5Q==} + peerDependencies: + '@tiptap/core': ^2.7.0 + '@tiptap/pm': ^2.7.0 + '@types/babel__core@7.20.5': resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==} @@ -1213,6 +1203,9 @@ packages: peerDependencies: '@types/react': ^19.0.0 + '@types/react-resizable@3.0.8': + resolution: {integrity: sha512-Pcvt2eGA7KNXldt1hkhVhAgZ8hK41m0mp89mFgQi7LAAEZiaLgm4fHJ5zbJZ/4m2LVaAyYrrRRv1LHDcrGQanA==} + '@types/react-transition-group@4.4.12': resolution: {integrity: sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==} peerDependencies: @@ -1277,11 +1270,11 @@ packages: resolution: {integrity: sha512-kCYXKAum9CecGVHGij7muybDfTS2sD3t0L4bJsEZLkyrXUImiCTq1M3LG2SRtOhiHFwMR9wAFplpT6XHYjTkwQ==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - '@vitejs/plugin-basic-ssl@1.2.0': - resolution: {integrity: sha512-mkQnxTkcldAzIsomk1UuLfAu9n+kpQ3JbHcpCp7d2Oo6ITtji8pHS3QToOWjhPFvNQSnhlkAjmGbhv2QvwO/7Q==} - engines: {node: '>=14.21.3'} + '@vitejs/plugin-basic-ssl@2.0.0': + resolution: {integrity: sha512-gc9Tjg8bUxBVSTzeWT3Njc0Cl3PakHFKdNfABnZWiUgbxqmHDEn7uECv3fHVylxoYgNzAcmU7ZrILz+BwSo3sA==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} peerDependencies: - vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 + vite: ^6.0.0 '@vitejs/plugin-react@4.3.4': resolution: {integrity: sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug==} @@ -1323,12 +1316,6 @@ packages: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} - antd@5.24.2: - resolution: {integrity: sha512-7Z9HsE3ZIK3sE/WuUqii3w7Gl1IJuRL21sDUTtkN95JS5KhRYP8ISv7m/HxsJ3Mn/yxgojBCgLPJ212+Dn+aPw==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - argparse@2.0.1: resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} @@ -1365,19 +1352,32 @@ packages: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} + camel-case@4.1.2: + resolution: {integrity: sha512-gxGWBrTT1JuMx6R+o5PTXMmUnhnVzLQ9SNutD4YqKtI6ap897t3tKECYla6gCWEkplXnlNybEkZg9GEGxKFCgw==} + caniuse-lite@1.0.30001684: resolution: {integrity: sha512-G1LRwLIQjBQoyq0ZJGqGIJUXzJ8irpbjHLpVRXDvBEScFJ9b17sgK6vlx0GAJFE21okD7zXl08rRRUfq6HdoEQ==} + capital-case@1.0.4: + resolution: {integrity: sha512-ds37W8CytHgwnhGGTi88pcPyR15qoNkOpYwmMMfnWqqWgESapLqvDx6huFjQ5vqWSn2Z06173XNA7LtMOeUh1A==} + chalk@4.1.2: resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} engines: {node: '>=10'} + change-case@4.1.2: + resolution: {integrity: sha512-bSxY2ws9OtviILG1EiY5K7NNxkqg/JnRnFxLtKQ96JaviiIxi7djMrSd0ECT9AC+lttClmYwKw53BWpOMblo7A==} + classcat@5.0.5: resolution: {integrity: sha512-JhZUT7JFcQy/EzW605k/ktHtncoo9vnyW/2GspNYwFlN1C/WmjuV/xtS04e9SOkL2sTdw0VAZ2UGCcQ9lR6p6w==} classnames@2.5.1: resolution: {integrity: sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==} + clsx@1.2.1: + resolution: {integrity: sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==} + engines: {node: '>=6'} + clsx@2.1.1: resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} engines: {node: '>=6'} @@ -1396,12 +1396,12 @@ packages: commondir@1.0.1: resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} - compute-scroll-into-view@3.1.0: - resolution: {integrity: sha512-rj8l8pD4bJ1nx+dAkMhV1xB5RuZEyVysfxJqB1pRchh1KVvwOv9b7CGB8ZfjTImVv2oF+sYMUkMZq6Na5Ftmbg==} - concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + constant-case@3.0.4: + resolution: {integrity: sha512-I2hSBi7Vvs7BEuJDr5dDHfzb/Ruj3FyvFyh7KLilAjNQw3Be+xgqUBA2W6scVEcL0hL1dwPRtIqEPVUCKkSsyQ==} + convert-source-map@1.9.0: resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} @@ -1412,9 +1412,6 @@ packages: resolution: {integrity: sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==} engines: {node: '>=18'} - copy-to-clipboard@3.3.3: - resolution: {integrity: sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==} - cosmiconfig@7.1.0: resolution: {integrity: sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==} engines: {node: '>=10'} @@ -1505,6 +1502,9 @@ packages: dom-helpers@5.2.1: resolution: {integrity: sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==} + dot-case@3.0.4: + resolution: {integrity: sha512-Kv5nKlh6yRrdrGvxeJ2e5y2eRUpkUosIW4A2AS38zwSz27zu7ufDwQPi5Jhs3XAlGNetl3bmnGhQsMtkKJnj3w==} + dunder-proto@1.0.1: resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} engines: {node: '>= 0.4'} @@ -1739,6 +1739,9 @@ packages: resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} engines: {node: '>= 0.4'} + header-case@2.0.4: + resolution: {integrity: sha512-H/vuk5TEEVZwrR0lp2zed9OCo1uAILMlx0JEMgC26rzyJJ3N1v6XkwHHXJQdR2doSjcGPM6OKPYoJgf0plJ11Q==} + highlight.js@11.11.1: resolution: {integrity: sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==} engines: {node: '>=12.0.0'} @@ -1829,9 +1832,6 @@ packages: json-stable-stringify-without-jsonify@1.0.1: resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - json2mq@0.2.0: - resolution: {integrity: sha512-SzoRg7ux5DWTII9J2qkrZrqV1gt+rTaoufMxEzXbS26Uid0NwaJd123HcoB80TgubEppxxIGdNxCx50fEoEWQA==} - json5@2.2.3: resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} engines: {node: '>=6'} @@ -1928,6 +1928,9 @@ packages: resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} hasBin: true + lower-case@2.0.2: + resolution: {integrity: sha512-7fm3l3NAF9WfN6W3JOmf5drwpVqX78JtoGJ3A6W0a6ZnldM41w2fV5D490psKFTpMds8TJse/eHLFFsNHHjHgg==} + lowlight@3.3.0: resolution: {integrity: sha512-0JNhgFoPvP6U6lE/UdVsSq99tn6DhjjpAj5MxG49ewd2mOBVtwWYIT8ClyABhq198aXXODMU6Ox8DrGy/CpTZQ==} @@ -2000,6 +2003,9 @@ packages: natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + no-case@3.0.4: + resolution: {integrity: sha512-fgAN3jGAh+RoxUGZHTSOLJIqUc2wmoBwGR4tbpNAKmmovFoWq0OdRkb0VkldReO2a2iBT/OEulG9XSUc10r3zg==} + node-domexception@1.0.0: resolution: {integrity: sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==} engines: {node: '>=10.5.0'} @@ -2020,6 +2026,9 @@ packages: node-releases@2.0.18: resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==} + normalize.css@8.0.1: + resolution: {integrity: sha512-qizSNPO93t1YUuUhP22btGOo3chcvDFqFaj2TRybP0DMxkHOCTYwp3n34fel4a31ORXy4m1Xq0Gyqpb5m33qIg==} + object-assign@4.1.1: resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} engines: {node: '>=0.10.0'} @@ -2051,6 +2060,9 @@ packages: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} + param-case@3.0.4: + resolution: {integrity: sha512-RXlj7zCYokReqWpOPH9oYivUzLYZ5vAPIfEmCTNViosC78F8F0H9y7T7gG2M39ymgutxF5gcFEsyZQSph9Bp3A==} + parent-module@1.0.1: resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} engines: {node: '>=6'} @@ -2059,6 +2071,12 @@ packages: resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} engines: {node: '>=8'} + pascal-case@3.1.2: + resolution: {integrity: sha512-uWlGT3YSnK9x3BQJaOdcZwrnV6hPpd8jFH1/ucpiLRPh/2zCVJKS19E4GvYHvaCcACn3foXZ0cLB9Wrx1KGe5g==} + + path-case@3.0.4: + resolution: {integrity: sha512-qO4qCFjXqVTrcbPt/hQfhTQ+VhFsqNKOPtytgNKkKxSoEp3XPUQ8ObFuePylOIok5gjn69ry8XiULxCwot3Wfg==} + path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} @@ -2172,245 +2190,26 @@ packages: queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - rc-cascader@3.33.0: - resolution: {integrity: sha512-JvZrMbKBXIbEDmpIORxqvedY/bck6hGbs3hxdWT8eS9wSQ1P7//lGxbyKjOSyQiVBbgzNWriSe6HoMcZO/+0rQ==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-checkbox@3.5.0: - resolution: {integrity: sha512-aOAQc3E98HteIIsSqm6Xk2FPKIER6+5vyEFMZfo73TqM+VVAIqOkHoPjgKLqSNtVLWScoaM7vY2ZrGEheI79yg==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-collapse@3.9.0: - resolution: {integrity: sha512-swDdz4QZ4dFTo4RAUMLL50qP0EY62N2kvmk2We5xYdRwcRn8WcYtuetCJpwpaCbUfUt5+huLpVxhvmnK+PHrkA==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-dialog@9.6.0: - resolution: {integrity: sha512-ApoVi9Z8PaCQg6FsUzS8yvBEQy0ZL2PkuvAgrmohPkN3okps5WZ5WQWPc1RNuiOKaAYv8B97ACdsFU5LizzCqg==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-drawer@7.2.0: - resolution: {integrity: sha512-9lOQ7kBekEJRdEpScHvtmEtXnAsy+NGDXiRWc2ZVC7QXAazNVbeT4EraQKYwCME8BJLa8Bxqxvs5swwyOepRwg==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-dropdown@4.2.1: - resolution: {integrity: sha512-YDAlXsPv3I1n42dv1JpdM7wJ+gSUBfeyPK59ZpBD9jQhK9jVuxpjj3NmWQHOBceA1zEPVX84T2wbdb2SD0UjmA==} - peerDependencies: - react: '>=16.11.0' - react-dom: '>=16.11.0' - - rc-field-form@2.7.0: - resolution: {integrity: sha512-hgKsCay2taxzVnBPZl+1n4ZondsV78G++XVsMIJCAoioMjlMQR9YwAp7JZDIECzIu2Z66R+f4SFIRrO2DjDNAA==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-image@7.11.0: - resolution: {integrity: sha512-aZkTEZXqeqfPZtnSdNUnKQA0N/3MbgR7nUnZ+/4MfSFWPFHZau4p5r5ShaI0KPEMnNjv4kijSCFq/9wtJpwykw==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-input-number@9.4.0: - resolution: {integrity: sha512-Tiy4DcXcFXAf9wDhN8aUAyMeCLHJUHA/VA/t7Hj8ZEx5ETvxG7MArDOSE6psbiSCo+vJPm4E3fGN710ITVn6GA==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-input@1.7.2: - resolution: {integrity: sha512-g3nYONnl4edWj2FfVoxsU3Ec4XTE+Hb39Kfh2MFxMZjp/0gGyPUgy/v7ZhS27ZxUFNkuIDYXm9PJsLyJbtg86A==} - peerDependencies: - react: '>=16.0.0' - react-dom: '>=16.0.0' - - rc-mentions@2.19.1: - resolution: {integrity: sha512-KK3bAc/bPFI993J3necmaMXD2reZTzytZdlTvkeBbp50IGH1BDPDvxLdHDUrpQx2b2TGaVJsn+86BvYa03kGqA==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-menu@9.16.1: - resolution: {integrity: sha512-ghHx6/6Dvp+fw8CJhDUHFHDJ84hJE3BXNCzSgLdmNiFErWSOaZNsihDAsKq9ByTALo/xkNIwtDFGIl6r+RPXBg==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-motion@2.9.5: - resolution: {integrity: sha512-w+XTUrfh7ArbYEd2582uDrEhmBHwK1ZENJiSJVb7uRxdE7qJSYjbO2eksRXmndqyKqKoYPc9ClpPh5242mV1vA==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-notification@5.6.3: - resolution: {integrity: sha512-42szwnn8VYQoT6GnjO00i1iwqV9D1TTMvxObWsuLwgl0TsOokzhkYiufdtQBsJMFjJravS1hfDKVMHLKLcPE4g==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-overflow@1.3.2: - resolution: {integrity: sha512-nsUm78jkYAoPygDAcGZeC2VwIg/IBGSodtOY3pMof4W3M9qRJgqaDYm03ZayHlde3I6ipliAxbN0RUcGf5KOzw==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-pagination@5.1.0: - resolution: {integrity: sha512-8416Yip/+eclTFdHXLKTxZvn70duYVGTvUUWbckCCZoIl3jagqke3GLsFrMs0bsQBikiYpZLD9206Ej4SOdOXQ==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-picker@4.11.2: - resolution: {integrity: sha512-Cwa3frWpefhESBF20HBJtvWx3q1hCrMxSUrzuuWMTGoZVPhQllGEp2IUfzo9jC5LKm4kJx7IrH8q/W/y9wClAw==} - engines: {node: '>=8.x'} - peerDependencies: - date-fns: '>= 2.x' - dayjs: '>= 1.x' - luxon: '>= 3.x' - moment: '>= 2.x' - react: '>=16.9.0' - react-dom: '>=16.9.0' - peerDependenciesMeta: - date-fns: - optional: true - dayjs: - optional: true - luxon: - optional: true - moment: - optional: true - - rc-progress@4.0.0: - resolution: {integrity: sha512-oofVMMafOCokIUIBnZLNcOZFsABaUw8PPrf1/y0ZBvKZNpOiu5h4AO9vv11Sw0p4Hb3D0yGWuEattcQGtNJ/aw==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-rate@2.13.1: - resolution: {integrity: sha512-QUhQ9ivQ8Gy7mtMZPAjLbxBt5y9GRp65VcUyGUMF3N3fhiftivPHdpuDIaWIMOTEprAjZPC08bls1dQB+I1F2Q==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-resize-observer@1.4.3: - resolution: {integrity: sha512-YZLjUbyIWox8E9i9C3Tm7ia+W7euPItNWSPX5sCcQTYbnwDb5uNpnLHQCG1f22oZWUhLw4Mv2tFmeWe68CDQRQ==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-segmented@2.7.0: - resolution: {integrity: sha512-liijAjXz+KnTRVnxxXG2sYDGd6iLL7VpGGdR8gwoxAXy2KglviKCxLWZdjKYJzYzGSUwKDSTdYk8brj54Bn5BA==} - peerDependencies: - react: '>=16.0.0' - react-dom: '>=16.0.0' - - rc-select@14.16.6: - resolution: {integrity: sha512-YPMtRPqfZWOm2XGTbx5/YVr1HT0vn//8QS77At0Gjb3Lv+Lbut0IORJPKLWu1hQ3u4GsA0SrDzs7nI8JG7Zmyg==} - engines: {node: '>=8.x'} - peerDependencies: - react: '*' - react-dom: '*' - - rc-slider@11.1.8: - resolution: {integrity: sha512-2gg/72YFSpKP+Ja5AjC5DPL1YnV8DEITDQrcc1eASrUYjl0esptaBVJBh5nLTXCCp15eD8EuGjwezVGSHhs9tQ==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-steps@6.0.1: - resolution: {integrity: sha512-lKHL+Sny0SeHkQKKDJlAjV5oZ8DwCdS2hFhAkIjuQt1/pB81M0cA0ErVFdHq9+jmPmFw1vJB2F5NBzFXLJxV+g==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-switch@4.1.0: - resolution: {integrity: sha512-TI8ufP2Az9oEbvyCeVE4+90PDSljGyuwix3fV58p7HV2o4wBnVToEyomJRVyTaZeqNPAp+vqeo4Wnj5u0ZZQBg==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-table@7.50.3: - resolution: {integrity: sha512-Z4/zNCzjv7f/XzPRecb+vJU0DJKdsYt4YRkDzNl4G05m7JmxrKGYC2KqN1Ew6jw2zJq7cxVv3z39qyZOHMuf7A==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-tabs@15.5.1: - resolution: {integrity: sha512-yiWivLAjEo5d1v2xlseB2dQocsOhkoVSfo1krS8v8r+02K+TBUjSjXIf7dgyVSxp6wRIPv5pMi5hanNUlQMgUA==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-textarea@1.9.0: - resolution: {integrity: sha512-dQW/Bc/MriPBTugj2Kx9PMS5eXCCGn2cxoIaichjbNvOiARlaHdI99j4DTxLl/V8+PIfW06uFy7kjfUIDDKyxQ==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-tooltip@6.4.0: - resolution: {integrity: sha512-kqyivim5cp8I5RkHmpsp1Nn/Wk+1oeloMv9c7LXNgDxUpGm+RbXJGL+OPvDlcRnx9DBeOe4wyOIl4OKUERyH1g==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-tree-select@5.27.0: - resolution: {integrity: sha512-2qTBTzwIT7LRI1o7zLyrCzmo5tQanmyGbSaGTIf7sYimCklAToVVfpMC6OAldSKolcnjorBYPNSKQqJmN3TCww==} - peerDependencies: - react: '*' - react-dom: '*' - - rc-tree@5.13.0: - resolution: {integrity: sha512-2+lFvoVRnvHQ1trlpXMOWtF8BUgF+3TiipG72uOfhpL5CUdXCk931kvDdUkTL/IZVtNEDQKwEEmJbAYJSA5NnA==} - engines: {node: '>=10.x'} - peerDependencies: - react: '*' - react-dom: '*' - - rc-upload@4.8.1: - resolution: {integrity: sha512-toEAhwl4hjLAI1u8/CgKWt30BR06ulPa4iGQSMvSXoHzO88gPCslxqV/mnn4gJU7PDoltGIC9Eh+wkeudqgHyw==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - rc-util@5.43.0: resolution: {integrity: sha512-AzC7KKOXFqAdIBqdGWepL9Xn7cm3vnAmjlHqUnoQaTMZYhM4VlXGLkkHHxj/BZ7Td0+SOPKB4RGPboBVKT9htw==} peerDependencies: react: '>=16.9.0' react-dom: '>=16.9.0' - rc-util@5.44.4: - resolution: {integrity: sha512-resueRJzmHG9Q6rI/DfK6Kdv9/Lfls05vzMs1Sk3M2P+3cJa+MakaZyWY8IPfehVuhPJFKrIY1IK4GqbiaiY5w==} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - - rc-virtual-list@3.14.5: - resolution: {integrity: sha512-ZMOnkCLv2wUN8Jz7yI4XiSLa9THlYvf00LuMhb1JlsQCewuU7ydPuHw1rGVPhe9VZYl/5UqODtNd7QKJ2DMGfg==} - engines: {node: '>=8.x'} - peerDependencies: - react: '>=16.9.0' - react-dom: '>=16.9.0' - react-dom@19.0.0: resolution: {integrity: sha512-4GV5sHFG0e/0AD4X+ySy6UJd3jVl1iNsNHdpad0qhABJ11twS3TTBnseqsKurKcsNqCEFeGL3uLpVChpIO3QfQ==} peerDependencies: react: ^19.0.0 + react-draggable@4.4.6: + resolution: {integrity: sha512-LtY5Xw1zTPqHkVmtM3X8MUOxNDOUhv/khTgBgrUvwaS064bwVvxT+q5El0uUFNx5IEPKXuRejr7UqLwBIg5pdw==} + peerDependencies: + react: '>= 16.3.0' + react-dom: '>= 16.3.0' + + react-fast-compare@3.2.2: + resolution: {integrity: sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==} + react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} @@ -2420,10 +2219,28 @@ packages: react-is@19.0.0: resolution: {integrity: sha512-H91OHcwjZsbq3ClIDHMzBShc1rotbfACdWENsmEf0IFvZ3FgGPtdHMcsv45bQ1hAbgdfiA8SnxTKfDS+x/8m2g==} + react-popper@2.3.0: + resolution: {integrity: sha512-e1hj8lL3uM+sgSR4Lxzn5h1GxBlpa4CQz0XLF8kx4MDrDRWY0Ena4c97PUeSX9i5W3UAfDP0z0FXCTQkoXUl3Q==} + peerDependencies: + '@popperjs/core': ^2.0.0 + react: ^16.8.0 || ^17 || ^18 + react-dom: ^16.8.0 || ^17 || ^18 + react-refresh@0.14.2: resolution: {integrity: sha512-jCvmsr+1IUSMUyzOkRcvnVbX3ZYC6g9TDrDbFuFmRDq7PD4yaGbLKNQL6k2jnArV8hjYxh7hVhAZB6s9HDGpZA==} engines: {node: '>=0.10.0'} + react-resizable-panels@2.1.7: + resolution: {integrity: sha512-JtT6gI+nURzhMYQYsx8DKkx6bSoOGFp7A3CwMrOb8y5jFHFyqwo9m68UhmXRw57fRVJksFn1TSlm3ywEQ9vMgA==} + peerDependencies: + react: ^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + react-dom: ^16.14.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc + + react-resizable@3.0.5: + resolution: {integrity: sha512-vKpeHhI5OZvYn82kXOs1bC8aOXktGU5AmKAgaZS4F5JPburCtbmDPqE7Pzp+1kN4+Wb81LlF33VpGwWwtXem+w==} + peerDependencies: + react: '>= 16.3' + react-router-dom@7.2.0: resolution: {integrity: sha512-cU7lTxETGtQRQbafJubvZKHEn5izNABxZhBY0Jlzdv0gqQhCPQt2J8aN5ZPjS6mQOXn5NnirWNh+FpE8TTYN0Q==} engines: {node: '>=20.0.0'} @@ -2453,6 +2270,16 @@ packages: react: '>=16.6.0' react-dom: '>=16.6.0' + react-uid@2.4.0: + resolution: {integrity: sha512-+MVs/25NrcZuGrmlVRWPOSsbS8y72GJOBsR7d68j3/wqOrRBF52U29XAw4+XSelw0Vm6s5VmGH5mCbTCPGVCVg==} + engines: {node: '>=10'} + peerDependencies: + '@types/react': ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + peerDependenciesMeta: + '@types/react': + optional: true + react@19.0.0: resolution: {integrity: sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==} engines: {node: '>=0.10.0'} @@ -2460,9 +2287,6 @@ packages: regenerator-runtime@0.14.1: resolution: {integrity: sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==} - resize-observer-polyfill@1.5.1: - resolution: {integrity: sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==} - resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} @@ -2497,9 +2321,6 @@ packages: scheduler@0.25.0: resolution: {integrity: sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA==} - scroll-into-view-if-needed@3.1.0: - resolution: {integrity: sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ==} - selfsigned@2.4.1: resolution: {integrity: sha512-th5B4L2U+eGLq1TVh7zNRGBapioSORUeymIydxgFpwww9d2qyKvtuPU2jJuHvYAwwqi2Y596QBL3eEqcPEYL8Q==} engines: {node: '>=10'} @@ -2513,6 +2334,9 @@ packages: engines: {node: '>=10'} hasBin: true + sentence-case@3.0.4: + resolution: {integrity: sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==} + set-cookie-parser@2.7.1: resolution: {integrity: sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==} @@ -2524,6 +2348,9 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} + snake-case@3.0.4: + resolution: {integrity: sha512-LAOh4z89bGQvl9pFfNF8V146i7o7/CqFPbqzYgP+yYzDIDeS9HaNFtXABamRW+AQzEVODcvE79ljJ+8a9YSdMg==} + source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} @@ -2532,9 +2359,6 @@ packages: resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} engines: {node: '>=0.10.0'} - string-convert@0.2.1: - resolution: {integrity: sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A==} - strip-json-comments@3.1.1: resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} engines: {node: '>=8'} @@ -2545,9 +2369,6 @@ packages: stylis@4.2.0: resolution: {integrity: sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==} - stylis@4.3.4: - resolution: {integrity: sha512-osIBl6BGUmSfDkyH2mB7EFvCJntXDrLhKjHTRj/rK6xLH0yuPrHULDRQzKokSOD4VoorhtKpfcfW1GAntu8now==} - supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} @@ -2571,10 +2392,6 @@ packages: resolution: {integrity: sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==} engines: {node: '>=6'} - throttle-debounce@5.0.2: - resolution: {integrity: sha512-B71/4oyj61iNH0KeCamLuE2rmKuTO5byTOSVwECM5FA7TiAiAW+UqTKZ9ERueC4qvgSttUhdmq1mXC3kJqGX7A==} - engines: {node: '>=12.22'} - tiptap-markdown@0.8.10: resolution: {integrity: sha512-iDVkR2BjAqkTDtFX0h94yVvE2AihCXlF0Q7RIXSJPRSR5I0PA1TMuAg6FHFpmqTn4tPxJ0by0CK7PUMlnFLGEQ==} peerDependencies: @@ -2588,9 +2405,6 @@ packages: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} - toggle-selection@1.0.6: - resolution: {integrity: sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==} - tr46@0.0.3: resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} @@ -2600,6 +2414,9 @@ packages: peerDependencies: typescript: '>=4.8.4' + tslib@2.6.3: + resolution: {integrity: sha512-xNvxJEOUiWPGhUuUdQgAJPKOOJfGnIyKySOc09XkKsgdUV/3E2zvwZYdejjmRgPCgcym1juLH3226yA7sEFJKQ==} + turbo-stream@2.4.0: resolution: {integrity: sha512-FHncC10WpBd2eOmGwpmQsWLDoK4cqsA/UT/GqNoaKOQnT8uzhtCbg3EoUDMvqpOSAI0S26mr0rkjzbOO6S3v1g==} @@ -2637,6 +2454,12 @@ packages: peerDependencies: browserslist: '>= 4.21.0' + upper-case-first@2.0.2: + resolution: {integrity: sha512-514ppYHBaKwfJRK/pNC6c/OxfGa0obSnAl106u97Ed0I625Nin96KAjttZF6ZL3e1XLtphxnqrOi9iWgm+u+bg==} + + upper-case@2.0.2: + resolution: {integrity: sha512-KgdgDGJt2TpuwBUIjgG6lzw2GWFRCW9Qkfkiv0DxqHHLYJHmtmdUIKcZd8rHgFSjopVTlw6ggzCm1b8MFQwikg==} + uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} @@ -2688,6 +2511,9 @@ packages: w3c-keyname@2.2.8: resolution: {integrity: sha512-dpojBhNsCNN7T82Tm7k26A6G9ML3NkhDsnw9n/eoxSRlVBB4CEtIQ/KTCLI2Fwf3ataSXRhYFkQi3SlnFwPvPQ==} + warning@4.0.3: + resolution: {integrity: sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==} + web-streams-polyfill@4.0.0-beta.3: resolution: {integrity: sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==} engines: {node: '>= 14'} @@ -2779,34 +2605,6 @@ snapshots: dependencies: '@ctrl/tinycolor': 3.6.1 - '@ant-design/colors@7.2.0': - dependencies: - '@ant-design/fast-color': 2.0.6 - - '@ant-design/cssinjs-utils@1.1.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': - dependencies: - '@ant-design/cssinjs': 1.23.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@babel/runtime': 7.26.0 - rc-util: 5.44.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - - '@ant-design/cssinjs@1.23.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': - dependencies: - '@babel/runtime': 7.26.0 - '@emotion/hash': 0.8.0 - '@emotion/unitless': 0.7.5 - classnames: 2.5.1 - csstype: 3.1.3 - rc-util: 5.44.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - stylis: 4.3.4 - - '@ant-design/fast-color@2.0.6': - dependencies: - '@babel/runtime': 7.26.0 - '@ant-design/icons-svg@4.4.2': {} '@ant-design/icons@5.6.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': @@ -2819,15 +2617,6 @@ snapshots: react: 19.0.0 react-dom: 19.0.0(react@19.0.0) - '@ant-design/react-slick@1.1.2(react@19.0.0)': - dependencies: - '@babel/runtime': 7.26.0 - classnames: 2.5.1 - json2mq: 0.2.0 - react: 19.0.0 - resize-observer-polyfill: 1.5.1 - throttle-debounce: 5.0.2 - '@babel/code-frame@7.26.2': dependencies: '@babel/helper-validator-identifier': 7.25.9 @@ -2956,6 +2745,37 @@ snapshots: '@babel/helper-string-parser': 7.25.9 '@babel/helper-validator-identifier': 7.25.9 + '@blueprintjs/colors@5.1.8': + dependencies: + tslib: 2.6.3 + + '@blueprintjs/core@5.17.2(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + dependencies: + '@blueprintjs/colors': 5.1.8 + '@blueprintjs/icons': 5.19.1(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + '@popperjs/core': 2.11.8 + classnames: 2.5.1 + normalize.css: 8.0.1 + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) + react-popper: 2.3.0(@popperjs/core@2.11.8)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + react-transition-group: 4.4.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + react-uid: 2.4.0(@types/react@19.0.10)(react@19.0.0) + tslib: 2.6.3 + use-sync-external-store: 1.2.2(react@19.0.0) + optionalDependencies: + '@types/react': 19.0.10 + + '@blueprintjs/icons@5.19.1(@types/react@19.0.10)(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': + dependencies: + change-case: 4.1.2 + classnames: 2.5.1 + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) + tslib: 2.6.3 + optionalDependencies: + '@types/react': 19.0.10 + '@ctrl/tinycolor@3.6.1': {} '@emotion/babel-plugin@11.13.5': @@ -2982,8 +2802,6 @@ snapshots: '@emotion/weak-memoize': 0.4.0 stylis: 4.2.0 - '@emotion/hash@0.8.0': {} - '@emotion/hash@0.9.2': {} '@emotion/is-prop-valid@1.3.1': @@ -3035,8 +2853,6 @@ snapshots: '@emotion/unitless@0.10.0': {} - '@emotion/unitless@0.7.5': {} - '@emotion/use-insertion-effect-with-fallbacks@1.2.0(react@19.0.0)': dependencies: react: 19.0.0 @@ -3192,11 +3008,11 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.0 - '@kevisual/cache@0.0.1(rollup@4.34.8)(typescript@5.8.2)': + '@kevisual/cache@0.0.1(rollup@4.34.8)(tslib@2.6.3)(typescript@5.8.2)': dependencies: '@rollup/plugin-commonjs': 28.0.2(rollup@4.34.8) '@rollup/plugin-node-resolve': 16.0.0(rollup@4.34.8) - '@rollup/plugin-typescript': 12.1.2(rollup@4.34.8)(typescript@5.8.2) + '@rollup/plugin-typescript': 12.1.2(rollup@4.34.8)(tslib@2.6.3)(typescript@5.8.2) idb-keyval: 6.2.1 rollup-plugin-dts: 6.1.1(rollup@4.34.8)(typescript@5.8.2) transitivePeerDependencies: @@ -3212,7 +3028,7 @@ snapshots: - ws - zod - '@kevisual/router@0.0.7': + '@kevisual/router@0.0.8': dependencies: path-to-regexp: 8.2.0 selfsigned: 2.4.1 @@ -3221,6 +3037,8 @@ snapshots: - bufferutil - utf-8-validate + '@kevisual/system-lib@0.0.21-beta.2': {} + '@kevisual/system-ui@0.0.3': dependencies: dayjs: 1.11.13 @@ -3328,75 +3146,6 @@ snapshots: '@popperjs/core@2.11.8': {} - '@rc-component/async-validator@5.0.4': - dependencies: - '@babel/runtime': 7.26.0 - - '@rc-component/color-picker@2.0.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': - dependencies: - '@ant-design/fast-color': 2.0.6 - '@babel/runtime': 7.26.0 - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - - '@rc-component/context@1.4.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': - dependencies: - '@babel/runtime': 7.26.0 - rc-util: 5.44.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - - '@rc-component/mini-decimal@1.1.0': - dependencies: - '@babel/runtime': 7.26.0 - - '@rc-component/mutate-observer@1.1.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': - dependencies: - '@babel/runtime': 7.26.0 - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - - '@rc-component/portal@1.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': - dependencies: - '@babel/runtime': 7.26.0 - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - - '@rc-component/qrcode@1.0.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': - dependencies: - '@babel/runtime': 7.26.0 - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - - '@rc-component/tour@1.15.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': - dependencies: - '@babel/runtime': 7.26.0 - '@rc-component/portal': 1.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@rc-component/trigger': 2.2.6(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - - '@rc-component/trigger@2.2.6(react-dom@19.0.0(react@19.0.0))(react@19.0.0)': - dependencies: - '@babel/runtime': 7.26.0 - '@rc-component/portal': 1.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - classnames: 2.5.1 - rc-motion: 2.9.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-resize-observer: 1.4.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-util: 5.44.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - '@remirror/core-constants@3.0.0': {} '@rollup/plugin-commonjs@28.0.2(rollup@4.34.8)': @@ -3421,13 +3170,14 @@ snapshots: optionalDependencies: rollup: 4.34.8 - '@rollup/plugin-typescript@12.1.2(rollup@4.34.8)(typescript@5.8.2)': + '@rollup/plugin-typescript@12.1.2(rollup@4.34.8)(tslib@2.6.3)(typescript@5.8.2)': dependencies: '@rollup/pluginutils': 5.1.4(rollup@4.34.8) resolve: 1.22.10 typescript: 5.8.2 optionalDependencies: rollup: 4.34.8 + tslib: 2.6.3 '@rollup/pluginutils@5.1.4(rollup@4.34.8)': dependencies: @@ -3640,6 +3390,11 @@ snapshots: dependencies: '@tiptap/core': 2.11.5(@tiptap/pm@2.11.5) + '@tiptap/extension-placeholder@2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))(@tiptap/pm@2.11.5)': + dependencies: + '@tiptap/core': 2.11.5(@tiptap/pm@2.11.5) + '@tiptap/pm': 2.11.5 + '@tiptap/extension-strike@2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))': dependencies: '@tiptap/core': 2.11.5(@tiptap/pm@2.11.5) @@ -3701,6 +3456,11 @@ snapshots: '@tiptap/extension-text-style': 2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5)) '@tiptap/pm': 2.11.5 + '@tiptap/suggestion@2.11.5(@tiptap/core@2.11.5(@tiptap/pm@2.11.5))(@tiptap/pm@2.11.5)': + dependencies: + '@tiptap/core': 2.11.5(@tiptap/pm@2.11.5) + '@tiptap/pm': 2.11.5 + '@types/babel__core@7.20.5': dependencies: '@babel/parser': 7.25.6 @@ -3802,6 +3562,10 @@ snapshots: dependencies: '@types/react': 19.0.10 + '@types/react-resizable@3.0.8': + dependencies: + '@types/react': 19.0.10 + '@types/react-transition-group@4.4.12(@types/react@19.0.10)': dependencies: '@types/react': 19.0.10 @@ -3893,7 +3657,7 @@ snapshots: '@typescript-eslint/types': 8.25.0 eslint-visitor-keys: 4.2.0 - '@vitejs/plugin-basic-ssl@1.2.0(vite@6.2.0(@types/node@22.13.8)(jiti@2.4.2)(lightningcss@1.29.1)(yaml@2.5.1))': + '@vitejs/plugin-basic-ssl@2.0.0(vite@6.2.0(@types/node@22.13.8)(jiti@2.4.2)(lightningcss@1.29.1)(yaml@2.5.1))': dependencies: vite: 6.2.0(@types/node@22.13.8)(jiti@2.4.2)(lightningcss@1.29.1)(yaml@2.5.1) @@ -3954,64 +3718,6 @@ snapshots: dependencies: color-convert: 2.0.1 - antd@5.24.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0): - dependencies: - '@ant-design/colors': 7.2.0 - '@ant-design/cssinjs': 1.23.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@ant-design/cssinjs-utils': 1.1.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@ant-design/fast-color': 2.0.6 - '@ant-design/icons': 5.6.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@ant-design/react-slick': 1.1.2(react@19.0.0) - '@babel/runtime': 7.26.0 - '@rc-component/color-picker': 2.0.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@rc-component/mutate-observer': 1.1.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@rc-component/qrcode': 1.0.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@rc-component/tour': 1.15.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - '@rc-component/trigger': 2.2.6(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - classnames: 2.5.1 - copy-to-clipboard: 3.3.3 - dayjs: 1.11.13 - rc-cascader: 3.33.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-checkbox: 3.5.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-collapse: 3.9.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-dialog: 9.6.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-drawer: 7.2.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-dropdown: 4.2.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-field-form: 2.7.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-image: 7.11.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-input: 1.7.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-input-number: 9.4.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-mentions: 2.19.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-menu: 9.16.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-motion: 2.9.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-notification: 5.6.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-pagination: 5.1.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-picker: 4.11.2(dayjs@1.11.13)(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-progress: 4.0.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-rate: 2.13.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-resize-observer: 1.4.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-segmented: 2.7.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-select: 14.16.6(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-slider: 11.1.8(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-steps: 6.0.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-switch: 4.1.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-table: 7.50.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-tabs: 15.5.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-textarea: 1.9.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-tooltip: 6.4.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-tree: 5.13.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-tree-select: 5.27.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-upload: 4.8.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-util: 5.44.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - scroll-into-view-if-needed: 3.1.0 - throttle-debounce: 5.0.2 - transitivePeerDependencies: - - date-fns - - luxon - - moment - argparse@2.0.1: {} asynckit@0.4.0: {} @@ -4051,17 +3757,45 @@ snapshots: callsites@3.1.0: {} + camel-case@4.1.2: + dependencies: + pascal-case: 3.1.2 + tslib: 2.6.3 + caniuse-lite@1.0.30001684: {} + capital-case@1.0.4: + dependencies: + no-case: 3.0.4 + tslib: 2.6.3 + upper-case-first: 2.0.2 + chalk@4.1.2: dependencies: ansi-styles: 4.3.0 supports-color: 7.2.0 + change-case@4.1.2: + dependencies: + camel-case: 4.1.2 + capital-case: 1.0.4 + constant-case: 3.0.4 + dot-case: 3.0.4 + header-case: 2.0.4 + no-case: 3.0.4 + param-case: 3.0.4 + pascal-case: 3.1.2 + path-case: 3.0.4 + sentence-case: 3.0.4 + snake-case: 3.0.4 + tslib: 2.6.3 + classcat@5.0.5: {} classnames@2.5.1: {} + clsx@1.2.1: {} + clsx@2.1.1: {} color-convert@2.0.1: @@ -4076,20 +3810,20 @@ snapshots: commondir@1.0.1: {} - compute-scroll-into-view@3.1.0: {} - concat-map@0.0.1: {} + constant-case@3.0.4: + dependencies: + no-case: 3.0.4 + tslib: 2.6.3 + upper-case: 2.0.2 + convert-source-map@1.9.0: {} convert-source-map@2.0.0: {} cookie@1.0.2: {} - copy-to-clipboard@3.3.3: - dependencies: - toggle-selection: 1.0.6 - cosmiconfig@7.1.0: dependencies: '@types/parse-json': 4.0.2 @@ -4169,6 +3903,11 @@ snapshots: '@babel/runtime': 7.26.0 csstype: 3.1.3 + dot-case@3.0.4: + dependencies: + no-case: 3.0.4 + tslib: 2.6.3 + dunder-proto@1.0.1: dependencies: call-bind-apply-helpers: 1.0.2 @@ -4432,6 +4171,11 @@ snapshots: dependencies: function-bind: 1.1.2 + header-case@2.0.4: + dependencies: + capital-case: 1.0.4 + tslib: 2.6.3 + highlight.js@11.11.1: {} hoist-non-react-statics@3.3.2: @@ -4499,10 +4243,6 @@ snapshots: json-stable-stringify-without-jsonify@1.0.1: {} - json2mq@0.2.0: - dependencies: - string-convert: 0.2.1 - json5@2.2.3: {} keyv@4.5.4: @@ -4577,6 +4317,10 @@ snapshots: dependencies: js-tokens: 4.0.0 + lower-case@2.0.2: + dependencies: + tslib: 2.6.3 + lowlight@3.3.0: dependencies: '@types/hast': 3.0.4 @@ -4641,6 +4385,11 @@ snapshots: natural-compare@1.4.0: {} + no-case@3.0.4: + dependencies: + lower-case: 2.0.2 + tslib: 2.6.3 + node-domexception@1.0.0: {} node-fetch@2.7.0: @@ -4651,6 +4400,8 @@ snapshots: node-releases@2.0.18: {} + normalize.css@8.0.1: {} + object-assign@4.1.1: {} openai@4.86.1(ws@8.18.0): @@ -4686,6 +4437,11 @@ snapshots: dependencies: p-limit: 3.1.0 + param-case@3.0.4: + dependencies: + dot-case: 3.0.4 + tslib: 2.6.3 + parent-module@1.0.1: dependencies: callsites: 3.1.0 @@ -4697,6 +4453,16 @@ snapshots: json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 + pascal-case@3.1.2: + dependencies: + no-case: 3.0.4 + tslib: 2.6.3 + + path-case@3.0.4: + dependencies: + dot-case: 3.0.4 + tslib: 2.6.3 + path-exists@4.0.0: {} path-key@3.1.1: {} @@ -4838,309 +4604,6 @@ snapshots: queue-microtask@1.2.3: {} - rc-cascader@3.33.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0): - dependencies: - '@babel/runtime': 7.26.0 - classnames: 2.5.1 - rc-select: 14.16.6(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-tree: 5.13.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-util: 5.44.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - - rc-checkbox@3.5.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0): - dependencies: - '@babel/runtime': 7.26.0 - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - - rc-collapse@3.9.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0): - dependencies: - '@babel/runtime': 7.26.0 - classnames: 2.5.1 - rc-motion: 2.9.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-util: 5.44.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - - rc-dialog@9.6.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0): - dependencies: - '@babel/runtime': 7.26.0 - '@rc-component/portal': 1.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - classnames: 2.5.1 - rc-motion: 2.9.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-util: 5.44.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - - rc-drawer@7.2.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0): - dependencies: - '@babel/runtime': 7.26.0 - '@rc-component/portal': 1.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - classnames: 2.5.1 - rc-motion: 2.9.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-util: 5.44.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - - rc-dropdown@4.2.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0): - dependencies: - '@babel/runtime': 7.26.0 - '@rc-component/trigger': 2.2.6(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - - rc-field-form@2.7.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0): - dependencies: - '@babel/runtime': 7.26.0 - '@rc-component/async-validator': 5.0.4 - rc-util: 5.44.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - - rc-image@7.11.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0): - dependencies: - '@babel/runtime': 7.26.0 - '@rc-component/portal': 1.1.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - classnames: 2.5.1 - rc-dialog: 9.6.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-motion: 2.9.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-util: 5.44.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - - rc-input-number@9.4.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0): - dependencies: - '@babel/runtime': 7.26.0 - '@rc-component/mini-decimal': 1.1.0 - classnames: 2.5.1 - rc-input: 1.7.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-util: 5.44.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - - rc-input@1.7.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0): - dependencies: - '@babel/runtime': 7.26.0 - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - - rc-mentions@2.19.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0): - dependencies: - '@babel/runtime': 7.26.0 - '@rc-component/trigger': 2.2.6(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - classnames: 2.5.1 - rc-input: 1.7.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-menu: 9.16.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-textarea: 1.9.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-util: 5.44.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - - rc-menu@9.16.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0): - dependencies: - '@babel/runtime': 7.26.0 - '@rc-component/trigger': 2.2.6(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - classnames: 2.5.1 - rc-motion: 2.9.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-overflow: 1.3.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-util: 5.44.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - - rc-motion@2.9.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0): - dependencies: - '@babel/runtime': 7.26.0 - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - - rc-notification@5.6.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0): - dependencies: - '@babel/runtime': 7.26.0 - classnames: 2.5.1 - rc-motion: 2.9.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-util: 5.44.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - - rc-overflow@1.3.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0): - dependencies: - '@babel/runtime': 7.26.0 - classnames: 2.5.1 - rc-resize-observer: 1.4.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-util: 5.44.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - - rc-pagination@5.1.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0): - dependencies: - '@babel/runtime': 7.26.0 - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - - rc-picker@4.11.2(dayjs@1.11.13)(react-dom@19.0.0(react@19.0.0))(react@19.0.0): - dependencies: - '@babel/runtime': 7.26.0 - '@rc-component/trigger': 2.2.6(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - classnames: 2.5.1 - rc-overflow: 1.3.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-resize-observer: 1.4.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-util: 5.44.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - optionalDependencies: - dayjs: 1.11.13 - - rc-progress@4.0.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0): - dependencies: - '@babel/runtime': 7.26.0 - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - - rc-rate@2.13.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0): - dependencies: - '@babel/runtime': 7.26.0 - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - - rc-resize-observer@1.4.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0): - dependencies: - '@babel/runtime': 7.26.0 - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - resize-observer-polyfill: 1.5.1 - - rc-segmented@2.7.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0): - dependencies: - '@babel/runtime': 7.26.0 - classnames: 2.5.1 - rc-motion: 2.9.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-util: 5.44.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - - rc-select@14.16.6(react-dom@19.0.0(react@19.0.0))(react@19.0.0): - dependencies: - '@babel/runtime': 7.26.0 - '@rc-component/trigger': 2.2.6(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - classnames: 2.5.1 - rc-motion: 2.9.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-overflow: 1.3.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-util: 5.44.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-virtual-list: 3.14.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - - rc-slider@11.1.8(react-dom@19.0.0(react@19.0.0))(react@19.0.0): - dependencies: - '@babel/runtime': 7.26.0 - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - - rc-steps@6.0.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0): - dependencies: - '@babel/runtime': 7.26.0 - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - - rc-switch@4.1.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0): - dependencies: - '@babel/runtime': 7.26.0 - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - - rc-table@7.50.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0): - dependencies: - '@babel/runtime': 7.26.0 - '@rc-component/context': 1.4.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - classnames: 2.5.1 - rc-resize-observer: 1.4.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-util: 5.44.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-virtual-list: 3.14.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - - rc-tabs@15.5.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0): - dependencies: - '@babel/runtime': 7.26.0 - classnames: 2.5.1 - rc-dropdown: 4.2.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-menu: 9.16.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-motion: 2.9.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-resize-observer: 1.4.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-util: 5.44.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - - rc-textarea@1.9.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0): - dependencies: - '@babel/runtime': 7.26.0 - classnames: 2.5.1 - rc-input: 1.7.2(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-resize-observer: 1.4.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-util: 5.44.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - - rc-tooltip@6.4.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0): - dependencies: - '@babel/runtime': 7.26.0 - '@rc-component/trigger': 2.2.6(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - - rc-tree-select@5.27.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0): - dependencies: - '@babel/runtime': 7.26.0 - classnames: 2.5.1 - rc-select: 14.16.6(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-tree: 5.13.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-util: 5.44.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - - rc-tree@5.13.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0): - dependencies: - '@babel/runtime': 7.26.0 - classnames: 2.5.1 - rc-motion: 2.9.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-util: 5.44.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-virtual-list: 3.14.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - - rc-upload@4.8.1(react-dom@19.0.0(react@19.0.0))(react@19.0.0): - dependencies: - '@babel/runtime': 7.26.0 - classnames: 2.5.1 - rc-util: 5.44.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - rc-util@5.43.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0): dependencies: '@babel/runtime': 7.26.0 @@ -5148,35 +4611,49 @@ snapshots: react-dom: 19.0.0(react@19.0.0) react-is: 18.3.1 - rc-util@5.44.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0): - dependencies: - '@babel/runtime': 7.26.0 - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - react-is: 18.3.1 - - rc-virtual-list@3.14.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0): - dependencies: - '@babel/runtime': 7.26.0 - classnames: 2.5.1 - rc-resize-observer: 1.4.3(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - rc-util: 5.44.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) - react: 19.0.0 - react-dom: 19.0.0(react@19.0.0) - react-dom@19.0.0(react@19.0.0): dependencies: react: 19.0.0 scheduler: 0.25.0 + react-draggable@4.4.6(react-dom@19.0.0(react@19.0.0))(react@19.0.0): + dependencies: + clsx: 1.2.1 + prop-types: 15.8.1 + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) + + react-fast-compare@3.2.2: {} + react-is@16.13.1: {} react-is@18.3.1: {} react-is@19.0.0: {} + react-popper@2.3.0(@popperjs/core@2.11.8)(react-dom@19.0.0(react@19.0.0))(react@19.0.0): + dependencies: + '@popperjs/core': 2.11.8 + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) + react-fast-compare: 3.2.2 + warning: 4.0.3 + react-refresh@0.14.2: {} + react-resizable-panels@2.1.7(react-dom@19.0.0(react@19.0.0))(react@19.0.0): + dependencies: + react: 19.0.0 + react-dom: 19.0.0(react@19.0.0) + + react-resizable@3.0.5(react-dom@19.0.0(react@19.0.0))(react@19.0.0): + dependencies: + prop-types: 15.8.1 + react: 19.0.0 + react-draggable: 4.4.6(react-dom@19.0.0(react@19.0.0))(react@19.0.0) + transitivePeerDependencies: + - react-dom + react-router-dom@7.2.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0): dependencies: react: 19.0.0 @@ -5208,12 +4685,17 @@ snapshots: react: 19.0.0 react-dom: 19.0.0(react@19.0.0) + react-uid@2.4.0(@types/react@19.0.10)(react@19.0.0): + dependencies: + react: 19.0.0 + tslib: 2.6.3 + optionalDependencies: + '@types/react': 19.0.10 + react@19.0.0: {} regenerator-runtime@0.14.1: {} - resize-observer-polyfill@1.5.1: {} - resolve-from@4.0.0: {} resolve@1.22.10: @@ -5265,10 +4747,6 @@ snapshots: scheduler@0.25.0: {} - scroll-into-view-if-needed@3.1.0: - dependencies: - compute-scroll-into-view: 3.1.0 - selfsigned@2.4.1: dependencies: '@types/node-forge': 1.3.11 @@ -5278,6 +4756,12 @@ snapshots: semver@7.6.3: {} + sentence-case@3.0.4: + dependencies: + no-case: 3.0.4 + tslib: 2.6.3 + upper-case-first: 2.0.2 + set-cookie-parser@2.7.1: {} shebang-command@2.0.0: @@ -5286,12 +4770,15 @@ snapshots: shebang-regex@3.0.0: {} + snake-case@3.0.4: + dependencies: + dot-case: 3.0.4 + tslib: 2.6.3 + source-map-js@1.2.1: {} source-map@0.5.7: {} - string-convert@0.2.1: {} - strip-json-comments@3.1.1: {} style-to-object@1.0.8: @@ -5300,8 +4787,6 @@ snapshots: stylis@4.2.0: {} - stylis@4.3.4: {} - supports-color@7.2.0: dependencies: has-flag: 4.0.0 @@ -5318,8 +4803,6 @@ snapshots: tapable@2.2.1: {} - throttle-debounce@5.0.2: {} - tiptap-markdown@0.8.10(@tiptap/core@2.11.5(@tiptap/pm@2.11.5)): dependencies: '@tiptap/core': 2.11.5(@tiptap/pm@2.11.5) @@ -5334,14 +4817,14 @@ snapshots: dependencies: is-number: 7.0.0 - toggle-selection@1.0.6: {} - tr46@0.0.3: {} ts-api-utils@2.0.1(typescript@5.8.2): dependencies: typescript: 5.8.2 + tslib@2.6.3: {} + turbo-stream@2.4.0: {} turndown@7.2.0: @@ -5376,6 +4859,14 @@ snapshots: escalade: 3.2.0 picocolors: 1.1.0 + upper-case-first@2.0.2: + dependencies: + tslib: 2.6.3 + + upper-case@2.0.2: + dependencies: + tslib: 2.6.3 + uri-js@4.4.1: dependencies: punycode: 2.3.1 @@ -5398,6 +4889,10 @@ snapshots: w3c-keyname@2.2.8: {} + warning@4.0.3: + dependencies: + loose-envify: 1.4.0 + web-streams-polyfill@4.0.0-beta.3: {} webidl-conversions@3.0.1: {} diff --git a/src/App.tsx b/src/App.tsx index 826e77c..1e765b1 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,38 +1,13 @@ import { Flow } from './pages/wall'; -import { BrowserRouter, Routes, Route, Navigate } from 'react-router-dom'; -import { Editor } from './pages/editor'; import { ToastContainer } from 'react-toastify'; import 'react-toastify/dist/ReactToastify.css'; -import { List } from './pages/wall/pages/List'; import { Auth } from './modules/layouts/Auth'; -import { basename } from './modules/basename'; +// import { basename } from './modules/basename'; import 'github-markdown-css/github-markdown.css'; -import { App as WallShareApp } from './pages/wall-share'; export const App = () => { return ( <> - - - }> - } /> - } /> - - }> - } /> - } /> - - - - - } - /> - - } /> - - + ); diff --git a/src/main.tsx b/src/main.tsx index 0b358e7..0f49c23 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,6 +1,87 @@ -import { createRoot } from 'react-dom/client'; +import { createRoot, Root } from 'react-dom/client'; import { App } from './App.tsx'; - +import { useContextKey } from '@kevisual/system-lib/dist/web-config'; import './index.css'; +import { QueryRouterServer } from '@kevisual/system-lib/dist/router-browser'; +import { Editor } from './pages/editor/index.tsx'; +import { ExampleApp } from './modules/panels/Example.tsx'; -createRoot(document.getElementById('root')!).render(); +const page = useContextKey('page'); +const wallnoteDom = useContextKey('wallnoteDom', () => { + return document.getElementById('root'); +}); +const app = useContextKey('app'); +app + .route({ + path: 'wallnote', + key: 'getDomId', + description: '获取墙记的dom', + run: async (ctx) => { + console.log('ctx', ctx); + ctx.body = 'wallnoteDom'; + }, + }) + .addTo(app); + +let root: Root | null = null; +app + .route({ + path: 'wallnote', + key: 'getWallnoteReactDom', + description: '获取墙记的react dom', + run: async (ctx) => { + const root = await useContextKey('wallReactRoot'); + if (!root) { + ctx.throw(404, 'wallReactRoot not found'); + } + ctx.body = 'wallReactRoot'; + }, + }) + .addTo(app); + +app + .route({ + path: 'wallnote', + key: 'render', + description: '渲染墙记', + run: async (ctx) => { + root = createRoot(wallnoteDom!); + root.render(); + useContextKey('wallReactRoot', () => root, true); + ctx.body = 'wallReactRoot'; + }, + }) + .addTo(app); + +page.addPage('/note/:id', 'wallnote'); +page.subscribe( + 'wallnote', + () => { + root = createRoot(wallnoteDom!); + root.render(); + }, + { runImmediately: false }, +); + +page.addPage('/editor', 'editor'); +page.subscribe( + 'editor', + () => { + root = createRoot(wallnoteDom!); + root.render(); + }, + { runImmediately: false }, +); + +page.addPage('/panels', 'panels'); + +setTimeout(() => { + page.subscribe( + 'panels', + () => { + root = createRoot(wallnoteDom!); + root.render(); + }, + { runImmediately: true }, + ); +}, 1000); diff --git a/src/modules/basename.ts b/src/modules/basename.ts index 263b1bb..c2905b5 100644 --- a/src/modules/basename.ts +++ b/src/modules/basename.ts @@ -1 +1 @@ -export const basename = DEV_SERVER ? '/' : BASE_NAME; +export const basename = DEV_SERVER ? '' : BASE_NAME; diff --git a/src/modules/panels/Example.tsx b/src/modules/panels/Example.tsx new file mode 100644 index 0000000..24386f2 --- /dev/null +++ b/src/modules/panels/Example.tsx @@ -0,0 +1,33 @@ +import React, { useEffect } from 'react'; +import WindowManager from './components/WindowManager'; +import { demoWindows } from './demo/DemoWindows'; +import './style.css'; +import { useShallow } from 'zustand/react/shallow'; +import { usePanelStore } from './store'; +import { useListenCmdB } from './hooks/use-listen-b'; + +export function ExampleApp() { + const { data, toggleAICommand, init } = usePanelStore( + useShallow((state) => { + return { + data: state.data, + toggleAICommand: state.toggleAICommand, + init: state.init, + }; + }), + ); + useEffect(() => { + init?.(); + }, [init]); + useListenCmdB(() => { + toggleAICommand?.(); + console.log('toggleAICommand'); + }); + return ( +
+ +
+ ); +} + +export default ExampleApp; diff --git a/src/modules/panels/components/WindowIcons.tsx b/src/modules/panels/components/WindowIcons.tsx new file mode 100644 index 0000000..610a20a --- /dev/null +++ b/src/modules/panels/components/WindowIcons.tsx @@ -0,0 +1,60 @@ +import React from 'react'; +import { + Code, + FileText, + BarChart2, + Settings, + Layers, + Database, + Server, + Terminal, + Image, + Calculator, + MessageSquare, + DivideIcon, + NotebookPen, + SquareTerminal, +} from 'lucide-react'; +import { LucideIcon } from 'lucide-react'; + +// Map of window types to their corresponding icons +const windowTypeIcons: Record = { + code: Code, + document: FileText, + analytics: BarChart2, + settings: Settings, + layers: Layers, + database: Database, + server: Server, + terminal: Terminal, + image: Image, + calculator: Calculator, + welcome: MessageSquare, + notebook: NotebookPen, // 笔记本 + command: SquareTerminal, // 命令行 + // Add more types as needed +}; + +// Default colors for each window type +export const windowTypeColors: Record = { + code: 'text-blue-600', + document: 'text-gray-600', + analytics: 'text-purple-600', + settings: 'text-gray-600', + layers: 'text-indigo-600', + database: 'text-green-600', + server: 'text-red-600', + terminal: 'text-gray-600', + image: 'text-pink-600', + calculator: 'text-yellow-600', + welcome: 'text-blue-600', + // Add more types as needed +}; + +// Function to get the icon component for a window type +export const getIconForWindowType = (type: string): LucideIcon => { + return windowTypeIcons[type] || MessageSquare; // Default to MessageSquare if type not found +}; +export const getColorForWindowType = (type: string): string => { + return windowTypeColors[type] || 'text-gray-600'; // Default to gray if type not found +}; diff --git a/src/modules/panels/components/WindowManager.tsx b/src/modules/panels/components/WindowManager.tsx new file mode 100644 index 0000000..3dea0ab --- /dev/null +++ b/src/modules/panels/components/WindowManager.tsx @@ -0,0 +1,420 @@ +import React, { useState, useCallback, useRef, useEffect, RefObject } from 'react'; +import { Maximize2, Minimize2, Minimize, Expand, X, SquareMinus, Maximize, ChevronDown } from 'lucide-react'; +import { WindowData, WindowPosition } from '../types'; +import classNames from 'clsx'; +import Draggable from 'react-draggable'; +import { ResizableBox } from 'react-resizable'; +import { getIconForWindowType } from './WindowIcons'; +import { useImperativeHandle } from 'react'; +interface WindowManagerProps { + windows: WindowData[]; + showTaskbar?: boolean; + onSave?: (windows: WindowData[]) => void; +} + +// Minimum window dimensions +const MIN_WINDOW_WIDTH = 300; +const MIN_WINDOW_HEIGHT = 200; + +const WindowManager = React.forwardRef(({ windows: initialWindows, showTaskbar = true, onSave }: WindowManagerProps, ref) => { + const [windows, setWindows] = useState(initialWindows); + const [minimizedWindows, setMinimizedWindows] = useState([]); + const [fullscreenWindow, setFullscreenWindow] = useState(null); + const [windowPositions, setWindowPositions] = useState>({}); + const [activeWindow, setActiveWindow] = useState(null); + const [maxZIndex, setMaxZIndex] = useState(100); + const containerRef = useRef(null); + const [mount, setMount] = useState(false); + // Create stable refs for each window + const windowRefs = useRef>>({}); + const draggableRefs = useRef>>({}); + + useImperativeHandle(ref, () => ({ + addWindow: (window: WindowData) => { + addWindow(window); + }, + getWindows: () => { + return windows; + }, + })); + useEffect(() => { + console.log('initialWindows', initialWindows); + setWindows(initialWindows); + }, [initialWindows]); + + // Initialize refs for all windows + useEffect(() => { + windows.forEach((window) => { + if (!windowRefs.current[window.id]) { + windowRefs.current[window.id] = React.createRef(); + } + if (!draggableRefs.current[window.id]) { + draggableRefs.current[window.id] = React.createRef(); + } + }); + }, [windows]); + + // Initialize window positions + useEffect(() => { + const positions: Record = {}; + windows.forEach((window) => { + positions[window.id] = { + x: 0, + y: 0, + width: 0, + height: 0, + zIndex: 1000, + ...window.position, + }; + }); + + setWindowPositions(positions); + setMaxZIndex(1000 + windows.length); + setMount(true); + }, [windows.length]); + useEffect(() => { + if (mount) { + const newWindows = windows + .map((window) => { + return { + ...window, + position: windowPositions[window.id], + }; + }) + .sort((a, b) => a.position.zIndex - b.position.zIndex) + .map((item, index) => { + return { + ...item, + position: { + ...item.position, + zIndex: 1000 + index, + }, + }; + }); + onSave?.(newWindows); + } + }, [mount, windowPositions]); + const addWindow = useCallback((window: WindowData) => { + const has = windows.find((w) => w.id === window.id); + if (has) { + setWindows((prev) => prev.map((w) => (w.id === window.id ? window : w))); + } else { + setWindows((prev) => [...prev, window]); + } + }, []); + // Handle window removal + const handleRemoveWindow = useCallback( + (windowId: string) => { + const window = windows.find((w) => w.id === windowId); + if (window?.onHidden) { + window.onHidden(); + return; + } + setWindows((prev) => prev.filter((w) => w.id !== windowId)); + setMinimizedWindows((prev) => prev.filter((id) => id !== windowId)); + if (fullscreenWindow === windowId) { + setFullscreenWindow(null); + } + }, + [fullscreenWindow], + ); + + // Handle window minimize + const handleMinimizeWindow = useCallback( + (windowId: string) => { + if (minimizedWindows.includes(windowId)) { + setMinimizedWindows((prev) => prev.filter((id) => id !== windowId)); + // Bring window to front when unminimizing + bringToFront(windowId); + } else { + setMinimizedWindows((prev) => [...prev, windowId]); + } + + if (fullscreenWindow === windowId) { + setFullscreenWindow(null); + } + }, + [minimizedWindows, fullscreenWindow], + ); + + // Handle window fullscreen + const handleFullscreenWindow = useCallback( + (windowId: string) => { + setFullscreenWindow((prev) => (prev === windowId ? null : windowId)); + + // Ensure window is not minimized when going fullscreen + if (minimizedWindows.includes(windowId)) { + setMinimizedWindows((prev) => prev.filter((id) => id !== windowId)); + } + + // Bring to front when going fullscreen + bringToFront(windowId); + }, + [minimizedWindows], + ); + + // Bring window to front + const bringToFront = useCallback( + (windowId: string, e?: any) => { + setActiveWindow(windowId); + setMaxZIndex((prev) => prev + 1); + setWindowPositions((prev) => ({ + ...prev, + [windowId]: { + ...prev[windowId], + zIndex: maxZIndex + 1, + }, + })); + if (e) { + e.stopPropagation(); + return e.target.className.includes('window-draggable'); + } + }, + [maxZIndex], + ); + + // Handle window resize + const handleResize = useCallback((windowId: string, e: any, { size }: { size: { width: number; height: number } }) => { + // Ensure minimum dimensions are respected + const width = Math.max(MIN_WINDOW_WIDTH, size.width); + const height = Math.max(MIN_WINDOW_HEIGHT, size.height); + + setWindowPositions((prev) => ({ + ...prev, + [windowId]: { + ...prev[windowId], + width, + height, + }, + })); + }, []); + + // Render window controls + const renderWindowControls = useCallback( + (windowId: string) => { + const isFullscreen = fullscreenWindow === windowId; + return ( +
+ + + +
+ ); + }, + [handleMinimizeWindow, handleFullscreenWindow, handleRemoveWindow], + ); + + // Render the taskbar with minimized windows + const renderTaskbar = () => { + const showWindowsList = windows.filter((window) => window.show && window.showTaskbar); + if (showWindowsList.length === 0) return null; + // useEffect(() => { + // const handleResize = () => { + // const icons = document.querySelectorAll('.more-icon'); + // icons.forEach((iconEl) => { + // const icon = iconEl as HTMLElement; + // const button = icon.closest('button'); + // if (button && button.offsetWidth <= 150) { + // icon.style.display = 'none'; + // } else { + // icon.style.display = 'block'; + // } + // }); + // }; + + // window.addEventListener('resize', handleResize); + // handleResize(); // Initial check + + // return () => { + // window.removeEventListener('resize', handleResize); + // }; + // }, []); + return ( +
+ {showWindowsList.map((window) => { + const isMinimized = minimizedWindows.includes(window.id); + return ( + + ); + })} +
+ ); + }; + + // Add this useEffect to handle window resize + + // Render a fixed position window + const renderFixedWindow = (windowData: WindowData) => { + const isMinimized = minimizedWindows.includes(windowData.id); + const isFullscreen = fullscreenWindow === windowData.id; + const position = windowPositions[windowData.id]; + const Icon = getIconForWindowType(windowData.type || 'welcome'); + const showRounded = windowData.showRounded ?? true; + if (!position) return null; + if (isMinimized) return null; + + // Convert width and height to numbers for Resizable component + const width = isFullscreen ? window.innerWidth : position.width; + const height = isFullscreen ? window.innerHeight - 40 : position.height; + + // Get or create refs for this window + if (!windowRefs.current[windowData.id]) { + windowRefs.current[windowData.id] = React.createRef(); + } + if (!draggableRefs.current[windowData.id]) { + draggableRefs.current[windowData.id] = React.createRef(); + } + + const windowRef = windowRefs.current[windowData.id]; + const draggableRef = draggableRefs.current[windowData.id]; + + return ( +
+
+ bringToFront(windowData.id)} + onStop={(e, data) => { + if (!isFullscreen) { + // Update the window's position in the state + const newX = position.x + data.x; + const newY = position.y + data.y; + setWindowPositions((prev) => ({ + ...prev, + [windowData.id]: { + ...prev[windowData.id], + x: newX, + y: newY, + }, + })); + } + }} + nodeRef={draggableRef as RefObject} + allowAnyClick={true} + disabled={isFullscreen}> +
+ !isFullscreen && handleResize(windowData.id, e, data)} + // resizeHandles={isFullscreen ? [] : ['e', 's', 'se']} + resizeHandles={windowData.resizeHandles || ['e', 's', 'se']} + minConstraints={[MIN_WINDOW_WIDTH, MIN_WINDOW_HEIGHT]} + draggableOpts={{ disabled: isFullscreen }}> +
bringToFront(windowData.id)}> +
+
+ {windowData.showTitle && ( + <> + + {windowData.title} + + )} +
+
{renderWindowControls(windowData.id)}
+
+
+
+ +
+
+
+
+
+
+
+
+ ); + }; + + return ( +
+ {windows.map((window) => renderFixedWindow(window))} + {showTaskbar && renderTaskbar()} +
+ ); +}); +WindowManager.displayName = 'WindowManager'; +export const WindowContent = React.memo((props: { window: WindowData }) => { + const { window } = props; + const ref = useRef(null); + useEffect(() => { + if (ref.current) { + // 获取属性,判断是否加载对应的应用 + } + console.log('window editor render', window); + }, []); + return
; +}); + +export default WindowManager; diff --git a/src/modules/panels/demo/DemoWindows.tsx b/src/modules/panels/demo/DemoWindows.tsx new file mode 100644 index 0000000..9bea555 --- /dev/null +++ b/src/modules/panels/demo/DemoWindows.tsx @@ -0,0 +1,120 @@ +import { WindowData } from '../types'; + +export const createEditorWindow = (data: any): WindowData => { + return { + ...data, + showTitle: true, + show: true, + showTaskbar: true, + showRounded: false, + }; +}; +const windowPositions = { + window1: { + x: 50, + y: 50, + width: 300, + height: 200, + zIndex: 1000, + }, + window2: { + x: 410, + y: 50, + width: 300, + height: 200, + zIndex: 1001, + }, + window3: { + x: 770, + y: 50, + width: 300, + height: 200, + zIndex: 1002, + }, + window4: { + x: 1130, + y: 50, + width: 300, + height: 200, + zIndex: 1003, + }, + 'code-editor': { + x: 50, + y: 230, + width: 300, + height: 200, + zIndex: 1004, + }, + document: { + x: 410, + y: 230, + width: 300, + height: 200, + zIndex: 1005, + }, + analytics: { + x: 770, + y: 230, + width: 300, + height: 200, + zIndex: 1006, + }, + settings: { + x: 1130, + y: 230, + width: 300, + height: 200, + zIndex: 1007, + }, + layers: { + x: 50, + y: 410, + width: 300, + height: 200, + zIndex: 1008, + }, + database: { + x: 410, + y: 410, + width: 300, + height: 200, + zIndex: 1009, + }, + server: { + x: 770, + y: 410, + width: 300, + height: 200, + zIndex: 1010, + }, + terminal: { + x: 1130, + y: 410, + width: 300, + height: 200, + zIndex: 1011, + }, + command: { + x: 50, + y: 590, + width: 300, + height: 200, + }, +}; + +// Demo windows data using the createEditorWindow function +export const demoWindows: WindowData[] = [ + createEditorWindow({ title: 'Welcome', id: 'window1', type: 'welcome' }), + createEditorWindow({ title: 'Image Viewer', id: 'window2', type: 'image' }), + createEditorWindow({ title: 'Text Editor', id: 'window3', type: 'document' }), + createEditorWindow({ title: 'Calculator', id: 'window4', type: 'calculator' }), + createEditorWindow({ title: 'Code Editor', id: 'code-editor', type: 'code' }), + createEditorWindow({ title: 'Document', id: 'document', type: 'document' }), + createEditorWindow({ title: 'Analytics', id: 'analytics', type: 'analytics' }), + createEditorWindow({ title: 'Settings', id: 'settings', type: 'settings' }), + createEditorWindow({ title: 'Layers', id: 'layers', type: 'layers' }), + createEditorWindow({ title: 'Database', id: 'database', type: 'database' }), + createEditorWindow({ title: 'Server', id: 'server', type: 'server' }), + createEditorWindow({ title: 'Terminal', id: 'terminal', type: 'terminal' }), + createEditorWindow({ title: 'Command', id: 'command', type: 'command' }), +].map((window) => ({ ...window, position: windowPositions[window.id] })); diff --git a/src/modules/panels/hooks/use-listen-b.ts b/src/modules/panels/hooks/use-listen-b.ts new file mode 100644 index 0000000..c8dfcf7 --- /dev/null +++ b/src/modules/panels/hooks/use-listen-b.ts @@ -0,0 +1,17 @@ +import { useEffect } from 'react'; +export const isMac = navigator.userAgent.includes('Mac'); + +export const useListenCmdB = (callback: () => void) => { + useEffect(() => { + const handleKeyDown = (event: KeyboardEvent) => { + // Check for Command key on macOS + if (isMac ? event.metaKey && event.key === 'b' : event.ctrlKey && event.key === 'b') { + callback(); + } + }; + window.addEventListener('keydown', handleKeyDown); + return () => { + window.removeEventListener('keydown', handleKeyDown); + }; + }, []); +}; diff --git a/src/modules/panels/index.tsx b/src/modules/panels/index.tsx new file mode 100644 index 0000000..edddc8e --- /dev/null +++ b/src/modules/panels/index.tsx @@ -0,0 +1,2 @@ +import './style.css'; + diff --git a/src/modules/panels/store/index.ts b/src/modules/panels/store/index.ts new file mode 100644 index 0000000..0358344 --- /dev/null +++ b/src/modules/panels/store/index.ts @@ -0,0 +1,119 @@ +import { create } from 'zustand'; +import { WindowData } from '../types'; +import { MyCache } from '@kevisual/cache'; +import { query } from '@/modules/query'; +import { toast } from 'react-toastify'; +import { getDocumentWidthAndHeight } from '../utils/document-width'; +import { produce } from 'immer'; + +interface PanelStore { + data?: PanelData; + setData: (data: PanelData) => void; + init?: (id?: string) => Promise; + id: string; + setId: (id: string) => void; + toggleAICommand: () => void; +} +interface PanelData { + /** + * 窗口列表 + */ + windows: WindowData[]; + /** + * 是否显示任务栏 + */ + showTaskbar: boolean; +} + +export const usePanelStore = create((set, get) => ({ + id: '', + setId: (id: string) => set({ id }), + data: undefined, + setData: (data: PanelData) => set({ data }), + initNewEnv: async (id?: string) => { + const cache = new MyCache(id || 'panel'); + const data = await cache.getData(); + set({ + data: data, + }); + }, + + init: async (id?: string) => { + const cache = new MyCache(id || 'workspace'); + if (id) { + // id存在,则获取本地和获取远程,进行对比,如果需要更新,则更新 + if (cache.data) { + const updatedAt = cache.updatedAt; + const res = await query.post({ path: 'workspace', key: 'env', id, updatedAt }); + if (res.code === 200) { + const newData = res.data; + if (newData) { + cache.setData(newData); + set({ + data: newData, + id: id, + }); + } else { + set({ data: cache.data, id: id }); + } + } else { + toast.error('获取环境失败'); + return; + } + } else { + const res = await query.post({ path: 'workspace', key: 'env', id }); + if (res.code === 200) { + const newData = res.data; + if (newData) { + cache.setData(newData); + set({ + data: newData, + id: id, + }); + } + } + } + } else if (cache.data) { + set({ + data: cache.data, + }); + } else { + set({ + data: { windows: [], showTaskbar: true }, + }); + } + }, + toggleAICommand: () => { + const { data } = get(); + if (!data) { + return; + } + const has = data.windows.find((w) => w.id === '__ai__'); + if (has) { + data.windows = data.windows.map((w) => { + if (w.id === '__ai__') { + return { ...w, show: !w.show }; + } + return w; + }); + } else { + const { width, height } = getDocumentWidthAndHeight(); + data.windows.push({ + id: '__ai__', + title: 'AI Command', + type: 'commandƒ', + position: { + x: 100, + y: height - 200, + width: width - 200, + height: 200, + zIndex: 1000, + }, + resizeHandles: ['se', 'sw', 'ne', 'nw', 's', 'w', 'n', 'e'], + show: true, + }); + } + set({ data: { ...data, windows: data.windows } }); + console.log('data', data); + }, +})); diff --git a/src/modules/panels/style.css b/src/modules/panels/style.css new file mode 100644 index 0000000..77aa626 --- /dev/null +++ b/src/modules/panels/style.css @@ -0,0 +1,132 @@ +@import 'tailwindcss'; +/* Fixed window styles */ +.window { + box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1), 0 2px 4px -1px rgba(0, 0, 0, 0.06); + transition: box-shadow 0.2s ease; + min-width: 300px; + min-height: 200px; +} + +.window.active { + box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.5), 0 10px 15px -3px rgba(0, 0, 0, 0.1); +} + +.window.fullscreen { + border-radius: 0 !important; +} + +.window-container.fullscreen { + position: fixed !important; + top: 0 !important; + left: 0 !important; + right: 0 !important; + bottom: 40px !important; /* Leave space for taskbar */ + width: 100% !important; + height: calc(100% - 40px) !important; + z-index: 9999 !important; +} + +/* Resize handles */ +.react-resizable { + position: relative; +} + +.react-resizable-handle { + position: absolute; + background-color: rgba(0, 0, 0, 0.2); + z-index: 10; +} + +.react-resizable-handle-se { + bottom: 0; + right: 0; + width: 20px; + height: 20px; + cursor: se-resize; + border-top-left-radius: 100%; +} + +.react-resizable-handle-sw { + bottom: 0; + left: 0; + width: 20px; + height: 20px; + cursor: sw-resize; +} + +.react-resizable-handle-nw { + top: 0; + left: 0; + width: 20px; + height: 20px; + cursor: nw-resize; +} + +.react-resizable-handle-ne { + top: 0; + right: 0; + width: 20px; + height: 20px; + cursor: ne-resize; +} + +.react-resizable-handle-w { + top: 50%; + left: 0; + transform: translateY(-50%); + width: 8px; + height: 30px; + cursor: ew-resize; +} + +.react-resizable-handle-e { + top: 50%; + right: 0; + transform: translateY(-50%); + width: 8px; + height: 30px; + cursor: ew-resize; +} + +.react-resizable-handle-n { + top: 0; + left: 50%; + transform: translateX(-50%); + width: 30px; + height: 8px; + cursor: ns-resize; +} + +.react-resizable-handle-s { + bottom: 0; + left: 50%; + transform: translateX(-50%); + width: 30px; + height: 8px; + cursor: ns-resize; +} + +/* Taskbar styles */ +.taskbar { + background-color: #1f2937; + border-top: 1px solid #374151; +} + +/* Window content */ +.window-content { + background-color: white; +} +.react-resizable-handle { + z-index: 1300; /* 确保手柄在其他元素之上 */ + background-color: rgba(0, 0, 0, 0); +} + +.react-resizable-handle-e, +.react-resizable-handle-w { + height: 100%; +} + +.react-resizable-handle-s, +.react-resizable-handle-n { + width: 100%; +} diff --git a/src/modules/panels/types.ts b/src/modules/panels/types.ts new file mode 100644 index 0000000..2df3297 --- /dev/null +++ b/src/modules/panels/types.ts @@ -0,0 +1,51 @@ +import { ResizeHandle } from 'react-resizable'; +export interface WindowPosition { + x: number; + y: number; + width: number; + height: number; + zIndex: number; +} +export interface WindowData { + // 窗口的唯一标识 + id: string; + // 窗口的标题 + title: string; + // 窗口的类型 notebook,command,code,document,image,calculator,welcome,analytics,settings,layers,database,server,terminal + type?: string; + // 是否最小化 + isMinimized?: boolean; + // 是否全屏 + isFullscreen?: boolean; + // 是否显示标题 + showTitle?: boolean; + // 是否显示圆角 + showRounded?: boolean; + // 是否显示在任务栏 + showTaskbar?: boolean; + // 窗口的resize手柄 + resizeHandles?: ResizeHandle[]; + // 窗口的默认位置 + position?: WindowPosition; + // 窗口的默认位置 + defaultPosition?: WindowPosition; + // 是否显示 + show?: boolean; + // 是否显示更多工具 + showMoreTools?: boolean; + // 更多工具 + moreTools?: MoreTool[]; + // 当隐藏窗口存在,只关闭隐藏窗口,不退出程序 + onHidden?: () => void; +} +export interface MoreTool { + // 工具的名称 + title?: string; + description?: string; + path?: string; + key?: string; + // 工具的图标 + icon?: string; + // 工具的点击事件 + onClick?: () => void; +} diff --git a/src/modules/panels/utils/document-width.ts b/src/modules/panels/utils/document-width.ts new file mode 100644 index 0000000..7a1d411 --- /dev/null +++ b/src/modules/panels/utils/document-width.ts @@ -0,0 +1,14 @@ +export const getDocumentWidth = () => { + return document.documentElement.clientWidth; +}; + +export const getDocumentHeight = () => { + return document.documentElement.clientHeight; +}; + +export const getDocumentWidthAndHeight = () => { + return { + width: getDocumentWidth(), + height: getDocumentHeight(), + }; +}; diff --git a/src/modules/tiptap/components/CommandsList.tsx b/src/modules/tiptap/components/CommandsList.tsx new file mode 100644 index 0000000..fe23e00 --- /dev/null +++ b/src/modules/tiptap/components/CommandsList.tsx @@ -0,0 +1,112 @@ +import React, { forwardRef, useEffect, useImperativeHandle, useState } from 'react'; +import { CommandItem } from '../extensions/suggestions/commands'; + +interface CommandsListProps { + items: CommandItem[]; + command: (props: { content: string }) => void; +} + +export const CommandsList = forwardRef((props: CommandsListProps, ref) => { + const [selectedIndex, setSelectedIndex] = useState(0); + + const selectItem = (index: number) => { + const item = props.items[index]; + + if (item) { + props.command({ content: item.content }); + } + }; + + const upHandler = () => { + setSelectedIndex((selectedIndex + props.items.length - 1) % props.items.length); + }; + + const downHandler = () => { + setSelectedIndex((selectedIndex + 1) % props.items.length); + }; + + const enterHandler = () => { + selectItem(selectedIndex); + }; + + useEffect(() => setSelectedIndex(0), [props.items]); + + useImperativeHandle(ref, () => ({ + onKeyDown: ({ event }: { event: KeyboardEvent }) => { + if (event.key === 'ArrowUp') { + upHandler(); + return true; + } + + if (event.key === 'ArrowDown') { + downHandler(); + return true; + } + + if (event.key === 'Enter') { + enterHandler(); + return true; + } + + return false; + }, + })); + + // Scroll to selected item when it changes + useEffect(() => { + const element = document.getElementById(`command-item-${selectedIndex}`); + if (element) { + element.scrollIntoView({ block: 'nearest', behavior: 'smooth' }); + } + }, [selectedIndex]); + + return ( +
+
+
Commands ({props.items.length})
+
Type to filter commands
+
+ +
+ {props.items.length ? ( + props.items.map((item, index) => ( + + )) + ) : ( +
No results
+ )} +
+ +
+ + + + to navigate + + + Enter + to select + +
+
+ ); +}); + +CommandsList.displayName = 'CommandsList'; \ No newline at end of file diff --git a/src/modules/tiptap/components/ReactRenderer.tsx b/src/modules/tiptap/components/ReactRenderer.tsx new file mode 100644 index 0000000..1e17bf5 --- /dev/null +++ b/src/modules/tiptap/components/ReactRenderer.tsx @@ -0,0 +1,42 @@ +import React from 'react'; +import { createRoot } from 'react-dom/client'; + +export class ReactRenderer { + component: any; + element: HTMLElement; + ref: React.RefObject; + props: any; + editor: any; + root: any; + + constructor(component: any, { props, editor }: any) { + this.component = component; + this.element = document.createElement('div'); + this.ref = React.createRef(); + this.props = { + ...props, + ref: this.ref, + }; + this.editor = editor; + this.root = createRoot(this.element); + this.render(); + } + + updateProps(props: any) { + this.props = { + ...this.props, + ...props, + }; + this.render(); + } + + render() { + this.root.render(React.createElement(this.component, this.props)); + } + + destroy() { + this.root.unmount(); + } +} + +export default ReactRenderer; diff --git a/src/modules/tiptap/editor.css b/src/modules/tiptap/editor.css new file mode 100644 index 0000000..f812721 --- /dev/null +++ b/src/modules/tiptap/editor.css @@ -0,0 +1,11 @@ +.ProseMirror p.is-empty::before { + content: attr(data-placeholder); + color: #aaa; /* Adjust the color as needed */ + font-style: italic; /* Optional: make the placeholder italic */ + pointer-events: none; /* Ensure the placeholder is not interactive */ + height: 0; /* Ensure it doesn't affect layout */ + display: block; /* Ensure it displays as a block element */ +} +.tiptap .ProseMirror { + border: none; +} diff --git a/src/modules/tiptap/editor.ts b/src/modules/tiptap/editor.ts index 77126bf..5c095ab 100644 --- a/src/modules/tiptap/editor.ts +++ b/src/modules/tiptap/editor.ts @@ -4,6 +4,8 @@ import Highlight from '@tiptap/extension-highlight'; import Typography from '@tiptap/extension-typography'; import { Markdown } from 'tiptap-markdown'; +import Placeholder from '@tiptap/extension-placeholder'; +import { Commands, getSuggestionItems, createSuggestionConfig } from './extensions/suggestions'; import CodeBlockLowlight from '@tiptap/extension-code-block-lowlight'; import { all, createLowlight } from 'lowlight'; import 'highlight.js/styles/github.css'; @@ -13,6 +15,8 @@ import ts from 'highlight.js/lib/languages/typescript'; import html from 'highlight.js/lib/languages/xml'; import css from 'highlight.js/lib/languages/css'; import markdown from 'highlight.js/lib/languages/markdown'; +import './editor.css'; + const lowlight = createLowlight(all); // you can also register individual languages @@ -31,11 +35,16 @@ export class TextEditor { this.destroy(); } const html = opts?.html || ''; + const items = getSuggestionItems(); + const suggestionConfig = createSuggestionConfig(items); this.editor = new Editor({ element: el, // 指定编辑器容器 extensions: [ StarterKit, // 使用 StarterKit 包含基础功能 Highlight, + Placeholder.configure({ + placeholder: 'Type ! to see commands (e.g., !today, !list, !good)...', + }), Typography, Markdown, CodeBlockLowlight.extend({ @@ -68,6 +77,9 @@ export class TextEditor { }).configure({ lowlight, }), + Commands.configure({ + suggestion: suggestionConfig, + }), ], content: html, // 初始化内容 }); diff --git a/src/modules/tiptap/extensions/suggestions/commands.ts b/src/modules/tiptap/extensions/suggestions/commands.ts new file mode 100644 index 0000000..06600ab --- /dev/null +++ b/src/modules/tiptap/extensions/suggestions/commands.ts @@ -0,0 +1,41 @@ +import { Extension } from '@tiptap/core'; +import Suggestion from '@tiptap/suggestion'; +import { PluginKey } from '@tiptap/pm/state'; + +export const CommandsPluginKey = new PluginKey('commands'); + +export interface CommandItem { + title: string; + description: string; + content: string; +} + +export const Commands = Extension.create({ + name: 'commands', + + addOptions() { + return { + suggestion: { + char: '!', + command: ({ editor, range, props }: any) => { + console.log('sdfsd') + editor + .chain() + .focus() + .deleteRange(range) + .insertContent(props.content) + .run(); + }, + }, + }; + }, + + addProseMirrorPlugins() { + return [ + Suggestion({ + editor: this.editor, + ...this.options.suggestion, + }), + ]; + }, +}); \ No newline at end of file diff --git a/src/modules/tiptap/extensions/suggestions/index.ts b/src/modules/tiptap/extensions/suggestions/index.ts new file mode 100644 index 0000000..ed53886 --- /dev/null +++ b/src/modules/tiptap/extensions/suggestions/index.ts @@ -0,0 +1,3 @@ +export * from './commands'; +export * from './suggestionConfig'; +export * from './suggestionItems'; \ No newline at end of file diff --git a/src/modules/tiptap/extensions/suggestions/suggestionConfig.ts b/src/modules/tiptap/extensions/suggestions/suggestionConfig.ts new file mode 100644 index 0000000..feac6fc --- /dev/null +++ b/src/modules/tiptap/extensions/suggestions/suggestionConfig.ts @@ -0,0 +1,121 @@ +import { CommandItem } from './commands'; +import { CommandsList } from '../../components/CommandsList'; +import ReactRenderer from '../../components/ReactRenderer'; + +export const createSuggestionConfig = (items: CommandItem[]) => { + return { + items: ({ query }: { query: string }) => { + return items.filter(item => item.title.toLowerCase().startsWith(query.toLowerCase())); + }, + render: () => { + let component: ReactRenderer | null = null; + let popup: HTMLElement | null = null; + + const calculatePosition = (view: any, from: number) => { + const coords = view.coordsAtPos(from); + const editorRect = view.dom.getBoundingClientRect(); + const popupRect = popup?.getBoundingClientRect(); + + if (!popup || !popupRect) return { left: coords.left, top: coords.bottom + 10 }; + + // Default position below the cursor + let left = coords.left; + let top = coords.bottom + 10; + + // Check if we're near the bottom of the viewport + const viewportHeight = window.innerHeight; + const bottomSpace = viewportHeight - coords.bottom; + const popupHeight = popupRect.height; + + // If there's not enough space below, position above + if (bottomSpace < popupHeight + 10 && coords.top > popupHeight + 10) { + top = coords.top - popupHeight - 10; + } + + // Check if we're near the right edge of the viewport + const viewportWidth = window.innerWidth; + const rightSpace = viewportWidth - coords.left; + const popupWidth = popupRect.width; + + // If there's not enough space to the right, align right edge + if (rightSpace < popupWidth) { + left = Math.max(10, viewportWidth - popupWidth - 10); + } + + // Ensure popup stays within editor bounds horizontally if possible + if (left < editorRect.left) { + left = editorRect.left; + } + + return { left, top }; + }; + + return { + onStart: (props: any) => { + component = new ReactRenderer(CommandsList, { + props, + editor: props.editor, + }); + + popup = document.createElement('div'); + popup.className = 'commands-popup'; + popup.style.position = 'fixed'; // Use fixed instead of absolute for better viewport positioning + popup.style.zIndex = '1000'; + document.body.appendChild(popup); + + popup.appendChild(component.element); + + // Initial position + const { view } = props.editor; + const { from } = props.range; + + // Set initial position to get popup dimensions + popup.style.left = '0px'; + popup.style.top = '0px'; + + // Calculate proper position after the popup is rendered + setTimeout(() => { + if (!popup) return; + const { left, top } = calculatePosition(view, from); + popup.style.left = `${left}px`; + popup.style.top = `${top}px`; + }, 0); + }, + onUpdate: (props: any) => { + if (!component) return; + + component.updateProps(props); + + if (!popup) return; + + // Update position + const { view } = props.editor; + const { from } = props.range; + const { left, top } = calculatePosition(view, from); + + popup.style.left = `${left}px`; + popup.style.top = `${top}px`; + }, + onKeyDown: (props: any) => { + if (props.event.key === 'Escape') { + if (popup) popup.remove(); + if (component) component.destroy(); + return true; + } + + if (component && component.ref && component.ref.current) { + return component.ref.current.onKeyDown(props); + } + + return false; + }, + onExit: () => { + if (popup) popup.remove(); + if (component) component.destroy(); + component = null; + popup = null; + }, + }; + }, + }; +}; \ No newline at end of file diff --git a/src/modules/tiptap/extensions/suggestions/suggestionItems.ts b/src/modules/tiptap/extensions/suggestions/suggestionItems.ts new file mode 100644 index 0000000..49c4871 --- /dev/null +++ b/src/modules/tiptap/extensions/suggestions/suggestionItems.ts @@ -0,0 +1,203 @@ +import { CommandItem } from './commands'; + +export const getSuggestionItems = (): CommandItem[] => { + // Basic commands + const basicCommands = [ + { + title: 'today', + description: 'Insert today\'s date', + content: new Date().toLocaleDateString(), + }, + { + title: 'now', + description: 'Insert current time', + content: new Date().toLocaleTimeString(), + }, + { + title: 'datetime', + description: 'Insert current date and time', + content: new Date().toLocaleString(), + }, + { + title: 'list', + description: 'Insert a bullet list', + content: '
  • Item 1
  • Item 2
  • Item 3
', + }, + { + title: 'numbered', + description: 'Insert a numbered list', + content: '
  1. First item
  2. Second item
  3. Third item
', + }, + { + title: 'good', + description: 'Insert a positive message', + content: 'Great job! Keep up the good work! 👍', + }, + { + title: 'meeting', + description: 'Insert meeting template', + content: '

Meeting Notes

Date: ' + new Date().toLocaleDateString() + '

Attendees:

  • Person 1
  • Person 2

Agenda:

  1. Topic 1
  2. Topic 2

Action Items:

  • [ ] Task 1
  • [ ] Task 2
', + }, + { + title: 'signature', + description: 'Insert your signature', + content: '

Best regards,
Your Name
your.email@example.com

', + }, + ]; + + // Text formatting commands + const formattingCommands = [ + { + title: 'h1', + description: 'Insert heading 1', + content: '

Heading 1

', + }, + { + title: 'h2', + description: 'Insert heading 2', + content: '

Heading 2

', + }, + { + title: 'h3', + description: 'Insert heading 3', + content: '

Heading 3

', + }, + { + title: 'quote', + description: 'Insert blockquote', + content: '
This is a quote
', + }, + { + title: 'code', + description: 'Insert code block', + content: '
// Your code here\nconsole.log("Hello world");
', + }, + { + title: 'bold', + description: 'Insert bold text', + content: 'Bold text', + }, + { + title: 'italic', + description: 'Insert italic text', + content: 'Italic text', + }, + { + title: 'underline', + description: 'Insert underlined text', + content: 'Underlined text', + }, + { + title: 'strike', + description: 'Insert strikethrough text', + content: 'Strikethrough text', + }, + { + title: 'highlight', + description: 'Insert highlighted text', + content: 'Highlighted text', + }, + ]; + + // Template commands + const templateCommands = [ + { + title: 'email', + description: 'Insert email template', + content: '

Subject: [Your Subject]

Dear [Name],

I hope this email finds you well.

[Your message here]

Thank you for your time and consideration.

Best regards,
Your Name

', + }, + { + title: 'letter', + description: 'Insert formal letter template', + content: '

[Your Name]
[Your Address]
[City, State ZIP]
[Your Email]
[Your Phone]

[Date]

[Recipient Name]
[Recipient Title]
[Company Name]
[Street Address]
[City, State ZIP]

Dear [Recipient Name],

[Letter content]

Sincerely,

[Your Name]

', + }, + { + title: 'report', + description: 'Insert report template', + content: '

Report Title

Date: ' + new Date().toLocaleDateString() + '

Author: Your Name

Executive Summary

[Brief summary of the report]

Introduction

[Introduction text]

Findings

[Detailed findings]

Conclusion

[Conclusion text]

Recommendations

[Recommendations]

', + }, + { + title: 'proposal', + description: 'Insert proposal template', + content: '

Project Proposal

Date: ' + new Date().toLocaleDateString() + '

Prepared by: Your Name

Project Overview

[Brief description of the project]

Objectives

  • [Objective 1]
  • [Objective 2]

Scope of Work

[Detailed scope]

Timeline

[Project timeline]

Budget

[Budget details]

', + }, + { + title: 'invoice', + description: 'Insert invoice template', + content: '

INVOICE

Invoice #: [Number]

Date: ' + new Date().toLocaleDateString() + '

Due Date: [Due Date]

From:
[Your Name/Company]
[Your Address]
[Your Contact Info]
To:
[Client Name/Company]
[Client Address]
DescriptionAmount
[Item/Service Description][Amount]
Total[Total Amount]

Payment Terms: [Terms]

Payment Method: [Method]

', + }, + ]; + + // Task management commands + const taskCommands = [ + { + title: 'todo', + description: 'Insert todo list', + content: '

To-Do List

  • [ ] Task 1
  • [ ] Task 2
  • [ ] Task 3
', + }, + { + title: 'checklist', + description: 'Insert checklist', + content: '

Checklist

  • [ ] Item 1
  • [ ] Item 2
  • [ ] Item 3
', + }, + { + title: 'progress', + description: 'Insert progress tracker', + content: '

Project Progress

  • [x] Planning - Complete
  • [x] Research - Complete
  • [ ] Implementation - In Progress
  • [ ] Testing
  • [ ] Deployment
', + }, + { + title: 'timeline', + description: 'Insert project timeline', + content: '

Project Timeline

  • Week 1: Planning and Research
  • Week 2-3: Design and Development
  • Week 4: Testing
  • Week 5: Deployment
', + }, + { + title: 'goals', + description: 'Insert goals list', + content: '

Goals

  1. Short-term goal 1
  2. Short-term goal 2
  3. Long-term goal 1
  4. Long-term goal 2
', + }, + ]; + + // Table commands + const tableCommands = [ + { + title: 'table2x2', + description: 'Insert 2x2 table', + content: '
Header 1Header 2
Row 1, Cell 1Row 1, Cell 2
Row 2, Cell 1Row 2, Cell 2
', + }, + { + title: 'table3x3', + description: 'Insert 3x3 table', + content: '
Header 1Header 2Header 3
Row 1, Cell 1Row 1, Cell 2Row 1, Cell 3
Row 2, Cell 1Row 2, Cell 2Row 2, Cell 3
Row 3, Cell 1Row 3, Cell 2Row 3, Cell 3
', + }, + { + title: 'schedule', + description: 'Insert schedule table', + content: '
TimeMondayTuesdayWednesdayThursdayFriday
9:00 AM
10:00 AM
11:00 AM
', + }, + { + title: 'comparison', + description: 'Insert comparison table', + content: '
FeatureOption AOption BOption C
Feature 1
Feature 2
Feature 3
Price$$$$$$
', + }, + ]; + + // Additional commands to reach 100 total + const additionalCommands = Array.from({ length: 100 - (basicCommands.length + formattingCommands.length + templateCommands.length + taskCommands.length + tableCommands.length) }, (_, i) => { + const index = i + 1; + return { + title: `command${index}`, + description: `Example command ${index}`, + content: `

This is example command ${index}

`, + }; + }); + + // Combine all command categories + return [ + ...basicCommands, + ...formattingCommands, + ...templateCommands, + ...taskCommands, + ...tableCommands, + ...additionalCommands, + ]; +}; \ No newline at end of file diff --git a/src/modules/tiptap/extensions/suggestions/suggestions.ts b/src/modules/tiptap/extensions/suggestions/suggestions.ts new file mode 100644 index 0000000..49c4871 --- /dev/null +++ b/src/modules/tiptap/extensions/suggestions/suggestions.ts @@ -0,0 +1,203 @@ +import { CommandItem } from './commands'; + +export const getSuggestionItems = (): CommandItem[] => { + // Basic commands + const basicCommands = [ + { + title: 'today', + description: 'Insert today\'s date', + content: new Date().toLocaleDateString(), + }, + { + title: 'now', + description: 'Insert current time', + content: new Date().toLocaleTimeString(), + }, + { + title: 'datetime', + description: 'Insert current date and time', + content: new Date().toLocaleString(), + }, + { + title: 'list', + description: 'Insert a bullet list', + content: '
  • Item 1
  • Item 2
  • Item 3
', + }, + { + title: 'numbered', + description: 'Insert a numbered list', + content: '
  1. First item
  2. Second item
  3. Third item
', + }, + { + title: 'good', + description: 'Insert a positive message', + content: 'Great job! Keep up the good work! 👍', + }, + { + title: 'meeting', + description: 'Insert meeting template', + content: '

Meeting Notes

Date: ' + new Date().toLocaleDateString() + '

Attendees:

  • Person 1
  • Person 2

Agenda:

  1. Topic 1
  2. Topic 2

Action Items:

  • [ ] Task 1
  • [ ] Task 2
', + }, + { + title: 'signature', + description: 'Insert your signature', + content: '

Best regards,
Your Name
your.email@example.com

', + }, + ]; + + // Text formatting commands + const formattingCommands = [ + { + title: 'h1', + description: 'Insert heading 1', + content: '

Heading 1

', + }, + { + title: 'h2', + description: 'Insert heading 2', + content: '

Heading 2

', + }, + { + title: 'h3', + description: 'Insert heading 3', + content: '

Heading 3

', + }, + { + title: 'quote', + description: 'Insert blockquote', + content: '
This is a quote
', + }, + { + title: 'code', + description: 'Insert code block', + content: '
// Your code here\nconsole.log("Hello world");
', + }, + { + title: 'bold', + description: 'Insert bold text', + content: 'Bold text', + }, + { + title: 'italic', + description: 'Insert italic text', + content: 'Italic text', + }, + { + title: 'underline', + description: 'Insert underlined text', + content: 'Underlined text', + }, + { + title: 'strike', + description: 'Insert strikethrough text', + content: 'Strikethrough text', + }, + { + title: 'highlight', + description: 'Insert highlighted text', + content: 'Highlighted text', + }, + ]; + + // Template commands + const templateCommands = [ + { + title: 'email', + description: 'Insert email template', + content: '

Subject: [Your Subject]

Dear [Name],

I hope this email finds you well.

[Your message here]

Thank you for your time and consideration.

Best regards,
Your Name

', + }, + { + title: 'letter', + description: 'Insert formal letter template', + content: '

[Your Name]
[Your Address]
[City, State ZIP]
[Your Email]
[Your Phone]

[Date]

[Recipient Name]
[Recipient Title]
[Company Name]
[Street Address]
[City, State ZIP]

Dear [Recipient Name],

[Letter content]

Sincerely,

[Your Name]

', + }, + { + title: 'report', + description: 'Insert report template', + content: '

Report Title

Date: ' + new Date().toLocaleDateString() + '

Author: Your Name

Executive Summary

[Brief summary of the report]

Introduction

[Introduction text]

Findings

[Detailed findings]

Conclusion

[Conclusion text]

Recommendations

[Recommendations]

', + }, + { + title: 'proposal', + description: 'Insert proposal template', + content: '

Project Proposal

Date: ' + new Date().toLocaleDateString() + '

Prepared by: Your Name

Project Overview

[Brief description of the project]

Objectives

  • [Objective 1]
  • [Objective 2]

Scope of Work

[Detailed scope]

Timeline

[Project timeline]

Budget

[Budget details]

', + }, + { + title: 'invoice', + description: 'Insert invoice template', + content: '

INVOICE

Invoice #: [Number]

Date: ' + new Date().toLocaleDateString() + '

Due Date: [Due Date]

From:
[Your Name/Company]
[Your Address]
[Your Contact Info]
To:
[Client Name/Company]
[Client Address]
DescriptionAmount
[Item/Service Description][Amount]
Total[Total Amount]

Payment Terms: [Terms]

Payment Method: [Method]

', + }, + ]; + + // Task management commands + const taskCommands = [ + { + title: 'todo', + description: 'Insert todo list', + content: '

To-Do List

  • [ ] Task 1
  • [ ] Task 2
  • [ ] Task 3
', + }, + { + title: 'checklist', + description: 'Insert checklist', + content: '

Checklist

  • [ ] Item 1
  • [ ] Item 2
  • [ ] Item 3
', + }, + { + title: 'progress', + description: 'Insert progress tracker', + content: '

Project Progress

  • [x] Planning - Complete
  • [x] Research - Complete
  • [ ] Implementation - In Progress
  • [ ] Testing
  • [ ] Deployment
', + }, + { + title: 'timeline', + description: 'Insert project timeline', + content: '

Project Timeline

  • Week 1: Planning and Research
  • Week 2-3: Design and Development
  • Week 4: Testing
  • Week 5: Deployment
', + }, + { + title: 'goals', + description: 'Insert goals list', + content: '

Goals

  1. Short-term goal 1
  2. Short-term goal 2
  3. Long-term goal 1
  4. Long-term goal 2
', + }, + ]; + + // Table commands + const tableCommands = [ + { + title: 'table2x2', + description: 'Insert 2x2 table', + content: '
Header 1Header 2
Row 1, Cell 1Row 1, Cell 2
Row 2, Cell 1Row 2, Cell 2
', + }, + { + title: 'table3x3', + description: 'Insert 3x3 table', + content: '
Header 1Header 2Header 3
Row 1, Cell 1Row 1, Cell 2Row 1, Cell 3
Row 2, Cell 1Row 2, Cell 2Row 2, Cell 3
Row 3, Cell 1Row 3, Cell 2Row 3, Cell 3
', + }, + { + title: 'schedule', + description: 'Insert schedule table', + content: '
TimeMondayTuesdayWednesdayThursdayFriday
9:00 AM
10:00 AM
11:00 AM
', + }, + { + title: 'comparison', + description: 'Insert comparison table', + content: '
FeatureOption AOption BOption C
Feature 1
Feature 2
Feature 3
Price$$$$$$
', + }, + ]; + + // Additional commands to reach 100 total + const additionalCommands = Array.from({ length: 100 - (basicCommands.length + formattingCommands.length + templateCommands.length + taskCommands.length + tableCommands.length) }, (_, i) => { + const index = i + 1; + return { + title: `command${index}`, + description: `Example command ${index}`, + content: `

This is example command ${index}

`, + }; + }); + + // Combine all command categories + return [ + ...basicCommands, + ...formattingCommands, + ...templateCommands, + ...taskCommands, + ...tableCommands, + ...additionalCommands, + ]; +}; \ No newline at end of file diff --git a/src/pages/wall/docs.ts b/src/pages/wall/docs.ts index fa8f9f5..1ba8f1e 100644 --- a/src/pages/wall/docs.ts +++ b/src/pages/wall/docs.ts @@ -1,2 +1,13 @@ // wallnote v1版工作区(/workspace/wallnote) -export const DOCS_NODE = [{"id":"e15owpuh9cv3fgwx5zymtc","position":{"x":-1613.6078090729259,"y":-726.9366215444888},"data":{"html":"

Wallnote 基本使用介绍 v0.0.7

可拖拽的随笔记功能。

  • 纯网页界面,数据存储在浏览器(不登陆情况下,只有单个页面)

  • 这个墙随便拖动

  • 双击空格添加一条记录,并打开编辑,esc关闭

  • 富文本编辑器(md语法)

  • 点击节点聚焦后,delete删除

  • 右键空白处粘贴

    • html的内容,编辑会丢失样式

    • 图片的内容(粘贴后不能编辑)

    • 文本内容

    • 复制的节点信息

  • 边框可拖动大小

注意

  • 点击节点聚焦后,如果有滚动条,节点内容才能滚动

  • 图片复制,只能是二进制,文件夹的图片复制后无效。比如snipaste 贴图复制(Can To Do)。

登录后功能

  • 保存而不是临时编辑

新版

![ai-workspace](https://kevisual.xiongxiao.me/workspace/wallnote/)

TODO

  • do do do

  • ai ++++

","width":1113,"height":444},"type":"wallnote"},{"id":"kb0vbz4ffi1x6aw8clo0ho","position":{"x":-1613.4790358693674,"y":-256.0352475384902},"data":{"width":356,"height":50,"html":"wallnote v1版工作区(/workspace/wallnote)"},"type":"wallnote"}] \ No newline at end of file +export const DOCS_NODE = [ + { + id: 'e15owpuh9cv3fgwx5zymtc', + position: { x: -1498.479327713264, y: -734.7581188564604 }, + data: { + html: '

Wallnote 基本使用介绍 v0.1.0

可拖拽的随笔记功能。

  • 这个墙随便拖动

  • 双击空的地方添加一条文本记录,并打开编辑,esc关闭

  • 富文本编辑器(md语法)

  • 点击节点聚焦后,delete删除

  • 右键空白处粘贴

    • html的内容,编辑会丢失样式

    • 图片的内容(粘贴后不能编辑)

    • 文本内容

    • 复制的节点信息

  • 边框可拖动大小

注意

  • 点击节点聚焦后,如果有滚动条,节点内容才能滚动

  • 图片复制,只能是二进制,文件夹的图片复制后无效,读不到文件。比如snipaste 贴图复制。

', + width: 1113, + height: 444, + }, + type: 'wallnote', + }, +]; diff --git a/src/pages/wall/index.tsx b/src/pages/wall/index.tsx index 88ae93a..f7a015e 100644 --- a/src/pages/wall/index.tsx +++ b/src/pages/wall/index.tsx @@ -25,7 +25,7 @@ import { message } from '@/modules/message'; import { useShallow } from 'zustand/react/shallow'; import { BlankNoteText } from './constants'; import { Toolbar } from './modules/toolbar/Toolbar'; -import { useNavigate, useParams } from 'react-router-dom'; +// import { useNavigate, useParams } from 'react-router-dom'; import { SaveModal } from './modules/FormDialog'; import { useTabNode } from './hooks/tab-node'; import { Button } from '@mui/material'; @@ -210,8 +210,9 @@ export function FlowContent() { ); } export const Flow = ({ checkLogin = true }: { checkLogin?: boolean }) => { - const { id } = useParams(); - const navigate = useNavigate(); + // const { id } = useParams(); + const id = ''; + // const navigate = useNavigate(); const wallStore = useWallStore( useShallow((state) => { return { @@ -236,7 +237,7 @@ export const Flow = ({ checkLogin = true }: { checkLogin?: boolean }) => {