From d805d9f7e406fa9a178aa23093d97181edeba074 Mon Sep 17 00:00:00 2001 From: Caio Pizzol Date: Fri, 21 Nov 2025 17:54:39 -0300 Subject: [PATCH 1/2] feat: enhance field management with grouping and improved UI - Introduced grouping functionality for fields in FieldList component. - Added FieldItem component for better encapsulation of field rendering logic. - Implemented expand/collapse feature for grouped fields. - Enhanced styling for field items and group headers for better UX. - Updated FieldMenu to support selection of existing fields with grouping. - Modified TemplateField type to include group property for better organization. - Improved overall code structure and readability. --- demo/package.json | 4 +- demo/pnpm-lock.yaml | 23 +-- demo/src/App.tsx | 25 +-- package.json | 6 +- pnpm-lock.yaml | 384 +++++++++++++++++++------------------ src/defaults/FieldList.tsx | 332 +++++++++++++++++++++----------- src/defaults/FieldMenu.tsx | 306 +++++++++++++++++------------ src/index.tsx | 162 ++++++++++------ src/types.ts | 15 +- 9 files changed, 746 insertions(+), 511 deletions(-) diff --git a/demo/package.json b/demo/package.json index fd56d0d..9b9f87a 100644 --- a/demo/package.json +++ b/demo/package.json @@ -11,7 +11,7 @@ "@superdoc-dev/template-builder": "link:../.", "react": "^19.2.0", "react-dom": "^19.2.0", - "superdoc": "^0.29.0" + "superdoc": "^0.31.2" }, "devDependencies": { "@types/react": "^19.2.6", @@ -20,4 +20,4 @@ "typescript": "^5.9.3", "vite": "^7.2.2" } -} +} \ No newline at end of file diff --git a/demo/pnpm-lock.yaml b/demo/pnpm-lock.yaml index fe929a9..bae0666 100644 --- a/demo/pnpm-lock.yaml +++ b/demo/pnpm-lock.yaml @@ -18,8 +18,8 @@ importers: specifier: ^19.2.0 version: 19.2.0(react@19.2.0) superdoc: - specifier: ^0.29.0 - version: 0.29.0(@hocuspocus/provider@2.15.3(y-protocols@1.0.6(yjs@13.6.19))(yjs@13.6.19))(canvas@2.11.2)(pdfjs-dist@4.6.82)(typescript@5.9.3)(y-prosemirror@1.3.7(prosemirror-model@1.25.3)(prosemirror-state@1.4.3)(prosemirror-view@1.41.3)(y-protocols@1.0.6(yjs@13.6.19))(yjs@13.6.19))(yjs@13.6.19) + specifier: ^0.31.2 + version: 0.31.2(@hocuspocus/provider@2.15.3(y-protocols@1.0.6(yjs@13.6.19))(yjs@13.6.19))(canvas@2.11.2)(pdfjs-dist@4.6.82)(typescript@5.9.3)(y-prosemirror@1.3.7(prosemirror-model@1.25.3)(prosemirror-state@1.4.3)(prosemirror-view@1.41.3)(y-protocols@1.0.6(yjs@13.6.19))(yjs@13.6.19))(yjs@13.6.19) devDependencies: '@types/react': specifier: ^19.2.6 @@ -687,9 +687,6 @@ packages: csstype@3.0.11: resolution: {integrity: sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw==} - csstype@3.1.3: - resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} - csstype@3.2.3: resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} @@ -1252,8 +1249,8 @@ packages: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} - superdoc@0.29.0: - resolution: {integrity: sha512-twxGy5/CNkPpplzhCk0VmvdI9goJkZwjiBBijNHHrsfT0LK3b7qQ5gBlV8IUR1/9/E8VtsfRHSKueBH8AlOtAQ==} + superdoc@0.31.2: + resolution: {integrity: sha512-3mWHJnww23UQKiuNZqVX+Gv14on11UuSZYNpHJ7GmTFeXvTF+aakFU+Z8sZGq6ZPhq2vlVreR6hZ8V2MXnHMEA==} peerDependencies: '@hocuspocus/provider': ^2.13.6 pdfjs-dist: '>=4.3.136 <=4.6.82' @@ -1930,7 +1927,7 @@ snapshots: '@vue/compiler-core@3.5.22': dependencies: - '@babel/parser': 7.28.4 + '@babel/parser': 7.28.5 '@vue/shared': 3.5.22 entities: 4.5.0 estree-walker: 2.0.2 @@ -1943,7 +1940,7 @@ snapshots: '@vue/compiler-sfc@3.5.22': dependencies: - '@babel/parser': 7.28.4 + '@babel/parser': 7.28.5 '@vue/compiler-core': 3.5.22 '@vue/compiler-dom': 3.5.22 '@vue/compiler-ssr': 3.5.22 @@ -1974,7 +1971,7 @@ snapshots: '@vue/reactivity': 3.5.22 '@vue/runtime-core': 3.5.22 '@vue/shared': 3.5.22 - csstype: 3.1.3 + csstype: 3.2.3 '@vue/server-renderer@3.5.22(vue@3.5.22(typescript@5.9.3))': dependencies: @@ -2085,8 +2082,6 @@ snapshots: csstype@3.0.11: {} - csstype@3.1.3: {} - csstype@3.2.3: {} data-urls@5.0.0: @@ -2485,7 +2480,7 @@ snapshots: '@types/lodash-es': 4.17.12 async-validator: 4.2.5 css-render: 0.15.14 - csstype: 3.1.3 + csstype: 3.2.3 date-fns: 3.6.0 date-fns-tz: 3.2.0(date-fns@3.6.0) evtd: 0.2.4 @@ -2722,7 +2717,7 @@ snapshots: ansi-regex: 5.0.1 optional: true - superdoc@0.29.0(@hocuspocus/provider@2.15.3(y-protocols@1.0.6(yjs@13.6.19))(yjs@13.6.19))(canvas@2.11.2)(pdfjs-dist@4.6.82)(typescript@5.9.3)(y-prosemirror@1.3.7(prosemirror-model@1.25.3)(prosemirror-state@1.4.3)(prosemirror-view@1.41.3)(y-protocols@1.0.6(yjs@13.6.19))(yjs@13.6.19))(yjs@13.6.19): + superdoc@0.31.2(@hocuspocus/provider@2.15.3(y-protocols@1.0.6(yjs@13.6.19))(yjs@13.6.19))(canvas@2.11.2)(pdfjs-dist@4.6.82)(typescript@5.9.3)(y-prosemirror@1.3.7(prosemirror-model@1.25.3)(prosemirror-state@1.4.3)(prosemirror-view@1.41.3)(y-protocols@1.0.6(yjs@13.6.19))(yjs@13.6.19))(yjs@13.6.19): dependencies: '@hocuspocus/provider': 2.15.3(y-protocols@1.0.6(yjs@13.6.19))(yjs@13.6.19) buffer-crc32: 1.0.0 diff --git a/demo/src/App.tsx b/demo/src/App.tsx index 65e4a49..b94600c 100644 --- a/demo/src/App.tsx +++ b/demo/src/App.tsx @@ -9,24 +9,13 @@ import "superdoc/dist/style.css"; import "./App.css"; const availableFields: FieldDefinition[] = [ - // Agreement - { id: '1242142770', label: 'Agreement Date', category: 'Agreement' }, - - // Parties - { id: '1242142771', label: 'User Name', category: 'Parties' }, - { id: '1242142772', label: 'Company Name', category: 'Parties' }, - - // Scope - { id: '1242142773', label: 'Service Type', category: 'Scope' }, - - // Legal - { id: '1242142774', label: 'Agreement Jurisdiction', category: 'Legal' }, - - // Company Details - { id: '1242142775', label: 'Company Address', category: 'Company' }, - - // Signatures - { id: '1242142776', label: 'Signature', category: 'Signatures' }, + { id: '1242142770', label: 'Agreement Date' }, + { id: '1242142771', label: 'User Name' }, + { id: '1242142772', label: 'Company Name' }, + { id: '1242142773', label: 'Service Type' }, + { id: '1242142774', label: 'Agreement Jurisdiction' }, + { id: '1242142775', label: 'Company Address' }, + { id: '1242142776', label: 'Signature' }, ]; export function App() { diff --git a/package.json b/package.json index 3671da1..62e0250 100644 --- a/package.json +++ b/package.json @@ -52,7 +52,7 @@ "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0", - "superdoc": "^0.29.0" + "superdoc": "^0.31.2" }, "devDependencies": { "@commitlint/cli": "^20.1.0", @@ -78,9 +78,9 @@ "semantic-release": "^25.0.2", "typescript": "^5.9.3", "typescript-eslint": "^8.47.0", - "vite": "^7.2.2", + "vite": "^7.2.4", "vite-plugin-dts": "^4.5.4", - "vitest": "^4.0.10" + "vitest": "^4.0.13" }, "publishConfig": { "access": "public" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index afa3645..3c0c625 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,8 +9,8 @@ importers: .: dependencies: superdoc: - specifier: ^0.29.0 - version: 0.29.0(@hocuspocus/provider@2.15.3(y-protocols@1.0.6(yjs@13.6.19))(yjs@13.6.19))(pdfjs-dist@4.6.82)(typescript@5.9.3)(y-prosemirror@1.3.7(prosemirror-model@1.25.3)(prosemirror-state@1.4.3)(prosemirror-view@1.41.3)(y-protocols@1.0.6(yjs@13.6.19))(yjs@13.6.19))(yjs@13.6.19) + specifier: ^0.31.2 + version: 0.31.2(@hocuspocus/provider@2.15.3(y-protocols@1.0.6(yjs@13.6.19))(yjs@13.6.19))(pdfjs-dist@4.6.82)(typescript@5.9.3)(y-prosemirror@1.3.7(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.3)(y-protocols@1.0.6(yjs@13.6.19))(yjs@13.6.19))(yjs@13.6.19) devDependencies: '@commitlint/cli': specifier: ^20.1.0 @@ -47,7 +47,7 @@ importers: version: 19.2.3(@types/react@19.2.6) '@vitejs/plugin-react': specifier: ^5.1.1 - version: 5.1.1(vite@7.2.2(@types/node@24.10.1)(jiti@2.6.1)) + version: 5.1.1(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)) eslint: specifier: ^9.39.1 version: 9.39.1(jiti@2.6.1) @@ -82,14 +82,14 @@ importers: specifier: ^8.47.0 version: 8.47.0(eslint@9.39.1(jiti@2.6.1))(typescript@5.9.3) vite: - specifier: ^7.2.2 - version: 7.2.2(@types/node@24.10.1)(jiti@2.6.1) + specifier: ^7.2.4 + version: 7.2.4(@types/node@24.10.1)(jiti@2.6.1) vite-plugin-dts: specifier: ^4.5.4 - version: 4.5.4(@types/node@24.10.1)(rollup@4.52.4)(typescript@5.9.3)(vite@7.2.2(@types/node@24.10.1)(jiti@2.6.1)) + version: 4.5.4(@types/node@24.10.1)(rollup@4.52.4)(typescript@5.9.3)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)) vitest: - specifier: ^4.0.10 - version: 4.0.10(@types/node@24.10.1)(jiti@2.6.1)(jsdom@27.2.0(postcss@8.5.6)) + specifier: ^4.0.13 + version: 4.0.13(@types/node@24.10.1)(jiti@2.6.1)(jsdom@27.2.0(postcss@8.5.6)) packages: @@ -1073,11 +1073,11 @@ packages: peerDependencies: vite: ^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 - '@vitest/expect@4.0.10': - resolution: {integrity: sha512-3QkTX/lK39FBNwARCQRSQr0TP9+ywSdxSX+LgbJ2M1WmveXP72anTbnp2yl5fH+dU6SUmBzNMrDHs80G8G2DZg==} + '@vitest/expect@4.0.13': + resolution: {integrity: sha512-zYtcnNIBm6yS7Gpr7nFTmq8ncowlMdOJkWLqYvhr/zweY6tFbDkDi8BPPOeHxEtK1rSI69H7Fd4+1sqvEGli6w==} - '@vitest/mocker@4.0.10': - resolution: {integrity: sha512-e2OfdexYkjkg8Hh3L9NVEfbwGXq5IZbDovkf30qW2tOh7Rh9sVtmSr2ztEXOFbymNxS4qjzLXUQIvATvN4B+lg==} + '@vitest/mocker@4.0.13': + resolution: {integrity: sha512-eNCwzrI5djoauklwP1fuslHBjrbR8rqIVbvNlAnkq1OTa6XT+lX68mrtPirNM9TnR69XUPt4puBCx2Wexseylg==} peerDependencies: msw: ^2.4.9 vite: ^6.0.0 || ^7.0.0-0 @@ -1087,20 +1087,20 @@ packages: vite: optional: true - '@vitest/pretty-format@4.0.10': - resolution: {integrity: sha512-99EQbpa/zuDnvVjthwz5bH9o8iPefoQZ63WV8+bsRJZNw3qQSvSltfut8yu1Jc9mqOYi7pEbsKxYTi/rjaq6PA==} + '@vitest/pretty-format@4.0.13': + resolution: {integrity: sha512-ooqfze8URWbI2ozOeLDMh8YZxWDpGXoeY3VOgcDnsUxN0jPyPWSUvjPQWqDGCBks+opWlN1E4oP1UYl3C/2EQA==} - '@vitest/runner@4.0.10': - resolution: {integrity: sha512-EXU2iSkKvNwtlL8L8doCpkyclw0mc/t4t9SeOnfOFPyqLmQwuceMPA4zJBa6jw0MKsZYbw7kAn+gl7HxrlB8UQ==} + '@vitest/runner@4.0.13': + resolution: {integrity: sha512-9IKlAru58wcVaWy7hz6qWPb2QzJTKt+IOVKjAx5vb5rzEFPTL6H4/R9BMvjZ2ppkxKgTrFONEJFtzvnyEpiT+A==} - '@vitest/snapshot@4.0.10': - resolution: {integrity: sha512-2N4X2ZZl7kZw0qeGdQ41H0KND96L3qX1RgwuCfy6oUsF2ISGD/HpSbmms+CkIOsQmg2kulwfhJ4CI0asnZlvkg==} + '@vitest/snapshot@4.0.13': + resolution: {integrity: sha512-hb7Usvyika1huG6G6l191qu1urNPsq1iFc2hmdzQY3F5/rTgqQnwwplyf8zoYHkpt7H6rw5UfIw6i/3qf9oSxQ==} - '@vitest/spy@4.0.10': - resolution: {integrity: sha512-AsY6sVS8OLb96GV5RoG8B6I35GAbNrC49AO+jNRF9YVGb/g9t+hzNm1H6kD0NDp8tt7VJLs6hb7YMkDXqu03iw==} + '@vitest/spy@4.0.13': + resolution: {integrity: sha512-hSu+m4se0lDV5yVIcNWqjuncrmBgwaXa2utFLIrBkQCQkt+pSwyZTPFQAZiiF/63j8jYa8uAeUZ3RSfcdWaYWw==} - '@vitest/utils@4.0.10': - resolution: {integrity: sha512-kOuqWnEwZNtQxMKg3WmPK1vmhZu9WcoX69iwWjVz+jvKTsF1emzsv3eoPcDr6ykA3qP2bsCQE7CwqfNtAVzsmg==} + '@vitest/utils@4.0.13': + resolution: {integrity: sha512-ydozWyQ4LZuu8rLp47xFUWis5VOKMdHjXCWhs1LuJsTNKww+pTHQNK4e0assIB9K80TxFyskENL6vCu3j34EYA==} '@volar/language-core@2.4.23': resolution: {integrity: sha512-hEEd5ET/oSmBC6pi1j6NaNYRWoAiDhINbT8rmwtINugR39loROSlufGdYMF9TaKGfz+ViGs1Idi3mAhnuPcoGQ==} @@ -1114,14 +1114,20 @@ packages: '@vue/compiler-core@3.5.22': resolution: {integrity: sha512-jQ0pFPmZwTEiRNSb+i9Ow/I/cHv2tXYqsnHKKyCQ08irI2kdF5qmYedmF8si8mA7zepUFmJ2hqzS8CQmNOWOkQ==} + '@vue/compiler-core@3.5.24': + resolution: {integrity: sha512-eDl5H57AOpNakGNAkFDH+y7kTqrQpJkZFXhWZQGyx/5Wh7B1uQYvcWkvZi11BDhscPgj8N7XV3oRwiPnx1Vrig==} + '@vue/compiler-dom@3.5.22': resolution: {integrity: sha512-W8RknzUM1BLkypvdz10OVsGxnMAuSIZs9Wdx1vzA3mL5fNMN15rhrSCLiTm6blWeACwUwizzPVqGJgOGBEN/hA==} - '@vue/compiler-sfc@3.5.22': - resolution: {integrity: sha512-tbTR1zKGce4Lj+JLzFXDq36K4vcSZbJ1RBu8FxcDv1IGRz//Dh2EBqksyGVypz3kXpshIfWKGOCcqpSbyGWRJQ==} + '@vue/compiler-dom@3.5.24': + resolution: {integrity: sha512-1QHGAvs53gXkWdd3ZMGYuvQFXHW4ksKWPG8HP8/2BscrbZ0brw183q2oNWjMrSWImYLHxHrx1ItBQr50I/q2zw==} + + '@vue/compiler-sfc@3.5.24': + resolution: {integrity: sha512-8EG5YPRgmTB+YxYBM3VXy8zHD9SWHUJLIGPhDovo3Z8VOgvP+O7UP5vl0J4BBPWYD9vxtBabzW1EuEZ+Cqs14g==} - '@vue/compiler-ssr@3.5.22': - resolution: {integrity: sha512-GdgyLvg4R+7T8Nk2Mlighx7XGxq/fJf9jaVofc3IL0EPesTE86cP/8DD1lT3h1JeZr2ySBvyqKQJgbS54IX1Ww==} + '@vue/compiler-ssr@3.5.24': + resolution: {integrity: sha512-trOvMWNBMQ/odMRHW7Ae1CdfYx+7MuiQu62Jtu36gMLXcaoqKvAyh+P73sYG9ll+6jLB6QPovqoKGGZROzkFFg==} '@vue/compiler-vue2@2.7.16': resolution: {integrity: sha512-qYC3Psj9S/mfu9uVi5WvNZIzq+xnXMhOwbTFKKDD7b1lhpnn71jXSFdTQ+WsIEk0ONCd7VV2IMm7ONl6tbQ86A==} @@ -1137,23 +1143,26 @@ packages: typescript: optional: true - '@vue/reactivity@3.5.22': - resolution: {integrity: sha512-f2Wux4v/Z2pqc9+4SmgZC1p73Z53fyD90NFWXiX9AKVnVBEvLFOWCEgJD3GdGnlxPZt01PSlfmLqbLYzY/Fw4A==} + '@vue/reactivity@3.5.24': + resolution: {integrity: sha512-BM8kBhtlkkbnyl4q+HiF5R5BL0ycDPfihowulm02q3WYp2vxgPcJuZO866qa/0u3idbMntKEtVNuAUp5bw4teg==} - '@vue/runtime-core@3.5.22': - resolution: {integrity: sha512-EHo4W/eiYeAzRTN5PCextDUZ0dMs9I8mQ2Fy+OkzvRPUYQEyK9yAjbasrMCXbLNhF7P0OUyivLjIy0yc6VrLJQ==} + '@vue/runtime-core@3.5.24': + resolution: {integrity: sha512-RYP/byyKDgNIqfX/gNb2PB55dJmM97jc9wyF3jK7QUInYKypK2exmZMNwnjueWwGceEkP6NChd3D2ZVEp9undQ==} - '@vue/runtime-dom@3.5.22': - resolution: {integrity: sha512-Av60jsryAkI023PlN7LsqrfPvwfxOd2yAwtReCjeuugTJTkgrksYJJstg1e12qle0NarkfhfFu1ox2D+cQotww==} + '@vue/runtime-dom@3.5.24': + resolution: {integrity: sha512-Z8ANhr/i0XIluonHVjbUkjvn+CyrxbXRIxR7wn7+X7xlcb7dJsfITZbkVOeJZdP8VZwfrWRsWdShH6pngMxRjw==} - '@vue/server-renderer@3.5.22': - resolution: {integrity: sha512-gXjo+ao0oHYTSswF+a3KRHZ1WszxIqO7u6XwNHqcqb9JfyIL/pbWrrh/xLv7jeDqla9u+LK7yfZKHih1e1RKAQ==} + '@vue/server-renderer@3.5.24': + resolution: {integrity: sha512-Yh2j2Y4G/0/4z/xJ1Bad4mxaAk++C2v4kaa8oSYTMJBJ00/ndPuxCnWeot0/7/qafQFLh5pr6xeV6SdMcE/G1w==} peerDependencies: - vue: 3.5.22 + vue: 3.5.24 '@vue/shared@3.5.22': resolution: {integrity: sha512-F4yc6palwq3TT0u+FYf0Ns4Tfl9GRFURDN2gWG7L1ecIaS/4fCIuFOjMTnCyjsu/OK6vaDKLCrGAa+KvvH+h4w==} + '@vue/shared@3.5.24': + resolution: {integrity: sha512-9cwHL2EsJBdi8NY22pngYYWzkTDhld6fAD6jlaeloNGciNSJL6bLpbxVgXl96X00Jtc6YWQv96YA/0sxex/k1A==} + JSONStream@1.3.5: resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} hasBin: true @@ -1564,9 +1573,6 @@ packages: csstype@3.0.11: resolution: {integrity: sha512-sa6P2wJ+CAbgyy4KFssIb/JNMLxFvKF1pCYCSXS8ZMuqZnMsrxqI2E5sPyoTpxoPU/gVZMzr2zjOfg8GIZOMsw==} - csstype@3.1.3: - resolution: {integrity: sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==} - csstype@3.2.3: resolution: {integrity: sha512-z1HGKcYy2xA8AGQfwrn0PAy+PB7X/GSj3UVJW9qKyn43xWa+gl5nXmU4qqLMRzWVLFC8KusUX8T/0kCiOYpAIQ==} @@ -1599,8 +1605,8 @@ packages: peerDependencies: date-fns: ^3.0.0 || ^4.0.0 - date-fns@3.6.0: - resolution: {integrity: sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==} + date-fns@4.1.0: + resolution: {integrity: sha512-Ukq0owbQXxa/U3EGtsdVBkR1w7KOQ5gIBqdH2hkvknzZPYvBxb/aa6E8L7tmjFtkwZBu3UXBbjIgPo/Ez4xaNg==} de-indent@1.0.2: resolution: {integrity: sha512-e/1zu3xH5MQryN2zdVaF0OrdNLUbvWxzMbi+iNA6Bky7l1RoP8a2fIbRocyHclXt/arDrrR6lL3TqFD9pMQTsg==} @@ -1930,8 +1936,8 @@ packages: resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} engines: {node: '>= 0.4'} - form-data@4.0.4: - resolution: {integrity: sha512-KrGhL9Q4zjj0kiUt5OO4Mr/A/jlI2jDYs5eHBpYHPcBEVSiipAvn2Ko2HnPe20rmcuuvMHNdZFp+4IlGTMF0Ow==} + form-data@4.0.5: + resolution: {integrity: sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==} engines: {node: '>= 6'} from2@2.3.0: @@ -2699,13 +2705,13 @@ packages: mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} - naive-ui@2.43.1: - resolution: {integrity: sha512-w52W0mOhdOGt4uucFSZmP0DI44PCsFyuxeLSs9aoUThfIuxms90MYjv46Qrr7xprjyJRw5RU6vYpCx4o9ind3A==} + naive-ui@2.43.2: + resolution: {integrity: sha512-YlLMnGrwGTOc+zMj90sG3ubaH5/7czsgLgGcjTLA981IUaz8r6t4WIujNt8r9PNr+dqv6XNEr0vxkARgPPjfBQ==} peerDependencies: vue: ^3.0.0 - nan@2.23.0: - resolution: {integrity: sha512-1UxuyYGdoQHcGg87Lkqm3FzefucTa0NAiOcuRsDmysep3c1LVCRK2krrUDafMWtjSG04htvAmvg96+SDknOmgQ==} + nan@2.23.1: + resolution: {integrity: sha512-r7bBUGKzlqk8oPBDYxt6Z0aEdF1G1rwlMcLk8LCOMbOzf0mG+JUfUzG4fIMWwHWP0iyaLWEQZJmtB7nOHEm/qw==} nanoid@3.3.11: resolution: {integrity: sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==} @@ -3091,14 +3097,14 @@ packages: prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} - prosemirror-model@1.25.3: - resolution: {integrity: sha512-dY2HdaNXlARknJbrManZ1WyUtos+AP97AmvqdOQtWtrrC5g4mohVX5DTi9rXNFSk09eczLq9GuNTtq3EfMeMGA==} + prosemirror-model@1.25.4: + resolution: {integrity: sha512-PIM7E43PBxKce8OQeezAs9j4TP+5yDpZVbuurd1h5phUxEKIu+G2a+EUZzIC5nS1mJktDJWzbqS23n1tsAf5QA==} - prosemirror-state@1.4.3: - resolution: {integrity: sha512-goFKORVbvPuAQaXhpbemJFRKJ2aixr+AZMGiquiqKxaucC6hlpHNZHWgz5R7dS4roHiwq9vDctE//CZ++o0W1Q==} + prosemirror-state@1.4.4: + resolution: {integrity: sha512-6jiYHH2CIGbCfnxdHbXZ12gySFY/fz/ulZE333G6bPqIZ4F+TXo9ifiR86nAHpWnfoNjOb3o5ESi7J8Uz1jXHw==} - prosemirror-transform@1.10.4: - resolution: {integrity: sha512-pwDy22nAnGqNR1feOQKHxoFkkUtepoFAd3r2hbEDsnf4wp57kKA36hXsB3njA9FtONBEwSDnDeCiJe+ItD+ykw==} + prosemirror-transform@1.10.5: + resolution: {integrity: sha512-RPDQCxIDhIBb1o36xxwsaeAvivO8VLJcgBtzmOwQ64bMtsVFh5SSuJ6dWSxO1UsHTiTXPCgQm3PDJt7p6IOLbw==} prosemirror-view@1.41.3: resolution: {integrity: sha512-SqMiYMUQNNBP9kfPhLO8WXEk/fon47vc52FQsUiJzTBuyjKgEcoAwMyF04eQ4WZ2ArMn7+ReypYL60aKngbACQ==} @@ -3237,9 +3243,6 @@ packages: safe-buffer@5.1.2: resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} - safe-buffer@5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - safe-push-apply@1.0.0: resolution: {integrity: sha512-iKE9w/Z7xCzUMIZqdBsp6pEQvwuEebH4vdpjcDWnyzaI6yl6O9FHvVpmGelvEHNsoY6wGblkxR6Zty/h00WiSA==} engines: {node: '>= 0.4'} @@ -3436,9 +3439,6 @@ packages: string_decoder@1.1.1: resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} - string_decoder@1.3.0: - resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} - strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} @@ -3479,8 +3479,8 @@ packages: resolution: {integrity: sha512-CY8u7DtbvucKuquCmOFEKhr9Besln7n9uN8eFbwcoGYWXOMW07u2o8njWaiXt11ylS3qoGF55pILjRmPlbodyg==} engines: {node: '>=18'} - superdoc@0.29.0: - resolution: {integrity: sha512-twxGy5/CNkPpplzhCk0VmvdI9goJkZwjiBBijNHHrsfT0LK3b7qQ5gBlV8IUR1/9/E8VtsfRHSKueBH8AlOtAQ==} + superdoc@0.31.2: + resolution: {integrity: sha512-3mWHJnww23UQKiuNZqVX+Gv14on11UuSZYNpHJ7GmTFeXvTF+aakFU+Z8sZGq6ZPhq2vlVreR6hZ8V2MXnHMEA==} peerDependencies: '@hocuspocus/provider': ^2.13.6 pdfjs-dist: '>=4.3.136 <=4.6.82' @@ -3758,8 +3758,8 @@ packages: vite: optional: true - vite@7.2.2: - resolution: {integrity: sha512-BxAKBWmIbrDgrokdGZH1IgkIk/5mMHDreLDmCJ0qpyJaAteP8NvMhkwr/ZCQNqNH97bw/dANTE9PDzqwJghfMQ==} + vite@7.2.4: + resolution: {integrity: sha512-NL8jTlbo0Tn4dUEXEsUg8KeyG/Lkmc4Fnzb8JXN/Ykm9G4HNImjtABMJgkQoVjOBN/j2WAwDTRytdqJbZsah7w==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true peerDependencies: @@ -3798,23 +3798,26 @@ packages: yaml: optional: true - vitest@4.0.10: - resolution: {integrity: sha512-2Fqty3MM9CDwOVet/jaQalYlbcjATZwPYGcqpiYQqgQ/dLC7GuHdISKgTYIVF/kaishKxLzleKWWfbSDklyIKg==} + vitest@4.0.13: + resolution: {integrity: sha512-QSD4I0fN6uZQfftryIXuqvqgBxTvJ3ZNkF6RWECd82YGAYAfhcppBLFXzXJHQAAhVFyYEuFTrq6h0hQqjB7jIQ==} engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} hasBin: true peerDependencies: '@edge-runtime/vm': '*' + '@opentelemetry/api': ^1.9.0 '@types/debug': ^4.1.12 '@types/node': ^20.0.0 || ^22.0.0 || >=24.0.0 - '@vitest/browser-playwright': 4.0.10 - '@vitest/browser-preview': 4.0.10 - '@vitest/browser-webdriverio': 4.0.10 - '@vitest/ui': 4.0.10 + '@vitest/browser-playwright': 4.0.13 + '@vitest/browser-preview': 4.0.13 + '@vitest/browser-webdriverio': 4.0.13 + '@vitest/ui': 4.0.13 happy-dom: '*' jsdom: '*' peerDependenciesMeta: '@edge-runtime/vm': optional: true + '@opentelemetry/api': + optional: true '@types/debug': optional: true '@types/node': @@ -3851,8 +3854,8 @@ packages: '@vue/composition-api': optional: true - vue@3.5.22: - resolution: {integrity: sha512-toaZjQ3a/G/mYaLSbV+QsQhIdMo9x5rrqIpYRObsJ6T/J+RyCSFwN2LHNVH9v8uIcljDNa3QzPVdv3Y6b9hAJQ==} + vue@3.5.24: + resolution: {integrity: sha512-uTHDOpVQTMjcGgrqFPSb8iO2m1DUvo+WbGqoXQz8Y1CeBYQ0FXf2z1gLRaBtHjlRz7zZUBHxjVB5VTLzYkvftg==} peerDependencies: typescript: '*' peerDependenciesMeta: @@ -4388,9 +4391,9 @@ snapshots: dependencies: css-render: 0.15.14 - '@css-render/vue3-ssr@0.15.14(vue@3.5.22(typescript@5.9.3))': + '@css-render/vue3-ssr@0.15.14(vue@3.5.24(typescript@5.9.3))': dependencies: - vue: 3.5.22(typescript@5.9.3) + vue: 3.5.24(typescript@5.9.3) '@csstools/color-helpers@5.1.0': {} @@ -5162,7 +5165,7 @@ snapshots: '@typescript-eslint/types': 8.47.0 eslint-visitor-keys: 4.2.1 - '@vitejs/plugin-react@5.1.1(vite@7.2.2(@types/node@24.10.1)(jiti@2.6.1))': + '@vitejs/plugin-react@5.1.1(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1))': dependencies: '@babel/core': 7.28.5 '@babel/plugin-transform-react-jsx-self': 7.27.1(@babel/core@7.28.5) @@ -5170,47 +5173,47 @@ snapshots: '@rolldown/pluginutils': 1.0.0-beta.47 '@types/babel__core': 7.20.5 react-refresh: 0.18.0 - vite: 7.2.2(@types/node@24.10.1)(jiti@2.6.1) + vite: 7.2.4(@types/node@24.10.1)(jiti@2.6.1) transitivePeerDependencies: - supports-color - '@vitest/expect@4.0.10': + '@vitest/expect@4.0.13': dependencies: '@standard-schema/spec': 1.0.0 '@types/chai': 5.2.2 - '@vitest/spy': 4.0.10 - '@vitest/utils': 4.0.10 + '@vitest/spy': 4.0.13 + '@vitest/utils': 4.0.13 chai: 6.2.1 tinyrainbow: 3.0.3 - '@vitest/mocker@4.0.10(vite@7.2.2(@types/node@24.10.1)(jiti@2.6.1))': + '@vitest/mocker@4.0.13(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1))': dependencies: - '@vitest/spy': 4.0.10 + '@vitest/spy': 4.0.13 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 7.2.2(@types/node@24.10.1)(jiti@2.6.1) + vite: 7.2.4(@types/node@24.10.1)(jiti@2.6.1) - '@vitest/pretty-format@4.0.10': + '@vitest/pretty-format@4.0.13': dependencies: tinyrainbow: 3.0.3 - '@vitest/runner@4.0.10': + '@vitest/runner@4.0.13': dependencies: - '@vitest/utils': 4.0.10 + '@vitest/utils': 4.0.13 pathe: 2.0.3 - '@vitest/snapshot@4.0.10': + '@vitest/snapshot@4.0.13': dependencies: - '@vitest/pretty-format': 4.0.10 + '@vitest/pretty-format': 4.0.13 magic-string: 0.30.21 pathe: 2.0.3 - '@vitest/spy@4.0.10': {} + '@vitest/spy@4.0.13': {} - '@vitest/utils@4.0.10': + '@vitest/utils@4.0.13': dependencies: - '@vitest/pretty-format': 4.0.10 + '@vitest/pretty-format': 4.0.13 tinyrainbow: 3.0.3 '@volar/language-core@2.4.23': @@ -5233,27 +5236,40 @@ snapshots: estree-walker: 2.0.2 source-map-js: 1.2.1 + '@vue/compiler-core@3.5.24': + dependencies: + '@babel/parser': 7.28.5 + '@vue/shared': 3.5.24 + entities: 4.5.0 + estree-walker: 2.0.2 + source-map-js: 1.2.1 + '@vue/compiler-dom@3.5.22': dependencies: '@vue/compiler-core': 3.5.22 '@vue/shared': 3.5.22 - '@vue/compiler-sfc@3.5.22': + '@vue/compiler-dom@3.5.24': dependencies: - '@babel/parser': 7.28.4 - '@vue/compiler-core': 3.5.22 - '@vue/compiler-dom': 3.5.22 - '@vue/compiler-ssr': 3.5.22 - '@vue/shared': 3.5.22 + '@vue/compiler-core': 3.5.24 + '@vue/shared': 3.5.24 + + '@vue/compiler-sfc@3.5.24': + dependencies: + '@babel/parser': 7.28.5 + '@vue/compiler-core': 3.5.24 + '@vue/compiler-dom': 3.5.24 + '@vue/compiler-ssr': 3.5.24 + '@vue/shared': 3.5.24 estree-walker: 2.0.2 - magic-string: 0.30.19 + magic-string: 0.30.21 postcss: 8.5.6 source-map-js: 1.2.1 - '@vue/compiler-ssr@3.5.22': + '@vue/compiler-ssr@3.5.24': dependencies: - '@vue/compiler-dom': 3.5.22 - '@vue/shared': 3.5.22 + '@vue/compiler-dom': 3.5.24 + '@vue/shared': 3.5.24 '@vue/compiler-vue2@2.7.16': dependencies: @@ -5275,30 +5291,32 @@ snapshots: optionalDependencies: typescript: 5.9.3 - '@vue/reactivity@3.5.22': + '@vue/reactivity@3.5.24': dependencies: - '@vue/shared': 3.5.22 + '@vue/shared': 3.5.24 - '@vue/runtime-core@3.5.22': + '@vue/runtime-core@3.5.24': dependencies: - '@vue/reactivity': 3.5.22 - '@vue/shared': 3.5.22 + '@vue/reactivity': 3.5.24 + '@vue/shared': 3.5.24 - '@vue/runtime-dom@3.5.22': + '@vue/runtime-dom@3.5.24': dependencies: - '@vue/reactivity': 3.5.22 - '@vue/runtime-core': 3.5.22 - '@vue/shared': 3.5.22 - csstype: 3.1.3 + '@vue/reactivity': 3.5.24 + '@vue/runtime-core': 3.5.24 + '@vue/shared': 3.5.24 + csstype: 3.2.3 - '@vue/server-renderer@3.5.22(vue@3.5.22(typescript@5.9.3))': + '@vue/server-renderer@3.5.24(vue@3.5.24(typescript@5.9.3))': dependencies: - '@vue/compiler-ssr': 3.5.22 - '@vue/shared': 3.5.22 - vue: 3.5.22(typescript@5.9.3) + '@vue/compiler-ssr': 3.5.24 + '@vue/shared': 3.5.24 + vue: 3.5.24(typescript@5.9.3) '@vue/shared@3.5.22': {} + '@vue/shared@3.5.24': {} + JSONStream@1.3.5: dependencies: jsonparse: 1.3.1 @@ -5545,7 +5563,7 @@ snapshots: canvas@2.11.2: dependencies: '@mapbox/node-pre-gyp': 1.0.11 - nan: 2.23.0 + nan: 2.23.1 simple-get: 3.1.1 transitivePeerDependencies: - encoding @@ -5744,8 +5762,6 @@ snapshots: csstype@3.0.11: {} - csstype@3.1.3: {} - csstype@3.2.3: {} dargs@8.1.0: {} @@ -5778,11 +5794,11 @@ snapshots: es-errors: 1.3.0 is-data-view: 1.0.2 - date-fns-tz@3.2.0(date-fns@3.6.0): + date-fns-tz@3.2.0(date-fns@4.1.0): dependencies: - date-fns: 3.6.0 + date-fns: 4.1.0 - date-fns@3.6.0: {} + date-fns@4.1.0: {} de-indent@1.0.2: {} @@ -6243,7 +6259,7 @@ snapshots: dependencies: is-callable: 1.2.7 - form-data@4.0.4: + form-data@4.0.5: dependencies: asynckit: 0.4.0 combined-stream: 1.0.8 @@ -6731,7 +6747,7 @@ snapshots: cssstyle: 4.6.0 data-urls: 5.0.0 decimal.js: 10.6.0 - form-data: 4.0.4 + form-data: 4.0.5 html-encoding-sniffer: 4.0.0 http-proxy-agent: 7.0.2 https-proxy-agent: 7.0.6 @@ -7016,30 +7032,30 @@ snapshots: object-assign: 4.1.1 thenify-all: 1.6.0 - naive-ui@2.43.1(vue@3.5.22(typescript@5.9.3)): + naive-ui@2.43.2(vue@3.5.24(typescript@5.9.3)): dependencies: '@css-render/plugin-bem': 0.15.14(css-render@0.15.14) - '@css-render/vue3-ssr': 0.15.14(vue@3.5.22(typescript@5.9.3)) + '@css-render/vue3-ssr': 0.15.14(vue@3.5.24(typescript@5.9.3)) '@types/katex': 0.16.7 '@types/lodash': 4.17.20 '@types/lodash-es': 4.17.12 async-validator: 4.2.5 css-render: 0.15.14 - csstype: 3.1.3 - date-fns: 3.6.0 - date-fns-tz: 3.2.0(date-fns@3.6.0) + csstype: 3.2.3 + date-fns: 4.1.0 + date-fns-tz: 3.2.0(date-fns@4.1.0) evtd: 0.2.4 highlight.js: 11.11.1 lodash: 4.17.21 lodash-es: 4.17.21 seemly: 0.3.10 treemate: 0.3.11 - vdirs: 0.1.8(vue@3.5.22(typescript@5.9.3)) - vooks: 0.2.12(vue@3.5.22(typescript@5.9.3)) - vue: 3.5.22(typescript@5.9.3) - vueuc: 0.4.65(vue@3.5.22(typescript@5.9.3)) + vdirs: 0.1.8(vue@3.5.24(typescript@5.9.3)) + vooks: 0.2.12(vue@3.5.24(typescript@5.9.3)) + vue: 3.5.24(typescript@5.9.3) + vueuc: 0.4.65(vue@3.5.24(typescript@5.9.3)) - nan@2.23.0: + nan@2.23.1: optional: true nanoid@3.3.11: {} @@ -7292,11 +7308,11 @@ snapshots: pify@3.0.0: {} - pinia@2.3.1(typescript@5.9.3)(vue@3.5.22(typescript@5.9.3)): + pinia@2.3.1(typescript@5.9.3)(vue@3.5.24(typescript@5.9.3)): dependencies: '@vue/devtools-api': 6.6.4 - vue: 3.5.22(typescript@5.9.3) - vue-demi: 0.14.10(vue@3.5.22(typescript@5.9.3)) + vue: 3.5.24(typescript@5.9.3) + vue-demi: 0.14.10(vue@3.5.24(typescript@5.9.3)) optionalDependencies: typescript: 5.9.3 transitivePeerDependencies: @@ -7349,25 +7365,25 @@ snapshots: object-assign: 4.1.1 react-is: 16.13.1 - prosemirror-model@1.25.3: + prosemirror-model@1.25.4: dependencies: orderedmap: 2.1.1 - prosemirror-state@1.4.3: + prosemirror-state@1.4.4: dependencies: - prosemirror-model: 1.25.3 - prosemirror-transform: 1.10.4 + prosemirror-model: 1.25.4 + prosemirror-transform: 1.10.5 prosemirror-view: 1.41.3 - prosemirror-transform@1.10.4: + prosemirror-transform@1.10.5: dependencies: - prosemirror-model: 1.25.3 + prosemirror-model: 1.25.4 prosemirror-view@1.41.3: dependencies: - prosemirror-model: 1.25.3 - prosemirror-state: 1.4.3 - prosemirror-transform: 1.10.4 + prosemirror-model: 1.25.4 + prosemirror-state: 1.4.4 + prosemirror-transform: 1.10.5 proto-list@1.2.4: {} @@ -7438,7 +7454,7 @@ snapshots: readable-stream@3.6.2: dependencies: inherits: 2.0.4 - string_decoder: 1.3.0 + string_decoder: 1.1.1 util-deprecate: 1.0.2 optional: true @@ -7552,9 +7568,6 @@ snapshots: safe-buffer@5.1.2: {} - safe-buffer@5.2.1: - optional: true - safe-push-apply@1.0.0: dependencies: es-errors: 1.3.0 @@ -7816,11 +7829,6 @@ snapshots: dependencies: safe-buffer: 5.1.2 - string_decoder@1.3.0: - dependencies: - safe-buffer: 5.2.1 - optional: true - strip-ansi@6.0.1: dependencies: ansi-regex: 5.0.1 @@ -7850,19 +7858,19 @@ snapshots: function-timeout: 1.0.2 time-span: 5.1.0 - superdoc@0.29.0(@hocuspocus/provider@2.15.3(y-protocols@1.0.6(yjs@13.6.19))(yjs@13.6.19))(pdfjs-dist@4.6.82)(typescript@5.9.3)(y-prosemirror@1.3.7(prosemirror-model@1.25.3)(prosemirror-state@1.4.3)(prosemirror-view@1.41.3)(y-protocols@1.0.6(yjs@13.6.19))(yjs@13.6.19))(yjs@13.6.19): + superdoc@0.31.2(@hocuspocus/provider@2.15.3(y-protocols@1.0.6(yjs@13.6.19))(yjs@13.6.19))(pdfjs-dist@4.6.82)(typescript@5.9.3)(y-prosemirror@1.3.7(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.3)(y-protocols@1.0.6(yjs@13.6.19))(yjs@13.6.19))(yjs@13.6.19): dependencies: '@hocuspocus/provider': 2.15.3(y-protocols@1.0.6(yjs@13.6.19))(yjs@13.6.19) buffer-crc32: 1.0.0 eventemitter3: 5.0.1 jsdom: 25.0.1 - naive-ui: 2.43.1(vue@3.5.22(typescript@5.9.3)) + naive-ui: 2.43.2(vue@3.5.24(typescript@5.9.3)) pdfjs-dist: 4.6.82 - pinia: 2.3.1(typescript@5.9.3)(vue@3.5.22(typescript@5.9.3)) + pinia: 2.3.1(typescript@5.9.3)(vue@3.5.24(typescript@5.9.3)) rollup-plugin-copy: 3.5.0 uuid: 9.0.1 - vue: 3.5.22(typescript@5.9.3) - y-prosemirror: 1.3.7(prosemirror-model@1.25.3)(prosemirror-state@1.4.3)(prosemirror-view@1.41.3)(y-protocols@1.0.6(yjs@13.6.19))(yjs@13.6.19) + vue: 3.5.24(typescript@5.9.3) + y-prosemirror: 1.3.7(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.3)(y-protocols@1.0.6(yjs@13.6.19))(yjs@13.6.19) y-websocket: 3.0.0(yjs@13.6.19) yjs: 13.6.19 transitivePeerDependencies: @@ -8113,12 +8121,12 @@ snapshots: spdx-correct: 3.2.0 spdx-expression-parse: 3.0.1 - vdirs@0.1.8(vue@3.5.22(typescript@5.9.3)): + vdirs@0.1.8(vue@3.5.24(typescript@5.9.3)): dependencies: evtd: 0.2.4 - vue: 3.5.22(typescript@5.9.3) + vue: 3.5.24(typescript@5.9.3) - vite-plugin-dts@4.5.4(@types/node@24.10.1)(rollup@4.52.4)(typescript@5.9.3)(vite@7.2.2(@types/node@24.10.1)(jiti@2.6.1)): + vite-plugin-dts@4.5.4(@types/node@24.10.1)(rollup@4.52.4)(typescript@5.9.3)(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)): dependencies: '@microsoft/api-extractor': 7.53.1(@types/node@24.10.1) '@rollup/pluginutils': 5.3.0(rollup@4.52.4) @@ -8131,13 +8139,13 @@ snapshots: magic-string: 0.30.19 typescript: 5.9.3 optionalDependencies: - vite: 7.2.2(@types/node@24.10.1)(jiti@2.6.1) + vite: 7.2.4(@types/node@24.10.1)(jiti@2.6.1) transitivePeerDependencies: - '@types/node' - rollup - supports-color - vite@7.2.2(@types/node@24.10.1)(jiti@2.6.1): + vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1): dependencies: esbuild: 0.25.10 fdir: 6.5.0(picomatch@4.0.3) @@ -8150,15 +8158,15 @@ snapshots: fsevents: 2.3.3 jiti: 2.6.1 - vitest@4.0.10(@types/node@24.10.1)(jiti@2.6.1)(jsdom@27.2.0(postcss@8.5.6)): + vitest@4.0.13(@types/node@24.10.1)(jiti@2.6.1)(jsdom@27.2.0(postcss@8.5.6)): dependencies: - '@vitest/expect': 4.0.10 - '@vitest/mocker': 4.0.10(vite@7.2.2(@types/node@24.10.1)(jiti@2.6.1)) - '@vitest/pretty-format': 4.0.10 - '@vitest/runner': 4.0.10 - '@vitest/snapshot': 4.0.10 - '@vitest/spy': 4.0.10 - '@vitest/utils': 4.0.10 + '@vitest/expect': 4.0.13 + '@vitest/mocker': 4.0.13(vite@7.2.4(@types/node@24.10.1)(jiti@2.6.1)) + '@vitest/pretty-format': 4.0.13 + '@vitest/runner': 4.0.13 + '@vitest/snapshot': 4.0.13 + '@vitest/spy': 4.0.13 + '@vitest/utils': 4.0.13 debug: 4.4.3 es-module-lexer: 1.7.0 expect-type: 1.2.2 @@ -8170,7 +8178,7 @@ snapshots: tinyexec: 0.3.2 tinyglobby: 0.2.15 tinyrainbow: 3.0.3 - vite: 7.2.2(@types/node@24.10.1)(jiti@2.6.1) + vite: 7.2.4(@types/node@24.10.1)(jiti@2.6.1) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 24.10.1 @@ -8189,37 +8197,37 @@ snapshots: - tsx - yaml - vooks@0.2.12(vue@3.5.22(typescript@5.9.3)): + vooks@0.2.12(vue@3.5.24(typescript@5.9.3)): dependencies: evtd: 0.2.4 - vue: 3.5.22(typescript@5.9.3) + vue: 3.5.24(typescript@5.9.3) vscode-uri@3.1.0: {} - vue-demi@0.14.10(vue@3.5.22(typescript@5.9.3)): + vue-demi@0.14.10(vue@3.5.24(typescript@5.9.3)): dependencies: - vue: 3.5.22(typescript@5.9.3) + vue: 3.5.24(typescript@5.9.3) - vue@3.5.22(typescript@5.9.3): + vue@3.5.24(typescript@5.9.3): dependencies: - '@vue/compiler-dom': 3.5.22 - '@vue/compiler-sfc': 3.5.22 - '@vue/runtime-dom': 3.5.22 - '@vue/server-renderer': 3.5.22(vue@3.5.22(typescript@5.9.3)) - '@vue/shared': 3.5.22 + '@vue/compiler-dom': 3.5.24 + '@vue/compiler-sfc': 3.5.24 + '@vue/runtime-dom': 3.5.24 + '@vue/server-renderer': 3.5.24(vue@3.5.24(typescript@5.9.3)) + '@vue/shared': 3.5.24 optionalDependencies: typescript: 5.9.3 - vueuc@0.4.65(vue@3.5.22(typescript@5.9.3)): + vueuc@0.4.65(vue@3.5.24(typescript@5.9.3)): dependencies: - '@css-render/vue3-ssr': 0.15.14(vue@3.5.22(typescript@5.9.3)) + '@css-render/vue3-ssr': 0.15.14(vue@3.5.24(typescript@5.9.3)) '@juggle/resize-observer': 3.4.0 css-render: 0.15.14 evtd: 0.2.4 seemly: 0.3.10 - vdirs: 0.1.8(vue@3.5.22(typescript@5.9.3)) - vooks: 0.2.12(vue@3.5.22(typescript@5.9.3)) - vue: 3.5.22(typescript@5.9.3) + vdirs: 0.1.8(vue@3.5.24(typescript@5.9.3)) + vooks: 0.2.12(vue@3.5.24(typescript@5.9.3)) + vue: 3.5.24(typescript@5.9.3) w3c-xmlserializer@5.0.0: dependencies: @@ -8335,11 +8343,11 @@ snapshots: xtend@4.0.2: {} - y-prosemirror@1.3.7(prosemirror-model@1.25.3)(prosemirror-state@1.4.3)(prosemirror-view@1.41.3)(y-protocols@1.0.6(yjs@13.6.19))(yjs@13.6.19): + y-prosemirror@1.3.7(prosemirror-model@1.25.4)(prosemirror-state@1.4.4)(prosemirror-view@1.41.3)(y-protocols@1.0.6(yjs@13.6.19))(yjs@13.6.19): dependencies: lib0: 0.2.114 - prosemirror-model: 1.25.3 - prosemirror-state: 1.4.3 + prosemirror-model: 1.25.4 + prosemirror-state: 1.4.4 prosemirror-view: 1.41.3 y-protocols: 1.0.6(yjs@13.6.19) yjs: 13.6.19 diff --git a/src/defaults/FieldList.tsx b/src/defaults/FieldList.tsx index 622f7d6..8a8558f 100644 --- a/src/defaults/FieldList.tsx +++ b/src/defaults/FieldList.tsx @@ -1,5 +1,125 @@ -import React from "react"; -import type { FieldListProps } from "../types"; +import React, { useMemo, useState } from "react"; +import type { FieldListProps, TemplateField } from "../types"; + +const shortenGroupId = (group: string): string => { + const parts = group.split('-'); + return parts.length > 2 ? parts[parts.length - 1].substring(0, 6) : group.substring(0, 6); +}; +const FieldItem: React.FC<{ + field: TemplateField; + onSelect: (field: TemplateField) => void; + onDelete: (id: string | number) => void; + isSelected: boolean; + isGrouped?: boolean; +}> = ({ field, onSelect, onDelete, isSelected, isGrouped = false }) => { + return ( +
onSelect(field)} + style={{ + position: "relative", + padding: "10px 12px", + background: isSelected ? "#eff6ff" : "#f9fafb", + border: isSelected ? "1px solid #3b82f6" : "1px solid #e5e7eb", + borderRadius: "6px", + cursor: "pointer", + transition: "all 0.2s", + fontSize: isGrouped ? "13px" : "14px", + }} + onMouseEnter={(e) => { + if (!isSelected) { + e.currentTarget.style.background = "#f3f4f6"; + } + }} + onMouseLeave={(e) => { + if (!isSelected) { + e.currentTarget.style.background = "#f9fafb"; + } + }} + title={field.alias} + > + +
+
+ {field.alias || field.id} +
+
+ ID: {field.id} + {field.mode && ( + + {field.mode} + + )} +
+
+
+ ); +}; export const FieldList: React.FC = ({ fields, @@ -7,6 +127,38 @@ export const FieldList: React.FC = ({ onDelete, selectedFieldId, }) => { + const [expandedGroups, setExpandedGroups] = useState>(new Set()); + + const { groupedFields, ungroupedFields } = useMemo(() => { + const grouped: Record = {}; + const ungrouped: typeof fields = []; + + fields.forEach((field) => { + if (field.group) { + if (!grouped[field.group]) { + grouped[field.group] = []; + } + grouped[field.group].push(field); + } else { + ungrouped.push(field); + } + }); + + return { groupedFields: grouped, ungroupedFields: ungrouped }; + }, [fields]); + + const toggleGroup = (groupId: string) => { + setExpandedGroups((prev) => { + const next = new Set(prev); + if (next.has(groupId)) { + next.delete(groupId); + } else { + next.add(groupId); + } + return next; + }); + }; + return (
= ({
) : (
- {fields.map((field) => ( -
( + onSelect(field)} - style={{ - position: "relative", - padding: "12px", - background: - selectedFieldId === field.id ? "#eff6ff" : "#f9fafb", - border: - selectedFieldId === field.id - ? "1px solid #3b82f6" - : "1px solid #e5e7eb", - borderRadius: "6px", - cursor: "pointer", - transition: "all 0.2s", - }} - onMouseEnter={(e) => { - if (selectedFieldId !== field.id) { - e.currentTarget.style.background = "#f3f4f6"; - } - }} - onMouseLeave={(e) => { - if (selectedFieldId !== field.id) { - e.currentTarget.style.background = "#f9fafb"; - } - }} - title={field.alias} - > - -
+ field={field} + onSelect={onSelect} + onDelete={onDelete} + isSelected={selectedFieldId === field.id} + /> + ))} + + {Object.entries(groupedFields).map(([groupId, groupFields]) => { + const isExpanded = expandedGroups.has(groupId); + const firstField = groupFields[0]; + + return ( +
- {field.id} -
-
toggleGroup(groupId)} + onMouseEnter={(e) => { + e.currentTarget.style.background = "#f3f4f6"; + }} + onMouseLeave={(e) => { + e.currentTarget.style.background = "#f9fafb"; }} > - {field.alias && field.alias !== field.id && ( - {field.alias} - )} - {field.mode && ( - - {field.mode} +
+ + {isExpanded ? "▼" : "▶"} - )} +
+
+ {firstField.alias} +
+
+ group: {shortenGroupId(groupId)} ({groupFields.length} fields) +
+
+
+ + {isExpanded && ( +
+ {groupFields.map((field) => ( + + ))} +
+ )}
-
- ))} + ); + })}
)}
diff --git a/src/defaults/FieldMenu.tsx b/src/defaults/FieldMenu.tsx index 53347a2..c5442f8 100644 --- a/src/defaults/FieldMenu.tsx +++ b/src/defaults/FieldMenu.tsx @@ -1,4 +1,4 @@ -import { useCallback, useEffect, useMemo, useState } from "react"; +import { useEffect, useMemo, useState } from "react"; import type { FieldDefinition, FieldMenuProps } from "../types"; export const FieldMenu: React.FC = ({ @@ -11,10 +11,14 @@ export const FieldMenu: React.FC = ({ onSelect, onClose, onCreateField, + existingFields = [], + onSelectExisting, }) => { const [isCreating, setIsCreating] = useState(false); const [newFieldName, setNewFieldName] = useState(""); const [fieldMode, setFieldMode] = useState<"inline" | "block">("inline"); + const [existingExpanded, setExistingExpanded] = useState(true); + const [availableExpanded, setAvailableExpanded] = useState(true); useEffect(() => { if (!isVisible) { @@ -35,65 +39,18 @@ export const FieldMenu: React.FC = ({ borderRadius: "4px", boxShadow: "0 2px 8px rgba(0,0,0,0.1)", padding: "8px 0", - minWidth: "200px", + width: "280px", }; }, [position]); const fieldsToDisplay = filteredFields ?? availableFields; const hasFilter = Boolean(filterQuery); - const groupedFields = useMemo(() => { - const groups: { category: string; fields: FieldDefinition[] }[] = []; - const categoryIndex = new Map(); - - fieldsToDisplay.forEach((field) => { - const categoryName = field.category?.trim() || "Uncategorized"; - const existingIndex = categoryIndex.get(categoryName); - - if (existingIndex !== undefined) { - groups[existingIndex].fields.push(field); - return; - } - - categoryIndex.set(categoryName, groups.length); - groups.push({ category: categoryName, fields: [field] }); - }); - - return groups; - }, [fieldsToDisplay]); - - const [expandedCategories, setExpandedCategories] = useState< - Record - >({}); - useEffect(() => { - setExpandedCategories((previous) => { - if (groupedFields.length === 0) { - return Object.keys(previous).length === 0 ? previous : {}; - } - - const next: Record = {}; - let hasChanges = Object.keys(previous).length !== groupedFields.length; - - groupedFields.forEach(({ category }, index) => { - // Auto-expand all categories when filtering is active - const target = hasFilter ? true : (previous[category] ?? index === 0); - next[category] = target; - if (!hasChanges && previous[category] !== target) { - hasChanges = true; - } - }); - - return hasChanges ? next : previous; - }); - }, [groupedFields, hasFilter]); - - const toggleCategory = useCallback((category: string) => { - setExpandedCategories((previous) => ({ - ...previous, - [category]: !previous[category], - })); - }, []); + if (hasFilter) { + setAvailableExpanded(true); + } + }, [hasFilter]); if (!isVisible) return null; @@ -104,7 +61,6 @@ export const FieldMenu: React.FC = ({ const newField: FieldDefinition = { id: `custom_${Date.now()}`, label: trimmedName, - category: "Custom", metadata: { mode: fieldMode }, }; @@ -272,7 +228,110 @@ export const FieldMenu: React.FC = ({ /> )} - {groupedFields.length === 0 ? ( + {existingFields.length > 0 && (() => { + const groupedExisting = new Map(); + + existingFields.forEach((field) => { + const key = field.group || `individual-${field.id}`; + const existing = groupedExisting.get(key) || []; + existing.push(field); + groupedExisting.set(key, existing); + }); + + const uniqueEntries = Array.from(groupedExisting.values()).map((fields) => { + const representative = fields[0]; + return { + ...representative, + count: fields.length, + }; + }); + + return ( +
+ + {existingExpanded && ( +
+ {uniqueEntries.map((entry) => ( +
onSelectExisting?.(entry)} + style={{ + padding: "8px 16px", + cursor: "pointer", + display: "flex", + alignItems: "flex-start", + justifyContent: "space-between", + gap: "8px", + }} + > +
+
+ {entry.alias || entry.id} +
+
+ {entry.group ? `group (${entry.count} fields)` : `ID: ${entry.id}`} +
+
+ + {entry.mode || "inline"} + +
+ ))} +
+ )} +
+ ); + })()} + + {fieldsToDisplay.length === 0 ? (
= ({ No matching fields
) : ( - groupedFields.map(({ category, fields }, index) => { - const isExpanded = Boolean(expandedCategories[category]); - const itemsMaxHeight = `${Math.max(fields.length * 40, 0)}px`; - - return ( -
+ + {availableExpanded && ( +
+ {fieldsToDisplay.map((field) => ( +
onSelect(field)} style={{ - display: "inline-block", - width: "8px", - height: "8px", - borderRight: "2px solid #666", - borderBottom: "2px solid #666", - transform: isExpanded ? "rotate(45deg)" : "rotate(-45deg)", - transition: "transform 0.2s ease", - marginLeft: "12px", + padding: "8px 16px", + cursor: "pointer", + display: "flex", + alignItems: "flex-start", + justifyContent: "space-between", + gap: "8px", }} - /> - -
-
- {fields.map((field) => ( + > +
+
+ {field.label || field.id} +
onSelect(field)} style={{ - padding: "8px 16px", - cursor: "pointer", - display: "flex", - alignItems: "center", - justifyContent: "space-between", + fontSize: "11px", + color: "#9ca3af", + marginTop: "2px", }} > - {field.label} + ID: {field.id}
- ))} +
+ + {field.metadata?.mode || "inline"} +
-
+ ))}
- ); - }) + )} +
)}
{ alias: attrs.alias || attrs.label || "", tag: attrs.tag, mode, + group: structuredContentHelpers.getGroup?.(attrs.tag) ?? undefined, } as Types.TemplateField; }); }; @@ -165,7 +166,7 @@ const SuperDocTemplateBuilder = forwardRef< menuVisibleRef.current = menuVisible; }, [menuVisible]); - const trigger = menu.trigger || "{{"; // Default trigger + const trigger = menu.trigger || "{{"; const availableFields = fieldsRef.current.available || []; @@ -176,8 +177,7 @@ const SuperDocTemplateBuilder = forwardRef< return availableFields.filter((field) => { const label = field.label.toLowerCase(); - const category = field.category?.toLowerCase() || ""; - return label.includes(normalized) || category.includes(normalized); + return label.includes(normalized); }); }, [availableFields], @@ -195,7 +195,6 @@ const SuperDocTemplateBuilder = forwardRef< updateMenuFilter(""); }, [updateMenuFilter]); - // Field operations const insertFieldInternal = useCallback( ( mode: "inline" | "block", @@ -213,7 +212,7 @@ const SuperDocTemplateBuilder = forwardRef< alias: field.alias, tag: field.metadata ? JSON.stringify(field.metadata) - : field.category, + : undefined, }, text: field.defaultValue || field.alias, }) @@ -222,7 +221,7 @@ const SuperDocTemplateBuilder = forwardRef< alias: field.alias, tag: field.metadata ? JSON.stringify(field.metadata) - : field.category, + : undefined, }, text: field.defaultValue || field.alias, }); @@ -279,10 +278,6 @@ const SuperDocTemplateBuilder = forwardRef< const editor = superdocRef.current?.activeEditor; if (!editor) { - console.warn( - "[SuperDocTemplateBuilder] deleteField called without active editor", - ); - let removed = false; setTemplateFields((prev) => { if (!prev.some((field) => field.id === id)) return prev; @@ -301,15 +296,15 @@ const SuperDocTemplateBuilder = forwardRef< return removed; } + const fieldToDelete = templateFields.find((f) => f.id === id); + const groupId = fieldToDelete?.group; + let commandResult = false; try { commandResult = editor.commands.deleteStructuredContentById?.(id) ?? false; - } catch (error) { - console.error( - "[SuperDocTemplateBuilder] Delete command failed:", - error, - ); + } catch { + commandResult = false; } let documentFields = getTemplateFieldsFromEditor(editor); @@ -319,6 +314,20 @@ const SuperDocTemplateBuilder = forwardRef< documentFields = documentFields.filter((field) => field.id !== id); } + if (groupId) { + const remainingFieldsInGroup = documentFields.filter( + (field) => field.group === groupId, + ); + + if (remainingFieldsInGroup.length === 1) { + const lastField = remainingFieldsInGroup[0]; + editor.commands.updateStructuredContentById?.(lastField.id, { + attrs: { tag: undefined }, + }); + documentFields = getTemplateFieldsFromEditor(editor); + } + } + let removedFromState = false; setTemplateFields((prev) => { @@ -344,7 +353,7 @@ const SuperDocTemplateBuilder = forwardRef< return commandResult || removedFromState; }, - [onFieldDelete, onFieldsChange], + [onFieldDelete, onFieldsChange, templateFields], ); const selectField = useCallback( @@ -379,7 +388,6 @@ const SuperDocTemplateBuilder = forwardRef< [onFieldsChange], ); - // Initialize SuperDoc useEffect(() => { if (!containerRef.current) return; @@ -394,7 +402,6 @@ const SuperDocTemplateBuilder = forwardRef< if (instance.activeEditor) { const editor = instance.activeEditor; - // Setup trigger detection editor.on("update", ({ editor: e }: any) => { const { state } = e; const { from } = state.selection; @@ -414,7 +421,7 @@ const SuperDocTemplateBuilder = forwardRef< if (!editor) return; const currentPos = editor.state.selection.from; const tr = editor.state.tr.delete(triggerStart, currentPos); - editor.view.dispatch(tr); + (editor as any).view.dispatch(tr); }; triggerCleanupRef.current = cleanup; @@ -463,7 +470,6 @@ const SuperDocTemplateBuilder = forwardRef< setMenuPosition(bounds); }); - // Track field changes editor.on("update", () => { discoverFields(editor); }); @@ -531,29 +537,23 @@ const SuperDocTemplateBuilder = forwardRef< const mode = (field.metadata?.mode as "inline" | "block") || "inline"; if (field.id.startsWith("custom_") && onFieldCreate) { - try { - const createdField = await onFieldCreate(field); - - if (createdField) { - const createdMode = - (createdField.metadata?.mode as "inline" | "block") || mode; - insertFieldInternal(createdMode, { - alias: createdField.label, - category: createdField.category, - metadata: createdField.metadata, - defaultValue: createdField.defaultValue, - }); - setMenuVisible(false); - return; - } - } catch (error) { - console.error("Field creation failed:", error); + const createdField = await onFieldCreate(field); + + if (createdField) { + const createdMode = + (createdField.metadata?.mode as "inline" | "block") || mode; + insertFieldInternal(createdMode, { + alias: createdField.label, + metadata: createdField.metadata, + defaultValue: createdField.defaultValue, + }); + setMenuVisible(false); + return; } } insertFieldInternal(mode, { alias: field.label, - category: field.category, metadata: field.metadata, defaultValue: field.defaultValue, }); @@ -562,6 +562,65 @@ const SuperDocTemplateBuilder = forwardRef< [insertFieldInternal, onFieldCreate, resetMenuFilter], ); + const handleSelectExisting = useCallback( + (field: Types.TemplateField) => { + if (triggerCleanupRef.current) { + triggerCleanupRef.current(); + triggerCleanupRef.current = null; + } + menuTriggerFromRef.current = null; + resetMenuFilter(); + + const editor = superdocRef.current?.activeEditor; + if (!editor) return; + + const structuredContentHelpers = (editor.helpers as any) + ?.structuredContentCommands; + + if (!structuredContentHelpers) return; + + const groupId = + field.group || + `group-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`; + + const tagWithGroup = structuredContentHelpers.createTagObject?.({ + group: groupId, + }); + + const mode = field.mode || "inline"; + + const success = + mode === "inline" + ? editor.commands.insertStructuredContentInline?.({ + attrs: { + alias: field.alias, + tag: tagWithGroup, + }, + text: field.alias, + }) + : editor.commands.insertStructuredContentBlock?.({ + attrs: { + alias: field.alias, + tag: tagWithGroup, + }, + text: field.alias, + }); + + if (success) { + if (!field.group) { + updateField(field.id, { tag: tagWithGroup }); + } + + setMenuVisible(false); + + const updatedFields = getTemplateFieldsFromEditor(editor); + setTemplateFields(updatedFields); + onFieldsChange?.(updatedFields); + } + }, + [updateField, resetMenuFilter, onFieldsChange], + ); + const handleMenuClose = useCallback(() => { setMenuVisible(false); menuTriggerFromRef.current = null; @@ -572,7 +631,6 @@ const SuperDocTemplateBuilder = forwardRef< } }, [resetMenuFilter]); - // Navigation methods const nextField = useCallback(() => { if (!superdocRef.current?.activeEditor || templateFields.length === 0) return; @@ -601,23 +659,17 @@ const SuperDocTemplateBuilder = forwardRef< async (config?: Types.ExportConfig): Promise => { const { fileName = "document", triggerDownload = true } = config || {}; - try { - const result = await superdocRef.current?.export({ - exportType: ["docx"], - exportedName: fileName, - triggerDownload, - }); + const result = await superdocRef.current?.export({ + exportType: ["docx"], + exportedName: fileName, + triggerDownload, + }); - return result; - } catch (error) { - console.error("Failed to export DOCX", error); - throw error; - } + return result; }, [], ); - // Imperative handle useImperativeHandle(ref, () => ({ insertField: (field) => insertFieldInternal("inline", field), insertBlockField: (field) => insertFieldInternal("block", field), @@ -628,9 +680,9 @@ const SuperDocTemplateBuilder = forwardRef< previousField, getFields: () => templateFields, exportTemplate, + getSuperDoc: () => superdocRef.current, })); - // Components const MenuComponent = menu.component || FieldMenu; const ListComponent = list.component || FieldList; @@ -642,7 +694,6 @@ const SuperDocTemplateBuilder = forwardRef< style={style} >
- {/* Field List (if left) */} {list.position === "left" && (
)} - {/* Document */}
{toolbarSettings?.renderDefaultContainer && (
- {/* Field List (if right) */} {list.position === "right" && (
- {/* Field Menu */}
); diff --git a/src/types.ts b/src/types.ts index d457a52..0fc8d50 100644 --- a/src/types.ts +++ b/src/types.ts @@ -3,9 +3,9 @@ import type { SuperDoc } from "superdoc"; // eslint-disable-line export interface FieldDefinition { id: string; label: string; - category?: string; defaultValue?: string; metadata?: Record; + group?: string; } export interface TemplateField { @@ -14,6 +14,7 @@ export interface TemplateField { tag?: string; position?: number; mode?: "inline" | "block"; + group?: string; } export interface TriggerEvent { @@ -34,6 +35,8 @@ export interface FieldMenuProps { onCreateField?: ( field: FieldDefinition, ) => void | Promise; + existingFields?: TemplateField[]; + onSelectExisting?: (field: TemplateField) => void; } export interface FieldListProps { @@ -135,4 +138,14 @@ export interface SuperDocTemplateBuilderHandle { previousField: () => void; getFields: () => TemplateField[]; exportTemplate: (config?: ExportConfig) => Promise; + /** + * Returns the SuperDoc instance. + * Use this to access the full SuperDoc API, including: + * - The active editor: `getSuperDoc()?.activeEditor` + * - Editor commands: `getSuperDoc()?.activeEditor?.commands.*` + * - Editor state and helpers: `getSuperDoc()?.activeEditor?.state` + * + * Note: Full TypeScript types for SuperDoc will be available in a future update. + */ + getSuperDoc: () => SuperDoc | null; } From 769af7814e6bf73ab3ffdc8deb80e65c78e509c3 Mon Sep 17 00:00:00 2001 From: Caio Pizzol Date: Fri, 21 Nov 2025 18:06:48 -0300 Subject: [PATCH 2/2] fix: include group comparison in template fields equality check --- src/index.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/index.tsx b/src/index.tsx index 302f46b..3e843e0 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -60,7 +60,8 @@ const areTemplateFieldsEqual = ( left.alias !== right.alias || left.tag !== right.tag || left.position !== right.position || - left.mode !== right.mode + left.mode !== right.mode || + left.group !== right.group ) { return false; }