{"_id":"@angineer/smartree","_rev":"2-ae12aff70d30bf685b55c280c4c83c50","name":"@angineer/smartree","dist-tags":{"latest":"0.1.2"},"versions":{"0.1.1":{"name":"@angineer/smartree","version":"0.1.1","license":"MIT","_id":"@angineer/smartree@0.1.1","maintainers":[{"name":"0mao0","email":"orangen@aliyun.com"}],"dist":{"shasum":"8381a3762b9bb86335cf4db92260909c2e084bde","tarball":"https://registry.npmjs.org/@angineer/smartree/-/smartree-0.1.1.tgz","fileCount":11,"integrity":"sha512-P4Vgms7FXXr0VJzrhYgAKPIh5q/Vj+5MqiY4HHqJ3yjxUHFxCpGD2Z2aqZqB65H60k2pqshaVA4PHzaaQpCQEg==","signatures":[{"sig":"MEUCIQCLQWn5ATR9RVAO0BUiV0F5NwdPLjoB8IGQOW5idQDfQgIgEgYuJ00/+yw3VUdycs4RKyajt6a93pGsMuSlpiKnS8Y=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":53507},"main":"./src/index.ts","type":"module","types":"./src/index.ts","exports":{".":{"types":"./src/index.ts","import":"./src/index.ts"},"./style":"./src/styles/index.less","./utils/tree":{"types":"./src/utils/tree.ts","import":"./src/utils/tree.ts"}},"scripts":{"test":"node --test","typecheck":"vue-tsc --noEmit"},"_npmUser":{"name":"0mao0","email":"orangen@aliyun.com"},"_npmVersion":"11.4.2","description":"通用树组件库（Vue 3 + ant-design-vue）：SmartTree——搜索高亮、拖拽排序、文件拖入上传、状态标签、虚拟滚动，外加一套零依赖的树工具函数。","directories":{},"_nodeVersion":"24.3.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vue":"3.5.41","less":"^4.2.0","vue-tsc":"^2.0.6","typescript":"~5.4.0","ant-design-vue":"4.2.6","@ant-design/icons-vue":"7.0.1"},"peerDependencies":{"vue":"3.5.41","ant-design-vue":"4.2.6","@ant-design/icons-vue":"7.0.1"},"_npmOperationalInternal":{"tmp":"tmp/smartree_0.1.1_1787835462793_0.2823696455491542","host":"s3://npm-registry-packages-npm-production"}},"0.1.2":{"_id":"@angineer/smartree@0.1.2","dist":{"shasum":"0288f02e9ecd972f1ddeba13c6214230c8923d26","tarball":"https://registry.npmjs.org/@angineer/smartree/-/smartree-0.1.2.tgz","fileCount":11,"integrity":"sha512-zcvyfMz6GPBgrqKVF5Lc8MixUaddn2VVahUZ5Zgr/1lun5LZD/Qge+Zrxv2z3gDXWfjbrhvGMzS8cSTbWRcdzA==","signatures":[{"sig":"MEUCIQCLRJp1gvDmP2lR3IOiRobSXGL7y1uocq3uXPr2gaHrqwIgJoSjgAywIZQetEw3pfb0Aav1/eAb+pm6MJc6EoXnSHE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQD1hvhJfNMwEU1+2q7N5D1F/GsaXy7Wo2HXckI8cgozpQIhAPLpYC1DLT+PRm+8SsCVfR+sDiCb4rD/f8IFv29dkPNS"}],"unpackedSize":53507},"main":"./src/index.ts","name":"@angineer/smartree","type":"module","types":"./src/index.ts","exports":{".":{"types":"./src/index.ts","import":"./src/index.ts"},"./style":"./src/styles/index.less","./utils/tree":{"types":"./src/utils/tree.ts","import":"./src/utils/tree.ts"}},"license":"MIT","scripts":{"test":"node --test","typecheck":"vue-tsc --noEmit"},"version":"0.1.2","_npmUser":{"name":"0mao0","email":"orangen@aliyun.com"},"_npmVersion":"11.4.2","description":"通用树组件库（Vue 3 + ant-design-vue）：SmartTree——搜索高亮、拖拽排序、文件拖入上传、状态标签、虚拟滚动，外加一套零依赖的树工具函数。","directories":{},"maintainers":[{"name":"0mao0","email":"orangen@aliyun.com"}],"_nodeVersion":"24.3.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vue":"3.5.41","less":"^4.2.0","vue-tsc":"^2.0.6","typescript":"~5.4.0","ant-design-vue":"4.2.6","@ant-design/icons-vue":"7.0.1"},"peerDependencies":{"vue":"3.5.41","ant-design-vue":"4.2.6","@ant-design/icons-vue":"7.0.1"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/smartree_0.1.2_1787835986902_0.9578808770066776"}}},"time":{"created":"2026-08-27T12:57:42.624Z","modified":"2026-08-27T13:06:27.215Z","0.1.1":"2026-08-27T12:57:42.950Z","0.1.2":"2026-08-27T13:06:27.009Z"},"license":"MIT","description":"通用树组件库（Vue 3 + ant-design-vue）：SmartTree——搜索高亮、拖拽排序、文件拖入上传、状态标签、虚拟滚动，外加一套零依赖的树工具函数。","maintainers":[{"name":"0mao0","email":"orangen@aliyun.com"}],"readme":"# @angineer/smartree\n\n通用树组件库（Vue 3 + ant-design-vue）：SmartTree——搜索高亮、拖拽排序、文件拖入上传、状态标签、虚拟滚动，外加一套零依赖的树工具函数。\n\n## 特性\n\n- **搜索过滤**：内置搜索框，关键字高亮、自动展开命中路径\n- **拖拽排序**：节点拖拽移动 / 跨级放置，完整 `DropEvent` 上下文（含拖拽后整树）\n- **文件拖入上传**：从操作系统拖文件到目录节点，按 `allowedFileTypes` 白名单校验\n- **状态体系**：节点状态标签（pending/uploading/processing/queued/completed/failed/cancelled/partial）自动着色\n- **虚拟滚动**：`virtual` + `height` 开启大数据量虚拟列表\n- **暗色模式**：`dark` prop 或导入 `./style` 后跟随 `[data-theme=\"dark\"]`\n- **树工具函数**：`buildTreeFromFlat` / `sortTreeNodes` / `filterTree` / `getExpandedKeysForSearch` 等，可脱离组件单独使用（`@angineer/smartree/utils/tree`）\n\n## 安装\n\n未发布到 npm registry，从 GitHub 仓库钉 tag 安装：\n\n```jsonc\n// package.json\n{\n  \"dependencies\": {\n    \"@angineer/smartree\": \"github:0mao0/angineer-smartree-ui#v0.1.1\"\n  }\n}\n```\n\n```bash\npnpm install\n```\n\n**环境要求**：`vue 3.5.41` + `ant-design-vue 4.2.6` + `@ant-design/icons-vue 7.0.1`（peerDependencies）。包为源码分发（无构建产物），宿主需用 Vite + `@vitejs/plugin-vue` 与 less 编译。\n\n建议导入主题 token（提供 dark 模式下的专有颜色值；不导入则使用组件内 fallback 的 light 默认值）：\n\n```ts\nimport '@angineer/smartree/style'\n```\n\n## 快速上手\n\n```vue\n<template>\n  <SmartTree\n    :tree-data=\"treeData\"\n    draggable\n    multiple\n    :allowed-file-types=\"['.pdf', '.docx']\"\n    @select=\"onSelect\"\n    @drop=\"onDrop\"\n    @file-drop=\"onFileDrop\"\n  />\n</template>\n\n<script setup lang=\"ts\">\nimport { ref } from 'vue'\nimport { SmartTree, buildTreeFromFlat } from '@angineer/smartree'\nimport type { SmartTreeNode, DropEvent } from '@angineer/smartree'\n\nconst treeData = ref<SmartTreeNode[]>([])\n\n// 从扁平列表建树（按 sortOrder 排序）\ntreeData.value = buildTreeFromFlat<SmartTreeNode>({\n  items: [\n    { id: '1', parentId: null, name: '规范', sortOrder: 0 },\n    { id: '2', parentId: '1', name: '第一章.pdf', sortOrder: 0 },\n  ],\n  toNode: (item) => ({ key: item.id, title: item.name, isFolder: !item.parentId }),\n})\n\nfunction onSelect(keys: string[], nodes: SmartTreeNode[]) { /* ... */ }\nfunction onDrop(e: DropEvent) { /* e.siblings / e.targetParentKey / 拖拽后整树 */ }\nfunction onFileDrop(files: File[], folder: SmartTreeNode | null) { /* ... */ }\n</script>\n```\n\n## Props\n\n| Prop | 类型 | 默认 | 说明 |\n| --- | --- | --- | --- |\n| `treeData` | `T[]` | 必填 | 树数据（`T extends SmartTreeNode`） |\n| `showSearch` | `boolean` | `true` | 显示搜索框 |\n| `searchPlaceholder` | `string` | `'搜索...'` | 搜索框占位 |\n| `highlightSearch` | `boolean` | `true` | 搜索关键字高亮 |\n| `showAddRootFolder` | `boolean` | `true` | 显示\"新建根目录\"入口 |\n| `addRootFolderText` / `addRootFolderTitle` | `string` | — | 根目录入口文案/悬浮提示 |\n| `showIcon` / `showStatus` / `showLine` | `boolean` | `true` / `true` / `false` | 图标 / 状态标签 / 连接线 |\n| `draggable` | `boolean` | `false` | 节点可拖拽 |\n| `multiple` | `boolean` | `false` | 多选 |\n| `allowAddFile` | `boolean` | `true` | 允许\"新建文件\"操作 |\n| `allowBatchDelete` | `boolean` | `true` | 允许多选批量删除 |\n| `allowedFileTypes` | `string[]` | `['.pdf']` | 文件拖入类型白名单 |\n| `loading` | `boolean` | `false` | 加载态 |\n| `emptyText` | `string` | `'暂无数据'` | 空态文案 |\n| `defaultExpandedKeys` / `defaultSelectedKeys` | `string[]` | `[]` | 初始展开/选中 |\n| `defaultExpandAll` | `boolean` | `false` | 初始全部展开 |\n| `dark` | `boolean` | `false` | 强制暗色（不依赖 `[data-theme]`） |\n| `virtual` / `height` | `boolean` / `number` | `false` / — | 虚拟滚动与容器高度 |\n| `rootDropText` / `noSearchResultText` / `fileDropHintPrefix` | `string` | — | 各类提示文案 |\n| `actionLabels` | `Partial<Record<...>>` | `{}` | 节点操作文案覆盖（rename/addSubFolder/addFile/view/delete/batchDelete） |\n\n## 事件\n\n| 事件 | 签名 | 说明 |\n| --- | --- | --- |\n| `select` | `(keys: string[], nodes: T[])` | 选中变化 |\n| `rename` / `delete` / `view` | `(node: T)` | 节点操作 |\n| `add-folder` | `(node: T \\| null)` | 新建目录（null 表示根目录） |\n| `add-file` | `(node: T)` | 新建文件 |\n| `batch-delete` | `(node: T)` | 批量删除 |\n| `drop` | `(event: DropEvent)` | 节点拖放完成（含 `siblings`、`targetParentKey` 与拖拽后整树） |\n| `search` | `(text: string)` | 搜索输入 |\n| `file-drop` | `(files: File[], targetFolder: T \\| null)` | 系统文件拖入 |\n| `drop-invalid` | `(reason: string)` | 文件类型校验失败 |\n| `drop-root` | `(dragNodeKeys: string[])` | 拖到根级空白区 |\n\n## 暴露方法（`defineExpose`）\n\n`expandAll()` / `collapseAll()` / `getSelectedNodes()` / `validateFileType()` / `getAllowedFileTypesDesc()`，以及响应式状态 `searchText` / `expandedKeys` / `selectedKeys`。\n\n## 工具函数（`@angineer/smartree/utils/tree`）\n\n| 函数 | 说明 |\n| --- | --- |\n| `buildTreeFromFlat<T>({ items, toNode })` | 扁平列表建树（按 `sortOrder` 排序，`T extends SortableTreeNode`） |\n| `sortTreeNodes<T>(nodes)` | 树节点按 `sortOrder` 递归排序 |\n| `filterTree<T>(nodes, keyword)` | 按标题过滤（保留命中路径） |\n| `getExpandedKeysForSearch<T>(nodes, keyword)` | 计算搜索命中需展开的 key 集合 |\n| `cloneTree<T>(nodes)` | 深拷贝树 |\n| `escapeHtml` / `highlightText` | XSS 转义 / 关键字高亮 HTML |\n| `getFileIconType` / `getFileIconColor` | 按扩展名取图标类型/颜色 |\n| `getStatusColor` / `getStatusText` | 状态 → 颜色/文案映射 |\n\n## 主题定制\n\n组件颜色经 `var(--tree-*, 默认值)` 解析，使用处自带 fallback，不导入样式文件也能正常工作（light 默认值）。导入 `./style` 后获得 dark 模式专有值，并可在 `:root` 覆盖同名变量定制：\n\n| 变量 | light | dark |\n| --- | --- | --- |\n| `--tree-folder-color` | `#f0b90b` | `#f5c542` |\n| `--tree-danger-color` / `--tree-danger-hover` | `#cf1322` | `#e05353` |\n| `--tree-drop-zone-bg` | `rgba(24, 144, 255, 0.06)` | `rgba(24, 144, 255, 0.16)` |\n| `--tree-drop-border` | `rgba(24, 144, 255, 0.5)` | `rgba(23, 125, 220, 0.6)` |\n\n## 类型\n\n```ts\nimport type { SmartTreeNode, SmartTreeNodeStatus, TreeNodeAction, DropEvent } from '@angineer/smartree'\n```\n\n`SmartTreeNode` 业务字段经索引签名自由挂载，严格类型由消费方继承后定义。\n\n## 仓库说明\n\n本仓库为独立发布仓，代码唯一真相源在 [AnGIneer](https://github.com/0mao0/AnGIneer) monorepo 的 `packages/smartree`，经 `scripts/sync-standalone.ps1` 同步；版本以 git tag 发布。变更历史见 [CHANGELOG.md](./CHANGELOG.md)。\n","readmeFilename":"README.md"}