wendang-react 0.6.3 → 0.6.5
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.
- package/NOTICE.md +1 -1
- package/README.md +133 -1
- package/dist/bindings/yjs.js +1 -5
- package/dist/chunks/AnchoredPanel-C7jMoPze.js +1 -0
- package/dist/chunks/DocumentExportMenu-CUMsgq3w.js +2 -0
- package/dist/chunks/Dropdown-D98tXfe0.js +3 -0
- package/dist/chunks/MindMapCanvas-C46Q5JBU.js +163 -0
- package/dist/chunks/MindMapViewer-C9zxZIW8.js +13 -0
- package/dist/chunks/SpreadsheetViewer-CoQ4VIgj.js +23 -0
- package/dist/chunks/code-highlight-BmaqTe1m.js +1 -30
- package/dist/chunks/code-highlight-engine-BFDzDPzy.js +1 -40
- package/dist/chunks/comment-hint-BhUxKjKK.js +14 -0
- package/dist/chunks/composition-state-Bl-U1R_2.js +1 -40
- package/dist/chunks/extensions-BefQ1tDm.js +14 -0
- package/dist/chunks/fuzzy-match-DYQR-4w2.js +1 -89
- package/dist/chunks/hooks-C53Dp0pr.js +1 -35
- package/dist/chunks/i18n-B0kCsIjc.js +2 -0
- package/dist/chunks/index-COeA2QcQ.js +15 -0
- package/dist/chunks/katex-WjrodtTU.js +1 -71
- package/dist/chunks/locale-DWpIJ_9X.js +1 -0
- package/dist/chunks/mind-map-controller-Ce76mETT.js +1 -0
- package/dist/chunks/mind-map-delete-CVsxdXfs.js +1 -31
- package/dist/chunks/mind-map-input-CEWRz_t6.js +1 -43
- package/dist/chunks/mind-topic-text-BHXkxexr.js +30 -0
- package/dist/chunks/popover-placement-D3xVYdkt.js +1 -47
- package/dist/chunks/worksheet-engine-c84sdD4N.js +1 -0
- package/dist/chunks/worksheet-preview-DsDVWxIM.js +1 -129
- package/dist/document/viewer.js +30 -289
- package/dist/document.js +120 -3811
- package/dist/export/json.js +1 -5
- package/dist/export/markdown.js +1 -2
- package/dist/export/mindmap.js +1 -2
- package/dist/export/pdf.js +1 -6
- package/dist/export/word.js +1 -2
- package/dist/export.js +1 -2
- package/dist/i18n.js +1 -0
- package/dist/index.js +1 -8
- package/dist/locales/en-US.js +1 -0
- package/dist/locales/es-ES.js +1 -0
- package/dist/locales/ja-JP.js +1 -0
- package/dist/locales/ko-KR.js +1 -0
- package/dist/locales/zh-CN.js +1 -0
- package/dist/locales/zh-TW.js +1 -0
- package/dist/mindmap/viewer.js +1 -6
- package/dist/mindmap.js +3 -123
- package/dist/shared.js +1 -52
- package/dist/spreadsheet/viewer.js +1 -5
- package/dist/spreadsheet/xlsx.js +1 -299
- package/dist/spreadsheet.js +2 -120
- package/dist/styles/callout.css +1 -34
- package/dist/styles/code-block.css +1 -58
- package/dist/styles/content-style.css +1 -619
- package/dist/styles/content-tokens.css +1 -29
- package/dist/styles/editor-interaction.css +1 -621
- package/dist/styles/file-video.css +1 -12
- package/dist/styles/image-preview.css +1 -103
- package/dist/styles/mind-map-block.css +1 -14
- package/dist/styles/mind-map-canvas.css +1 -80
- package/dist/styles/mind-map-comments.css +1 -93
- package/dist/styles/mind-map-details.css +1 -7
- package/dist/styles/mind-map-preview.css +1 -7
- package/dist/styles/mind-map-topic.css +1 -112
- package/dist/styles/page-picker.css +1 -47
- package/dist/styles/renderer.css +1 -45
- package/dist/styles/spreadsheet-editor.css +1 -3
- package/dist/styles/tokens.css +1 -142
- package/dist/styles/video-dialog.css +1 -41
- package/dist/styles/video-embed.css +1 -35
- package/dist/styles.css +1 -2655
- package/dist/types/editor/BlockAffordance.d.ts +5 -2
- package/dist/types/editor/CalloutView.d.ts +2 -1
- package/dist/types/editor/ImagePreview.d.ts +1 -1
- package/dist/types/editor/PagePicker.d.ts +1 -1
- package/dist/types/editor/extensions.d.ts +4 -1
- package/dist/types/engine/editor/block-commands.d.ts +1 -1
- package/dist/types/engine/editor/block-menu-hover.d.ts +16 -0
- package/dist/types/engine/editor/extensions/locale.d.ts +3 -0
- package/dist/types/engine/editor/nodes/image-nodeview.d.ts +1 -1
- package/dist/types/engine/editor/video-block-controls.d.ts +13 -0
- package/dist/types/engine/host.d.ts +60 -2
- package/dist/types/engine/renderer/attachments.d.ts +3 -3
- package/dist/types/engine/shared/video-feedback.d.ts +1 -1
- package/dist/types/engine/worksheets/worksheet-engine.d.ts +1 -0
- package/dist/types/engine/worksheets/worksheet-xlsx.d.ts +6 -1
- package/dist/types/host-types.d.ts +2 -60
- package/dist/types/host.d.ts +8 -1
- package/dist/types/i18n.d.ts +3 -0
- package/dist/types/index.d.ts +2 -0
- package/dist/types/locales/en-US.d.ts +1 -0
- package/dist/types/locales/es-ES.d.ts +1 -0
- package/dist/types/locales/ja-JP.d.ts +1 -0
- package/dist/types/locales/ko-KR.d.ts +1 -0
- package/dist/types/locales/zh-CN.d.ts +1 -0
- package/dist/types/locales/zh-TW.d.ts +1 -0
- package/dist/types/renderer/media.d.ts +2 -1
- package/dist/types/spreadsheet/xlsx.d.ts +1 -1
- package/dist/types/wui/Dropdown.d.ts +2 -1
- package/dist/types/wui/index.d.ts +2 -1
- package/integrity.json +3140 -0
- package/package.json +15 -5
- package/verify-integrity.mjs +138 -0
- package/dist/chunks/AnchoredPanel-Cv4RURwF.js +0 -68
- package/dist/chunks/DocumentExportMenu-BrGipZ59.js +0 -75
- package/dist/chunks/MindMapCanvas-tkFBBs4g.js +0 -2090
- package/dist/chunks/MindMapViewer-DJrryb2Y.js +0 -180
- package/dist/chunks/SpreadsheetViewer-DxCxIUx_.js +0 -163
- package/dist/chunks/comment-hint-B9qcrqvn.js +0 -296
- package/dist/chunks/extensions-ByORRoRa.js +0 -4210
- package/dist/chunks/host-C-V688Rq.js +0 -197
- package/dist/chunks/index-DdfMnva8.js +0 -726
- package/dist/chunks/mind-map-controller-B6SxK3GZ.js +0 -479
- package/dist/chunks/mind-topic-text-DSyb95vL.js +0 -446
- package/dist/chunks/nodes-iKqTGr_N.js +0 -291
- package/dist/chunks/worksheet-engine-TJ54m0KC.js +0 -125
- package/third-party-notices/wendang-export@0.6.0-NOTICE.md.txt +0 -51
- package/third-party-notices/wendang-export@0.6.1-LICENSE.txt +0 -21
- package/third-party-notices/wendang-export@0.6.2-LICENSE.txt +0 -21
- package/third-party-notices/wendang-export@0.6.2-NOTICE.md.txt +0 -70
- /package/third-party-notices/{wendang-export@0.6.0-LICENSE.txt → wendang-export@0.6.4-LICENSE.txt} +0 -0
- /package/third-party-notices/{wendang-export@0.6.1-NOTICE.md.txt → wendang-export@0.6.4-NOTICE.md.txt} +0 -0
package/NOTICE.md
CHANGED
|
@@ -410,7 +410,7 @@ Wendang is licensed under the MIT License; see LICENSE. Third-party components r
|
|
|
410
410
|
| util-deprecate | 1.0.2 | MIT | LICENSE |
|
|
411
411
|
| uuid | 8.3.2 | MIT | LICENSE.md |
|
|
412
412
|
| w3c-keyname | 2.2.8 | MIT | LICENSE |
|
|
413
|
-
| wendang-export | 0.6.
|
|
413
|
+
| wendang-export | 0.6.4 | MIT | LICENSE, NOTICE.md |
|
|
414
414
|
| which-boxed-primitive | 1.1.1 | MIT | LICENSE |
|
|
415
415
|
| which-builtin-type | 1.2.1 | MIT | LICENSE |
|
|
416
416
|
| which-collection | 1.0.2 | MIT | LICENSE |
|
package/README.md
CHANGED
|
@@ -4,6 +4,8 @@
|
|
|
4
4
|
|
|
5
5
|
[在线演示](https://doc.yjmf.com) · [Vue 版本](https://www.npmjs.com/package/wendang-vue) · [数据工具与服务端校验](https://www.npmjs.com/package/wendang) · [源码](https://gitee.com/ztes/wendang)
|
|
6
6
|
|
|
7
|
+
在线使用说明:[简体中文](https://doc.yjmf.com/?view=sdk&lang=zh-CN&package=wendang-react) · [繁體中文](https://doc.yjmf.com/?view=sdk&lang=zh-TW&package=wendang-react) · [English](https://doc.yjmf.com/?view=sdk&lang=en-US&package=wendang-react) · [日本語](https://doc.yjmf.com/?view=sdk&lang=ja-JP&package=wendang-react) · [한국어](https://doc.yjmf.com/?view=sdk&lang=ko-KR&package=wendang-react) · [Español](https://doc.yjmf.com/?view=sdk&lang=es-ES&package=wendang-react)。
|
|
8
|
+
|
|
7
9
|
## 安装
|
|
8
10
|
|
|
9
11
|
在 React **18.3+ 或 19** 应用中安装:
|
|
@@ -503,7 +505,9 @@ return file; // { blob, name, warnings },宿主提示降级信息并下载 blo
|
|
|
503
505
|
}
|
|
504
506
|
```
|
|
505
507
|
|
|
506
|
-
PDF 直接生成文件,正文可搜索、复制,支持中文、图片、合并表格和重复表头。块级与行内公式按需转为可缩放矢量,保留上下标、分式、根号和矩阵等排版;语法无效或不支持时保留 LaTeX
|
|
508
|
+
PDF 直接生成文件,正文可搜索、复制,支持中文、图片、合并表格和重复表头。块级与行内公式按需转为可缩放矢量,保留上下标、分式、根号和矩阵等排版;语法无效或不支持时保留 LaTeX 并告警。公式图形不提供可编辑文本层。PDF/Word 保留并排分栏;视频以含原站链接的静态卡片保留。转换提示从 `warnings` 返回。`ContentHost.exports.request` 接管组件内的文件导出;配置后拒绝请求不回退导出当前模型,权限与版本由宿主决定。
|
|
509
|
+
|
|
510
|
+
Word 与 PDF 共用正文、标题、颜色和间距基线,保留表格列宽比例、合并、对齐、背景及图片行分组。高亮块图标与正文并排,短块同页,长块允许分页;常规公式生成可编辑的 Word 公式,复杂公式尝试图形后备并提示。正文与表格仍可编辑。Word/WPS 的字体、分页及直角边框可能与 PDF 不同。
|
|
507
511
|
|
|
508
512
|
### Vite 开发环境的字体资源
|
|
509
513
|
|
|
@@ -516,3 +520,131 @@ export default {
|
|
|
516
520
|
```
|
|
517
521
|
|
|
518
522
|
只排除字体地址模块,PDF 引擎仍可预打包。生产构建继续自动生成带散列的静态字体资源。`loadPdfFont` 会校验实际字体字节,拒绝 HTTP 200 的 HTML 回退响应。
|
|
523
|
+
|
|
524
|
+
## 包完整性校验
|
|
525
|
+
|
|
526
|
+
发布构建压缩 JS/CSS,保留 `use client`、公开导出、属性名称和许可证,不分发 source map。包内 `integrity.json` 与独立 Node 工具记录 JS/CSS、类型、资源、说明、许可证和规范化包元数据的 SHA-256。安装后可执行:
|
|
527
|
+
|
|
528
|
+
```sh
|
|
529
|
+
node node_modules/wendang-react/verify-integrity.mjs
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
从可信发布记录取得清单的 `digest` 后,加 `--expected "64位SHA256摘要"` 可固定校验基线。未固定摘要的自校验不能识别文件与清单被同时改写;哈希不是签名或代码加密。请保留锁文件的包完整性信息。此工具按需运行,不在页面加载或安装时自动执行。
|
|
533
|
+
|
|
534
|
+
## 国际化与语言包
|
|
535
|
+
|
|
536
|
+
界面默认简体中文。首批提供 `zh-CN`、`zh-TW`、`en-US`、`ja-JP`、`ko-KR`、`es-ES`,通过 `ContentProvider` 的 `locale` 属性切换。语言包与 Vue 共用,不需要安装 react-i18next。下面是可直接运行的动态切换示例:
|
|
537
|
+
|
|
538
|
+
```tsx
|
|
539
|
+
import { useState } from 'react';
|
|
540
|
+
import { ContentProvider } from 'wendang-react';
|
|
541
|
+
import { DocumentEditor } from 'wendang-react/document';
|
|
542
|
+
import zhCN from 'wendang-react/locales/zh-CN';
|
|
543
|
+
import enUS from 'wendang-react/locales/en-US';
|
|
544
|
+
import type { ProseMirrorDoc } from 'wendang/types';
|
|
545
|
+
import 'wendang-react/styles.css';
|
|
546
|
+
|
|
547
|
+
const languages = { 'zh-CN': zhCN, 'en-US': enUS };
|
|
548
|
+
type Language = keyof typeof languages;
|
|
549
|
+
const messages = { 'export.trigger': 'Download' };
|
|
550
|
+
|
|
551
|
+
export default function App() {
|
|
552
|
+
const [language, setLanguage] = useState<Language>('zh-CN');
|
|
553
|
+
const [doc, setDoc] = useState<ProseMirrorDoc>({ type: 'doc', content: [{ type: 'paragraph' }] });
|
|
554
|
+
return <>
|
|
555
|
+
<select value={language} aria-label="Language"
|
|
556
|
+
onChange={event => setLanguage(event.target.value as Language)}>
|
|
557
|
+
<option value="zh-CN">简体中文</option>
|
|
558
|
+
<option value="en-US">English</option>
|
|
559
|
+
</select>
|
|
560
|
+
<ContentProvider locale={languages[language]} messages={messages}>
|
|
561
|
+
<DocumentEditor value={doc} onChange={setDoc} />
|
|
562
|
+
</ContentProvider>
|
|
563
|
+
</>;
|
|
564
|
+
}
|
|
565
|
+
```
|
|
566
|
+
|
|
567
|
+
不需要覆盖文案时省略 `messages`。对象键使用类型检查的语义键,覆盖优先于语言包,再回退默认中文。不要给 Provider 或 Editor 加 `key={language}`,以免重建实例;语言变化只刷新界面,既有正文、标题、表名和快照字段保持原值。多实例可以分别传入不同语言,不使用全局语言单例。
|
|
568
|
+
|
|
569
|
+
按需加载时使用显式导入表,加载完语言对象后更新 Provider 的 `locale`:
|
|
570
|
+
|
|
571
|
+
```ts
|
|
572
|
+
import type { WendangLocale } from 'wendang-react/i18n';
|
|
573
|
+
export const localeLoaders: Record<string, () => Promise<{ default: WendangLocale }>> = {
|
|
574
|
+
'en-US': () => import('wendang-react/locales/en-US'),
|
|
575
|
+
'ja-JP': () => import('wendang-react/locales/ja-JP'),
|
|
576
|
+
};
|
|
577
|
+
export async function loadLocale(id: string): Promise<WendangLocale> {
|
|
578
|
+
const loader = localeLoaders[id];
|
|
579
|
+
if (!loader) throw new Error('Unsupported locale');
|
|
580
|
+
return (await loader()).default;
|
|
581
|
+
}
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
已有宿主语言系统可用其当前标识选择上述对象。SSR 每个请求持有独立状态;快速切换需忽略过期加载结果,失败继续保留当前语言。SDK 不自动读取或持久化宿主语言,不修改网页全局语言;Provider 和门户具有实例自己的 `lang`。
|
|
585
|
+
|
|
586
|
+
工作表菜单同样使用 Provider 语言,不重建工作簿;已有日期/数字格式不被自动改写。Univer 部分金融函数和输入归一化与语言相关,业务公式仍需按目标语言验收。导出器可接收相同语言对象,例如 `wordFile(snapshot, assets, { locale: enUS })`。韩文等 PDF 正文须提供覆盖相应字形的字体,语言包不附带额外字体。示例正文与开发者参考不自动翻译。
|
|
587
|
+
|
|
588
|
+
### 韩文与外部字体接入
|
|
589
|
+
|
|
590
|
+
韩文字体可从宿主外部接入;缺少字形时仍可导出,通过 `warnings` 给出非阻断提示,部分文字可能显示异常。请使用有嵌入授权的字体,Word 的家族名需与文件一致;SDK 不主动下载外部字体。宿主可将 `warnings` 显示为带配置链接的 Notification 或 Alert。演示站右上角通知默认 12 秒后关闭,悬停或聚焦时暂停。
|
|
591
|
+
|
|
592
|
+
```ts
|
|
593
|
+
import { pdfFile, loadPdfFont } from 'wendang-react/export/pdf';
|
|
594
|
+
import { wordFile } from 'wendang-react/export/word';
|
|
595
|
+
import type { ExportSnapshot, ExportAssets } from 'wendang-react/export';
|
|
596
|
+
import type { WendangLocale } from 'wendang-react/i18n';
|
|
597
|
+
export async function exportWithExternalFont(
|
|
598
|
+
snapshot: ExportSnapshot, assets: ExportAssets, signal: AbortSignal, locale?: WendangLocale,
|
|
599
|
+
) {
|
|
600
|
+
const font = await loadPdfFont('/fonts/NotoSansCJKsc-Regular.otf', { signal });
|
|
601
|
+
const pdf = await pdfFile(snapshot, assets, { font, signal, locale });
|
|
602
|
+
const word = await wordFile(snapshot, assets, {
|
|
603
|
+
signal, locale, font: { family: 'Noto Sans CJK SC', data: font },
|
|
604
|
+
});
|
|
605
|
+
return { pdf, word }; // 每个结果的 warnings 由宿主显示为通知。
|
|
606
|
+
}
|
|
607
|
+
```
|
|
608
|
+
|
|
609
|
+
语言选择控件、当前语言标识与持久化由接入应用提供;SDK 只通过 ContentProvider 的 locale / messages 接收界面语言。演示站的语言按钮位于 examples 中,不属于 SDK 公共组件。
|
|
610
|
+
|
|
611
|
+
### 视频加载配置
|
|
612
|
+
|
|
613
|
+
插入弹窗只显示链接输入及必要校验,不展示固定平台长说明。播放器外框、按钮和链接使用 Provider 的语言,编辑态与阅读态一致。默认点击后才创建外部 iframe:
|
|
614
|
+
|
|
615
|
+
```tsx
|
|
616
|
+
import { useState } from 'react';
|
|
617
|
+
import { ContentProvider } from 'wendang-react';
|
|
618
|
+
import { DocumentViewer } from 'wendang-react/document/viewer';
|
|
619
|
+
import enUS from 'wendang-react/locales/en-US';
|
|
620
|
+
import type { ProseMirrorDoc } from 'wendang/types';
|
|
621
|
+
import 'wendang-react/styles.css';
|
|
622
|
+
const doc: ProseMirrorDoc = { type: 'doc', content: [{
|
|
623
|
+
type: 'videoEmbed', attrs: { provider: 'youtube', videoId: 'dQw4w9WgXcQ', page: 1, startSeconds: 0 },
|
|
624
|
+
}] };
|
|
625
|
+
export default function VideoExample() {
|
|
626
|
+
const [load, setLoad] = useState<'manual' | 'auto'>('manual');
|
|
627
|
+
return <>
|
|
628
|
+
<select value={load} aria-label="Video loading"
|
|
629
|
+
onChange={event => setLoad(event.target.value as 'manual' | 'auto')}>
|
|
630
|
+
<option value="manual">Click to load</option>
|
|
631
|
+
<option value="auto">Load automatically</option>
|
|
632
|
+
</select>
|
|
633
|
+
<ContentProvider locale={enUS} video={{ load, providers: ['youtube', 'bilibili', 'vimeo'] }}>
|
|
634
|
+
<DocumentViewer value={doc} />
|
|
635
|
+
</ContentProvider>
|
|
636
|
+
</>;
|
|
637
|
+
}
|
|
638
|
+
```
|
|
639
|
+
|
|
640
|
+
省略 `video` 使用默认 `load: 'manual'`;`load: 'auto'` 在挂载后创建播放器,浏览器仍可按可见范围延迟网络加载,SDK 不开启自动播放权限。`providers` 省略时启用全部内置平台,空数组禁止内嵌加载,可选 `youtube`、`bilibili`、`vimeo`、`youku`、`tencent`、`acfun`。该配置不写入文档快照,未启用平台保留原文链接。新增平台需要相应的安全链接解析和播放器映射,不将任意输入直接作为 iframe 地址。
|
|
641
|
+
|
|
642
|
+
插入视频时可勾选「自动加载视频」。此选择保存为视频节点的 `attrs.autoLoad`:`true` 直接加载播放器,`false` 显示「加载视频」按钮,均不自动播放。未设置或为 `null` 的旧节点继承 Provider 的 `video.load` 默认值;平台限制和窄栏限制仍然生效。Provider 配置本身不写入正文。
|
|
643
|
+
|
|
644
|
+
在编辑态,将鼠标移到视频上,或用 Tab 聚焦视频块,即可显示视频工具栏;聚焦后按 Enter 可进入工具栏。可重新加载播放器、修改视频链接、切换自动加载、在原站打开、复制原始网页链接或删除。修改链接、加载方式和删除均支持撤销、重做;重新加载只刷新当前播放器。通用块操作仍可通过左侧块菜单完成。
|
|
645
|
+
|
|
646
|
+
点击工具栏的链条图标,在加宽的链接浮层中修改当前地址。短链接显示一行,长链接自动换行并增高;点「确认」或按 Enter 提交,按 Esc 或点击外部取消。此入口不访问剪贴板,复制原链接使用独立的复制图标。
|
|
647
|
+
|
|
648
|
+
`autoLoad` 是正文格式 13 的新持久属性;`requiredSchemaVersion` 会据此抬升最低内容版本。使用此功能的前后端应同步更新 `wendang`,工作簿格式版本仍为 10。
|
|
649
|
+
|
|
650
|
+
第三方 iframe 内文字由视频平台控制,语言包覆盖 SDK 外框、按钮与链接,不保证改变第三方播放器内部语言;原生 video 控件语言由浏览器决定。
|
package/dist/bindings/yjs.js
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";import{jsx as e}from"react/jsx-runtime";import{c as t,a as n}from"./i18n-B0kCsIjc.js";import{useRef as o,useState as r,useLayoutEffect as i}from"react";import{createPortal as l}from"react-dom";import{p as s}from"./popover-placement-D3xVYdkt.js";import{u as a,L as p,p as d}from"./index-COeA2QcQ.js";function AnchoredPanel({anchor:c,onClose:h,align:u="start",prefer:w="below",gap:f=8,label:g,role:v="dialog",className:m="",portal:b,children:x,onKeyDown:y}){t().text;const C=n(),P="function"==typeof b?b():void 0!==b?b:C.portal,j=o(null),L=o(c);L.current=c;const z=a(L,j,!0,h),[A,D]=r(null);return i(()=>{const measure=()=>{var e;const t=null==c?void 0:c.getBoundingClientRect(),n=null==(e=j.current)?void 0:e.getBoundingClientRect();if(!t||!n)return;const o="end"===u?d({trigger:t,panel:n,position:"above"===w?"tr":"br",gap:f,viewport:{width:innerWidth,height:innerHeight}}):s({align:u,prefer:w,anchor:{left:t.left,top:t.top,width:t.width,height:t.height},host:{left:0,top:0},card:{width:n.width,height:n.height},bounds:{left:0,top:0,width:window.innerWidth,height:window.innerHeight},gap:f});D({left:o.left,top:o.top})};measure();const e="undefined"==typeof ResizeObserver?null:new ResizeObserver(measure);return j.current&&(null==e||e.observe(j.current)),window.addEventListener("resize",measure),window.addEventListener("scroll",measure,!0),()=>{null==e||e.disconnect(),window.removeEventListener("resize",measure),window.removeEventListener("scroll",measure,!0)}},[c,u,w,f]),P?/* @__PURE__ */e(p,{layer:z,children:l(/* @__PURE__ */e("div",{ref:j,className:"w-popover w-popover--flush"+(m?` ${m}`:""),role:v,"aria-label":g,onKeyDown:y,onPointerDown:e=>e.stopPropagation(),onWheel:e=>e.stopPropagation(),onContextMenu:e=>e.stopPropagation(),style:{position:"fixed",left:(null==A?void 0:A.left)??-9999,top:(null==A?void 0:A.top)??-9999},children:x}),P)}):null}export{AnchoredPanel as A};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use client";import{jsxs as r,jsx as e}from"react/jsx-runtime";import{c as o,b as t}from"./i18n-B0kCsIjc.js";import{useRef as a,useState as l,useEffect as n}from"react";import{W as s}from"./index-COeA2QcQ.js";const c=[{value:"pdf",label:"PDF (.pdf)"},{value:"docx",label:"Word (.docx)"},{value:"markdown",label:"Markdown (.md)"},{value:"json",label:"JSON (.json)"}];function DocumentExportMenu(i){const u=o().text,d=t(),p=a(void 0),[m,x]=l(!1),[f,v]=l("");return n(()=>(x(!1),v(""),()=>{var r;null==(r=p.current)||r.abort(),p.current=void 0}),[i.resourceId,i.allowExport,d.scope,d.exports]),i.allowExport&&d.exports?/* @__PURE__ */r("div",{className:"document-export-menu","aria-busy":m||void 0,style:{display:"flex",alignItems:"center",flexWrap:"wrap",gap:8,fontSize:12},children:[
|
|
2
|
+
/* @__PURE__ */e(s,{value:"",label:u(m?"正在导出…":"导出"),ariaLabel:u("导出文档"),width:112,options:c,disabled:i.disabled||m,onChange:r=>{!async function execute(r){var e;if(p.current||i.disabled||!i.allowExport||!d.exports)return;if(!c.some(e=>e.value===r))return;const o=new AbortController;p.current=o,x(!0),v("");try{await d.exports.request({kind:"document",format:r,resourceId:i.resourceId,signal:o.signal})}catch(r){if(!o.signal.aborted){const o=r instanceof Error?r:new Error(String(r));v(o.message),null==(e=i.onError)||e.call(i,o)}}finally{p.current===o&&(p.current=void 0,x(!1))}}(r)}}),m&&/* @__PURE__ */e("span",{role:"status",style:{color:"var(--color-text-muted)"},children:u("正在生成文件…")}),f&&/* @__PURE__ */e("span",{role:"alert",style:{color:"var(--color-danger, #cf3d48)",overflowWrap:"anywhere"},children:f})]}):null}export{DocumentExportMenu as D};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
"use client";import{jsxs as e,Fragment as n,jsx as o}from"react/jsx-runtime";import{c as r}from"./i18n-B0kCsIjc.js";import{useState as l,useRef as t}from"react";import{a}from"./index-COeA2QcQ.js";import{A as i}from"./AnchoredPanel-C7jMoPze.js";function WDropdown({label:d,groups:s,onSelect:c,buttonProps:p,onOpenChange:u}){r().text;const[m,h]=l(!1),w=t(null),g=t(null);function changeOpen(e){h(e),null==u||u(e)}function keydown(e){var n,o;if(!m||e.nativeEvent.isComposing)return;const r=Array.from((null==(n=g.current)?void 0:n.querySelectorAll('[role="menuitem"]:not([aria-disabled="true"])'))??[]),l=r.indexOf(document.activeElement);["ArrowDown","ArrowUp","Home","End"].includes(e.key)&&r.length&&(e.preventDefault(),e.stopPropagation(),null==(o=r["Home"===e.key?0:"End"===e.key?r.length-1:l<0?"ArrowUp"===e.key?r.length-1:0:(l+("ArrowUp"===e.key?-1:1)+r.length)%r.length])||o.focus())}function select(e){e.disabled||(changeOpen(!1),c(e.value))}/* @__PURE__ */
|
|
2
|
+
return e(n,{children:[
|
|
3
|
+
/* @__PURE__ */o(a,{...p,ref:w,"aria-haspopup":"menu","aria-expanded":m,onClick:()=>changeOpen(!m),onKeyDown:keydown,children:d}),m&&/* @__PURE__ */o(i,{anchor:w.current,align:"center",gap:6,role:"menu",className:"mind-dropdown-popup",label:"string"==typeof d?d:void 0,onClose:()=>changeOpen(!1),onKeyDown:keydown,children:/* @__PURE__ */o("div",{ref:g,className:"w-dropdown",children:s.map((n,r)=>/* @__PURE__ */e("div",{className:"w-dropdown-group",role:"group","aria-label":n.title,children:[n.title&&/* @__PURE__ */o("div",{className:"w-dropdown-group__title",children:n.title}),n.items.map(n=>/* @__PURE__ */e("div",{className:"w-dropdown-option"+(n.disabled?" is-disabled":""),role:"menuitem",tabIndex:n.disabled?void 0:-1,"aria-disabled":n.disabled||void 0,onClick:()=>select(n),onKeyDown:e=>{"Enter"!==e.key&&" "!==e.key||(e.preventDefault(),select(n))},children:[n.label,n.shortcut&&/* @__PURE__ */o("span",{className:"mind-menu-key",children:n.shortcut})]},n.value))]},r))})})]})}export{WDropdown as W};
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
"use client";import{jsxs as e,jsx as t,Fragment as n}from"react/jsx-runtime";import{c as i,b as l,a as o}from"./i18n-B0kCsIjc.js";import{useState as a,useRef as r,useEffect as d,useMemo as c}from"react";import{textDifference as s,mindMapTree as u,layoutMindMap as m,MIND_MAP_PALETTE as h,mindMapDescendants as p,projectMindSideMove as v,mindMapBranchSides as f,mindMapOutline as g,mindRelationPaths as b,mindMapMarkdown as y,mindMapSvg as w,mindMapToJson as x,MIND_MAP_MAX_TOPICS as k}from"wendang/mindmap";import{TEXT_COLORS as C,HIGHLIGHT_COLORS as N,mindTopicLineHeight as I,MIND_TOPIC_FONT as S,readableTextColor as M}from"wendang/shared";import{MIND_ICONS as D,MIND_COLORS as z,MIND_BACKGROUNDS as L,branchModel as P,searchMindMap as E,parseMindMapImport as T,importBranch as A,mindMapTemplate as _,parseMindBranch as $,ancestorIds as K}from"wendang/internal/mind-map-phase2";import{normalizeMindFolds as j,firstLevelMindFolds as B}from"wendang/internal/mind-map-folding";import{p as R}from"./mind-map-delete-CVsxdXfs.js";import{mindMapDescendants as W}from"wendang/internal/mind-map";import{m as U,s as F}from"./mind-map-input-CEWRz_t6.js";import{createPortal as H}from"react-dom";import{u as G}from"./hooks-C53Dp0pr.js";import{a as Y,c as X,W as O,d as q}from"./index-COeA2QcQ.js";import{T as J,A as V}from"./mind-topic-text-BHXkxexr.js";import{W as Q}from"./Dropdown-D98tXfe0.js";import{A as Z}from"./AnchoredPanel-C7jMoPze.js";function topicsInMarquee(e,t,n=[]){const i=new Set(e.map(e=>e.id)),l=new Set([...n].filter(e=>i.has(e)));if(t.width<=0||t.height<=0)return l;for(const n of e)n.x<t.x+t.width&&n.x+n.width>t.x&&n.y<t.y+t.height&&n.y+n.height>t.y&&l.add(n.id);return l}function MindMapComments({pageId:n,blockId:o,topicId:c,topicLabel:s,canComment:u,onClose:m,onChanged:h}){const p=i(),v=p.text,f=l(),[g,b]=a([]),[y,w]=a(""),[x,k]=a(""),[C,N]=a(!1),[I,S]=a(!0),[M,D]=a(null),[z,L]=a(null),[P,E]=a(0),T=r(!0),A=r(!1);async function perform(e){if(!A.current){A.current=!0,N(!0),k("");try{await e(),null==h||h(),T.current&&(w(""),D(null),E(e=>e+1))}catch(e){T.current&&k(String(e))}finally{A.current=!1,T.current&&N(!1)}}}d(()=>(T.current=!0,()=>{T.current=!1}),[]),d(()=>{let e=!0;if(w(""),D(null),L(null),k(""),S(!0),f.comments)return f.comments.list(n).then(t=>{e&&b(t.items.filter(e=>{var t,n;return(null==(t=e.anchor)?void 0:t.prefix)===`mind:${o}`&&(null==(n=e.anchor)?void 0:n.suffix)===c}))}).catch(t=>{e&&k(String(t))}).finally(()=>{e&&S(!1)}),()=>{e=!1};S(!1)},[f.comments,n,o,c,P]);const _=s.trim()?`「${s.trim()}」`:v("当前主题"),time=e=>{const t=new Date(e);return Number.isNaN(t.getTime())?"":t.toLocaleString(p.locale)};function compose(i){if(!M||M.id!==i.id)return null;const l="edit"===M.kind;/* @__PURE__ */
|
|
2
|
+
return e("form",{className:"mind-comment__compose",onSubmit:e=>{e.preventDefault(),M.text.trim()&&(l||u)&&perform(()=>l?f.comments.update(M.id,M.text.trim()):f.comments.create(n,M.text.trim(),M.id))},children:[
|
|
3
|
+
/* @__PURE__ */t("label",{className:"mind-comment__label",children:l?v("正在编辑评论"):v("回复 {0}",{0:i.authorName})}),
|
|
4
|
+
/* @__PURE__ */t("textarea",{"aria-label":v(l?"编辑主题讨论":"回复主题讨论"),rows:l?3:2,maxLength:5e3,value:M.text,onChange:e=>D({...M,text:e.target.value})}),
|
|
5
|
+
/* @__PURE__ */e("div",{className:"mind-comment__actions",children:[
|
|
6
|
+
/* @__PURE__ */t(Y,{variant:"primary",loading:C,disabled:!M.text.trim(),htmlType:"submit",children:v(l?"保存":"发表回复")}),
|
|
7
|
+
/* @__PURE__ */t(Y,{onClick:()=>D(null),children:v("取消")})]})]})}function comment(n,i=!1){var l,o;const a="edit"===(null==M?void 0:M.kind)&&M.id===n.id;/* @__PURE__ */
|
|
8
|
+
return e("article",{className:i?"mind-comment__reply":"mind-comment",children:[
|
|
9
|
+
/* @__PURE__ */e("header",{className:"mind-comment__head",children:[
|
|
10
|
+
/* @__PURE__ */t("strong",{children:n.authorName||v("用户")}),
|
|
11
|
+
/* @__PURE__ */e("span",{children:[time(n.createdAt),n.resolved?" · 已解决":""]})]}),a?compose(n):/* @__PURE__ */t("p",{className:"mind-comment__body",children:n.deleted?v(i?"回复已删除":"评论已删除"):n.body}),!a&&/* @__PURE__ */e("div",{className:"mind-comment__actions",children:[n.canResolve&&!i&&/* @__PURE__ */t(Y,{variant:"text",disabled:C,onClick:()=>{perform(()=>f.comments.resolve(n.id,!n.resolved))},children:n.resolved?v("重新打开"):v("标记解决")}),u&&!n.deleted&&!i&&/* @__PURE__ */t(Y,{variant:"text",onClick:()=>D({kind:"reply",id:n.id,text:""}),children:v("回复")}),(null==(l=f.comments)?void 0:l.update)&&n.canEdit&&/* @__PURE__ */t(Y,{variant:"text",onClick:()=>D({kind:"edit",id:n.id,text:n.body}),children:v("编辑")}),n.canDelete&&/* @__PURE__ */t(Y,{variant:"text",disabled:C,onClick:()=>L(n.id),children:v("删除")})]}),!i&&(null==(o=n.replies)?void 0:o.map(e=>comment(e,!0))),!a&&compose(n)]},n.id)}/* @__PURE__ */
|
|
12
|
+
return e("aside",{className:"mind-comments","aria-label":v("主题讨论"),children:[
|
|
13
|
+
/* @__PURE__ */e("header",{className:"mind-comments__head",children:[
|
|
14
|
+
/* @__PURE__ */e("div",{className:"mind-comments__intro",children:[
|
|
15
|
+
/* @__PURE__ */t("strong",{children:p.t("mind.discussionTitle",{title:_})}),
|
|
16
|
+
/* @__PURE__ */t("p",{children:v("讨论跟随这个主题移动;复制分支时不会复制。")})]}),
|
|
17
|
+
/* @__PURE__ */e("div",{className:"mind-comments__head-actions",children:[
|
|
18
|
+
/* @__PURE__ */t(Y,{variant:"text",disabled:C,onClick:()=>E(e=>e+1),children:v("刷新")}),
|
|
19
|
+
/* @__PURE__ */t(Y,{variant:"text",onClick:m,children:v("关闭")})]})]}),x&&/* @__PURE__ */t("p",{className:"mind-comments__error",role:"alert",children:x}),
|
|
20
|
+
/* @__PURE__ */e("div",{className:"mind-comments__list",children:[I&&/* @__PURE__ */t("p",{role:"status",children:v("正在加载讨论…")}),!I&&!x&&!g.length&&/* @__PURE__ */e("p",{className:"mind-comments__empty",children:[v("这个主题还没有讨论。"),u?v("在下方写下第一条即可。"):""]}),g.map(e=>comment(e))]}),u?/* @__PURE__ */e("form",{className:"mind-comments__compose",onSubmit:e=>{e.preventDefault(),y.trim()&&perform(()=>f.comments.create(n,y.trim(),void 0,{blockId:o,topicId:c}))},children:[
|
|
21
|
+
/* @__PURE__ */t("label",{className:"mind-comment__label",children:p.t("mind.discussTitle",{title:_})}),
|
|
22
|
+
/* @__PURE__ */t("textarea",{"aria-label":v("主题评论内容"),rows:3,maxLength:5e3,placeholder:v("写下你的想法…"),value:y,onChange:e=>w(e.target.value)}),
|
|
23
|
+
/* @__PURE__ */t("div",{className:"mind-comment__actions",children:/* @__PURE__ */t(Y,{variant:"primary",loading:C,disabled:!y.trim(),htmlType:"submit",children:v("发表讨论")})})]}):/* @__PURE__ */t("p",{className:"mind-comments__empty",children:v("你没有在这个空间发表讨论的权限。")}),z&&/* @__PURE__ */e(X,{title:v("删除评论"),onClose:()=>L(null),children:[
|
|
24
|
+
/* @__PURE__ */t("p",{children:v("确定删除这条评论?")}),
|
|
25
|
+
/* @__PURE__ */e("div",{className:"wr-toolbar",children:[
|
|
26
|
+
/* @__PURE__ */t(Y,{onClick:()=>L(null),children:v("取消")}),
|
|
27
|
+
/* @__PURE__ */t(Y,{variant:"primary",onClick:()=>{const e=z;L(null),perform(()=>f.comments.remove(e))},children:v("删除")})]})]})]})}function MindMapField({id:e,field:n,value:l,controller:o,label:c,onFocus:u,onCommand:m}){i().text;const h=r(null),p=r(!1),v=r(!1),[f,g]=a(l),b=r(l);function apply(t){(null==o?void 0:o.text(e,t,n))&&g(t)}return b.current=f,d(()=>{if(p.current||b.current===l)return;const e=h.current,t=(null==e?void 0:e.selectionStart)??0,n=(null==e?void 0:e.selectionEnd)??t,i=s(b.current,l),o=i.text.length-i.to+i.from,map=e=>e<=i.from?e:e>=i.to?e+o:i.from+i.text.length;g(l),v.current&&queueMicrotask(()=>null==e?void 0:e.setSelectionRange(map(t),map(n)))},[l]),d(()=>()=>{null==o||o.composition(!1),null==o||o.endText(e,n)},[o,e,n]),/* @__PURE__ */t("textarea",{ref:h,"aria-label":c,value:f,readOnly:!(null==o?void 0:o.editable()),maxLength:"title"===n?2e3:4e3,rows:"title"===n?1:"note"===n?4:3,onFocus:()=>{v.current=!0,null==o||o.beginText(e,n),null==u||u()},onBlur:()=>{v.current=!1,null==o||o.composition(!1),null==o||o.endText(e,n)},onChange:e=>apply(e.target.value),onCompositionStart:()=>{p.current=!0,null==o||o.composition(!0)},onCompositionEnd:t=>{apply(t.currentTarget.value),p.current=!1,null==o||o.composition(!1),null==o||o.beginText(e,n)},onKeyDown:e=>{e.stopPropagation(),e.nativeEvent.isComposing||p.current||229===e.keyCode||((e.metaKey||e.ctrlKey)&&["z","y"].includes(e.key.toLowerCase())?(e.preventDefault(),e.shiftKey||"y"===e.key.toLowerCase()?null==o||o.redo():null==o||o.undo()):null==m||m(e))}})}const ee=z.map((e,t)=>({value:e,label:["默认","深灰","白色","蓝色","青绿","紫色","棕色","红色"][t]})),te=L.map((e,t)=>({value:e,label:["默认","浅灰","浅蓝","浅绿","浅紫","浅黄","浅红","深蓝"][t]}));function MindMapDetails({model:l,id:o,controller:d,range:c,onClose:s,onNotice:u}){var m;const h=i().text,p=l.topics.find(e=>e.id===o),v=(null==d?void 0:d.editable())??!1,[f,g]=a(""),[b,y]=a(!1),[w,x]=a(""),[k,I]=a(""),[S,M]=a("related"),[z,L]=a(void 0),P=r(null);if(!p)return null;const patch=(e,t)=>{v&&(null==d||d.patch(o,{[e]:t||null}))};function format(e,t){const n=c.from,i=c.to;i<=n?null==u||u(h("请先在主题文字中选中要设置格式的文字。")):"link"!==e||!t||t.href?null==d||d.format(o,n,i,e,t):null==d||d.clearFormat(o,n,i,["link"])}const E=(null==(m=l.relations)?void 0:m.filter(e=>e.source===o||e.target===o))??[];/* @__PURE__ */
|
|
28
|
+
return e("aside",{className:"mind-details","aria-label":h("主题属性"),children:[
|
|
29
|
+
/* @__PURE__ */e("header",{children:[
|
|
30
|
+
/* @__PURE__ */t("strong",{children:h("主题属性")}),
|
|
31
|
+
/* @__PURE__ */t(Y,{size:"small",variant:"text",onClick:s,children:h("关闭")})]}),
|
|
32
|
+
/* @__PURE__ */t("p",{className:"mind-details-title",children:p.text||h("未命名主题")}),v&&/* @__PURE__ */e(n,{children:[
|
|
33
|
+
/* @__PURE__ */e("fieldset",{children:[
|
|
34
|
+
/* @__PURE__ */t("legend",{children:h("选中文字格式")}),
|
|
35
|
+
/* @__PURE__ */e("div",{className:"mind-format-buttons",onMouseDown:e=>e.preventDefault(),children:[
|
|
36
|
+
/* @__PURE__ */t(Y,{size:"small","aria-label":h("主题文字加粗"),onClick:()=>format("bold"),children:/* @__PURE__ */t("b",{children:"B"})}),
|
|
37
|
+
/* @__PURE__ */t(Y,{size:"small","aria-label":h("主题文字斜体"),onClick:()=>format("italic"),children:/* @__PURE__ */t("i",{children:"I"})}),
|
|
38
|
+
/* @__PURE__ */t(Y,{size:"small","aria-label":h("主题文字删除线"),onClick:()=>format("strike"),children:/* @__PURE__ */t("s",{children:"S"})})]}),
|
|
39
|
+
/* @__PURE__ */t("span",{children:h("选区文字色")}),
|
|
40
|
+
/* @__PURE__ */t("div",{className:"mind-color-grid",onMouseDown:e=>e.preventDefault(),children:C.filter(e=>e.value).map(e=>/* @__PURE__ */t(Y,{size:"small",variant:"outline",narrow:!0,"aria-label":h("选区字体:{0}",{0:e.name}),title:h(e.name),onClick:()=>format("textStyle",{color:e.value}),children:/* @__PURE__ */t("span",{style:{color:e.value},children:"A"})},e.value))}),
|
|
41
|
+
/* @__PURE__ */t("span",{children:h("选区高亮")}),
|
|
42
|
+
/* @__PURE__ */t("div",{className:"mind-color-grid",onMouseDown:e=>e.preventDefault(),children:N.filter(e=>e.value).map(e=>/* @__PURE__ */t(Y,{size:"small",variant:"outline",narrow:!0,"aria-label":h("选区高亮:{0}",{0:e.name}),title:h(e.name),style:{background:e.value},onClick:()=>format("highlight",{color:e.value})},e.value))}),
|
|
43
|
+
/* @__PURE__ */e("label",{children:[h("选区链接"),
|
|
44
|
+
/* @__PURE__ */t("input",{value:f,type:"url",placeholder:h("https://… 或站内路径"),"aria-label":h("主题选区链接"),onChange:e=>g(e.target.value)})]}),
|
|
45
|
+
/* @__PURE__ */t(Y,{size:"small",onClick:()=>format("link",{href:f}),children:h("应用链接")}),
|
|
46
|
+
/* @__PURE__ */t(Y,{size:"small",onClick:()=>null==d?void 0:d.clearFormat(o,c.from,c.to),children:h("清除选区格式")})]}),
|
|
47
|
+
/* @__PURE__ */e("fieldset",{children:[
|
|
48
|
+
/* @__PURE__ */t("legend",{children:h("外观")}),
|
|
49
|
+
/* @__PURE__ */e("label",{children:[h("形状"),
|
|
50
|
+
/* @__PURE__ */t(O,{label:h("主题形状"),ariaLabel:h("主题形状"),value:p.shape??"round",onChange:e=>patch("shape",e),options:[{value:"round",label:h("圆角矩形")},{value:"pill",label:h("胶囊")},{value:"text",label:h("文本")}]})]}),
|
|
51
|
+
/* @__PURE__ */e("label",{children:[h("字号"),
|
|
52
|
+
/* @__PURE__ */t(O,{label:h("主题字号"),ariaLabel:h("主题字号"),value:p.fontSize??14,onChange:e=>patch("fontSize",Number(e)),options:[12,14,16,18,20].map(e=>({value:e,label:String(e)}))})]}),
|
|
53
|
+
/* @__PURE__ */e("label",{children:[h("对齐"),
|
|
54
|
+
/* @__PURE__ */t(O,{label:h("主题对齐"),ariaLabel:h("主题对齐"),value:p.align??"center",onChange:e=>patch("align",e),options:[{value:"left",label:h("左对齐")},{value:"center",label:h("居中")},{value:"right",label:h("右对齐")}]})]}),
|
|
55
|
+
/* @__PURE__ */t("span",{children:h("节点文字色")}),
|
|
56
|
+
/* @__PURE__ */t("div",{className:"mind-color-grid",onMouseDown:e=>e.preventDefault(),children:ee.map(e=>/* @__PURE__ */t(Y,{size:"small",variant:"outline",narrow:!0,"aria-label":h("节点字体:{0}",{0:e.label}),title:h(e.label),onClick:()=>patch("color",e.value),children:/* @__PURE__ */t("span",{style:e.value?{color:e.value}:void 0,children:"A"})},e.label))}),
|
|
57
|
+
/* @__PURE__ */t("span",{children:h("节点背景")}),
|
|
58
|
+
/* @__PURE__ */t("div",{className:"mind-color-grid",onMouseDown:e=>e.preventDefault(),children:te.map(e=>/* @__PURE__ */t(Y,{size:"small",variant:"outline",narrow:!0,"aria-label":h("节点背景:{0}",{0:e.label}),title:h(e.label),style:e.value?{background:e.value}:void 0,onClick:()=>patch("background",e.value),children:e.value?"":"/"},e.label))}),
|
|
59
|
+
/* @__PURE__ */e("label",{children:[h("图标"),
|
|
60
|
+
/* @__PURE__ */t(O,{label:h("主题图标"),ariaLabel:h("主题图标"),value:p.icon??"",onChange:e=>patch("icon",e),options:D.map(e=>({value:e,label:e||h("无图标")}))})]}),
|
|
61
|
+
/* @__PURE__ */t(Y,{size:"small",onClick:()=>null==d?void 0:d.patch(o,{done:!p.done}),children:p.done?h("取消完成"):h("标记完成")})]})]}),
|
|
62
|
+
/* @__PURE__ */e("fieldset",{children:[
|
|
63
|
+
/* @__PURE__ */t("legend",{children:h("描述")}),
|
|
64
|
+
/* @__PURE__ */t(MindMapField,{id:o,field:"description",value:p.description??"",controller:d,label:h("主题描述")})]}),
|
|
65
|
+
/* @__PURE__ */e("fieldset",{children:[
|
|
66
|
+
/* @__PURE__ */t("legend",{children:h("备注")}),
|
|
67
|
+
/* @__PURE__ */t(MindMapField,{id:o,field:"note",value:p.note??"",controller:d,label:h("主题备注")})]}),v&&(null==d?void 0:d.context.uploadImage)&&/* @__PURE__ */e("fieldset",{children:[
|
|
68
|
+
/* @__PURE__ */t("legend",{children:h("节点图片")}),
|
|
69
|
+
/* @__PURE__ */t("input",{ref:P,hidden:!0,type:"file",accept:"image/png,image/jpeg,image/webp,image/gif",onChange:e=>{var t;!async function upload(e){var t;if(e&&(null==d?void 0:d.context.uploadImage)&&v)if(["image/png","image/jpeg","image/webp","image/gif"].includes(e.type)){y(!0);try{const n=await d.context.uploadImage(e);d.editable()&&(null==(t=d.snapshot())?void 0:t.topics.some(e=>e.id===o))&&d.patch(o,{attachmentId:n.id})}catch(e){null==u||u(e instanceof Error?e.message:h("图片上传失败"))}finally{y(!1),P.current&&(P.current.value="")}}else null==u||u(h("请选择 PNG、JPEG、WebP 或 GIF 图片"))}(null==(t=e.target.files)?void 0:t[0])}}),
|
|
70
|
+
/* @__PURE__ */t(Y,{size:"small",loading:b,onClick:()=>{var e;return null==(e=P.current)?void 0:e.click()},children:p.attachmentId?h("替换图片"):h("添加图片")}),p.attachmentId&&/* @__PURE__ */t(Y,{size:"small",onClick:()=>patch("attachmentId",null),children:h("移除图片")})]}),
|
|
71
|
+
/* @__PURE__ */e("fieldset",{children:[
|
|
72
|
+
/* @__PURE__ */t("legend",{children:h("主题关系")}),E.map(n=>{var i;/* @__PURE__ */
|
|
73
|
+
return e("div",{className:"mind-relation-item",children:[
|
|
74
|
+
/* @__PURE__ */e("span",{children:[n.label||{related:h("相关"),depends:h("依赖"),reference:h("参考")}[n.kind]," → ",(null==(i=l.topics.find(e=>e.id===(n.source===o?n.target:n.source)))?void 0:i.text)||h("已移除主题")]}),v&&n.source===o&&/* @__PURE__ */t(Y,{variant:"text",size:"small",onClick:()=>{L(n.id),x(n.target),M(n.kind),I(n.label)},children:h("编辑")}),v&&/* @__PURE__ */t(Y,{variant:"text",size:"small",onClick:()=>null==d?void 0:d.deleteRelation(n.id),children:h("删除")})]},n.id)}),v&&/* @__PURE__ */e(n,{children:[
|
|
75
|
+
/* @__PURE__ */t(O,{label:h("关系目标主题"),ariaLabel:h("关系目标主题"),value:w,onChange:x,options:l.topics.filter(e=>e.id!==o).map(e=>({value:e.id,label:e.text||h("未命名主题")})),searchable:!0}),
|
|
76
|
+
/* @__PURE__ */t(O,{label:h("主题关系类型"),ariaLabel:h("主题关系类型"),value:S,onChange:e=>M(e),options:[{value:"related",label:h("相关")},{value:"depends",label:h("依赖")},{value:"reference",label:h("参考")}]}),
|
|
77
|
+
/* @__PURE__ */t("input",{"aria-label":h("关系说明"),placeholder:h("关系说明(可选)"),maxLength:200,value:k,onChange:e=>I(e.target.value)}),
|
|
78
|
+
/* @__PURE__ */t(Y,{size:"small",disabled:!w,onClick:function addRelation(){(null==d?void 0:d.relation({id:z,source:o,target:w,kind:S,label:k}))?(I(""),L(void 0),null==u||u(h("已保存主题关系"))):null==u||u(h("请选择不同的目标主题"))},children:h(z?"保存关系":"添加关系")})]})]})]})}function WTooltip({children:n,content:l}){var o;i().text;const[c,s]=a(!1),u=r(null),m=r(void 0);function close(){clearTimeout(m.current),s(!1)}function show(){clearTimeout(m.current),m.current=setTimeout(()=>s(!0),200)}return d(()=>()=>clearTimeout(m.current),[]),d(()=>{if(c)return window.addEventListener("scroll",close,!0),()=>window.removeEventListener("scroll",close,!0)},[c]),/* @__PURE__ */e("span",{ref:u,style:{display:"contents"},onMouseEnter:show,onMouseLeave:close,onFocus:show,onBlur:close,children:[n,c&&/* @__PURE__ */t(Z,{anchor:(null==(o=u.current)?void 0:o.firstElementChild)??null,align:"center",prefer:"above",gap:8,role:"tooltip",onClose:close,className:"code-tooltip-popup",children:/* @__PURE__ */t("div",{className:"w-tooltip",children:l})})]})}function MindMapCanvas(l){var C,N,D,z,L,ee,te;const ne=i(),ie=ne.text,{host:le,portal:oe}=o(),ae=l.controller,[,re]=a(0);d(()=>{const e=null==ae?void 0:ae.subscribe(()=>re(e=>e+1));return()=>{null==e||e()}},[ae]);const de=(null==ae?void 0:ae.snapshot())??l.model,ce=(null==ae?void 0:ae.editable())??!1,se=r(null==(C=null==ae?void 0:ae.context.viewState)?void 0:C.maps[de.id]).current,[ue,me]=a(()=>new Set((null==se?void 0:se.selectedIds)??[(null==se?void 0:se.selectedId)??de.rootId])),[he,pe]=a((null==se?void 0:se.selectedId)??de.rootId),[ve,fe]=a(null),[ge,be]=a(""),ye=r(!1),[we,xe]=a(()=>j(de,(null==se?void 0:se.collapsed)??[])),[ke,Ce]=a((null==(N=null==se?void 0:se.viewport)?void 0:N.zoom)??1),[Ne,Ie]=a({x:(null==(D=null==se?void 0:se.viewport)?void 0:D.x)??0,y:(null==(z=null==se?void 0:se.viewport)?void 0:z.y)??0}),[Se,Me]=a((null==se?void 0:se.panMode)??!1),De=r(!1),[ze,Le]=a(!1),[Pe,Ee]=a((null==se?void 0:se.showGrid)??!0),[Te,Ae]=a(!1),[_e,$e]=a((null==se?void 0:se.showQuickControls)??!0),[Ke,je]=a(!1),Be=r(null),[Re,We]=a(!1),Ue=r(!1),[Fe,He]=a(!1),[Ge,Ye]=a(""),[Xe,Oe]=a(""),[qe,Je]=a(0),[Ve,Qe]=a(null),[Ze,et]=a(!1),[tt,nt]=a(!!l.openComments),[it,lt]=a({from:0,to:0}),[ot,at]=a(""),[rt,dt]=a(null),[ct,st]=a(null),ut=r([]),mt=r(he),[ht,pt]=a(!1),[vt,ft]=a(""),[gt,bt]=a(""),[yt,wt]=a(!1),[xt,kt]=a(!1),[Ct,Nt]=a(2),[It,St]=a(null),[Mt,Dt]=a(null),[zt,Lt]=a(null),Pt=r(null),[Et,Tt]=a(null),[At,_t]=a(!1),$t=r(!1),Kt=r(!0),jt=r(null),Bt=r(null),Rt=r(null),Wt=r(null),Ut=r([]),[Ft,Ht]=a({width:0,height:0}),Gt=u(de),Yt=Gt.find(e=>e.id===he)??Gt[0],Xt=rt&&Gt.some(e=>e.id===rt)?P(de,rt):de,Ot=m(Xt,j(Xt,we)),qt=h[de.theme],Jt=G({model:de,editable:ce,c:ae,active:he}),Vt=Et?p(de,Et.id):/* @__PURE__ */new Set,Qt="side"===(null==Mt?void 0:Mt.kind)&&Et?v(de,Et.id,Mt.side,Mt.beforeId):null,Zt=Qt?m(Qt,we):null,en=Ge?E(de,Ge):[],tn=c(()=>{try{return vt.trim()?T(vt):null}catch{return null}},[vt]),nn=l.saveStatus??(null==ae?void 0:ae.status())??"",ln=l.pageId??(null==ae?void 0:ae.context.pageId),on=ae?ae.canExport():!0===l.allowExport,an=(null==(L=de.topics.find(e=>e.id===de.rootId))?void 0:L.text)||ie("思维导图");d(()=>{const e=Bt.current;if(!e)return;const t=new ResizeObserver(()=>Ht({width:e.clientWidth,height:e.clientHeight})),wheel=e=>e.preventDefault();return e.addEventListener("wheel",wheel,{passive:!1}),t.observe(e),()=>{t.disconnect(),e.removeEventListener("wheel",wheel)}},[]),d(()=>{const keyup=e=>{"Space"===e.code&&(De.current=!1,Ae(!1))},blur=()=>{cancelGesture(),De.current=!1,Ae(!1),Lt(null)};return window.addEventListener("keyup",keyup),window.addEventListener("blur",blur),()=>{window.removeEventListener("keyup",keyup),window.removeEventListener("blur",blur)}},[]),d(()=>(Kt.current=!0,()=>{Kt.current=!1,null==ae||ae.composition(!1)}),[ae]),d(()=>{const close=e=>{var t;(null==(t=Pt.current)?void 0:t.contains(e.target))||Lt(null)},key=e=>{var t;e.isComposing||"Escape"!==e.key||(Wt.current||zt)&&(e.preventDefault(),e.stopImmediatePropagation(),cancelGesture(),Lt(null),null==(t=Bt.current)||t.focus())};return document.addEventListener("pointerdown",close,!0),window.addEventListener("keydown",key,!0),()=>{document.removeEventListener("pointerdown",close,!0),window.removeEventListener("keydown",key,!0)}},[zt]),d(()=>{const e=Pt.current;if(!e||!zt)return;const t=e.getBoundingClientRect();e.style.left=`${Math.max(8,Math.min(zt.x,innerWidth-t.width-8))}px`,e.style.top=`${Math.max(8,Math.min(zt.y,innerHeight-t.height-8))}px`,e.focus()},[zt,oe]),d(()=>{const e=Wt.current;e&&(e.doc!==JSON.stringify(de)||!ce&&"node"===e.kind)&&cancelGesture()},[de,ce]),d(()=>{var e,t;ve&&(null==(e=Rt.current)||e.focus(),null==(t=Rt.current)||t.select())},[ve]),d(()=>{if(!ve)return;const e=de.topics.find(e=>e.id===ve),t=Rt.current;if(!e||!ce)return null==ae||ae.endText(ve),void fe(null);if(ye.current||e.text===ge)return;const n=(null==t?void 0:t.selectionStart)??0,i=(null==t?void 0:t.selectionEnd)??n,l=s(ge,e.text),o=l.text.length-l.to+l.from,map=e=>e<=l.from?e:e>=l.to?e+o:l.from+l.text.length;be(e.text),queueMicrotask(()=>{t===document.activeElement&&(null==t||t.setSelectionRange(map(n),map(i)))})},[de,ce,ve]),d(()=>{const e=Rt.current;ve&&e&&(e.style.height="0px",e.style.height=`${Math.max(I(Yt.fontSize||14),e.scrollHeight)}px`)},[ve,ge,Yt.fontSize]),d(()=>{const e=new Set(Ot.nodes.map(e=>e.id));me(t=>{const n=new Set([...t].filter(t=>e.has(t)));return n.size===t.size?t:n}),e.has(he)||pe(de.rootId)},[de,he,rt,we]);const rn=r({zoom:ke,pan:Ne,grid:Pe,quickControls:_e,moving:Se,folds:we,active:he,selected:ue});rn.current={zoom:ke,pan:Ne,grid:Pe,quickControls:_e,moving:Se,folds:we,active:he,selected:ue},d(()=>()=>{const e=null==ae?void 0:ae.context.viewState;if(!e)return;const t=rn.current;e.maps[de.id]={selectedId:t.active,selectedIds:[...t.selected],showGrid:t.grid,showQuickControls:t.quickControls,panMode:t.moving,collapsed:[...t.folds],viewport:{x:t.pan.x,y:t.pan.y,zoom:t.zoom}}},[ae,de.id]);const dn=null==ae?void 0:ae.context.awareness,[cn,sn]=a(0);d(()=>{if(!dn)return;const change=()=>sn(e=>e+1);return dn.on("change",change),()=>{dn.off("change",change)}},[dn]),d(()=>{var e;const t=null==(e=null==dn?void 0:dn.getLocalState())?void 0:e.mindMap;!dn||(null==t?void 0:t.blockId)!==de.id&&t||dn.setLocalStateField("mindMap",{blockId:de.id,topicId:he,editing:!!ve,viewport:{...Ne,zoom:ke}})},[dn,de.id,he,ve,Ne.x,Ne.y,ke]),d(()=>()=>{var e,t;(null==(t=null==(e=null==dn?void 0:dn.getLocalState())?void 0:e.mindMap)?void 0:t.blockId)===de.id&&dn.setLocalStateField("mindMap",null)},[dn,de.id]),d(()=>{var e;if(!dn||null===Ve)return;const t=null==(e=dn.getStates().get(Ve))?void 0:e.mindMap;if((null==t?void 0:t.blockId)!==de.id||!t.viewport||![t.viewport.x,t.viewport.y,t.viewport.zoom].every(Number.isFinite))return;const n=Math.min(2.5,Math.max(.005,t.viewport.zoom));Ie({x:t.viewport.x,y:t.viewport.y}),Ce(n)},[dn,Ve,de.id,cn]);const un=c(()=>Array.from((null==dn?void 0:dn.getStates().entries())??[]).flatMap(([e,t])=>{var n,i;const l=t.mindMap;return e===(null==dn?void 0:dn.clientID)||(null==l?void 0:l.blockId)!==de.id?[]:[{client:e,name:String((null==(n=t.user)?void 0:n.name)||(null==(i=t.user)?void 0:i.displayName)||ie("协作者")),topicId:String(l.topicId||""),editing:!!l.editing}]}),[dn,de.id,cn]);function fit(e=Xt){var t,n;const i=m(e,j(e,we)).bounds,l=(null==(t=Bt.current)?void 0:t.clientWidth)??Ft.width,o=(null==(n=Bt.current)?void 0:n.clientHeight)??Ft.height,a=Math.min(1.15,Math.max(.005,Math.min((l-110)/i.width,(o-150)/i.height)));Ce(a),Ie({x:l/2-(i.x+i.width/2)*a,y:o/2-(i.y+i.height/2)*a})}const mn=r(!1),hn=r(de.layout),pn=r({details:Ze,comments:tt,outline:ze});d(()=>{const e=pn.current;!mn.current||hn.current===de.layout&&e.details===Ze&&e.comments===tt&&e.outline===ze||null!==Ve||fit(),hn.current=de.layout,pn.current={details:Ze,comments:tt,outline:ze}},[de.layout,Ze,tt,ze,Ft.width,Ft.height]),d(()=>{mn.current||Ft.width&&Ft.height&&Bt.current&&(mn.current=!0,(null==se?void 0:se.viewport)?Ie({x:se.viewport.x,y:se.viewport.y}):fit())},[Ft.width,Ft.height]);const point=(e,t)=>{const n=Bt.current.getBoundingClientRect();return{x:(e-n.left-Ne.x)/ke,y:(t-n.top-Ne.y)/ke}};function select(e,t=!1){var n;const i=F(ue,e,t);Qe(null),me(i),pe(i.has(e)?e:[...i].at(-1)??de.rootId),null==(n=Bt.current)||n.focus()}function locateHit(e){locate(e.id),"title"!==e.field&&(et(!0),nt(!1))}function locate(e){const t=(null==ae?void 0:ae.snapshot())??de;if(!t.topics.some(t=>t.id===e))return;const n=new Set(we);for(const i of K(t,e))n.delete(i);const i=m(t,n).nodes.find(t=>t.id===e);xe(n),dt(null),select(e),i&&Ie({x:Ft.width/2-(i.x+i.width/2)*ke,y:Ft.height/2-(i.y+i.height/2)*ke})}function jumpHit(e){if(!en.length)return;const t=(qe+e+en.length)%en.length;Je(t),locateHit(en[t])}function edit(e){if(e&&ce){const t=de.topics.find(t=>t.id===e);if(!t)return;pe(e),me(/* @__PURE__ */new Set([e])),null==ae||ae.beginText(e),be(t.text),fe(e)}else ve&&(null==ae||ae.endText(ve)),fe(null),queueMicrotask(()=>{var e;return null==(e=Bt.current)?void 0:e.focus()})}function add(e,t,n=he){if(!ae||!ce)return;if(de.topics.length>=k)return void at(ie("单张导图最多支持 500 个主题。"));const i="parent"===e?ae.addParent(n):void 0!==t&&n===de.rootId?ae.addRootChild(t):"sibling"===e?ae.addSibling(n,"after"):ae.add(n);i&&(xe(e=>{const t=new Set(e);return t.delete(n),t}),me(/* @__PURE__ */new Set([i])),pe(i),ae.beginText(i),be(ie("新主题")),fe(i))}function addSiblingAt(e,t){if(!ae||!ce)return;if(de.topics.length>=k)return void at(ie("单张导图最多支持 500 个主题。"));const n=ae.addSibling(e,t);n&&(xe(t=>{const n=new Set(t);return n.delete(e),n}),me(/* @__PURE__ */new Set([n])),pe(n),ae.beginText(n),be(ie("新主题")),fe(n))}function remove(e=he,t=ue){if(!ae||!ce)return;const n=R(de,t,e);n&&(ut.current=[...t],mt.current=e,n.ids.size>n.roots.length?st(n):performDelete(n,e))}function performDelete(e,t=mt.current){const n=R((null==ae?void 0:ae.snapshot())??de,ut.current,t);n&&n.ids.size===e.ids.size&&![...n.ids].some(t=>!e.ids.has(t))&&(null==ae?void 0:ae.removeMany(ut.current))?(me(/* @__PURE__ */new Set([n.nextId])),pe(n.nextId),fe(null),st(null),at(ie("已删除 {0} 个主题,可撤销。",{0:e.ids.size})),queueMicrotask(()=>{var e;return null==(e=Bt.current)?void 0:e.focus()})):at(ie("主题或权限已变化,请重新选择"))}function fold(e){p(de,e).size&&e!==de.rootId&&xe(t=>{const n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})}function copy(e=he){var t;ae&&(Ut.current=ae.copyBranch(e),at(ie("分支已复制,选择目标主题后粘贴。")),on&&(null==(t=navigator.clipboard)||t.writeText(`YWIKI_MINDMAP_BRANCH_V1\n${JSON.stringify(Ut.current)}`).catch(()=>{})))}async function paste(e=he){if(ce&&ae&&!$t.current){$t.current=!0,_t(!0);try{let t=Ut.current;if(on)try{const e=await Promise.race([navigator.clipboard.readText(),new Promise((e,t)=>setTimeout(()=>t(new Error(ie("剪贴板读取超时"))),1500))]);e.length<2e6&&e.startsWith("YWIKI_MINDMAP_BRANCH_V1\n")&&(t=$(e))}catch{}await insertBranch(t,e)}catch(e){Kt.current&&at(e instanceof Error?e.message:ie("图片复制失败"))}finally{$t.current=!1,Kt.current&&_t(!1)}}}async function insertBranch(e,t){var n;if(e.filter(e=>"mindMapTopic"===e.type).length+de.topics.length>k)throw new Error(ie("粘贴后主题超过 500 个,本次未修改"));const i=await async function materializeImages(e){var t,n;const i=structuredClone(e),o=new Set(de.topics.flatMap(e=>e.attachmentId?[e.attachmentId]:[])),a=/* @__PURE__ */new Map;for(const e of i){const i=null==(t=e.attrs)?void 0:t.attachmentId;if("string"==typeof i&&i&&!o.has(i)){if(!(null==ae?void 0:ae.context.uploadImage))throw new Error(ie("当前文档不支持图片复制,请移除图片后导入"));if(!a.has(i)){const e=ae.context.fetchAttachment??l.fetchAttachment??(null==(n=le.attachments)?void 0:n.fetch);if(!e)throw new Error(ie("当前文档未配置图片读取服务"));const t=await e(i),o=await ae.context.uploadImage(new File([t],"导图主题图片.png",{type:t.type||"image/png"}));a.set(i,o.id)}e.attrs.attachmentId=a.get(i)}}return i}(e),o=Jt.current;if(!Kt.current||o.c!==ae||!o.editable||o.model.id!==de.id)return;if(!(null==(n=null==ae?void 0:ae.snapshot())?void 0:n.topics.some(e=>e.id===t)))throw new Error(ie("目标主题已移除,请重新选择"));const a=ae.pasteBranch(t,i);if(!a)throw new Error(ie("没有可粘贴的分支,或主题容量超过上限"));at(ie("已粘贴分支。")),xe(e=>{const n=new Set(e);return n.delete(t),n}),locate(a)}function moveSide(e,t=he){var n;(null==ae?void 0:ae.moveToSide(t,e))&&(at(ie("已移到{0}侧",{0:ie(-1===e?"左":"右")})),null==(n=Bt.current)||n.focus())}function openContextMenu(e,t){t.preventDefault(),t.stopPropagation(),e&&select(e),Lt({id:e,x:t.clientX,y:t.clientY})}function contextAction(e){const t=(null==zt?void 0:zt.id)??he;Lt(null),t&&(pe(t),"child"===e||"sibling"===e||"parent"===e?add(e,void 0,t):"rename"===e?edit(t):"properties"===e?(et(!0),nt(!1)):"fold"===e?fold(t):"focus"===e?(dt(t),fit(P(de,t))):"left"===e?moveSide(-1,t):"right"===e?moveSide(1,t):"copy"===e?copy(t):"paste"===e?paste((null==zt?void 0:zt.id)?t:1===ue.size?he:Xt.rootId):"delete"===e?remove(t,/* @__PURE__ */new Set([t])):paneCommand(e))}function paneCommand(e){var t;Qe(null),"quick"===e?$e(e=>!e):"grid"===e?Ee(e=>!e):"comments"===e?(nt(e=>!e),et(!1)):"zoom-in"===e?zoomTo(1.2*ke):"zoom-out"===e?zoomTo(ke/1.2):"reset-zoom"===e?zoomTo(1):"fit"===e&&fit(),null==(t=Bt.current)||t.focus()}function followPeer(e){cancelGesture(),edit(null),Qe(e)}function zoomTo(e,t={x:Ft.width/2,y:Ft.height/2}){const n=Math.max(.005,Math.min(2.5,e)),i=n/ke,l=t.x-(t.x-Ne.x)*i,o=t.y-(t.y-Ne.y)*i;Ce(n),Ie({x:l,y:o})}function cancelGesture(e=!0){const t=Wt.current;e&&"box"===(null==t?void 0:t.kind)&&(me(t.selected),pe(t.active)),Wt.current=null,St(null),Dt(null),Tt(null)}function pointerDown(e,t){var n,i;if(!(null==(n=Bt.current)?void 0:n.contains(e.target)))return;if(e.target.closest("button,input,textarea,a"))return;Qe(null),Lt(null);const l={x:e.clientX,y:e.clientY,lastX:e.clientX,lastY:e.clientY,doc:JSON.stringify(de),count:ue.size,selected:new Set(ue),active:he};if(!t||0!==e.button||Se||De.current)if(1===e.button||0===e.button&&(Se||De.current))Wt.current={...l,kind:"pan"};else{if(t||0!==e.button)return;Wt.current={...l,kind:"box",additive:e.shiftKey||e.metaKey||e.ctrlKey},Wt.current.additive||me(/* @__PURE__ */new Set)}else{const n=e.shiftKey||e.metaKey||e.ctrlKey,i=ue.has(t)&&ue.size>1&&!n?ue:F(ue,t,n);me(i),pe(i.has(t)?t:[...i].at(-1)??de.rootId),Wt.current={...l,kind:"node",id:t,count:i.size,additive:n}}e.currentTarget.setPointerCapture(e.pointerId),null==(i=Bt.current)||i.focus(),e.preventDefault()}async function exportAs(e){var t,n;if(!on||Ue.current)return;if(le.exports&&"copy"!==e&&"copy-image"!==e){Ue.current=!0,We(!0);try{await le.exports.request({kind:"mindmap",format:"md"===e?"markdown":"print"===e?"pdf":e,resourceId:l.pageId??(null==ae?void 0:ae.context.pageId),blockId:de.id})}catch(e){at(e instanceof Error?e.message:ie("导出失败"))}finally{Ue.current=!1,We(!1)}return}Ue.current=!0,We(!0);const i=yt?P(de,he):de,o="print"===e?window.open("","_blank"):null;try{if("copy"===e)return void await navigator.clipboard.writeText(y(i));const a={};for(const e of i.topics)if(e.attachmentId){const n=l.fetchAttachment??(null==ae?void 0:ae.context.fetchAttachment)??(null==(t=le.attachments)?void 0:t.fetch);if(!n)throw new Error(ie("未配置主题图片读取服务"));const i=await n(e.attachmentId);a[e.attachmentId]=await new Promise((e,t)=>{const n=new FileReader;n.onload=()=>e(String(n.result)),n.onerror=t,n.readAsDataURL(i)})}const r=w(i,{transparent:xt,images:a}),download=(e,t)=>{const n=URL.createObjectURL(e),i=document.createElement("a");i.href=n,i.download=`思维导图.${t}`,i.click(),setTimeout(()=>URL.revokeObjectURL(n),1e3)};if("svg"===e)download(new Blob([r],{type:"image/svg+xml"}),"svg");else if("md"===e)download(new Blob([y(i)],{type:"text/markdown"}),"md");else if("json"===e)download(new Blob([JSON.stringify(x(i),null,2)],{type:"application/json"}),"json");else if("png"===e||"copy-image"===e||"print"===e){const t=new Image,i=URL.createObjectURL(new Blob([r],{type:"image/svg+xml"}));try{await new Promise((e,n)=>{t.onload=()=>e(),t.onerror=n,t.src=i});const l=document.createElement("canvas");l.width=t.width*Ct,l.height=t.height*Ct,null==(n=l.getContext("2d"))||n.drawImage(t,0,0,l.width,l.height);const a=await new Promise((e,t)=>l.toBlob(n=>n?e(n):t(new Error(ie("图片生成失败")))));if("copy-image"===e)await navigator.clipboard.write([new ClipboardItem({"image/png":a})]);else if("print"===e){if(!o)throw new Error(ie("打印窗口被浏览器拦截"));const e=o.document.createElement("img");e.src=l.toDataURL(),e.style.maxWidth="100%",o.document.body.append(e),e.onload=()=>o.print()}else download(a,"png")}finally{URL.revokeObjectURL(i)}}}catch(e){null==o||o.close(),at(String(e))}finally{Ue.current=!1,Kt.current&&We(!1)}}d(()=>{lt({from:0,to:0})},[he]),d(()=>{if(!le.location)return;const linked=()=>{const e=new URLSearchParams(le.location.current().replace(/^#/,"")),t=e.get("topic");e.get("mind")===de.id&&t&&locate(t)};return linked(),le.location.subscribe(linked)},[le.location,de.id]);const vn=f(de),fn=Yt.parentId===de.rootId,gn=Gt.find(e=>e.id===(null==zt?void 0:zt.id)),bn="undefined"!=typeof navigator&&/Mac|iPhone|iPad/.test(navigator.platform)?"⌘":"Ctrl",yn=(null==zt?void 0:zt.id)?[{items:[...ce?[{value:"child",label:ie("添加子主题")},{value:"sibling",label:ie("添加同级主题")},...zt.id!==de.rootId?[{value:"parent",label:ie("插入父主题")}]:[],{value:"rename",label:ie("修改文字")}]:[],{value:"properties",label:ie("主题属性")},...zt.id!==de.rootId&&p(de,zt.id).size>1?[{value:"fold",label:we.has(zt.id)?ie("展开分支"):ie("收起分支")}]:[],...ce&&(null==gn?void 0:gn.parentId)===de.rootId&&"down"!==de.layout?[{value:"left",label:ie("移到左侧"),disabled:-1===vn.get(zt.id)},{value:"right",label:ie("移到右侧"),disabled:1===vn.get(zt.id)}]:[],{value:"focus",label:ie("聚焦分支")},...ce?[{value:"copy",label:ie("复制分支")},{value:"paste",label:ie("粘贴分支"),disabled:At},...zt.id!==de.rootId?[{value:"delete",label:ie("删除分支")}]:[]]:[]]}]:[...ce?[{items:[{value:"paste",label:ie("粘贴"),disabled:At,shortcut:"⌘ / Ctrl+V"}]}]:[],{items:[...ln?[{value:"comments",label:ie(tt?"隐藏评论":"显示评论"),shortcut:"Shift+C"}]:[],...ce?[{value:"quick",label:ie(_e?"隐藏快捷创建":"显示快捷创建"),shortcut:"Shift+Q"}]:[],{value:"grid",label:ie(Pe?"隐藏网格":"显示网格"),shortcut:"Shift+G"}]},{items:[{value:"zoom-in",label:ie("放大"),shortcut:`${bn} + +`},{value:"zoom-out",label:ie("缩小"),shortcut:`${bn} + −`},{value:"reset-zoom",label:ie("缩放至 100%"),shortcut:`${bn} + 0`},{value:"fit",label:ie("画布全览"),shortcut:"Shift+1"}]}],wn=/* @__PURE__ */e("div",{className:"mind-map-workspace",ref:jt,onKeyDown:function keydown(e){var t,n,i,o;if(!(null==(t=jt.current)?void 0:t.contains(e.target))||e.defaultPrevented||e.nativeEvent.isComposing||229===e.keyCode||e.target.closest("input,textarea,[contenteditable=true]"))return;const a=e.ctrlKey||e.metaKey,r=U(e);if(!e.target.closest("button,select,[role=combobox]")||r||a){if("Space"===e.code)return e.preventDefault(),De.current=!0,void Ae(!0);if("Escape"===e.key){if(!(l.inline||Ze||tt||Fe))return;return e.preventDefault(),e.stopPropagation(),cancelGesture(),Lt(null),me(/* @__PURE__ */new Set),et(!1),nt(!1),void He(!1)}if(a&&"z"===e.key.toLowerCase()&&ce)return e.preventDefault(),void(e.shiftKey?null==ae||ae.redo():null==ae||ae.undo());if(a&&"y"===e.key.toLowerCase()&&ce)return e.preventDefault(),void(null==ae||ae.redo());if(a&&"f"===e.key.toLowerCase())return e.preventDefault(),void He(!0);if(a&&"c"===e.key.toLowerCase()&&ce&&1===ue.size)return e.preventDefault(),void copy();if(a&&"v"===e.key.toLowerCase()&&ce)return e.preventDefault(),void paste();if((a||e.altKey)&&"."===e.key)return e.preventDefault(),void fold(he);if(r)return e.preventDefault(),void paneCommand(r);if(("Delete"===e.key||"Backspace"===e.key)&&ce&&!a&&!e.altKey&&ue.size)return e.preventDefault(),void(e.repeat||remove());if(ce&&1===ue.size)if("Tab"===e.key)e.preventDefault(),add(e.shiftKey?"parent":"child");else if("Enter"===e.key)e.preventDefault(),add("sibling");else if("F2"===e.key)e.preventDefault(),edit(he);else if(e.altKey&&["ArrowUp","ArrowDown"].includes(e.key)){const t=Gt.filter(e=>e.parentId===Yt.parentId),n=t.findIndex(e=>e.id===he),i=t[n+("ArrowUp"===e.key?-1:1)];i&&(null==ae||ae.move(he,i.id,"ArrowUp"===e.key?"before":"after")),e.preventDefault()}else if(e.key.startsWith("Arrow")){e.preventDefault();const t=(null==(n=Ot.nodes.find(e=>e.id===he))?void 0:n.side)??1,l="down"===de.layout?"ArrowUp":1===t?"ArrowLeft":"ArrowRight",a="down"===de.layout?"ArrowDown":1===t?"ArrowRight":"ArrowLeft",r=Ot.nodes.filter(e=>e.parentId===Yt.parentId),d=r.findIndex(e=>e.id===he),c=e.key===l?Yt.parentId:e.key===a?null==(i=Ot.nodes.find(e=>e.parentId===he))?void 0:i.id:null==(o=r[d+("ArrowUp"===e.key||"ArrowLeft"===e.key?-1:1)])?void 0:o.id;c&&select(c)}}},onPaste:async function nativePaste(e){var t;if(!ce||e.target.closest('input,textarea,[contenteditable="true"]'))return;const n=(null==(t=e.clipboardData)?void 0:t.getData("text/plain"))??"";if(n.startsWith("YWIKI_MINDMAP_BRANCH_V1\n")){e.preventDefault(),e.stopPropagation();try{if($t.current)return;$t.current=!0,_t(!0),await insertBranch($(n),he)}catch(e){at(e instanceof Error?e.message:ie("分支格式无效"))}finally{$t.current=!1,Kt.current&&_t(!1)}}},style:{"--mind-color":qt},children:[ce&&!nn&&!1!==l.showSaveHint&&/* @__PURE__ */t(q,{closable:!0,closeLabel:ie("关闭保存提示"),className:"mind-save-hint",children:ie("编辑完成后,请确认已保存再离开。")}),
|
|
79
|
+
/* @__PURE__ */e("header",{className:"mind-canvas-toolbar",children:[
|
|
80
|
+
/* @__PURE__ */e("div",{className:"mind-canvas-tools",children:[!l.inline&&l.onClose&&/* @__PURE__ */t(Y,{onClick:l.onClose,children:ie("返回文档")}),
|
|
81
|
+
/* @__PURE__ */t(Q,{label:ie("展开与收起"),groups:[{items:[{value:"expand",label:ie("全部展开")},{value:"first-level",label:ie("收起至一级")}]}],onSelect:e=>xe("expand"===e?/* @__PURE__ */new Set:B(Xt))}),
|
|
82
|
+
/* @__PURE__ */t(Y,{ref:Be,"aria-expanded":Ke,onClick:()=>je(!Ke),children:ie("视图与导出设置")}),Ke&&/* @__PURE__ */t(Z,{anchor:Be.current,onClose:()=>je(!1),align:"center",gap:6,label:ie("视图与导出设置"),className:"mind-dropdown-popup",children:/* @__PURE__ */e("div",{className:"mind-settings-menu",children:[un.map(n=>{var i,l;/* @__PURE__ */
|
|
83
|
+
return e("span",{className:"mind-peer",children:[
|
|
84
|
+
/* @__PURE__ */e("span",{children:[n.name,n.editing?" 正在编辑":" 正在查看"," ",null==(l=null==(i=de.topics.find(e=>e.id===n.topicId))?void 0:i.text)?void 0:l.slice(0,12)]}),
|
|
85
|
+
/* @__PURE__ */t(Y,{variant:"text",onClick:()=>followPeer(n.client),children:ie("跟随")})]},n.client)}),null!==Ve&&/* @__PURE__ */t(Y,{onClick:()=>followPeer(null),children:ie("停止跟随")}),
|
|
86
|
+
/* @__PURE__ */t(Y,{variant:"text",onClick:()=>{const e=rt?null:he;dt(e),fit(e?P(de,e):de)},children:ie(rt?"返回全图":"聚焦分支")}),
|
|
87
|
+
/* @__PURE__ */t(Y,{variant:"text",onClick:()=>{!async function copyTopicLink(){var e,t;const n=null==(t=null==(e=le.location)?void 0:e.createLink)?void 0:t.call(e,{blockId:de.id,topicId:he});if(n)try{await navigator.clipboard.writeText(n),at(ie("已复制主题定位链接"))}catch{at(n)}else at(ie("宿主未提供主题定位链接"))}()},children:ie("复制主题链接")}),ce&&/* @__PURE__ */t(O,{label:ie("分支线型"),ariaLabel:ie("分支线型"),width:95,value:de.branchStyle??"curve",onChange:e=>null==ae?void 0:ae.settings({branchStyle:e}),options:["curve","straight","step"].map((e,t)=>({value:e,label:[ie("曲线"),ie("直线"),ie("折线")][t]}))}),on&&/* @__PURE__ */e(n,{children:[
|
|
88
|
+
/* @__PURE__ */e("label",{children:[
|
|
89
|
+
/* @__PURE__ */t("input",{type:"checkbox",checked:yt,onChange:e=>wt(e.target.checked)}),ie("仅导出选中分支")]}),
|
|
90
|
+
/* @__PURE__ */e("label",{children:[
|
|
91
|
+
/* @__PURE__ */t("input",{type:"checkbox",checked:xt,onChange:e=>kt(e.target.checked)}),ie("透明背景")]}),
|
|
92
|
+
/* @__PURE__ */t(O,{label:ie("图片分辨率"),ariaLabel:ie("图片分辨率"),width:90,value:Ct,onChange:e=>Nt(Number(e)),options:[1,2,3].map(e=>({value:e,label:ie("{0} 倍图片",{0:e})}))})]}),on&&/* @__PURE__ */e(n,{children:[
|
|
93
|
+
/* @__PURE__ */t(Y,{variant:"text",onClick:()=>{exportAs("copy-image")},children:ie("复制图片")}),
|
|
94
|
+
/* @__PURE__ */t(Y,{variant:"text",onClick:()=>{exportAs("print")},children:le.exports?ie("导出 PDF"):ie("打印 / PDF")})]})]})}),un.length>0&&/* @__PURE__ */t(Q,{label:ie("协作({0})",{0:un.length}),buttonProps:{variant:"text"},groups:[{items:un.map(e=>({value:String(e.client),label:`${e.name}${e.editing?" 正在编辑":" 正在查看"} · 跟随`}))}],onSelect:e=>followPeer(Number(e))})]}),
|
|
95
|
+
/* @__PURE__ */e("div",{className:"mind-canvas-tools mind-canvas-options",children:[nn||!ce?/* @__PURE__ */t("span",{className:"mind-canvas-status",role:"status","aria-label":ie("保存状态"),children:nn||ie("只读")}):null,ce&&/* @__PURE__ */e(n,{children:[
|
|
96
|
+
/* @__PURE__ */t(O,{label:ie("导图布局"),ariaLabel:ie("导图布局"),width:94,value:de.layout,onChange:e=>null==ae?void 0:ae.settings({layout:e}),options:["right","left","both","down"].map((e,t)=>({value:e,label:[ie("向右"),ie("向左"),ie("双侧"),ie("向下")][t]}))}),
|
|
97
|
+
/* @__PURE__ */t(O,{label:ie("导图主题"),ariaLabel:ie("导图主题"),width:94,value:de.theme,onChange:e=>null==ae?void 0:ae.settings({theme:e}),options:["blue","teal","violet","amber"].map((e,t)=>({value:e,label:[ie("靛蓝"),ie("青绿"),ie("紫藤"),ie("琥珀")][t]}))}),
|
|
98
|
+
/* @__PURE__ */t(O,{label:ie("正文预览高度"),ariaLabel:ie("正文预览高度"),width:114,value:de.height,onChange:e=>null==ae?void 0:ae.settings({height:Number(e)}),options:[280,380,520].map((e,t)=>({value:e,label:[ie("预览 · 紧凑"),ie("预览 · 标准"),ie("预览 · 宽松")][t]}))})]}),
|
|
99
|
+
/* @__PURE__ */t(Y,{onClick:()=>He(!Fe),children:ie("查找替换")}),!ce&&le.comments&&ln&&/* @__PURE__ */t(Y,{variant:tt?"primary":"default","aria-pressed":tt,onClick:()=>{nt(!tt),et(!1)},children:tt?"收起讨论":ie("查看讨论")}),
|
|
100
|
+
/* @__PURE__ */t(Q,{label:ie("更多"),groups:[{items:[{value:"outline",label:ie(ze?"隐藏文字大纲":"显示文字大纲")},{value:"details",label:ie("主题属性")},...le.comments&&ln?[{value:"comments",label:ie(tt?"隐藏主题讨论":"主题讨论")}]:[],...ce?[{value:"import",label:ie("导入")}]:[]]}],onSelect:e=>{"outline"===e?Le(!ze):"details"===e?(et(!Ze),nt(!1)):"comments"===e?(nt(!tt),et(!1)):"import"===e&&pt(!0)}}),on&&/* @__PURE__ */t(O,{label:ie("导出"),ariaLabel:ie("导出思维导图"),width:105,value:"",disabled:Re,onChange:e=>{exportAs(e)},options:[{value:"png",label:ie("PNG 图片")},{value:"svg",label:ie("SVG 图片")},{value:"md",label:ie("文字大纲")},{value:"json",label:ie("结构 JSON")}]})]})]}),Fe&&/* @__PURE__ */e("div",{className:"mind-search","aria-label":ie("图内查找替换"),children:[
|
|
101
|
+
/* @__PURE__ */t("input",{"aria-label":ie("查找导图文字"),placeholder:ie("查找主题、描述和备注"),value:Ge,onChange:e=>{Ye(e.target.value),Je(0)},onKeyDown:e=>{"Enter"===e.key&&(e.preventDefault(),jumpHit(1))}}),
|
|
102
|
+
/* @__PURE__ */t("span",{children:ne.t("mind.matches",{count:en.length>5e3?"5000+":en.length})}),
|
|
103
|
+
/* @__PURE__ */t(Y,{disabled:!en.length,onClick:()=>jumpHit(-1),children:ie("上一处")}),
|
|
104
|
+
/* @__PURE__ */t(Y,{disabled:!en.length,onClick:()=>jumpHit(1),children:ie("下一处")}),en.length>0&&/* @__PURE__ */t(O,{label:ie("导图搜索结果"),ariaLabel:ie("导图搜索结果"),width:180,value:qe,options:en.slice(0,500).map((e,t)=>{var n,i;return{value:t,label:`${t+1}. ${(null==(i=null==(n=Gt.find(t=>t.id===e.id))?void 0:n.text)?void 0:i.slice(0,24))??""} · ${"title"===e.field?ie("标题"):"note"===e.field?ie("备注"):ie("描述")}`}}),onChange:e=>{const t=Number(e),n=en[t];n&&(Je(t),locateHit(n))}}),ce&&/* @__PURE__ */e(n,{children:[
|
|
105
|
+
/* @__PURE__ */t("input",{"aria-label":ie("替换为"),placeholder:ie("替换为"),value:Xe,onChange:e=>Oe(e.target.value)}),
|
|
106
|
+
/* @__PURE__ */t(Y,{disabled:!en.length,onClick:()=>{const e=null==ae?void 0:ae.replace(Ge,Xe,en[qe]);at(-1===e?ie("匹配超过 5000 处,请缩小查找范围"):-2===e?ie("替换后文字超过上限,本次未修改"):ie("已替换 {0} 处",{0:e??0}))},children:ie("替换当前")}),
|
|
107
|
+
/* @__PURE__ */t(Y,{disabled:!en.length,onClick:()=>{const e=null==ae?void 0:ae.replace(Ge,Xe);at(-1===e?ie("匹配超过 5000 处,请缩小查找范围"):-2===e?ie("替换后文字超过上限,本次未修改"):ie("已替换 {0} 处",{0:e??0}))},children:ie("全部替换")})]}),
|
|
108
|
+
/* @__PURE__ */t(Y,{variant:"text",onClick:()=>He(!1),children:ie("关闭")})]}),
|
|
109
|
+
/* @__PURE__ */e("div",{className:"mind-canvas-body",children:[ze&&/* @__PURE__ */t("aside",{className:"mind-canvas-outline","aria-label":ie("导图文字大纲"),children:g(de).map(n=>/* @__PURE__ */e("div",{className:"mind-outline-row"+(n.id===he?" current":""),style:{paddingLeft:8+14*Math.min(12,n.depth)},children:[ce?/* @__PURE__ */t(MindMapField,{id:n.id,field:"title",value:n.text,controller:ae,label:ie("大纲主题 {0}",{0:n.text||ie("未命名")}),onFocus:()=>{pe(n.id),me(/* @__PURE__ */new Set([n.id]))},onCommand:e=>{"Tab"===e.key?(e.preventDefault(),null==ae||ae.indent(n.id,e.shiftKey)):"Enter"!==e.key||e.shiftKey||(e.preventDefault(),add("sibling",void 0,n.id))}}):/* @__PURE__ */t("button",{type:"button",onClick:()=>locate(n.id),children:n.text}),
|
|
110
|
+
/* @__PURE__ */t("button",{type:"button",title:ie("定位主题"),"aria-label":ie("定位大纲主题:{0}",{0:n.text}),onClick:()=>locate(n.id),children:"⌖"})]},n.id))}),
|
|
111
|
+
/* @__PURE__ */e("div",{ref:Bt,tabIndex:0,"aria-label":ie("思维导图画布"),className:`mind-canvas-stage${Pe?"":" mind-grid-hidden"}${Se||Te?" mind-space-pan":""}`,onPointerDown:e=>pointerDown(e),onPointerMove:function pointerMove(e){const t=Wt.current;if(t)if(t.doc===JSON.stringify(Jt.current.model)){if("pan"===t.kind){const n=e.clientX-t.lastX,i=e.clientY-t.lastY;Ie(e=>({x:e.x+n,y:e.y+i}))}else if("box"===t.kind){const n=point(t.x,t.y),i=point(e.clientX,e.clientY);t.box={x:Math.min(n.x,i.x),y:Math.min(n.y,i.y),w:Math.abs(i.x-n.x),h:Math.abs(i.y-n.y)},St(t.box),me(topicsInMarquee(Ot.nodes,{x:t.box.x,y:t.box.y,width:t.box.w,height:t.box.h},t.additive?t.selected:[]))}else ce&&t.id&&t.id!==de.rootId&&1===t.count&&Math.hypot(e.clientX-t.x,e.clientY-t.y)>8&&(t.drop=function mindMapDrop(e,t,n,i,l=!0){const o=t.nodes.find(e=>e.id===n),a=t.nodes.find(t=>t.id===e.rootId);if(!o||!a||n===e.rootId)return null;const r=W(e,n),{x:d,y:c}=i,s=t.nodes.filter(e=>!r.has(e.id)).map(e=>({t:e,distance:Math.hypot(d-e.x-e.width/2,c-e.y-e.height/2)})).sort((e,t)=>e.distance-t.distance)[0],u=d<a.x+a.width/2-24?-1:d>a.x+a.width/2+24?1:null,m=l&&"down"!==e.layout&&null!==u&&u!==o.side;if(s&&s.t.id!==a.id&&d>=s.t.x-18&&d<=s.t.x+s.t.width+18&&c>=s.t.y-18&&c<=s.t.y+s.t.height+18||!m&&s&&s.distance<Math.max(s.t.width,130))return{kind:"node",id:s.t.id,mode:s.t.id===a.id?"child":c<s.t.y+10?"before":c>s.t.y+s.t.height-10?"after":"child"};if(l&&"down"!==e.layout&&null!==u&&(m||o.parentId===a.id&&"both"===e.layout)){const e=t.nodes.filter(e=>e.parentId===a.id&&e.id!==n&&e.side===u).find(e=>c<e.y+e.height/2);return{kind:"side",id:a.id,mode:"side",side:u,...e?{beforeId:e.id}:{}}}return null}(Xt,Ot,t.id,point(e.clientX,e.clientY),!rt),Dt(t.drop),Tt({id:t.id,dx:(e.clientX-t.x)/ke,dy:(e.clientY-t.y)/ke}));t.lastX=e.clientX,t.lastY=e.clientY}else cancelGesture()},onPointerUp:function pointerUp(){const e=Wt.current;if(!e)return;if(cancelGesture(!1),e.doc!==JSON.stringify(Jt.current.model))return;const t=e.box;if("box"===e.kind&&t){const n=topicsInMarquee(Ot.nodes,{x:t.x,y:t.y,width:t.w,height:t.h},e.additive?e.selected:[]);me(n),n.size&&pe([...n].at(-1))}else"node"===e.kind&&e.id&&e.drop&&ce?"side"===e.drop.kind?null==ae||ae.moveToSide(e.id,e.drop.side,e.drop.beforeId):null==ae||ae.move(e.id,e.drop.id,e.drop.mode):"node"===e.kind&&e.id&&e.count>1&&!e.additive&&Math.hypot(e.lastX-e.x,e.lastY-e.y)<8&&(me(/* @__PURE__ */new Set([e.id])),pe(e.id))},onPointerCancel:()=>cancelGesture(),onLostPointerCapture:()=>cancelGesture(),onContextMenu:e=>{var t;openContextMenu((null==(t=e.target.closest("[data-topic-id]"))?void 0:t.dataset.topicId)??null,e)},onWheel:e=>{if(Qe(null),e.ctrlKey||e.metaKey){const t=Bt.current.getBoundingClientRect();zoomTo(ke*Math.exp(.002*-e.deltaY),{x:e.clientX-t.left,y:e.clientY-t.top})}else Ie(t=>({x:t.x-e.deltaX,y:t.y-e.deltaY}))},children:[
|
|
112
|
+
/* @__PURE__ */t("div",{className:"mind-canvas-surface",children:/* @__PURE__ */e("div",{className:"mind-canvas-layers",style:{transform:`translate(${Ne.x}px,${Ne.y}px) scale(${ke})`},children:[
|
|
113
|
+
/* @__PURE__ */e("svg",{className:"mind-canvas-edges",children:[Ot.edges.map(e=>/* @__PURE__ */t("path",{d:e.path,className:Vt.has(e.target)?"mind-drag-branch-edge":void 0,stroke:qt,strokeWidth:2,fill:"none"},e.id)),b(de,Ot).map(n=>/* @__PURE__ */e("g",{children:[
|
|
114
|
+
/* @__PURE__ */t("path",{d:n.path,stroke:"#9a68d4",strokeWidth:2,strokeDasharray:"6 4",fill:"none"}),
|
|
115
|
+
/* @__PURE__ */t("text",{x:n.x,y:n.y,fill:"var(--color-text)",fontSize:12,children:n.label||{related:ie("相关"),depends:ie("依赖"),reference:ie("参考")}[n.kind]})]},n.id)),Zt&&/* @__PURE__ */e("g",{className:"mind-side-projection",children:[Zt.edges.filter(e=>Vt.has(e.source)||Vt.has(e.target)).map(e=>/* @__PURE__ */t("path",{d:e.path,stroke:qt,fill:"none",strokeWidth:2,strokeDasharray:"5 4"},e.id)),Zt.nodes.filter(e=>Vt.has(e.id)).map(n=>/* @__PURE__ */e("g",{children:[
|
|
116
|
+
/* @__PURE__ */t("rect",{x:n.x,y:n.y,width:n.width,height:n.height,rx:8,fill:"var(--color-accent-soft)",stroke:qt,strokeDasharray:"5 4"}),
|
|
117
|
+
/* @__PURE__ */t("text",{x:n.x+n.width/2,y:n.y+n.height/2+5,textAnchor:"middle",fontSize:14,fill:"var(--color-text)",children:n.text.slice(0,24)})]},n.id))]})]}),Ot.nodes.map(i=>{const o=Gt.some(e=>e.parentId===i.id),a=_e&&!Se&&!Te&&!Et&&!It&&ce&&ue.has(i.id)&&1===ue.size&&ve!==i.id,r=i.side??1,d="down"===de.layout?"grows-down":-1===r?"grows-left":"";/* @__PURE__ */
|
|
118
|
+
return e("div",{"data-topic-id":i.id,className:`mind-topic-shell${i.id===de.rootId?" root":""}${ue.has(i.id)?" is-selected":""}${o?" has-children":""}${d?` ${d}`:""}${we.has(i.id)?" is-collapsed":""}`,style:{position:"absolute",left:i.x,top:i.y,width:i.width,height:i.height,transform:Et&&Vt.has(i.id)?`translate(${Et.dx}px,${Et.dy}px)`:void 0,opacity:Et&&Vt.has(i.id)?.35:void 0},children:[
|
|
119
|
+
/* @__PURE__ */e("div",{className:`mind-topic${i.id===de.rootId?" root":""}${ue.has(i.id)?" active":""}${ve===i.id?" editing":""}${d?` ${d}`:""}${(null==Mt?void 0:Mt.id)===i.id?` drop mind-drop-${Mt.mode}`:""}`,style:{width:"100%",minHeight:i.height,fontFamily:S,"--mind-topic-line-height":`${I(i.fontSize||14)}px`,color:i.color||("text"===i.shape?"var(--color-text)":i.background?M(i.background):void 0),background:"text"===i.shape?"transparent":i.background||void 0,borderRadius:"pill"===i.shape?28:void 0,border:"text"===i.shape?0:void 0,fontSize:i.fontSize||14,textAlign:i.align||"center"},onPointerDown:e=>{e.stopPropagation(),pointerDown(e,i.id)},onDoubleClick:()=>edit(i.id),onContextMenu:e=>openContextMenu(i.id,e),children:[(i.icon||i.done)&&/* @__PURE__ */e("span",{className:"mind-topic-icon",children:[i.done?"☑ ":"",i.icon]}),ve===i.id?/* @__PURE__ */t("textarea",{ref:Rt,className:"mind-topic-input","aria-label":ie("主题文字"),rows:Math.max(1,i.lines.length),maxLength:2e3,value:ge,onChange:e=>{(null==ae?void 0:ae.text(i.id,e.target.value))&&be(e.target.value)},onSelect:e=>{const t=e.currentTarget;lt({from:t.selectionStart??0,to:t.selectionEnd??0})},onKeyUp:e=>{const t=e.currentTarget;lt({from:t.selectionStart??0,to:t.selectionEnd??0})},onCompositionStart:()=>{ye.current=!0,null==ae||ae.composition(!0)},onCompositionEnd:e=>{null==ae||ae.text(i.id,e.currentTarget.value),ye.current=!1,null==ae||ae.composition(!1),null==ae||ae.beginText(i.id)},onKeyDown:e=>{if(e.stopPropagation(),!e.nativeEvent.isComposing&&!ye.current&&229!==e.keyCode)return(e.metaKey||e.ctrlKey)&&["z","y"].includes(e.key.toLowerCase())?(e.preventDefault(),void(e.shiftKey||"y"===e.key.toLowerCase()?null==ae||ae.redo():null==ae||ae.undo())):void("Escape"===e.key||"Enter"===e.key&&!e.shiftKey?(e.preventDefault(),edit(null)):"Tab"===e.key&&(e.preventDefault(),null==ae||ae.endText(i.id),add("child",void 0,i.id)))},onBlur:()=>{null==ae||ae.composition(!1),null==ae||ae.endText(i.id),fe(null)}}):/* @__PURE__ */t("div",{className:"mind-topic-label",style:{textAlign:i.align||"center",minHeight:i.lines.length*I(i.fontSize||14)},children:/* @__PURE__ */t(J,{topic:i})}),i.description&&/* @__PURE__ */t("div",{className:"mind-topic-description",style:"text"===i.shape?{color:"var(--color-text-muted)"}:i.background?{color:M(i.background)}:void 0,children:i.description}),i.note&&/* @__PURE__ */t("div",{className:"mind-topic-note",title:ie("此主题有备注"),onClick:e=>{e.stopPropagation(),select(i.id),et(!0)},children:ie("▤ 备注")}),i.attachmentId&&/* @__PURE__ */t("div",{className:"mind-topic-image",children:/* @__PURE__ */t(V,{id:i.attachmentId,alt:ie("主题图片"),fetcher:l.fetchAttachment})}),un.filter(e=>e.topicId===i.id).map(e=>/* @__PURE__ */t("span",{className:"mind-peer-badge",title:`${e.name}${e.editing?" 正在编辑":""}`,"aria-label":`${e.name}${e.editing?" 正在编辑此主题":" 正在查看此主题"}`,children:e.name.slice(0,2)},e.client))]}),a&&i.id!==de.rootId&&/* @__PURE__ */t("button",{type:"button",className:"mind-topic-sibling before","aria-label":"down"===de.layout?ie("在左侧添加同级主题"):ie("在上方添加同级主题"),title:"down"===de.layout?ie("在左侧添加同级主题"):ie("在上方添加同级主题"),onPointerDown:e=>e.stopPropagation(),onClick:e=>{e.stopPropagation(),addSiblingAt(i.id,"before")},children:/* @__PURE__ */t("span",{"aria-hidden":"true",children:"+"})}),a&&i.id===de.rootId&&"down"!==de.layout&&/* @__PURE__ */e(n,{children:[
|
|
120
|
+
/* @__PURE__ */t("button",{type:"button",className:"mind-topic-add root-left","aria-label":ie("在中心主题左侧添加子主题"),title:ie("在左侧添加子主题"),onPointerDown:e=>e.stopPropagation(),onClick:e=>{e.stopPropagation(),add("child",-1)},children:"+"}),
|
|
121
|
+
/* @__PURE__ */t("button",{type:"button",className:"mind-topic-add root-right","aria-label":ie("在中心主题右侧添加子主题"),title:ie("在右侧添加子主题"),onPointerDown:e=>e.stopPropagation(),onClick:e=>{e.stopPropagation(),add("child",1)},children:"+"})]}),a&&(i.id!==de.rootId||"down"===de.layout)&&/* @__PURE__ */t("button",{type:"button",className:"mind-topic-add","aria-label":ie("为当前主题添加子主题"),title:ie("添加子主题"),onPointerDown:e=>e.stopPropagation(),onClick:e=>{e.stopPropagation(),add("child")},children:"+"}),a&&i.id!==de.rootId&&/* @__PURE__ */t("button",{type:"button",className:"mind-topic-sibling after","aria-label":"down"===de.layout?ie("在右侧添加同级主题"):ie("在下方添加同级主题"),title:"down"===de.layout?ie("在右侧添加同级主题"):ie("在下方添加同级主题"),onPointerDown:e=>e.stopPropagation(),onClick:e=>{e.stopPropagation(),addSiblingAt(i.id,"after")},children:/* @__PURE__ */t("span",{"aria-hidden":"true",children:"+"})}),o&&i.id!==de.rootId&&ve!==i.id&&/* @__PURE__ */t("button",{type:"button",className:"mind-topic-fold","aria-label":we.has(i.id)?ie("展开分支:{0}(隐藏 {1} 个主题)",{0:i.text,1:p(de,i.id).size-1}):ie("收起分支:{0}",{0:i.text}),title:we.has(i.id)?ie("展开分支,共 {0} 个后代主题",{0:p(de,i.id).size-1}):ie("收起子分支"),"aria-expanded":!we.has(i.id),onClick:e=>{e.stopPropagation(),fold(i.id)},children:we.has(i.id)?/* @__PURE__ */t("span",{className:"mind-fold-count",children:p(de,i.id).size-1}):/* @__PURE__ */t("svg",{className:"mind-fold-chevron",width:"14",height:"14",viewBox:"0 0 16 16",fill:"none","aria-hidden":"true",children:/* @__PURE__ */t("path",{d:"m10 4-4 4 4 4",stroke:"currentColor",strokeWidth:"1.8",strokeLinecap:"round",strokeLinejoin:"round"})})})]},i.id)})]})}),It&&/* @__PURE__ */t("div",{className:"mind-marquee","aria-hidden":"true",style:{left:Ne.x+It.x*ke,top:Ne.y+It.y*ke,width:It.w*ke,height:It.h*ke}}),ce&&1===ue.size&&!ve&&!Et&&!It&&/* @__PURE__ */e("div",{className:"mind-node-actions","aria-label":ie("主题操作"),children:[
|
|
122
|
+
/* @__PURE__ */t(Y,{variant:"primary",onClick:()=>add("child"),children:ie("+ 子主题")}),
|
|
123
|
+
/* @__PURE__ */t(Y,{onClick:()=>add("sibling"),children:ie("同级主题")}),
|
|
124
|
+
/* @__PURE__ */t(Y,{disabled:he===de.rootId,onClick:()=>add("parent"),children:ie("父主题")}),
|
|
125
|
+
/* @__PURE__ */t(Q,{label:ie("调整层级"),groups:[{items:[{value:"out",label:ie("提升一级")},{value:"in",label:ie("缩进一级")}]},...fn&&"down"!==de.layout?[{title:ie("分支方向"),items:[{value:"left",label:ie("移到左侧"),disabled:-1===vn.get(he)},{value:"right",label:ie("移到右侧"),disabled:1===vn.get(he)}]}]:[]],onSelect:e=>"left"===e?moveSide(-1):"right"===e?moveSide(1):null==ae?void 0:ae.indent(he,"out"===e)}),
|
|
126
|
+
/* @__PURE__ */t(Y,{onClick:()=>edit(he),children:ie("改名")}),
|
|
127
|
+
/* @__PURE__ */t(Y,{onClick:()=>copy(),children:ie("复制")}),
|
|
128
|
+
/* @__PURE__ */t(Y,{loading:At,onClick:()=>{paste()},children:ie("粘贴")}),le.comments&&ln&&/* @__PURE__ */t(Y,{variant:tt?"primary":"default","aria-pressed":tt,"aria-label":ie("主题讨论"),onClick:()=>{nt(!tt),et(!1)},children:ie("讨论")}),
|
|
129
|
+
/* @__PURE__ */t(Y,{disabled:he===de.rootId,title:ie("删除主题(Delete / Backspace)"),onClick:()=>remove(),children:ie("删除")})]}),ue.size>1&&/* @__PURE__ */e("div",{className:"mind-selection-summary",role:"status",children:[ie("已选择"),ne.t("mind.topicCount",{count:ue.size}),ce&&/* @__PURE__ */t(Y,{title:ie("删除所选主题(Delete / Backspace)"),onClick:()=>remove(),children:ie("删除所选")}),
|
|
130
|
+
/* @__PURE__ */t(Y,{variant:"text",onClick:()=>me(/* @__PURE__ */new Set),children:ne.t("mind.deselect")})]}),
|
|
131
|
+
/* @__PURE__ */e("div",{className:"mind-canvas-bottom",children:[
|
|
132
|
+
/* @__PURE__ */e("span",{className:"mind-canvas-hint",children:[ie(Se?"移动模式:左键拖动画布":"选择模式:左键选择 / 空白处框选")," ",ie("· 中键或空格+拖动平移 · 双指平移 / 捏合缩放 · 右键菜单")]}),
|
|
133
|
+
/* @__PURE__ */e("div",{className:"mind-canvas-viewport",children:[ce&&/* @__PURE__ */e(n,{children:[
|
|
134
|
+
/* @__PURE__ */t(Y,{disabled:!(null==ae?void 0:ae.canUndo()),onClick:()=>null==ae?void 0:ae.undo(),children:ie("撤销")}),
|
|
135
|
+
/* @__PURE__ */t(Y,{disabled:!(null==ae?void 0:ae.canRedo()),onClick:()=>null==ae?void 0:ae.redo(),children:ie("重做")})]}),
|
|
136
|
+
/* @__PURE__ */t("span",{className:"mind-viewport-divider","aria-hidden":"true"}),
|
|
137
|
+
/* @__PURE__ */t(WTooltip,{content:/* @__PURE__ */e("span",{className:"mind-viewport-tip",children:[ie(Se?"切换为选择模式,左键点选或拖动框选":"切换为移动模式,左键拖动画布"),
|
|
138
|
+
/* @__PURE__ */t("kbd",{children:ie("中键拖动")}),
|
|
139
|
+
/* @__PURE__ */t("kbd",{children:ie("空格+拖动")}),
|
|
140
|
+
/* @__PURE__ */t("kbd",{children:ie("双指平移")})]}),children:/* @__PURE__ */t(Y,{variant:Se?"primary":"text","aria-pressed":Se,"aria-label":ie(Se?"切换为选择模式":"切换为移动模式"),onClick:()=>{var e;Me(!Se),edit(null),cancelGesture(),Qe(null),null==(e=Bt.current)||e.focus()},children:/* @__PURE__ */t("svg",Se?{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.7",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",children:/* @__PURE__ */t("path",{d:"M8 12V5a1.5 1.5 0 0 1 3 0v6-8a1.5 1.5 0 0 1 3 0v8-6a1.5 1.5 0 0 1 3 0v7-4a1.5 1.5 0 0 1 3 0v7c0 5-3 7-7 7-3 0-5-2-7-5l-3-5a1.5 1.5 0 0 1 2.5-1.6L8 14"})}:{width:"18",height:"18",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"1.7",strokeLinejoin:"round","aria-hidden":"true",children:/* @__PURE__ */t("path",{d:"m5 3 14 10-7 1-3 7z"})})})}),
|
|
141
|
+
/* @__PURE__ */t(WTooltip,{content:/* @__PURE__ */e("span",{className:"mind-viewport-tip",children:[ie("缩小")," ",
|
|
142
|
+
/* @__PURE__ */e("kbd",{children:[bn," −"]}),
|
|
143
|
+
/* @__PURE__ */e("kbd",{children:[bn,ie("+鼠标滚轮")]}),
|
|
144
|
+
/* @__PURE__ */t("kbd",{children:ie("捏合手势")})]}),children:/* @__PURE__ */t(Y,{"aria-label":ie("缩小导图"),onClick:()=>paneCommand("zoom-out"),children:"−"})}),
|
|
145
|
+
/* @__PURE__ */t(WTooltip,{content:/* @__PURE__ */e("span",{className:"mind-viewport-tip",children:[ie("缩放至 100%")," ",
|
|
146
|
+
/* @__PURE__ */e("kbd",{children:[bn," 0"]})]}),children:/* @__PURE__ */e(Y,{variant:"text","aria-label":ie("缩放至 100%"),className:"mind-zoom-percent",onClick:()=>paneCommand("reset-zoom"),children:[Math.round(100*ke),"%"]})}),
|
|
147
|
+
/* @__PURE__ */t(WTooltip,{content:/* @__PURE__ */e("span",{className:"mind-viewport-tip",children:[ie("放大")," ",
|
|
148
|
+
/* @__PURE__ */e("kbd",{children:[bn," +"]}),
|
|
149
|
+
/* @__PURE__ */e("kbd",{children:[bn,ie("+鼠标滚轮")]}),
|
|
150
|
+
/* @__PURE__ */t("kbd",{children:ie("捏合手势")})]}),children:/* @__PURE__ */t(Y,{"aria-label":ie("放大导图"),onClick:()=>paneCommand("zoom-in"),children:"+"})}),
|
|
151
|
+
/* @__PURE__ */t(WTooltip,{content:/* @__PURE__ */e("span",{className:"mind-viewport-tip",children:[ie("画布全览")," ",
|
|
152
|
+
/* @__PURE__ */t("kbd",{children:"Shift+1"})]}),children:/* @__PURE__ */t(Y,{onClick:()=>paneCommand("fit"),children:ie("适应画布")})})]})]}),(ot||Mt)&&/* @__PURE__ */t("p",{className:"mind-canvas-notice",role:"status",children:Mt?"side"===Mt.kind?`松开后移到中心主题${-1===Mt.side?ie("左"):ie("右")}侧,保留整条子分支`:ie("松开后{0}",{0:"child"===Mt.mode?"移入目标主题":"before"===Mt.mode?"放到目标上方":"放到目标下方"}):ot})]}),tt&&ln&&le.comments&&/* @__PURE__ */t(MindMapComments,{pageId:ln,blockId:de.id,topicId:he,topicLabel:Yt.text,canComment:l.canComment??(null==(te=null==ae?void 0:(ee=ae.context).canComment)?void 0:te.call(ee)),onClose:()=>nt(!1),onChanged:l.onCommentsChanged},`${ln}:${de.id}:${he}`),Ze&&/* @__PURE__ */t(MindMapDetails,{model:de,id:he,controller:ae,range:it,onClose:()=>et(!1),onNotice:at},he)]}),zt&&oe&&H(/* @__PURE__ */t("div",{ref:Pt,className:"mind-context-menu",role:"menu",tabIndex:-1,"aria-label":zt.id?ie("主题操作菜单"):ie("画布操作菜单"),onKeyDown:function menuKeydown(e){var t,n;const i=Array.from((null==(t=Pt.current)?void 0:t.querySelectorAll('[role="menuitem"]:not([aria-disabled="true"])'))??[]);if(!i.length||!["ArrowDown","ArrowUp","Home","End"].includes(e.key))return;e.preventDefault(),e.stopPropagation();const l=i.indexOf(document.activeElement);null==(n=i["Home"===e.key?0:"End"===e.key?i.length-1:l<0?"ArrowUp"===e.key?i.length-1:0:(l+("ArrowUp"===e.key?-1:1)+i.length)%i.length])||n.focus()},style:{left:zt.x,top:zt.y},children:/* @__PURE__ */t("div",{className:"w-dropdown",children:yn.map((n,i)=>/* @__PURE__ */e("div",{className:"w-dropdown-group",role:"group","aria-label":n.title,children:[n.title&&/* @__PURE__ */t("div",{className:"w-dropdown-group__title",children:n.title}),n.items.map(n=>/* @__PURE__ */e("div",{role:"menuitem",tabIndex:n.disabled?void 0:-1,"aria-disabled":n.disabled||void 0,className:"w-dropdown-option"+(n.disabled?" is-disabled":""),onClick:()=>{n.disabled||contextAction(n.value)},onKeyDown:e=>{n.disabled||"Enter"!==e.key&&" "!==e.key||(e.preventDefault(),contextAction(n.value))},children:["string"==typeof n.label?ie(n.label):n.label,n.shortcut&&/* @__PURE__ */t("span",{className:"mind-menu-key",children:n.shortcut})]},n.value))]},i))})}),oe),ct&&/* @__PURE__ */e(X,{title:ie("删除分支"),onClose:()=>{var e;st(null),null==(e=Bt.current)||e.focus()},children:[
|
|
153
|
+
/* @__PURE__ */t("p",{children:ne.t("mind.deleteConfirm",{count:ct.ids.size})}),
|
|
154
|
+
/* @__PURE__ */e("div",{className:"wr-toolbar",children:[
|
|
155
|
+
/* @__PURE__ */t(Y,{onClick:()=>{var e;st(null),null==(e=Bt.current)||e.focus()},children:ie("取消")}),
|
|
156
|
+
/* @__PURE__ */t(Y,{variant:"primary",onClick:()=>performDelete(ct),children:ie("删除分支")})]})]}),ht&&/* @__PURE__ */e(X,{title:ie("导入导图或列表"),onClose:()=>pt(!1),footer:/* @__PURE__ */e(n,{children:[
|
|
157
|
+
/* @__PURE__ */t(Y,{onClick:()=>pt(!1),children:ie("取消")}),
|
|
158
|
+
/* @__PURE__ */t(Y,{variant:"primary",loading:At,disabled:!tn,onClick:()=>{!$t.current&&tn&&($t.current=!0,_t(!0),bt(""),(async()=>{try{await insertBranch(A(tn),he),Kt.current&&pt(!1)}catch(e){Kt.current&&bt(e instanceof Error?e.message:ie("导入失败"))}finally{$t.current=!1,Kt.current&&_t(!1)}})())},children:ie("导入分支")})]}),children:[
|
|
159
|
+
/* @__PURE__ */t("p",{className:"mind-import-hint",children:ie("导入为当前主题的子分支;支持 JSON 和缩进列表。不会替换现有导图。")}),
|
|
160
|
+
/* @__PURE__ */t("input",{"aria-label":ie("选择导图文件"),type:"file",accept:".json,.md,.txt",onChange:e=>{var t;const n=null==(t=e.target.files)?void 0:t[0];n&&(n.size>2e6?bt(ie("文件超过 2 MB")):n.text().then(e=>{Kt.current&&(ft(e),bt(""))}).catch(()=>{Kt.current&&bt(ie("文件读取失败"))}))}}),
|
|
161
|
+
/* @__PURE__ */t("textarea",{"aria-label":ie("导入内容"),rows:10,placeholder:ie("粘贴缩进列表或导图 JSON"),style:{marginTop:12},value:vt,onChange:e=>{ft(e.target.value),bt("")}}),tn&&/* @__PURE__ */t("p",{children:ne.t("mind.detected",{count:tn.topics.length})}),gt&&/* @__PURE__ */t("p",{role:"alert",children:gt}),
|
|
162
|
+
/* @__PURE__ */t("div",{className:"wr-toolbar",children:["project","meeting","knowledge"].map((e,n)=>/* @__PURE__ */t(Y,{onClick:()=>{const t=null==ae?void 0:ae.pasteBranch(he,A(_(e)));t&&(select(t),pt(!1))},children:[ie("项目模板"),ie("会议模板"),ie("知识模板")][n]},e))})]})]});return l.inline?/* @__PURE__ */t("section",{className:"mind-canvas-shell mind-inline",children:wn}):/* @__PURE__ */t(X,{workspace:!0,fullscreen:!0,hideFooter:!0,className:"mind-canvas-shell mind-canvas-fullscreen",ariaLabel:ie("思维导图"),title:/* @__PURE__ */e("span",{className:"mind-canvas-title",children:[ie("思维导图")," ",
|
|
163
|
+
/* @__PURE__ */t("span",{children:an})]}),escToClose:!(ve||zt||Ke||ht||ct),onClose:()=>{var e;return null==(e=l.onClose)?void 0:e.call(l)},children:wn})}export{MindMapCanvas};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use client";import{jsx as e,jsxs as t}from"react/jsx-runtime";import{c as n,b as i}from"./i18n-B0kCsIjc.js";import{useState as o,useEffect as a,Suspense as d,useRef as l,lazy as r}from"react";import{readMindMap as s,mindMapOutline as c,MIND_MAP_PALETTE as h,layoutMindMap as m,mindRelationPaths as p}from"wendang/mindmap";import{MIND_TOPIC_FONT as u,mindTopicLineHeight as v,readableTextColor as w}from"wendang/shared";import{a as f}from"./index-COeA2QcQ.js";import{T as g,A as b}from"./mind-topic-text-BHXkxexr.js";const x=r(()=>import("./MindMapCanvas-C46Q5JBU.js").then(e=>({default:e.MindMapCanvas})));function MindMapViewer({value:i,modelValue:d,height:r,fetchAttachment:s}){var c;const f=n().text,x=i??d,k=l(null),[C,M]=o(900);if(a(()=>{const e=k.current;if(!e||"undefined"==typeof ResizeObserver)return;M(e.clientWidth||900);const t=new ResizeObserver(e=>{var t;return M((null==(t=e[0])?void 0:t.contentRect.width)||900)});return t.observe(e),()=>t.disconnect()},[]),!x)/* @__PURE__ */return e("p",{role:"alert",children:f("思维导图格式无效")});const y=m(x),N=p(x,y),I=h[x.theme],S=r??x.height,A=Math.min(1,(S-30)/y.bounds.height,Math.max(100,C-24)/y.bounds.width);/* @__PURE__ */
|
|
2
|
+
return e("div",{ref:k,className:"mind-preview-wrap",style:{height:S},role:"group","aria-label":(null==(c=x.topics.find(e=>e.id===x.rootId))?void 0:c.text)||f("思维导图"),children:/* @__PURE__ */e("div",{className:"mind-preview-sized",style:{width:y.bounds.width*A,height:y.bounds.height*A},children:/* @__PURE__ */t("div",{className:"mind-preview-scene",style:{width:y.bounds.width,height:y.bounds.height,transform:`scale(${A})`},children:[
|
|
3
|
+
/* @__PURE__ */t("svg",{className:"mind-preview-lines",width:y.bounds.width,height:y.bounds.height,viewBox:`${y.bounds.x} ${y.bounds.y} ${y.bounds.width} ${y.bounds.height}`,children:[y.edges.map(t=>/* @__PURE__ */e("path",{d:t.path,fill:"none",stroke:I,strokeWidth:2},t.id)),N.map(n=>/* @__PURE__ */t("g",{children:[
|
|
4
|
+
/* @__PURE__ */e("path",{d:n.path,fill:"none",stroke:"#9a68d4",strokeWidth:2,strokeDasharray:"6 4"}),
|
|
5
|
+
/* @__PURE__ */e("text",{x:n.x,y:n.y,fontSize:12,fill:"#9a68d4",children:n.label||{related:f("相关"),depends:f("依赖"),reference:f("参考")}[n.kind]})]},n.id))]}),y.nodes.map(n=>/* @__PURE__ */t("div",{className:`mind-preview-topic ${n.id===x.rootId?"root":""} ${"text"===n.shape?"text":""}`,style:{left:n.x-y.bounds.x,top:n.y-y.bounds.y,width:n.width,minHeight:n.height,fontFamily:u,borderRadius:"pill"===n.shape?28:void 0,background:"text"===n.shape?"transparent":n.background||void 0,color:n.color||("text"===n.shape?"var(--color-text)":n.background?w(n.background):void 0),fontSize:n.fontSize||14,textAlign:n.align||"center","--mind-color":I},children:[(n.icon||n.done)&&/* @__PURE__ */t("span",{className:"mind-preview-icon",children:[n.done?"☑ ":"",n.icon]}),
|
|
6
|
+
/* @__PURE__ */e("span",{className:"mind-preview-title",style:{minHeight:n.lines.length*v(n.fontSize||14),lineHeight:`${v(n.fontSize||14)}px`},children:/* @__PURE__ */e(g,{topic:n})}),n.description&&/* @__PURE__ */e("span",{className:"mind-preview-description",children:n.description}),n.note&&/* @__PURE__ */e("span",{className:"mind-preview-note",title:n.note,children:f("▤ 备注")}),n.attachmentId&&/* @__PURE__ */e("div",{className:"mind-preview-image",children:/* @__PURE__ */e(b,{id:n.attachmentId,alt:f("主题图片"),fetcher:s})})]},n.id))]})})})}function MindMapBlock(l){const r=n(),m=r.text,p=i(),u=l.controller,[v,w]=o(!1),[g,b]=o(!1),[k,C]=o(!1),[,M]=o(0),y=l.node??l.value??l.modelValue,N=u?u.snapshot():y?s(y):null,I=(null==u?void 0:u.editable())??!1,S=N?c(N):[];function show(){N&&(w(!0),(null==u?void 0:u.context.viewState)&&(u.context.viewState.openId=N.id))}return a(()=>{const e=null==u?void 0:u.subscribe(()=>{M(e=>e+1),u.snapshot()||w(!1)});return()=>{null==e||e()}},[u]),a(()=>{var e;if((null==(e=null==u?void 0:u.context.viewState)?void 0:e.openId)===(null==N?void 0:N.id)&&show(),!p.location||!N)return;const linked=()=>{const e=new URLSearchParams(p.location.current().replace(/^#/,""));e.get("mind")===N.id&&e.has("topic")&&show()};return linked(),p.location.subscribe(linked)},[p.location,null==N?void 0:N.id,u]),N?/* @__PURE__ */t("section",{className:"mind-map-block","aria-label":m("思维导图"),style:{"--mind-color":h[N.theme]},onDoubleClick:e=>{e.stopPropagation(),show()},children:[
|
|
7
|
+
/* @__PURE__ */t("header",{className:"mind-map-block-header",children:[
|
|
8
|
+
/* @__PURE__ */t("span",{className:"mind-map-block-label",children:[
|
|
9
|
+
/* @__PURE__ */e("span",{"aria-hidden":"true",children:"⌘"})," ",m("思维导图")," ",
|
|
10
|
+
/* @__PURE__ */e("span",{className:"mind-map-topic-count",children:r.t("mind.topicCount",{count:N.topics.length})})]}),
|
|
11
|
+
/* @__PURE__ */t("div",{className:"mind-map-block-actions",children:[p.comments&&l.pageId&&/* @__PURE__ */e(f,{variant:"text",onClick:()=>{C(!0),show()},children:m(I?"讨论":"查看讨论")}),
|
|
12
|
+
/* @__PURE__ */e(f,{variant:"text",onClick:()=>b(!g),children:m(g?"查看导图":"文字大纲")}),
|
|
13
|
+
/* @__PURE__ */e(f,{variant:"text",onClick:show,children:I?m("编辑导图"):"放大查看"})]})]}),g?/* @__PURE__ */e("div",{className:"mind-map-preview-outline",style:{maxHeight:N.height},children:S.map(t=>/* @__PURE__ */e("div",{style:{paddingLeft:18*Math.min(t.depth,20)},children:t.text||m("未命名主题")},t.id))}):/* @__PURE__ */e(MindMapViewer,{value:N,fetchAttachment:l.fetchAttachment??(null==u?void 0:u.context.fetchAttachment)}),v&&/* @__PURE__ */e(d,{fallback:/* @__PURE__ */e("p",{role:"status",children:m("正在加载导图…")}),children:/* @__PURE__ */e(x,{model:N,controller:u,pageId:l.pageId,canComment:l.canComment,allowExport:l.allowExport,fetchAttachment:l.fetchAttachment,openComments:k,onCommentsChanged:l.onCommentsChanged,onClose:function close(){w(!1),C(!1);const e=null==u?void 0:u.context.viewState;e&&e.openId===(null==N?void 0:N.id)&&(e.openId=null)}})})]}):/* @__PURE__ */e("p",{role:"alert",children:m("思维导图格式无效")})}export{MindMapBlock as M,MindMapViewer as a};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use client";import{jsx as e,jsxs as t}from"react/jsx-runtime";import{c as r,b as l}from"./i18n-B0kCsIjc.js";import{useState as o,useEffect as n,useMemo as i}from"react";import{validateWorkbook as a}from"wendang/spreadsheet";import{p as s,a as d,c,b as h,d as u,s as m}from"./worksheet-preview-DsDVWxIM.js";import{a as p}from"./index-COeA2QcQ.js";function SpreadsheetViewer({value:v,modelValue:b,allowExport:w=!1,standalone:f=!1,exportSnapshot:k,pageId:g}){const x=r(),C=x.text,$=l(),[y,S]=o(""),[M,N]=o(0),[j,R]=o(0),[D,I]=o(!1),[L,U]=o(""),[A,B]=o(!1);n(()=>{N(0),R(0)},[v,b,D,y]);const O=i(()=>{try{return{doc:a(v??b),error:""}}catch(e){return{doc:null,error:String(e)}}},[v,b]);if(!O.doc)/* @__PURE__ */return e("p",{role:"alert",children:O.error});const V=O.doc,F=V.workbook.sheetOrder.filter(e=>{var t;return D||!(null==(t=V.workbook.sheets[e])?void 0:t.hidden)}),W=V.workbook.sheets[F.includes(y)?y:F[0]];if(!W)/* @__PURE__ */return e("section",{className:"worksheet-preview","aria-label":C("工作表只读预览"),children:/* @__PURE__ */t("nav",{className:"sheet-tabs","aria-label":C("工作表页"),children:[
|
|
2
|
+
/* @__PURE__ */e("span",{className:"sheet-note",children:C("没有可见工作表")}),
|
|
3
|
+
/* @__PURE__ */e(p,{"aria-pressed":D,onClick:()=>I(!0),children:C("查看全部行列表页")})]})});const X=s(V,W,D),E=100,H=50,Q=Math.min(M,Math.floor(Math.max(0,X.rows.length-1)/E)*E),T=Math.min(j,Math.floor(Math.max(0,X.columns.length-1)/H)*H),q=X.rows.slice(Q,Q+E),z=X.columns.slice(T,T+H),G=d(W,q,z),dimension=(e,t,r=600)=>{const l=Number(e);return Number.isFinite(l)&&l>0?Math.min(Math.max(l,12),r):t},cellStyle=(e,t)=>{var r,l;const o=G.get(`${e}:${t}`),n=(null==o?void 0:o.sourceRow)??e,i=(null==o?void 0:o.sourceColumn)??t,a=h(V,W,n,i),border=e=>{var t;const r=null==(t=a.bd)?void 0:t[e];if(!(null==r?void 0:r.s))return;const l=7===r.s?"double":[3,4,5,6,9,10,11,12].includes(r.s)?"dashed":"solid";return`${13===r.s?3:r.s>=7?2:1}px ${l} ${m(r.cl)??"currentColor"}`};return{color:m(a.cl),backgroundColor:m(a.bg),fontWeight:1===a.bl?"bold":void 0,fontStyle:1===a.it?"italic":void 0,fontSize:"number"==typeof a.fs?`${dimension(a.fs,11,72)}pt`:void 0,textDecoration:[1===(null==(r=a.ul)?void 0:r.s)?"underline":"",1===(null==(l=a.st)?void 0:l.s)?"line-through":""].filter(Boolean).join(" ")||void 0,textAlign:2===a.ht?"center":3===a.ht?"right":void 0,verticalAlign:2===a.vt?"middle":3===a.vt?"bottom":"top",whiteSpace:3===a.tb?"pre-wrap":"pre",borderTop:border("t"),borderBottom:border("b"),borderLeft:border("l"),borderRight:border("r")}};/* @__PURE__ */
|
|
4
|
+
return t("section",{className:"worksheet-preview"+(f?" worksheet-preview-standalone":""),"aria-label":C("工作表只读预览"),children:[
|
|
5
|
+
/* @__PURE__ */t("nav",{className:"sheet-tabs","aria-label":C("工作表页"),children:[F.map(e=>/* @__PURE__ */t(p,{role:"tab",variant:W.id===e?"primary":"text","aria-selected":W.id===e,onClick:()=>{S(e),N(0),R(0)},children:[V.workbook.sheets[e].name,V.workbook.sheets[e].hidden?C("(隐藏)"):""]},e)),
|
|
6
|
+
/* @__PURE__ */e("span",{className:"sheet-note",children:C("只读预览")}),
|
|
7
|
+
/* @__PURE__ */e(p,{"aria-pressed":D,onClick:()=>I(!D),children:C(D?"恢复保存视图":"查看全部行列表页")}),w&&/* @__PURE__ */e(p,{loading:A,onClick:()=>{!async function exportFile(){if(w&&!A){B(!0),U("");try{if($.exports)return void await $.exports.request({kind:"spreadsheet",format:"xlsx",resourceId:g,blockId:V.workbook.id});const e=k?await k():{title:V.workbook.name,doc:V},{exportXlsx:t}=await(import("../spreadsheet/xlsx.js")),r=await t(e.doc),l=URL.createObjectURL(new Blob([new Uint8Array(r)])),o=document.createElement("a");o.href=l,o.download=`${e.title||C("工作表")}.xlsx`,o.click(),setTimeout(()=>URL.revokeObjectURL(l),1e3)}catch(e){U(String(e))}finally{B(!1)}}}()},children:C("导出 XLSX")})]}),L&&/* @__PURE__ */e("p",{role:"alert",children:L}),(X.hasFilter||X.hasHidden)&&/* @__PURE__ */e("p",{className:"sheet-view-note",role:"status",children:D?C("正在查看全部内容;仅改变本次预览。"):C("按保存的隐藏与筛选状态显示{0}。",{0:X.filtered?`,筛除 ${X.filtered} 行`:""})}),
|
|
8
|
+
/* @__PURE__ */e("div",{className:"sheet-table",tabIndex:0,children:/* @__PURE__ */t("table",{children:[
|
|
9
|
+
/* @__PURE__ */t("colgroup",{children:[
|
|
10
|
+
/* @__PURE__ */e("col",{style:{width:40}}),z.map(t=>{var r,l;/* @__PURE__ */
|
|
11
|
+
return e("col",{style:{width:dimension(null==(l=null==(r=W.columnData)?void 0:r[t])?void 0:l.w,dimension(W.defaultColumnWidth,100,600),600)}},t)})]}),
|
|
12
|
+
/* @__PURE__ */e("thead",{children:/* @__PURE__ */t("tr",{children:[
|
|
13
|
+
/* @__PURE__ */e("th",{"aria-label":C("行号")}),z.map(t=>/* @__PURE__ */e("th",{children:c(t)},t))]})}),
|
|
14
|
+
/* @__PURE__ */e("tbody",{children:q.map(r=>{var l,o,n,i;/* @__PURE__ */
|
|
15
|
+
return t("tr",{style:{height:dimension((null==(o=null==(l=W.rowData)?void 0:l[r])?void 0:o.h)??(null==(i=null==(n=W.rowData)?void 0:n[r])?void 0:i.ah),dimension(W.defaultRowHeight,30,600),600)},children:[
|
|
16
|
+
/* @__PURE__ */e("th",{children:r+1}),z.map(t=>{var l,o;const n=G.get(`${r}:${t}`);if(null==n?void 0:n.hidden)return null;const i=(null==n?void 0:n.sourceRow)??r,a=(null==n?void 0:n.sourceColumn)??t,s=h(V,W,i,a),d=u(null==(o=null==(l=W.cellData)?void 0:l[i])?void 0:o[a],s);/* @__PURE__ */
|
|
17
|
+
return e("td",{rowSpan:null==n?void 0:n.rowspan,colSpan:null==n?void 0:n.colspan,title:d.note,style:cellStyle(r,t),children:d.text},t)})]},r)})})]})}),
|
|
18
|
+
/* @__PURE__ */t("div",{className:"sheet-paging",children:[
|
|
19
|
+
/* @__PURE__ */e("span",{children:x.t("sheet.visibleRange",{rows:q.length?`${q[0]+1}–${q[q.length-1]+1}`:"—",columns:z.length?`${c(z[0])}–${c(z[z.length-1])}`:"—"})}),
|
|
20
|
+
/* @__PURE__ */e(p,{disabled:0===Q,onClick:()=>N(Math.max(0,Q-E)),children:C("上一页行")}),
|
|
21
|
+
/* @__PURE__ */e(p,{disabled:Q+E>=X.rows.length,onClick:()=>N(Q+E),children:C("下一页行")}),
|
|
22
|
+
/* @__PURE__ */e(p,{disabled:0===T,onClick:()=>R(Math.max(0,T-H)),children:C("上一页列")}),
|
|
23
|
+
/* @__PURE__ */e(p,{disabled:T+H>=X.columns.length,onClick:()=>R(T+H),children:C("下一页列")})]})]})}export{SpreadsheetViewer as S};
|