@lark-apaas/coding-template-nestjs-react-fullstack 0.1.59 → 0.1.60-alpha.20261105123111

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/package.json +1 -1
  2. package/template/client/src/components/business-ui/README.md +2 -0
  3. package/template/client/src/components/business-ui/comments/README.md +36 -0
  4. package/template/client/src/components/business-ui/comments/comments.tsx +626 -0
  5. package/template/client/src/components/business-ui/comments/contracts.ts +165 -0
  6. package/template/client/src/components/business-ui/comments/index.ts +19 -0
  7. package/template/client/src/components/business-ui/record-comments/README.md +141 -0
  8. package/template/client/src/components/business-ui/record-comments/app-source.ts +93 -0
  9. package/template/client/src/components/business-ui/record-comments/assets/reaction-sprite.png +0 -0
  10. package/template/client/src/components/business-ui/record-comments/comment-panel.contract.ts +240 -0
  11. package/template/client/src/components/business-ui/record-comments/comment-panel.tsx +231 -0
  12. package/template/client/src/components/business-ui/record-comments/extensions.ts +130 -0
  13. package/template/client/src/components/business-ui/record-comments/index.ts +9 -0
  14. package/template/client/src/components/business-ui/record-comments/internal/composer.tsx +529 -0
  15. package/template/client/src/components/business-ui/record-comments/internal/content.tsx +213 -0
  16. package/template/client/src/components/business-ui/record-comments/internal/discussion.tsx +522 -0
  17. package/template/client/src/components/business-ui/record-comments/internal/editor.tsx +681 -0
  18. package/template/client/src/components/business-ui/record-comments/internal/icons.tsx +148 -0
  19. package/template/client/src/components/business-ui/record-comments/internal/images.tsx +155 -0
  20. package/template/client/src/components/business-ui/record-comments/internal/mentions.tsx +163 -0
  21. package/template/client/src/components/business-ui/record-comments/internal/model.ts +581 -0
  22. package/template/client/src/components/business-ui/record-comments/internal/mutations.ts +184 -0
  23. package/template/client/src/components/business-ui/record-comments/internal/reaction-catalog.ts +196 -0
  24. package/template/client/src/components/business-ui/record-comments/internal/reactions.tsx +681 -0
  25. package/template/client/src/components/business-ui/record-comments/internal/styles.css +1109 -0
  26. package/template/client/src/components/business-ui/record-comments/internal/suggestions.tsx +456 -0
  27. package/template/client/src/components/business-ui/record-comments/internal/view-types.ts +89 -0
  28. package/template/client/src/components/business-ui/record-comments/types.ts +121 -0
  29. package/template/package-lock.json +1449 -216
  30. package/template/package.json +16 -5
@@ -0,0 +1,148 @@
1
+ import type { DocumentMentionMetadata, MentionRef } from '../types';
2
+ import * as React from 'react';
3
+ import type { SVGProps } from 'react';
4
+
5
+ // Static SVGs from @universe-design/icons-react 3.350.0, matching miaoda ud-provider-icons V2.
6
+ // Only the document glyphs are included; no icon library runtime dependency.
7
+ export const DOCUMENT_ICONS = {
8
+ "FileDocV2Outlined": "<svg width=\"100%\" height=\"100%\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" data-icon=\"FileDocV2Outlined\"><path d=\"M16.716 14.36a.783.783 0 0 1 0 1.565H7.282a.783.783 0 0 1 0-1.565h9.434Zm-5.001-4.229a.8.8 0 0 1 0 1.6h-4.4a.8.8 0 0 1 0-1.6h4.4Z\" fill=\"currentColor\"></path><path d=\"M15.153 1.5c.75.006 1.472.36 2.02.874l3.875 3.63c.607.569.952 1.366.952 2.198v8.28c0 3.323-2.687 6.017-6 6.017H8c-3.313 0-6-2.694-6-6.016v-8.97C2 4.17 4.72 1.469 8.056 1.5h7.097ZM8.037 3.503A4.006 4.006 0 0 0 4 7.514v8.969a4.006 4.006 0 0 0 4 4.01h8c2.209 0 4-1.796 4-4.01v-8.28c0-.083-.012-.164-.031-.243h-2.42l-.203-.01a2.005 2.005 0 0 1-1.796-1.996V3.666c0-.137-.152-.16-.29-.162H8.038Z\" fill=\"currentColor\"></path></svg>",
9
+ "FileSheetV2Outlined": "<svg width=\"100%\" height=\"100%\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" data-icon=\"FileSheetV2Outlined\"><path d=\"M12 7.96c.774 0 1.5.05 2.133.115a3.068 3.068 0 0 1 2.753 2.76A20.8 20.8 0 0 1 17 12.974c0 .775-.048 1.504-.114 2.139a3.069 3.069 0 0 1-2.753 2.76c-.634.067-1.36.115-2.133.115-.58 0-1.134-.027-1.642-.069l-.49-.046a3.065 3.065 0 0 1-2.714-2.488l-.04-.272A20.772 20.772 0 0 1 7 12.973c0-.58.027-1.136.068-1.645l.046-.493a3.066 3.066 0 0 1 2.482-2.72l.271-.04A20.58 20.58 0 0 1 12 7.96Zm-.386 8.418a17.484 17.484 0 0 0 2.353-.101 1.466 1.466 0 0 0 1.327-1.33c.061-.59.106-1.263.106-1.973 0-.125-.003-.25-.005-.371h-3.78v3.775ZM8.6 12.974c0 .7.043 1.364.103 1.95l.027.18c.13.634.636 1.103 1.303 1.173l.18.016v-3.69H8.605c-.002.122-.004.246-.004.37Zm1.455-3.306-.18.028a1.46 1.46 0 0 0-1.169 1.306l-.02.196h1.528V9.653l-.16.015Zm1.56-.098v1.628h3.697c-.006-.066-.011-.132-.018-.196a1.466 1.466 0 0 0-1.327-1.33 18.991 18.991 0 0 0-2.353-.102Z\" fill=\"currentColor\"></path><path d=\"M15.153 1.5c.75.007 1.472.362 2.02.875l3.875 3.63c.607.569.952 1.365.952 2.198v8.28c0 3.323-2.687 6.017-6 6.017H8c-3.313 0-6-2.694-6-6.016v-8.97C2 4.172 4.72 1.47 8.056 1.5h7.097ZM8.037 3.505A4.005 4.005 0 0 0 4 7.515v8.969a4.006 4.006 0 0 0 4 4.01h8c2.209 0 4-1.796 4-4.01v-8.28c0-.083-.012-.164-.031-.243h-2.42l-.203-.01a2.005 2.005 0 0 1-1.796-1.996V3.667c0-.138-.152-.16-.29-.162H8.038Z\" fill=\"currentColor\"></path></svg>",
10
+ "FileBitableV2Outlined": "<svg width=\"100%\" height=\"100%\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" data-icon=\"FileBitableV2Outlined\"><path d=\"M13.515 8.189a1.001 1.001 0 0 1 1.32.084l1.889 1.89a1 1 0 0 1 .084 1.319l-1.174 1.514 1.174 1.516a1 1 0 0 1-.084 1.32l-1.889 1.888a1.001 1.001 0 0 1-1.32.084L12 16.63l-1.513 1.174a1 1 0 0 1-1.32-.083l-1.89-1.89a1 1 0 0 1-.085-1.32l1.174-1.515-1.174-1.514a1 1 0 0 1 .084-1.32l1.891-1.89a1 1 0 0 1 1.32-.082L12 9.363l1.515-1.174Zm-5.149 4.807L12 16.63l3.634-3.634L12 9.363l-3.634 3.633Z\" fill=\"currentColor\"></path><path d=\"M15.153 1.5c.75.007 1.472.362 2.02.875l3.875 3.63c.607.569.952 1.365.952 2.198v8.28c0 3.323-2.686 6.017-6 6.017H8c-3.314 0-6-2.694-6-6.016v-8.97C2 4.172 4.72 1.47 8.056 1.5h7.097ZM8.037 3.505A4.005 4.005 0 0 0 4 7.515v8.969a4.006 4.006 0 0 0 4 4.01h8c2.209 0 4-1.796 4-4.01v-8.28c0-.083-.012-.164-.031-.243h-2.42l-.203-.01a2.004 2.004 0 0 1-1.796-1.996V3.667c0-.138-.152-.16-.29-.162H8.038Z\" fill=\"currentColor\"></path></svg>",
11
+ "FileMindnoteV2Outlined": "<svg width=\"100%\" height=\"100%\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" data-icon=\"FileMindnoteV2Outlined\"><path d=\"M12 7.96a1.403 1.403 0 0 1 .7 2.616v.666a4.909 4.909 0 0 1 4.2 4.862v.33a1.403 1.403 0 0 1-.8 2.554 1.403 1.403 0 0 1-.601-2.67v-.214a3.507 3.507 0 0 0-2.799-3.438v3.705a1.403 1.403 0 0 1-.7 2.617 1.403 1.403 0 0 1-.7-2.617v-3.705a3.508 3.508 0 0 0-2.8 3.438v.214a1.403 1.403 0 0 1-.6 2.67 1.403 1.403 0 0 1-.8-2.554v-.33a4.909 4.909 0 0 1 4.2-4.861v-.667A1.403 1.403 0 0 1 12 7.96Z\" fill=\"currentColor\"></path><path d=\"M15.153 2c.75.006 1.472.36 2.02.874l3.875 3.63c.607.569.952 1.366.952 2.198v8.28C22 20.306 19.313 23 16 23H8c-3.313 0-6-2.694-6-6.016v-8.97C2 4.67 4.72 1.969 8.056 2h7.097ZM8.037 4.003A4.006 4.006 0 0 0 4 8.014v8.969a4.006 4.006 0 0 0 4 4.01h8c2.209 0 4-1.796 4-4.01v-8.28c0-.083-.012-.164-.031-.243h-2.42l-.203-.01a2.005 2.005 0 0 1-1.796-1.996V4.166c0-.137-.152-.16-.29-.162H8.038Z\" fill=\"currentColor\"></path></svg>",
12
+ "FileUnknowV2Outlined": "<svg width=\"100%\" height=\"100%\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" data-icon=\"FileUnknowV2Outlined\"><path d=\"M12.001 16.484a1.002 1.002 0 0 1 0 2.005 1.001 1.001 0 0 1 0-2.006ZM12 7.694c1.692 0 3.008 1.423 3.009 3.109 0 .93-.397 1.774-1.033 2.347-.342.307-.644.575-.872.863-.222.282-.303.5-.303.683a.801.801 0 1 1-1.6 0c0-.691.314-1.254.65-1.678.33-.418.748-.785 1.055-1.062.304-.273.503-.685.503-1.153 0-.863-.662-1.506-1.409-1.506s-1.408.643-1.408 1.506c0 .148.02.291.056.425a.8.8 0 1 1-1.543.425 3.218 3.218 0 0 1-.113-.85c0-1.686 1.316-3.11 3.008-3.11Z\" fill=\"currentColor\"></path><path d=\"M15.153 1.5c.75.007 1.472.362 2.02.875l3.875 3.63c.607.569.952 1.365.952 2.198v8.28c0 3.323-2.686 6.017-6 6.017H8c-3.314 0-6-2.694-6-6.016v-8.97C2 4.172 4.72 1.47 8.056 1.5h7.097ZM8.037 3.505A4.005 4.005 0 0 0 4 7.515v8.969a4.006 4.006 0 0 0 4 4.01h8c2.209 0 4-1.796 4-4.01v-8.28c0-.083-.012-.164-.031-.243h-2.42l-.203-.01a2.004 2.004 0 0 1-1.796-1.996V3.667c0-.138-.152-.16-.29-.162H8.038Z\" fill=\"currentColor\"></path></svg>",
13
+ "FileLinkSlideV2Outlined": "<svg width=\"100%\" height=\"100%\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" data-icon=\"FileLinkSlideV2Outlined\"><path d=\"M15.204 17.49A2 2 0 0 0 17 15.5v-5a2 2 0 0 0-2-2H9a2 2 0 0 0-2 2v5l.01.204a2 2 0 0 0 1.786 1.785L9 17.5h6l.204-.01ZM9.3 15.5a.8.8 0 0 1-.8-.8v-3.6a.6.6 0 0 1 .6-.6h5.8a.6.6 0 0 1 .6.6v3.8a.6.6 0 0 1-.6.6H9.3Z\" fill=\"currentColor\"></path><path d=\"M16 22.5c3.314 0 6-2.694 6-6.016v-8.28c0-.834-.345-1.63-.952-2.199l-3.874-3.63c-.549-.513-1.27-.868-2.02-.875H8.055C4.72 1.47 2 4.171 2 7.515v8.969C2 19.806 4.686 22.5 8 22.5h8Zm-8-2.006c-2.21 0-4-1.795-4-4.01v-8.97a4.005 4.005 0 0 1 4.037-4.009h7.224c.137.003.289.025.289.162v2.288c0 1.039.787 1.893 1.796 1.995l.204.011h2.419c.02.079.03.16.031.242v8.28a4.004 4.004 0 0 1-4 4.011H8Z\" fill=\"currentColor\"></path></svg>",
14
+ "FileSlidesV2Outlined": "<svg width=\"100%\" height=\"100%\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" data-icon=\"FileSlidesV2Outlined\"><path d=\"M11.933 18.423c3 0 5.433-2.44 5.433-5.448 0-3.009-2.433-5.447-5.433-5.447S6.5 9.966 6.5 12.975c0 3.008 2.432 5.448 5.433 5.448Zm0-1.604A3.839 3.839 0 0 1 8.1 12.975a3.843 3.843 0 0 1 3.053-3.765v3.334c0 .72.582 1.304 1.3 1.304h3.213a3.838 3.838 0 0 1-3.733 2.97Zm.82-7.599a3.844 3.844 0 0 1 2.943 3.023h-2.943V9.22Z\" fill=\"currentColor\"></path><path d=\"M16 22.5c3.314 0 6-2.694 6-6.016v-8.28c0-.834-.345-1.63-.952-2.199l-3.874-3.63c-.549-.513-1.27-.868-2.02-.875H8.055C4.72 1.47 2 4.171 2 7.515v8.969C2 19.806 4.686 22.5 8 22.5h8Zm-8-2.006c-2.21 0-4-1.795-4-4.01v-8.97a4.005 4.005 0 0 1 4.037-4.009h7.224c.137.003.289.025.289.162v2.288c0 1.039.787 1.893 1.796 1.995l.204.011h2.419c.02.079.03.16.031.242v8.28a4.004 4.004 0 0 1-4 4.011H8Z\" fill=\"currentColor\"></path></svg>",
15
+ "FileBoardV2Outlined": "<svg width=\"100%\" height=\"100%\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" data-icon=\"FileBoardV2Outlined\"><path d=\"M13.633 8.19c.397.018.75.182 1.054.478.236.229.365.507.373.826.007.3-.08.63-.24.986-.16.35-.384.743-.67 1.175-.282.425-.61.898-.981 1.417l-.812 1.129c-.222.309-.403.567-.543.772-.14.204-.24.366-.305.485h-.001a.716.716 0 0 0-.084.218c0 .01 0 .016.003.021h.021a.91.91 0 0 0 .276-.124 5.89 5.89 0 0 0 .564-.405c.235-.185.53-.433.883-.745.379-.33.717-.618 1.014-.864v-.001c.304-.249.582-.445.83-.584l.193-.097c.19-.084.378-.129.56-.126.259.004.49.117.688.31l.105.116a.919.919 0 0 1 .185.396h.002c.04.185.025.383-.031.588h-.001a3.346 3.346 0 0 1-.25.633c-.055.112-.116.23-.182.353l-.214.386c-.16.28-.29.517-.393.707l-.001-.002a3.007 3.007 0 0 0-.17.367c.072-.032.172-.088.3-.18l.003-.002c.155-.111.341-.27.557-.48h.001a.544.544 0 0 1 .334-.154.454.454 0 0 1 .364.138.437.437 0 0 1 .127.4.67.67 0 0 1-.197.349l-.002.001c-.458.448-.888.744-1.288.855-.39.108-.743.069-1-.188l-.003-.002a.942.942 0 0 1-.268-.504l-.01-.082c-.015-.2.02-.406.097-.615a3.89 3.89 0 0 1 .288-.614v-.002c.117-.197.231-.393.344-.587l.304-.535a1.71 1.71 0 0 0 .152-.348l.001-.01a.62.62 0 0 0-.109.053h.001c-.16.1-.366.257-.62.476-.254.219-.538.467-.852.746l-.002.002a18.82 18.82 0 0 1-1.516 1.203l-.001-.001c-.445.311-.851.512-1.218.579l-.001-.001a1.08 1.08 0 0 1-1.015-.313 1.14 1.14 0 0 1-.355-.71H9.92c-.026-.26.021-.537.13-.824v-.002c.11-.28.266-.582.466-.903.197-.318.428-.66.691-1.023l.839-1.165v-.002c.198-.271.39-.542.578-.81.093-.135.18-.265.262-.389l.226-.357c.138-.229.227-.413.274-.556v-.002a.534.534 0 0 0 .025-.103.899.899 0 0 0-.223.11l-.002.001c-.22.138-.515.372-.886.708-.368.333-.8.745-1.295 1.235-.493.489-1.039 1.037-1.639 1.645l-.334.337-.002.002c-.096.096-.18.182-.252.256l-.186.186a3.591 3.591 0 0 1-.131.125 1.083 1.083 0 0 1-.996.256.893.893 0 0 1-.4-.226.925.925 0 0 1-.23-.394l-.002-.004a1.02 1.02 0 0 1-.007-.497c.04-.184.135-.354.272-.508H7.1c.031-.036.073-.08.125-.13l.186-.187.264-.253c.1-.096.213-.208.342-.336v-.001a56.897 56.897 0 0 1 2.495-2.337l.5-.42a9.95 9.95 0 0 1 1.28-.905l.184-.1c.423-.219.81-.332 1.156-.316Z\" fill=\"currentColor\"></path><path d=\"M15.153 1.5c.75.007 1.472.362 2.02.875l3.875 3.63c.607.569.952 1.365.952 2.198v8.28c0 3.323-2.686 6.017-6 6.017H8c-3.314 0-6-2.694-6-6.016v-8.97C2 4.172 4.72 1.47 8.056 1.5h7.097ZM8.037 3.505A4.005 4.005 0 0 0 4 7.515v8.969a4.006 4.006 0 0 0 4 4.01h8c2.209 0 4-1.796 4-4.01v-8.28c0-.083-.012-.164-.031-.243h-2.42l-.203-.01a2.004 2.004 0 0 1-1.796-1.996V3.667c0-.138-.152-.16-.29-.162H8.038Z\" fill=\"currentColor\"></path></svg>",
16
+ "FileRoundDocV2Colorful": "<svg width=\"100%\" height=\"100%\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" data-icon=\"FileRoundDocV2Colorful\"><circle cx=\"12\" cy=\"12\" r=\"12\" fill=\"#F0F4FF\"></circle><path opacity=\"0.99\" d=\"M5.333 11.4v1.2c0 2.24 0 3.36.436 4.216a4 4 0 0 0 1.748 1.748C8.373 19 9.493 19 11.733 19h.533c2.24 0 3.36 0 4.216-.436a4 4 0 0 0 1.748-1.748c.436-.856.436-1.976.436-4.216v-.833c0-.652 0-.978-.073-1.285a2.666 2.666 0 0 0-.32-.77c-.165-.27-.395-.5-.856-.962l-2.501-2.5c-.461-.462-.692-.692-.96-.857a2.667 2.667 0 0 0-.772-.32C12.877 5 12.551 5 11.9 5h-.166c-2.24 0-3.36 0-4.216.436A4 4 0 0 0 5.77 7.184c-.436.856-.436 1.976-.436 4.216Z\" fill=\"#fff\"></path><path d=\"M12.232 4.66c.637 0 1.01-.002 1.364.083a3 3 0 0 1 .867.359c.31.19.573.455 1.023.905l2.167 2.167c.45.45.715.713.905 1.023a3 3 0 0 1 .36.867c.084.354.082.727.082 1.364v1.166c0 1.114 0 1.97-.055 2.654-.056.687-.171 1.23-.417 1.713a4.334 4.334 0 0 1-1.894 1.894c-.483.245-1.025.36-1.713.416-.683.056-1.54.056-2.654.056h-.534c-1.114 0-1.97 0-2.654-.056-.688-.056-1.23-.17-1.713-.416a4.334 4.334 0 0 1-1.894-1.894c-.246-.483-.36-1.026-.417-1.713C5 14.564 5 13.708 5 12.594v-1.2c0-1.115 0-1.972.055-2.655.057-.688.171-1.23.417-1.713a4.334 4.334 0 0 1 1.894-1.894c.482-.246 1.025-.36 1.713-.417.683-.056 1.54-.055 2.654-.055h.5Zm-.499.667c-1.125 0-1.95 0-2.6.053-.646.053-1.091.156-1.464.346a3.673 3.673 0 0 0-1.603 1.603c-.19.373-.293.818-.346 1.464-.053.65-.053 1.475-.053 2.6v1.2c0 1.126 0 1.95.053 2.6.053.647.156 1.092.346 1.465.352.69.913 1.25 1.603 1.602.373.19.818.294 1.464.347.65.053 1.475.053 2.6.053h.534c1.125 0 1.95 0 2.6-.053.646-.053 1.091-.157 1.464-.347a3.666 3.666 0 0 0 1.603-1.602c.19-.373.293-.818.346-1.465.053-.65.053-1.474.053-2.6v-1.165c0-.669-.002-.949-.064-1.208a2.31 2.31 0 0 0-.086-.274.835.835 0 0 0-.208-.071 3.176 3.176 0 0 0-.642-.048v-.004c-.1.002-.216.004-.347.004-.457 0-.808 0-1.09-.02a2.238 2.238 0 0 1-.713-.14c-.54-.22-.97-.649-1.19-1.19a2.254 2.254 0 0 1-.14-.713c-.02-.282-.02-.632-.02-1.09 0-.13.001-.246.003-.347h-.003a3.18 3.18 0 0 0-.048-.642.832.832 0 0 0-.072-.209 2.332 2.332 0 0 0-.273-.085c-.26-.062-.54-.064-1.208-.064h-.499Z\" fill=\"#C0D2FC\"></path><path d=\"M15.214 12.993a.534.534 0 0 1 0 1.066H8.949a.534.534 0 1 1 0-1.066h6.265ZM11.88 9.66a.533.533 0 0 1 0 1.066H8.948a.533.533 0 1 1 0-1.066h2.932Z\" fill=\"#336DF4\"></path></svg>",
17
+ "FileRoundSheetV2Colorful": "<svg width=\"100%\" height=\"100%\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" data-icon=\"FileRoundSheetV2Colorful\"><circle cx=\"12\" cy=\"12\" r=\"12\" fill=\"#E4FAE1\"></circle><path opacity=\"0.99\" d=\"M5.333 11.4v1.2c0 2.24 0 3.36.436 4.216a4 4 0 0 0 1.748 1.748C8.373 19 9.493 19 11.733 19h.533c2.24 0 3.36 0 4.216-.436a4 4 0 0 0 1.748-1.748c.436-.856.436-1.976.436-4.216v-.833c0-.652 0-.978-.073-1.285a2.666 2.666 0 0 0-.32-.77c-.165-.27-.395-.5-.856-.962l-2.501-2.5c-.461-.462-.692-.692-.96-.857a2.667 2.667 0 0 0-.772-.32C12.877 5 12.551 5 11.9 5h-.166c-2.24 0-3.36 0-4.216.436A4 4 0 0 0 5.77 7.184c-.436.856-.436 1.976-.436 4.216Z\" fill=\"#fff\"></path><path d=\"M12.232 4.667c.637 0 1.01-.003 1.364.082a3 3 0 0 1 .867.36c.31.19.573.455 1.023.905l2.167 2.167c.45.45.715.712.905 1.023a3 3 0 0 1 .36.867c.084.354.082.727.082 1.363V12.6c0 1.115 0 1.97-.055 2.654-.056.688-.171 1.23-.417 1.713a4.334 4.334 0 0 1-1.894 1.894c-.483.246-1.025.36-1.713.417-.683.056-1.54.055-2.654.055h-.534c-1.114 0-1.97 0-2.654-.055-.688-.056-1.23-.17-1.713-.417a4.334 4.334 0 0 1-1.894-1.894c-.246-.482-.36-1.025-.417-1.713C5 14.571 5 13.714 5 12.6v-1.2c0-1.115 0-1.971.055-2.655.057-.687.171-1.23.417-1.713A4.334 4.334 0 0 1 7.366 5.14c.482-.246 1.025-.361 1.713-.417.683-.056 1.54-.055 2.654-.055h.5Zm-.499.666c-1.125 0-1.95 0-2.6.054-.646.052-1.091.156-1.464.346a3.666 3.666 0 0 0-1.603 1.602c-.19.373-.293.819-.346 1.465-.053.65-.053 1.474-.053 2.6v1.2c0 1.126 0 1.95.053 2.6.053.646.156 1.092.346 1.465.352.69.913 1.25 1.603 1.602.373.19.818.293 1.464.346.65.053 1.475.053 2.6.053h.534c1.125 0 1.95 0 2.6-.053.646-.053 1.091-.156 1.464-.346a3.667 3.667 0 0 0 1.603-1.602c.19-.373.293-.819.346-1.465.053-.65.053-1.474.053-2.6v-1.166c0-.668-.002-.948-.064-1.208a2.314 2.314 0 0 0-.086-.274.835.835 0 0 0-.208-.07 3.176 3.176 0 0 0-.642-.049V9.83c-.1.002-.216.003-.347.003-.457 0-.808 0-1.09-.019-.283-.019-.508-.057-.713-.14-.54-.22-.97-.65-1.19-1.19a2.254 2.254 0 0 1-.14-.713c-.02-.282-.02-.633-.02-1.09 0-.131.001-.247.003-.348h-.003a3.18 3.18 0 0 0-.048-.642.832.832 0 0 0-.072-.208 2.334 2.334 0 0 0-.273-.085c-.26-.063-.54-.065-1.208-.065h-.499Z\" fill=\"#9EE8A2\"></path><path d=\"M10.704 11.857v3.882l-.126-.008a2.04 2.04 0 0 1-1.809-1.654l-.026-.181a13.763 13.763 0 0 1-.062-2.039h2.023ZM12 9.14c.516 0 1 .033 1.422.077.98.102 1.79 1.413 1.835 1.835v.005h-3.753V9.151c.161-.006.327-.01.496-.01Zm-1.296 1.917H8.742v-.005a2.04 2.04 0 0 1 1.655-1.809l.181-.026.126-.013v1.853Z\" fill=\"#32A645\"></path><path d=\"M15.317 11.844c.007.151.012.306.014.465v.341c-.006.457-.035.886-.074 1.265a2.052 2.052 0 0 1-1.835 1.853 13.639 13.639 0 0 1-1.918.066v-3.99h3.813Z\" fill=\"#5CD168\"></path></svg>",
18
+ "FileRoundBitableV2Colorful": "<svg width=\"100%\" height=\"100%\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" data-icon=\"FileRoundBitableV2Colorful\"><circle cx=\"12\" cy=\"12\" r=\"12\" fill=\"#F5F0FE\"></circle><path opacity=\"0.99\" d=\"M5.333 11.4v1.2c0 2.24 0 3.36.436 4.216a4 4 0 0 0 1.748 1.748C8.373 19 9.493 19 11.733 19h.533c2.24 0 3.36 0 4.216-.436a4 4 0 0 0 1.748-1.748c.436-.856.436-1.976.436-4.216v-.833c0-.652 0-.978-.073-1.285a2.666 2.666 0 0 0-.32-.77c-.165-.27-.395-.5-.856-.962l-2.501-2.5c-.461-.462-.692-.692-.96-.857a2.667 2.667 0 0 0-.772-.32C12.877 5 12.551 5 11.9 5h-.166c-2.24 0-3.36 0-4.216.436A4 4 0 0 0 5.77 7.184c-.436.856-.436 1.976-.436 4.216Z\" fill=\"#fff\"></path><path d=\"M12.232 4.667c.637 0 1.01-.003 1.364.082a3 3 0 0 1 .867.36c.31.19.573.455 1.023.905l2.167 2.167c.45.45.715.712.905 1.023a3 3 0 0 1 .36.867c.084.354.082.727.082 1.363V12.6c0 1.115 0 1.97-.055 2.655-.056.687-.171 1.23-.417 1.712a4.334 4.334 0 0 1-1.894 1.894c-.483.246-1.025.36-1.713.417-.683.056-1.54.055-2.654.055h-.534c-1.114 0-1.97 0-2.654-.055-.688-.056-1.23-.17-1.713-.417a4.334 4.334 0 0 1-1.894-1.894c-.246-.482-.36-1.025-.417-1.712C5 14.57 5 13.715 5 12.6v-1.2c0-1.115 0-1.97.055-2.655.057-.687.171-1.23.417-1.712a4.334 4.334 0 0 1 1.894-1.894c.482-.246 1.025-.36 1.713-.417.683-.056 1.54-.055 2.654-.055h.5Zm-.499.666c-1.125 0-1.95 0-2.6.054-.646.053-1.091.156-1.464.346a3.671 3.671 0 0 0-1.603 1.602c-.19.373-.293.819-.346 1.465-.053.65-.053 1.474-.053 2.6v1.2c0 1.126 0 1.95.053 2.6.053.646.156 1.092.346 1.465.352.69.913 1.25 1.603 1.602.373.19.818.294 1.464.346.65.053 1.475.054 2.6.054h.534c1.125 0 1.95 0 2.6-.054.646-.052 1.091-.156 1.464-.346a3.666 3.666 0 0 0 1.603-1.602c.19-.373.293-.819.346-1.465.053-.65.053-1.474.053-2.6v-1.166c0-.668-.002-.948-.064-1.207a2.312 2.312 0 0 0-.086-.275.834.834 0 0 0-.208-.07 3.175 3.175 0 0 0-.642-.049V9.83c-.1.002-.216.003-.347.003-.457 0-.808 0-1.09-.019-.283-.019-.508-.057-.713-.14-.54-.22-.97-.65-1.19-1.19a2.254 2.254 0 0 1-.14-.713c-.02-.282-.02-.633-.02-1.09 0-.131.001-.247.003-.348h-.003a3.18 3.18 0 0 0-.048-.642.832.832 0 0 0-.072-.208 2.334 2.334 0 0 0-.273-.085c-.26-.063-.54-.065-1.208-.065h-.499Z\" fill=\"#D9C5FC\"></path><path d=\"m9.621 12.667-.761.983a.667.667 0 0 0 .056.88l1.222 1.221a.667.667 0 0 0 .88.056l.982-.762.983.762a.667.667 0 0 0 .88-.056l1.222-1.221a.667.667 0 0 0 .055-.88l-.761-.983.761-.984a.667.667 0 0 0-.055-.88l-1.222-1.221a.667.667 0 0 0-.88-.056l-.983.762-.982-.761a.667.667 0 0 0-.88.055l-1.222 1.222a.667.667 0 0 0-.056.88l.761.983ZM12 10.288l2.379 2.379L12 15.045l-2.379-2.378L12 10.288Z\" fill=\"#8D55ED\"></path></svg>",
19
+ "FileRoundMindnoteV2Colorful": "<svg width=\"100%\" height=\"100%\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" data-icon=\"FileRoundMindnoteV2Colorful\"><circle cx=\"12\" cy=\"12\" r=\"12\" fill=\"#E7F8FE\"></circle><path opacity=\"0.99\" d=\"M5.333 11.4v1.2c0 2.24 0 3.36.436 4.216a4 4 0 0 0 1.748 1.748C8.373 19 9.493 19 11.733 19h.533c2.24 0 3.36 0 4.216-.436a4 4 0 0 0 1.748-1.748c.436-.856.436-1.976.436-4.216v-.833c0-.652 0-.978-.073-1.285a2.666 2.666 0 0 0-.32-.77c-.165-.27-.395-.5-.856-.962l-2.501-2.5c-.461-.462-.692-.692-.96-.857a2.667 2.667 0 0 0-.772-.32C12.877 5 12.551 5 11.9 5h-.166c-2.24 0-3.36 0-4.216.436A4 4 0 0 0 5.77 7.184c-.436.856-.436 1.976-.436 4.216Z\" fill=\"#fff\"></path><path d=\"M12.232 4.667c.637 0 1.01-.003 1.364.082a3 3 0 0 1 .867.36c.31.19.573.455 1.023.905l2.167 2.167c.45.45.715.712.905 1.023a3 3 0 0 1 .36.867c.084.354.082.727.082 1.363V12.6c0 1.115 0 1.97-.055 2.655-.056.687-.171 1.23-.417 1.712a4.334 4.334 0 0 1-1.894 1.894c-.483.246-1.025.36-1.713.417-.683.056-1.54.055-2.654.055h-.534c-1.114 0-1.97 0-2.654-.055-.688-.056-1.23-.17-1.713-.417a4.334 4.334 0 0 1-1.894-1.894c-.246-.482-.36-1.025-.417-1.712C5 14.57 5 13.715 5 12.6v-1.2c0-1.115 0-1.97.055-2.655.057-.687.171-1.23.417-1.712a4.334 4.334 0 0 1 1.894-1.894c.482-.246 1.025-.36 1.713-.417.683-.056 1.54-.055 2.654-.055h.5Zm-.499.666c-1.125 0-1.95 0-2.6.054-.646.053-1.091.156-1.464.346a3.671 3.671 0 0 0-1.603 1.602c-.19.373-.293.819-.346 1.465-.053.65-.053 1.474-.053 2.6v1.2c0 1.126 0 1.95.053 2.6.053.646.156 1.092.346 1.465.352.69.913 1.25 1.603 1.602.373.19.818.294 1.464.346.65.053 1.475.054 2.6.054h.534c1.125 0 1.95 0 2.6-.054.646-.052 1.091-.156 1.464-.346a3.666 3.666 0 0 0 1.603-1.602c.19-.373.293-.819.346-1.465.053-.65.053-1.474.053-2.6v-1.166c0-.668-.002-.948-.064-1.207a2.312 2.312 0 0 0-.086-.275.834.834 0 0 0-.208-.07 3.175 3.175 0 0 0-.642-.049V9.83c-.1.002-.216.003-.347.003-.457 0-.808 0-1.09-.019-.283-.019-.508-.057-.713-.14-.54-.22-.97-.65-1.19-1.19a2.254 2.254 0 0 1-.14-.713c-.02-.282-.02-.633-.02-1.09 0-.131.001-.247.003-.348h-.003a3.18 3.18 0 0 0-.048-.642.832.832 0 0 0-.072-.208 2.334 2.334 0 0 0-.273-.085c-.26-.063-.54-.065-1.208-.065h-.499Z\" fill=\"#A5DFFA\"></path><path d=\"M15.61 15.098a.833.833 0 1 1-1.21-.743v-.072a2.4 2.4 0 0 0-1.978-2.362v2.433a.833.833 0 1 1-.8.028v-2.47a2.4 2.4 0 0 0-2.021 2.37v.074a.832.832 0 1 1-.8.024v-.097a3.2 3.2 0 0 1 2.821-3.177v-.687a.832.832 0 0 1 .422-1.552.834.834 0 0 1 .378 1.576v.67a3.199 3.199 0 0 1 2.778 3.17v.098c.245.145.41.411.41.717Z\" fill=\"#047FB0\"></path></svg>",
20
+ "FileRoundUnknowV2Colorful": "<svg width=\"100%\" height=\"100%\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" data-icon=\"FileRoundUnknowV2Colorful\"><circle cx=\"12\" cy=\"12\" r=\"12\" fill=\"#F5F6F7\"></circle><path opacity=\"0.99\" d=\"M5.333 11.4v1.2c0 2.24 0 3.36.436 4.216a4 4 0 0 0 1.748 1.748C8.373 19 9.493 19 11.733 19h.533c2.24 0 3.36 0 4.216-.436a4 4 0 0 0 1.748-1.748c.436-.856.436-1.976.436-4.216v-.833c0-.652 0-.978-.073-1.285a2.666 2.666 0 0 0-.32-.77c-.165-.27-.395-.5-.856-.962l-2.501-2.5c-.461-.462-.692-.692-.96-.857a2.667 2.667 0 0 0-.772-.32C12.877 5 12.551 5 11.9 5h-.166c-2.24 0-3.36 0-4.216.436A4 4 0 0 0 5.77 7.184c-.436.856-.436 1.976-.436 4.216Z\" fill=\"#fff\"></path><path d=\"M12.232 4.667c.637 0 1.01-.003 1.364.082a3 3 0 0 1 .867.36c.31.19.573.455 1.023.905l2.167 2.167c.45.45.715.712.905 1.023a3 3 0 0 1 .36.867c.084.354.082.727.082 1.363V12.6c0 1.115 0 1.97-.055 2.655-.056.687-.171 1.23-.417 1.712a4.334 4.334 0 0 1-1.894 1.894c-.483.246-1.025.36-1.713.417-.683.056-1.54.055-2.654.055h-.534c-1.114 0-1.97 0-2.654-.055-.688-.056-1.23-.17-1.713-.417a4.334 4.334 0 0 1-1.894-1.894c-.246-.482-.36-1.025-.417-1.712C5 14.57 5 13.715 5 12.6v-1.2c0-1.115 0-1.97.055-2.655.057-.687.171-1.23.417-1.712a4.334 4.334 0 0 1 1.894-1.894c.482-.246 1.025-.36 1.713-.417.683-.056 1.54-.055 2.654-.055h.5Zm-.499.666c-1.125 0-1.95 0-2.6.054-.646.053-1.091.156-1.464.346a3.671 3.671 0 0 0-1.603 1.602c-.19.373-.293.819-.346 1.465-.053.65-.053 1.474-.053 2.6v1.2c0 1.126 0 1.95.053 2.6.053.646.156 1.092.346 1.465.352.69.913 1.25 1.603 1.602.373.19.818.294 1.464.346.65.053 1.475.054 2.6.054h.534c1.125 0 1.95 0 2.6-.054.646-.052 1.091-.156 1.464-.346a3.666 3.666 0 0 0 1.603-1.602c.19-.373.293-.819.346-1.465.053-.65.053-1.474.053-2.6v-1.166c0-.668-.002-.948-.064-1.207a2.312 2.312 0 0 0-.086-.275.834.834 0 0 0-.208-.07 3.175 3.175 0 0 0-.642-.049V9.83c-.1.002-.216.003-.347.003-.457 0-.808 0-1.09-.019-.283-.019-.508-.057-.713-.14-.54-.22-.97-.65-1.19-1.19a2.254 2.254 0 0 1-.14-.713c-.02-.282-.02-.633-.02-1.09 0-.131.001-.247.003-.348h-.003a3.18 3.18 0 0 0-.048-.642.832.832 0 0 0-.072-.208 2.334 2.334 0 0 0-.273-.085c-.26-.063-.54-.065-1.208-.065h-.499Z\" fill=\"#D0D3D6\"></path><path d=\"M12 14.77a.667.667 0 1 1 0 1.334.667.667 0 0 1 0-1.334Zm0-5.844c1.128 0 2.006.947 2.006 2.067 0 .62-.265 1.18-.69 1.56-.227.205-.428.383-.58.575-.148.187-.202.331-.202.453a.534.534 0 0 1-1.067 0c0-.46.21-.833.433-1.115.22-.278.5-.522.704-.706.202-.182.335-.455.335-.767 0-.574-.441-1-.94-1-.497 0-.938.427-.938 1 0 .1.014.194.038.282a.534.534 0 0 1-1.029.283 2.11 2.11 0 0 1-.075-.565c0-1.12.877-2.067 2.005-2.067Z\" fill=\"#646A73\"></path></svg>",
21
+ "FileRoundPptV2Colorful": "<svg width=\"100%\" height=\"100%\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" data-icon=\"FileRoundPptV2Colorful\"><circle cx=\"12\" cy=\"12\" r=\"12\" fill=\"#FFF3E5\"></circle><path opacity=\"0.99\" d=\"M5.333 11.4v1.2c0 2.24 0 3.36.436 4.216a4 4 0 0 0 1.748 1.748C8.373 19 9.493 19 11.733 19h.533c2.24 0 3.36 0 4.216-.436a4 4 0 0 0 1.748-1.748c.436-.856.436-1.976.436-4.216v-.833c0-.652 0-.978-.073-1.285a2.666 2.666 0 0 0-.32-.77c-.165-.27-.395-.5-.856-.962l-2.501-2.5c-.461-.462-.692-.692-.96-.857a2.667 2.667 0 0 0-.772-.32C12.877 5 12.551 5 11.9 5h-.166c-2.24 0-3.36 0-4.216.436A4 4 0 0 0 5.77 7.184c-.436.856-.436 1.976-.436 4.216Z\" fill=\"#fff\"></path><path d=\"M12.232 4.667c.637 0 1.01-.003 1.364.082a3 3 0 0 1 .867.36c.31.19.573.455 1.023.905l2.167 2.167c.45.45.715.712.905 1.023a3 3 0 0 1 .36.867c.084.354.082.727.082 1.363V12.6c0 1.115 0 1.97-.055 2.655-.056.687-.171 1.23-.417 1.712a4.334 4.334 0 0 1-1.894 1.894c-.483.246-1.025.36-1.713.417-.683.056-1.54.055-2.654.055h-.534c-1.114 0-1.97 0-2.654-.055-.688-.056-1.23-.17-1.713-.417a4.334 4.334 0 0 1-1.894-1.894c-.246-.482-.36-1.025-.417-1.712C5 14.57 5 13.715 5 12.6v-1.2c0-1.115 0-1.97.055-2.655.057-.687.171-1.23.417-1.712a4.334 4.334 0 0 1 1.894-1.894c.482-.246 1.025-.36 1.713-.417.683-.056 1.54-.055 2.654-.055h.5Zm-.499.666c-1.125 0-1.95 0-2.6.054-.646.053-1.091.156-1.464.346a3.671 3.671 0 0 0-1.603 1.602c-.19.373-.293.819-.346 1.465-.053.65-.053 1.474-.053 2.6v1.2c0 1.126 0 1.95.053 2.6.053.646.156 1.092.346 1.465.352.69.913 1.25 1.603 1.602.373.19.818.294 1.464.346.65.053 1.475.054 2.6.054h.534c1.125 0 1.95 0 2.6-.054.646-.052 1.091-.156 1.464-.346a3.666 3.666 0 0 0 1.603-1.602c.19-.373.293-.819.346-1.465.053-.65.053-1.474.053-2.6v-1.166c0-.668-.002-.948-.064-1.207a2.312 2.312 0 0 0-.086-.275.834.834 0 0 0-.208-.07 3.175 3.175 0 0 0-.642-.049V9.83c-.1.002-.216.003-.347.003-.457 0-.808 0-1.09-.019-.283-.019-.508-.057-.713-.14-.54-.22-.97-.65-1.19-1.19a2.254 2.254 0 0 1-.14-.713c-.02-.282-.02-.633-.02-1.09 0-.131.001-.247.003-.348h-.003a3.18 3.18 0 0 0-.048-.642.832.832 0 0 0-.072-.208 2.334 2.334 0 0 0-.273-.085c-.26-.063-.54-.065-1.208-.065h-.499Z\" fill=\"#FCC38B\"></path><path d=\"M13.426 11.759c0-.666-.539-1.205-1.204-1.205h-1.156v2.41h1.156c.665 0 1.204-.54 1.204-1.205Zm1.067 0a2.272 2.272 0 0 1-2.271 2.271h-1.156v1.382a.533.533 0 0 1-1.066 0v-5.058c0-.479.388-.867.867-.867h1.355a2.272 2.272 0 0 1 2.271 2.272Z\" fill=\"#C25705\"></path></svg>",
22
+ "FileRoundSlidesV2Colorful": "<svg width=\"100%\" height=\"100%\" viewBox=\"0 0 24 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\" data-icon=\"FileRoundSlidesV2Colorful\"><circle cx=\"12\" cy=\"12\" r=\"12\" fill=\"#FFF3E5\"></circle><path opacity=\"0.99\" d=\"M5.333 11.4v1.2c0 2.24 0 3.36.436 4.216a4 4 0 0 0 1.748 1.748C8.373 19 9.493 19 11.733 19h.533c2.24 0 3.36 0 4.216-.436a4 4 0 0 0 1.748-1.748c.436-.856.436-1.976.436-4.216v-.833c0-.652 0-.978-.073-1.285a2.666 2.666 0 0 0-.32-.77c-.165-.27-.395-.5-.856-.962l-2.501-2.5c-.461-.462-.692-.692-.96-.857a2.667 2.667 0 0 0-.772-.32C12.877 5 12.551 5 11.9 5h-.166c-2.24 0-3.36 0-4.216.436A4 4 0 0 0 5.77 7.184c-.436.856-.436 1.976-.436 4.216Z\" fill=\"#fff\"></path><path d=\"M12.232 4.667c.637 0 1.01-.003 1.364.082a3 3 0 0 1 .867.36c.31.19.573.455 1.023.905l2.167 2.167c.45.45.715.712.905 1.023a3 3 0 0 1 .36.867c.084.354.082.727.082 1.363V12.6c0 1.115 0 1.97-.055 2.655-.056.687-.171 1.23-.417 1.712a4.334 4.334 0 0 1-1.894 1.894c-.483.246-1.025.36-1.713.417-.683.056-1.54.055-2.654.055h-.534c-1.114 0-1.97 0-2.654-.055-.688-.056-1.23-.17-1.713-.417a4.334 4.334 0 0 1-1.894-1.894c-.246-.482-.36-1.025-.417-1.712C5 14.57 5 13.715 5 12.6v-1.2c0-1.115 0-1.97.055-2.655.057-.687.171-1.23.417-1.712a4.334 4.334 0 0 1 1.894-1.894c.482-.246 1.025-.36 1.713-.417.683-.056 1.54-.055 2.654-.055h.5Zm-.499.666c-1.125 0-1.95 0-2.6.054-.646.053-1.091.156-1.464.346a3.671 3.671 0 0 0-1.603 1.602c-.19.373-.293.819-.346 1.465-.053.65-.053 1.474-.053 2.6v1.2c0 1.126 0 1.95.053 2.6.053.646.156 1.092.346 1.465.352.69.913 1.25 1.603 1.602.373.19.818.294 1.464.346.65.053 1.475.054 2.6.054h.534c1.125 0 1.95 0 2.6-.054.646-.052 1.091-.156 1.464-.346a3.666 3.666 0 0 0 1.603-1.602c.19-.373.293-.819.346-1.465.053-.65.053-1.474.053-2.6v-1.166c0-.668-.002-.948-.064-1.207a2.312 2.312 0 0 0-.086-.275.834.834 0 0 0-.208-.07 3.175 3.175 0 0 0-.642-.049V9.83c-.1.002-.216.003-.347.003-.457 0-.808 0-1.09-.019-.283-.019-.508-.057-.713-.14-.54-.22-.97-.65-1.19-1.19a2.254 2.254 0 0 1-.14-.713c-.02-.282-.02-.633-.02-1.09 0-.131.001-.247.003-.348h-.003a3.18 3.18 0 0 0-.048-.642.832.832 0 0 0-.072-.208 2.334 2.334 0 0 0-.273-.085c-.26-.063-.54-.065-1.208-.065h-.499Z\" fill=\"#FCC38B\"></path><path d=\"M14.833 12.833c.184 0 .335.15.317.333a3.333 3.333 0 1 1-3.65-3.65.31.31 0 0 1 .333.317V12.5c0 .184.15.333.334.333h2.666Z\" fill=\"#FF9D4C\"></path><path d=\"M15.167 12.167c.184 0 .335-.15.315-.333a2.998 2.998 0 0 0-2.65-2.649c-.182-.02-.332.13-.332.315v2.467c0 .11.09.2.2.2h2.467Z\" fill=\"#ED6D0C\"></path></svg>"
23
+ } as const;
24
+
25
+ export function DocumentIcon({
26
+ refValue,
27
+ metadata,
28
+ variant = 'inline',
29
+ }: {
30
+ refValue: MentionRef;
31
+ metadata?: DocumentMentionMetadata;
32
+ variant?: 'inline' | 'option';
33
+ }) {
34
+ const emoji = documentEmoji(metadata?.iconInfo);
35
+ const size = variant === 'option' ? 32 : 14;
36
+ const className =
37
+ variant === 'option'
38
+ ? 'inline-block shrink-0 text-center leading-none'
39
+ : '-mb-0.5 mr-0.5 inline-block text-center leading-none';
40
+ return emoji ? (
41
+ <span
42
+ aria-hidden
43
+ className={className}
44
+ style={{ width: size, height: size, fontSize: size }}
45
+ >
46
+ {emoji}
47
+ </span>
48
+ ) : (
49
+ <span
50
+ aria-hidden
51
+ className={className}
52
+ style={{ width: size, height: size }}
53
+ // Only bundled static UD SVGs enter this HTML sink; never document metadata.
54
+ dangerouslySetInnerHTML={{
55
+ __html: documentIconSvg(refValue, metadata, variant),
56
+ }}
57
+ />
58
+ );
59
+ }
60
+
61
+ const outline: Record<string, keyof typeof DOCUMENT_ICONS> = {
62
+ '1': 'FileDocV2Outlined',
63
+ '2': 'FileDocV2Outlined',
64
+ '22': 'FileDocV2Outlined',
65
+ '16': 'FileDocV2Outlined',
66
+ '44': 'FileDocV2Outlined',
67
+ '3': 'FileSheetV2Outlined',
68
+ '8': 'FileBitableV2Outlined',
69
+ '11': 'FileMindnoteV2Outlined',
70
+ '12': 'FileUnknowV2Outlined',
71
+ '15': 'FileLinkSlideV2Outlined',
72
+ '30': 'FileSlidesV2Outlined',
73
+ '38': 'FileBoardV2Outlined',
74
+ };
75
+ const colorful: Record<string, keyof typeof DOCUMENT_ICONS> = {
76
+ '1': 'FileRoundDocV2Colorful',
77
+ '2': 'FileRoundDocV2Colorful',
78
+ '22': 'FileRoundDocV2Colorful',
79
+ '3': 'FileRoundSheetV2Colorful',
80
+ '8': 'FileRoundBitableV2Colorful',
81
+ '11': 'FileRoundMindnoteV2Colorful',
82
+ '12': 'FileRoundUnknowV2Colorful',
83
+ '15': 'FileRoundPptV2Colorful',
84
+ '30': 'FileRoundSlidesV2Colorful',
85
+ };
86
+
87
+ export function documentIconSvg(
88
+ ref: MentionRef,
89
+ meta?: DocumentMentionMetadata,
90
+ variant: 'inline' | 'option' = 'inline',
91
+ ) {
92
+ const type = ref.kind === 'document' ? ref.resourceType : '';
93
+ // Inline AtSuite uses the mention type; the search panel uses a wiki's real type.
94
+ const iconType =
95
+ variant === 'option' && type === '16' && meta?.subType
96
+ ? String(meta.subType)
97
+ : type;
98
+ return DOCUMENT_ICONS[
99
+ variant === 'option'
100
+ ? colorful[iconType] || 'FileRoundDocV2Colorful'
101
+ : outline[iconType] || 'FileDocV2Outlined'
102
+ ];
103
+ }
104
+
105
+ export function documentEmoji(iconInfo?: string): string {
106
+ if (!iconInfo) return '';
107
+ try {
108
+ const { type, key } = JSON.parse(decodeURIComponent(iconInfo));
109
+ if (
110
+ type !== 1 ||
111
+ typeof key !== 'string' ||
112
+ !/^[0-9a-f]+(?:-[0-9a-f]+)*$/i.test(key)
113
+ )
114
+ return '';
115
+ return String.fromCodePoint(
116
+ ...key.split('-').map((part) => parseInt(part, 16)),
117
+ );
118
+ } catch {
119
+ return '';
120
+ }
121
+ }
122
+
123
+ // Paths inspected on the reference page (Universe Design); currentColor follows state.
124
+ const paths = {
125
+ image:
126
+ 'm10.141 17.988-4.275-.01a.3.3 0 0 1-.212-.512l4.133-4.133a.4.4 0 0 1 .566 0l1.907 1.907 5.057-5.057a.4.4 0 0 1 .683.283V17.7a.3.3 0 0 1-.3.3h-7.476a.301.301 0 0 1-.083-.012ZM4 22c-1.1 0-2-.9-2-2V4c0-1.1.9-2 2-2h16c1.1 0 2 .9 2 2v16c0 1.1-.9 2-2 2H4Zm0-2h16V4H4v16ZM6 6h3v3H6V6Z',
127
+ more: 'M5.5 11.75a1.75 1.75 0 1 1-3.5 0 1.75 1.75 0 0 1 3.5 0Zm8.225 0a1.75 1.75 0 1 1-3.5 0 1.75 1.75 0 0 1 3.5 0Zm8.275 0a1.75 1.75 0 1 1-3.5 0 1.75 1.75 0 0 1 3.5 0Z',
128
+ send: 'M21.696 13.354a1.541 1.541 0 0 0 0-2.707L3.762.937a1.515 1.515 0 0 0-1.512.03c-.469.28-.75.774-.75 1.323l1.979 7.728 8.413 1.232c.482 0 .871.335.871.75s-.39.75-.871.75a1932.6 1932.6 0 0 1-8.41 1.223L1.5 21.71c0 .548.281 1.043.75 1.324.469.279 1.034.29 1.512.03l17.934-9.71Z',
129
+ reply:
130
+ 'M16.25 19.511 13.5 22.5c-.401.438-.957.68-1.5.68s-.967-.137-1.523-.68L7.75 19.511 3 19.5c-1.1-.011-2-.9-2-2v-13c0-1.1.9-2 2-2h18c1.1 0 2 .9 2 2v13c0 1.1-.9 1.989-2 2l-4.75.011ZM5.5 10.5v1a1 1 0 0 0 1 1h1a1 1 0 0 0 1-1v-1a1 1 0 0 0-1-1h-1a1 1 0 0 0-1 1Zm6-1a1 1 0 0 0-1 1v1a1 1 0 0 0 1 1h1a1 1 0 0 0 1-1v-1a1 1 0 0 0-1-1h-1Zm5 0a1 1 0 0 0-1 1v1a1 1 0 0 0 1 1h1a1 1 0 0 0 1-1v-1a1 1 0 0 0-1-1h-1Z',
131
+ };
132
+ export function DiscussionIcon({
133
+ name,
134
+ ...props
135
+ }: SVGProps<SVGSVGElement> & { name: keyof typeof paths }) {
136
+ return (
137
+ <svg
138
+ width="14"
139
+ height="14"
140
+ viewBox="0 0 24 24"
141
+ fill="none"
142
+ aria-hidden="true"
143
+ {...props}
144
+ >
145
+ <path d={paths[name]} fill="currentColor" />
146
+ </svg>
147
+ );
148
+ }
@@ -0,0 +1,155 @@
1
+ import type { DiscussionImage } from './view-types';
2
+ import * as DialogPrimitive from '@radix-ui/react-dialog';
3
+ import { Dialog, DialogPortal, DialogOverlay, DialogTitle } from '@/components/ui/dialog';
4
+ import { ChevronLeft, ChevronRight, Maximize, Minus, Plus, RotateCcw, X } from 'lucide-react';
5
+ import { useEffect, useRef, useState } from 'react';
6
+
7
+ export const COMMENT_IMAGE_ACCEPT =
8
+ 'image/gif,image/jpg,image/jpeg,image/bmp,image/png';
9
+ export const MAX_COMMENT_IMAGE_BYTES = 20 * 1024 * 1024;
10
+
11
+ /** Decode before publishing, so a renamed/corrupt file never creates a broken attachment. */
12
+ export async function prepareCommentImage(
13
+ file: File,
14
+ owned: Set<string>,
15
+ ): Promise<DiscussionImage> {
16
+ if (!/^image\/(png|jpe?g|gif|bmp)$/.test(file.type))
17
+ throw new Error(`${file.name}:请选择 PNG、JPG、GIF 或 BMP 图片`);
18
+ if (file.size > MAX_COMMENT_IMAGE_BYTES)
19
+ throw new Error(`${file.name}:单张图片不能超过 20 MB`);
20
+ const url = URL.createObjectURL(file);
21
+ owned.add(url);
22
+ try {
23
+ const image = new window.Image();
24
+ image.src = url;
25
+ await image.decode();
26
+ if (!image.naturalWidth || !image.naturalHeight)
27
+ throw new Error('图片尺寸无效');
28
+ return {
29
+ id: crypto.randomUUID(),
30
+ url,
31
+ name: file.name,
32
+ file,
33
+ width: image.naturalWidth,
34
+ height: image.naturalHeight,
35
+ };
36
+ } catch {
37
+ owned.delete(url);
38
+ URL.revokeObjectURL(url);
39
+ throw new Error(`${file.name}:图片无法读取,请选择有效图片`);
40
+ }
41
+ }
42
+
43
+ /** Reconcile host-owned blobs after edits/deletions; retained images stay readable. */
44
+ export function releaseUnusedImageUrls(
45
+ owned: Set<string>,
46
+ activeUrls: Iterable<string>,
47
+ ): void {
48
+ const active = new Set(activeUrls);
49
+ owned.forEach((url) => {
50
+ if (!active.has(url)) {
51
+ owned.delete(url);
52
+ URL.revokeObjectURL(url);
53
+ }
54
+ });
55
+ }
56
+
57
+ /** Each message opens its own image gallery, just as the reference comment does. */
58
+ export function DiscussionImageViewer({ images, initialIndex, onClose }: {
59
+ images: DiscussionImage[];
60
+ initialIndex: number;
61
+ onClose: () => void;
62
+ }) {
63
+ const [index, setIndex] = useState(initialIndex);
64
+ const [size, setSize] = useState({ width: 0, height: 0 });
65
+ const [viewport, setViewport] = useState({ width: window.innerWidth, height: window.innerHeight });
66
+ const [zoom, setZoom] = useState<number | null>(null);
67
+ const [rotation, setRotation] = useState(0);
68
+ const [pan, setPan] = useState({ x: 0, y: 0 });
69
+ const drag = useRef<{ x: number; y: number; originX: number; originY: number } | null>(null);
70
+ const image = images[index];
71
+ const width = image.width || size.width;
72
+ const height = image.height || size.height;
73
+ const fit = width && height ? Math.min(1, viewport.width * 0.9 / width, viewport.height * 0.9 / height) : 1;
74
+ const scale = zoom ?? fit;
75
+ const changeZoom = (next: number) => setZoom(Math.min(8, Math.max(0.1, next)));
76
+ const select = (next: number) => {
77
+ if (next < 0 || next >= images.length || next === index) return;
78
+ setIndex(next);
79
+ setZoom(null);
80
+ setRotation(0);
81
+ setPan({ x: 0, y: 0 });
82
+ setSize({ width: 0, height: 0 });
83
+ };
84
+ useEffect(() => {
85
+ const resize = () => setViewport({ width: window.innerWidth, height: window.innerHeight });
86
+ window.addEventListener('resize', resize);
87
+ return () => window.removeEventListener('resize', resize);
88
+ }, []);
89
+ return (
90
+ <Dialog open onOpenChange={(open) => { if (!open) onClose(); }}>
91
+ <DialogPortal>
92
+ <DialogOverlay className="replica-image-backdrop" />
93
+ <DialogPrimitive.Content
94
+ className="replica-image-viewer"
95
+ aria-describedby={undefined}
96
+ onKeyDown={(event) => {
97
+ if (event.key === 'ArrowLeft') select(index - 1);
98
+ else if (event.key === 'ArrowRight') select(index + 1);
99
+ else if (event.key === '+' || event.key === '=') changeZoom(scale * 1.2);
100
+ else if (event.key === '-') changeZoom(scale / 1.2);
101
+ else return;
102
+ event.preventDefault();
103
+ }}
104
+ >
105
+ <DialogTitle className="sr-only">{image.name}</DialogTitle>
106
+ <div
107
+ className="replica-image-canvas"
108
+ onClick={(event) => { if (event.target === event.currentTarget) onClose(); }}
109
+ onWheel={(event) => changeZoom(scale * (event.deltaY < 0 ? 1.1 : 1 / 1.1))}
110
+ >
111
+ <img
112
+ src={image.url}
113
+ alt={image.name}
114
+ draggable={false}
115
+ onLoad={(event) => setSize({ width: event.currentTarget.naturalWidth, height: event.currentTarget.naturalHeight })}
116
+ style={{
117
+ width: width ? width * scale : undefined,
118
+ height: height ? height * scale : undefined,
119
+ transform: `translate(${pan.x}px, ${pan.y}px) rotate(${rotation}deg)`,
120
+ }}
121
+ onPointerDown={(event) => {
122
+ if (event.button !== 0) return;
123
+ event.preventDefault();
124
+ event.currentTarget.setPointerCapture(event.pointerId);
125
+ drag.current = { x: event.clientX, y: event.clientY, originX: pan.x, originY: pan.y };
126
+ }}
127
+ onPointerMove={(event) => {
128
+ if (drag.current) setPan({ x: drag.current.originX + event.clientX - drag.current.x, y: drag.current.originY + event.clientY - drag.current.y });
129
+ }}
130
+ onPointerUp={() => { drag.current = null; }}
131
+ onPointerCancel={() => { drag.current = null; }}
132
+ />
133
+ </div>
134
+ <DialogPrimitive.Close className="replica-viewer-close" aria-label="关闭图片预览"><X size={24} /></DialogPrimitive.Close>
135
+ {images.length > 1 && <>
136
+ <button type="button" className="replica-viewer-prev" aria-label="上一张" disabled={index === 0} onClick={() => select(index - 1)}><ChevronLeft size={30} /></button>
137
+ <button type="button" className="replica-viewer-next" aria-label="下一张" disabled={index === images.length - 1} onClick={() => select(index + 1)}><ChevronRight size={30} /></button>
138
+ </>}
139
+ <div className="replica-viewer-toolbar" role="toolbar" aria-label="图片操作">
140
+ <button type="button" aria-label="上一张" title="上一张" disabled={index === 0} onClick={() => select(index - 1)}><ChevronLeft size={20} /></button>
141
+ <span aria-live="polite">{index + 1}/{images.length}</span>
142
+ <button type="button" aria-label="下一张" title="下一张" disabled={index === images.length - 1} onClick={() => select(index + 1)}><ChevronRight size={20} /></button>
143
+ <i />
144
+ <button type="button" aria-label="缩小" title="缩小" onClick={() => changeZoom(scale / 1.2)}><Minus size={20} /></button>
145
+ <span className="replica-viewer-ratio">{Math.round(scale * 100)}%</span>
146
+ <button type="button" aria-label="放大" title="放大" onClick={() => changeZoom(scale * 1.2)}><Plus size={20} /></button>
147
+ <button type="button" aria-label="原始尺寸" title="原始尺寸" onClick={() => { setZoom(scale === 1 ? null : 1); setPan({ x: 0, y: 0 }); }}><Maximize size={20} /></button>
148
+ <i />
149
+ <button type="button" aria-label="旋转" title="旋转" onClick={() => setRotation((value) => value - 90)}><RotateCcw size={20} /></button>
150
+ </div>
151
+ </DialogPrimitive.Content>
152
+ </DialogPortal>
153
+ </Dialog>
154
+ );
155
+ }
@@ -0,0 +1,163 @@
1
+ import type { CommentDataSource, MentionOption, MentionRef, MentionResult, CommentValue } from '../types';
2
+ import { mentionKey, collectMentionRefs } from './model';
3
+ import * as React from 'react';
4
+ import { createContext, useContext, useEffect, useMemo, useSyncExternalStore, type ReactNode } from 'react';
5
+
6
+ /** One store per authenticated scope, shared by editors and all list items. */
7
+ export class EntityStore {
8
+ private cache = new Map<string, { value: MentionResult; until: number }>();
9
+ private listeners = new Set<() => void>();
10
+ private queue = new Map<string, MentionRef>();
11
+ private pending = new Set<string>();
12
+ private controllers = new Set<AbortController>();
13
+ private scheduled = false;
14
+ private generation = 0;
15
+
16
+ constructor(readonly source: CommentDataSource) {}
17
+ subscribe = (listener: () => void) => {
18
+ this.listeners.add(listener);
19
+ return () => {
20
+ this.listeners.delete(listener);
21
+ };
22
+ };
23
+ peek = (ref: MentionRef) => this.cache.get(mentionKey(ref))?.value;
24
+ seed(items: MentionOption[]) {
25
+ for (const item of items) this.write({ ...item, status: 'resolved' });
26
+ }
27
+ private write(value: MentionResult) {
28
+ const key = mentionKey(value.ref);
29
+ this.cache.delete(key);
30
+ this.cache.set(key, {
31
+ value,
32
+ until: Date.now() + (value.status === 'resolved' ? 300_000 : 30_000),
33
+ });
34
+ if (this.cache.size > 500)
35
+ this.cache.delete(this.cache.keys().next().value!);
36
+ for (const listener of this.listeners) listener();
37
+ }
38
+ ensure(refs: MentionRef[], force = false) {
39
+ for (const ref of refs) {
40
+ const key = mentionKey(ref);
41
+ if (
42
+ !this.pending.has(key) &&
43
+ (force || (this.cache.get(key)?.until || 0) <= Date.now())
44
+ )
45
+ this.queue.set(key, ref);
46
+ }
47
+ if (!this.scheduled && this.queue.size) {
48
+ this.scheduled = true;
49
+ queueMicrotask(() => {
50
+ this.scheduled = false;
51
+ void this.flush();
52
+ });
53
+ }
54
+ }
55
+ private async flush() {
56
+ const refs = [...this.queue.values()];
57
+ this.queue.clear();
58
+ const generation = this.generation;
59
+ for (let i = 0; i < refs.length; i += 50) {
60
+ const batch = refs.slice(i, i + 50);
61
+ batch.forEach((ref) => this.pending.add(mentionKey(ref)));
62
+ const controller = new AbortController();
63
+ this.controllers.add(controller);
64
+ void this.source
65
+ .resolve(batch, controller.signal)
66
+ .then((results) => {
67
+ if (generation !== this.generation) return;
68
+ const byKey = new Map(
69
+ results.map((item) => [mentionKey(item.ref), item]),
70
+ );
71
+ for (const ref of batch)
72
+ this.write(byKey.get(mentionKey(ref)) || { ref, status: 'error' });
73
+ })
74
+ .catch(() => {
75
+ if (generation === this.generation)
76
+ for (const ref of batch) this.write({ ref, status: 'error' });
77
+ })
78
+ .finally(() => {
79
+ this.controllers.delete(controller);
80
+ if (generation === this.generation)
81
+ batch.forEach((ref) => this.pending.delete(mentionKey(ref)));
82
+ });
83
+ }
84
+ }
85
+ clear() {
86
+ this.generation++;
87
+ for (const controller of this.controllers) controller.abort();
88
+ this.controllers.clear();
89
+ this.pending.clear();
90
+ this.queue.clear();
91
+ this.cache.clear();
92
+ for (const listener of this.listeners) listener();
93
+ }
94
+ }
95
+
96
+ const Context = createContext<{
97
+ store: EntityStore;
98
+ strict: boolean;
99
+ currentUserID?: string;
100
+ highlightUserIDs?: readonly string[];
101
+ resolveUserRef?: (id: string) => MentionRef;
102
+ } | null>(null);
103
+
104
+ export function MentionProvider({
105
+ source,
106
+ snapshotPolicy = 'immediate',
107
+ currentUserID,
108
+ highlightUserIDs,
109
+ resolveUserRef,
110
+ children,
111
+ }: {
112
+ source: CommentDataSource;
113
+ currentUserID?: string;
114
+ highlightUserIDs?: readonly string[];
115
+ resolveUserRef?: (id: string) => MentionRef;
116
+ snapshotPolicy?: 'immediate' | 'after-resolve';
117
+ children: ReactNode;
118
+ }) {
119
+ const store = useMemo(
120
+ () => new EntityStore(source),
121
+ [source, source.scopeKey],
122
+ );
123
+ useEffect(() => () => store.clear(), [store]);
124
+ const context = useMemo(
125
+ () => ({
126
+ store,
127
+ strict: snapshotPolicy === 'after-resolve',
128
+ currentUserID,
129
+ highlightUserIDs,
130
+ resolveUserRef,
131
+ }),
132
+ [store, snapshotPolicy, currentUserID, highlightUserIDs, resolveUserRef],
133
+ );
134
+ return React.createElement(Context.Provider, { value: context }, children);
135
+ }
136
+
137
+ export function useMentionContext() {
138
+ const context = useContext(Context);
139
+ if (!context) throw new Error('评论组件需要放在 MentionProvider 中');
140
+ return context;
141
+ }
142
+
143
+ export function useMentionEntity(ref: MentionRef) {
144
+ const { store } = useMentionContext();
145
+ const key = mentionKey(ref);
146
+ useEffect(() => {
147
+ store.ensure([ref]);
148
+ }, [store, key]);
149
+ return useSyncExternalStore(
150
+ store.subscribe,
151
+ () => store.peek(ref),
152
+ () => undefined,
153
+ );
154
+ }
155
+
156
+ export function useResolveComment(value: CommentValue) {
157
+ const { store } = useMentionContext();
158
+ const refs = collectMentionRefs(value);
159
+ const keys = JSON.stringify(refs.map(mentionKey));
160
+ useEffect(() => {
161
+ store.ensure(refs);
162
+ }, [store, keys]);
163
+ }