diff --git a/.changeset/rapid-input-number-icons.md b/.changeset/rapid-input-number-icons.md new file mode 100644 index 00000000..03625a1d --- /dev/null +++ b/.changeset/rapid-input-number-icons.md @@ -0,0 +1,10 @@ +--- +"@varo-ui/h5": patch +"@varo-ui/weapp": patch +"@varo/weapp-web": patch +"@varo-ui/headless": patch +"@varo-ui/cli": patch +"@varo/registry": patch +--- + +Replace input-number ASCII steppers with named VIcon plus/minus controls and restore its compact inline geometry, pin textarea word-limit to the bottom-right, use a circular cancel-x on Input/Select without stretching Select on focus, avoid the native Input `focus` prop/handler collision, add dual-target multi-column Picker, DateField, PullRefresh, Signature, and Watermark Registry components while keeping Calendar independent, add shared motion tokens and Spectrum-inspired Button, Switch, Radio, Toast card, and VToastRegion interactions without changing the Varo palette, teach weapp-web native controls to preserve hover and ARIA semantics without Glass-Easel property warnings, pad docs API tables, preview compiled mini-program artifacts through weapp-web, and add a root `docs:dev` command with in-page H5 and Weapp primitive previews. diff --git a/README.md b/README.md index bbbbe08f..cddadeb4 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,14 @@ pnpm --filter @varo/playground-weapp dev:ai `dev:ai` prepares the WeChat DevTools project, starts the MCP HTTP service, and forwards DevTools console output and uncaught errors to the active terminal. +## Documentation development + +```bash +pnpm run docs:dev +``` + +This starts VitePress at `http://localhost:5173` with in-page H5 and Weapp component previews. + ## Verification ```bash diff --git a/README.zh-CN.md b/README.zh-CN.md index f379f14a..84599ff9 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -70,6 +70,14 @@ pnpm --filter @varo/playground-weapp dev:ai `dev:ai` 会准备微信开发者工具项目、启动 MCP HTTP 服务,并将 DevTools console 与未捕获异常转发到当前终端。 +## 文档开发 + +```bash +pnpm run docs:dev +``` + +该命令会在 `http://localhost:5173` 启动 VitePress,并在文档页内提供 H5 与 Weapp 组件预览。 + ## 验证 ```bash diff --git a/apps/docs/.vitepress/config.test.ts b/apps/docs/.vitepress/config.test.ts new file mode 100644 index 00000000..3f5525c3 --- /dev/null +++ b/apps/docs/.vitepress/config.test.ts @@ -0,0 +1,84 @@ +import { resolve } from 'node:path' +import { createMarkdownRenderer, disposeMdItInstance } from 'vitepress' +import { afterAll, beforeAll, describe, expect, it } from 'vitest' +import { renderSearchMarkdown } from './config' + +const docsRoot = process.cwd() +const searchDocumentPath = resolve(docsRoot, 'search-test.md') + +let markdown: Awaited> + +beforeAll(async () => { + markdown = await createMarkdownRenderer(docsRoot, { + languages: ['ts', 'vue'], + }) +}) + +afterAll(() => disposeMdItInstance()) + +async function renderSearch(source: string) { + return renderSearchMarkdown(source, { + cleanUrls: true, + path: searchDocumentPath, + relativePath: 'search-test.md', + }, markdown) +} + +describe('VitePress search rendering', () => { + it('removes fenced code nested in blockquotes and ordered lists', async () => { + const html = await renderSearch([ + '# Visible heading', + '> Visible quote', + '> ```ts', + '> hiddenBlockquote()', + '> ```', + '1. Visible item', + ' ~~~vue', + ' ', + ' ~~~', + 'Visible ending.', + ].join('\n')) + + expect(html).toContain('Visible heading') + expect(html).toContain('Visible quote') + expect(html).toContain('Visible item') + expect(html).toContain('Visible ending.') + expect(html).not.toContain('hiddenBlockquote') + expect(html).not.toContain('hiddenList') + }) + + it('expands included prose while omitting code from included Markdown', async () => { + const html = await renderSearch('') + expect(html).toContain('Published packages') + expect(html).toContain('The CLI does not overwrite existing files by default.') + expect(html).not.toContain('pnpm dlx @varo-ui/cli') + }) + + it('leaves the normal page code renderer intact', async () => { + const html = await markdown.renderAsync('```ts\nconst visibleNormalCode = true\n```', { + cleanUrls: true, + path: searchDocumentPath, + relativePath: 'search-test.md', + }) + expect(html).toContain('visibleNormalCode') + }) + + it('keeps invalid backtick-info openers searchable', async () => { + const html = await renderSearch('Before\n```foo`bar\nAfter') + expect(html).toContain('Before') + expect(html).toContain('foo`bar') + expect(html).toContain('After') + }) + + it('removes indented code blocks from search', async () => { + const html = await renderSearch('Before\n\n hiddenIndented()\n\nAfter') + expect(html).toContain('Before') + expect(html).toContain('After') + expect(html).not.toContain('hiddenIndented') + }) + + it('preserves the documented search false frontmatter contract', async () => { + const html = await renderSearch('---\nsearch: false\n---\n# Hidden page') + expect(html).toBe('') + }) +}) diff --git a/apps/docs/.vitepress/config.ts b/apps/docs/.vitepress/config.ts index dfd4750d..df5813a2 100644 --- a/apps/docs/.vitepress/config.ts +++ b/apps/docs/.vitepress/config.ts @@ -1,3 +1,4 @@ +import type { DefaultTheme } from 'vitepress' import { fileURLToPath } from 'node:url' import tailwindcss from '@tailwindcss/vite' import { defineConfig } from 'vitepress' @@ -6,6 +7,48 @@ import { createComponentSidebarGroups } from '../src/component-catalog.js' const workspacePath = (relativePath: string) => fileURLToPath(new URL(relativePath, import.meta.url)) const docsBase = process.env.DOCS_BASE || '/' const docsAsset = (path: string) => `${docsBase}${path.replace(/^\/+/, '')}` +const docsPort = Number(process.env.DOCS_PORT || 5173) + +type LocalSearchRender = NonNullable +const searchRenderFlag = '__varoSearchRenderWithoutCode' +const searchFilterInstalled = '__varoSearchCodeFilterInstalled' + +type SearchMarkdownEnvironment = Parameters[1] & { + [searchRenderFlag]?: boolean +} + +type SearchMarkdownRenderer = Parameters[2] & { + [searchFilterInstalled]?: boolean +} + +function installSearchCodeFilter(md: SearchMarkdownRenderer) { + if (md[searchFilterInstalled]) { return } + + for (const ruleName of ['fence', 'code_block'] as const) { + const renderRule = md.renderer.rules[ruleName] + if (!renderRule) { continue } + md.renderer.rules[ruleName] = (tokens, index, options, env, self) => { + if ((env as SearchMarkdownEnvironment)[searchRenderFlag]) { return '' } + return renderRule(tokens, index, options, env, self) + } + } + + // VitePress shares this renderer with page builds, so normal page envs must retain the original rules. + md[searchFilterInstalled] = true +} + +export const renderSearchMarkdown: LocalSearchRender = async (source, env, md) => { + const searchEnvironment = env as SearchMarkdownEnvironment + installSearchCodeFilter(md) + searchEnvironment[searchRenderFlag] = true + try { + const html = await md.renderAsync(source, env) + return env.frontmatter?.search === false ? '' : html + } + finally { + delete searchEnvironment[searchRenderFlag] + } +} export default defineConfig({ title: 'Varo', @@ -13,6 +56,9 @@ export default defineConfig({ base: docsBase, cleanUrls: true, lastUpdated: true, + markdown: { + languages: ['bash', 'css', 'json', 'ts', 'vue'], + }, head: [ ['link', { rel: 'icon', type: 'image/svg+xml', href: docsAsset('/brand-assets/varo-symbol.svg') }], ['link', { rel: 'alternate icon', href: docsAsset('/favicon.ico') }], @@ -21,17 +67,21 @@ export default defineConfig({ ['meta', { name: 'theme-color', media: '(prefers-color-scheme: dark)', content: '#0b1016' }], ], vite: { + server: { host: 'localhost', port: docsPort, strictPort: true }, plugins: [tailwindcss()], resolve: { alias: { '@varo-ui/ai': workspacePath('../../../packages/agent-core/src/index.ts'), + '@varo/hooks': workspacePath('../../../packages/hooks/src/index.ts'), '@varo/shared': workspacePath('../../../packages/shared/src/index.ts'), '@varo/utils': workspacePath('../../../packages/utils/src/index.ts'), '@varo-ui/theme': workspacePath('../../../packages/theme/src/index.ts'), '@varo-ui/headless': workspacePath('../../../packages/primitives-core/src/index.ts'), '@varo/primitives-h5': workspacePath('../../../packages/primitives-h5/src/index.ts'), + '@varo/primitives-weapp': workspacePath('../../../packages/primitives-weapp/src/index.ts'), '@varo-ui/h5/source/style.css': workspacePath('../../../packages/ui-h5/src/style.css'), '@varo-ui/h5': workspacePath('../../../packages/ui-h5/src/index.ts'), + '@varo-ui/weapp/primitives': workspacePath('../../../packages/ui-weapp/src/primitives.ts'), '@varo-ui/weapp': workspacePath('../../../packages/ui-weapp/src/index.ts'), }, }, @@ -46,6 +96,7 @@ export default defineConfig({ search: { provider: 'local', options: { + _render: renderSearchMarkdown, detailedView: true, translations: { button: { buttonText: '搜索文档', buttonAriaLabel: '搜索文档' }, @@ -214,6 +265,7 @@ export default defineConfig({ { text: 'AgentFlowchart', link: '/ai/flowchart' }, { text: 'AgentFineTune', link: '/ai/fine-tune' }, { text: 'AgentChat Block', link: '/ai/agent-chat' }, + { text: 'AgentWorkspace Block', link: '/ai/agent-workspace' }, ], }, ], @@ -427,6 +479,7 @@ export default defineConfig({ { text: 'AgentFlowchart', link: '/en/ai/flowchart' }, { text: 'AgentFineTune', link: '/en/ai/fine-tune' }, { text: 'AgentChat Block', link: '/en/ai/agent-chat' }, + { text: 'AgentWorkspace Block', link: '/en/ai/agent-workspace' }, ], }, ], diff --git a/apps/docs/.vitepress/theme/custom.css b/apps/docs/.vitepress/theme/custom.css index c74c8e9d..fa036d1a 100644 --- a/apps/docs/.vitepress/theme/custom.css +++ b/apps/docs/.vitepress/theme/custom.css @@ -580,6 +580,14 @@ html:not(.dark) .VPFeature:hover { width: 100%; overflow: hidden; table-layout: fixed; + border-spacing: 0; + border-collapse: separate; +} + +.vp-doc > table th, +.vp-doc > table td { + padding: 12px 16px; + vertical-align: top; } .vp-doc > table th { @@ -1637,8 +1645,7 @@ html:not(.dark) .VPFeature:hover { .varo-color-token-card, .varo-role-card, .varo-color-component-system, -.varo-token-grid div, -.varo-primitive-stack section { +.varo-token-grid div { background: var(--varo-card); border: 1px solid var(--varo-border); border-radius: var(--varo-radius-lg); @@ -1655,16 +1662,14 @@ html:not(.dark) .VPFeature:hover { .varo-color-intro h2, .varo-color-scale h2, -.varo-color-component-system h2, -.varo-primitive-stack h2 { +.varo-color-component-system h2 { margin: 0 0 8px; letter-spacing: 0; } .varo-color-intro p, .varo-color-scale p, -.varo-color-component-system p, -.varo-primitive-stack p { +.varo-color-component-system p { margin: 0; color: var(--varo-muted); } @@ -1877,30 +1882,6 @@ html:not(.dark) .VPFeature:hover { overflow-wrap: anywhere; } -.varo-primitive-stack { - display: grid; - grid-template-columns: repeat(3, minmax(0, 1fr)); - gap: 14px; - margin: 22px 0 30px; -} - -.varo-primitive-stack section { - padding: 18px; -} - -.varo-primitive-stack span { - display: inline-flex; - align-items: center; - justify-content: center; - width: 30px; - height: 30px; - font-size: 12px; - font-weight: 800; - color: var(--varo-bg); - background: var(--varo-foreground); - border-radius: var(--varo-radius); -} - @media (max-width: 960px) { .varo-package-grid, .varo-stat-grid, @@ -1908,8 +1889,7 @@ html:not(.dark) .VPFeature:hover { .varo-color-matrix, .varo-color-roles, .varo-color-state-strip, - .varo-token-grid, - .varo-primitive-stack { + .varo-token-grid { grid-template-columns: 1fr; } diff --git a/apps/docs/.vitepress/theme/index.ts b/apps/docs/.vitepress/theme/index.ts index a33519e5..4958c422 100644 --- a/apps/docs/.vitepress/theme/index.ts +++ b/apps/docs/.vitepress/theme/index.ts @@ -5,6 +5,7 @@ import { VCascader, VCheckbox, VCheckboxGroup, + VDateField, VDatePicker, VForm, VFormItem, @@ -28,18 +29,21 @@ import { import DefaultTheme from 'vitepress/theme' import AgentComponentDemo from '../../src/components/AgentComponentDemo.vue' import AgentComponentsDemo from '../../src/components/AgentComponentsDemo.vue' -import ComponentCatalog from '../../src/components/ComponentCatalog.vue' +import DateFieldDemo from '../../src/components/DateFieldDemo.vue' import FormComponentDemo from '../../src/components/FormComponentDemo.vue' import InteractivePreview from '../../src/components/InteractivePreview.vue' +import ListDemo from '../../src/components/ListDemo.vue' import MapDemo from '../../src/components/MapDemo.vue' import MiniProgramBlocksGallery from '../../src/components/MiniProgramBlocksGallery.vue' import PlatformTabsDemo from '../../src/components/PlatformTabsDemo.vue' -import PrimitiveCatalog from '../../src/components/PrimitiveCatalog.vue' import PrimitiveExample from '../../src/components/PrimitiveExample.vue' import PrimitiveInteractionDemo from '../../src/components/PrimitiveInteractionDemo.vue' +import PullRefreshDemo from '../../src/components/PullRefreshDemo.vue' import RegistryCoverageEvidence from '../../src/components/RegistryCoverageEvidence.vue' -import RegistryInstallStrip from '../../src/components/RegistryInstallStrip.vue' import RobotChatDemo from '../../src/components/RobotChatDemo.vue' +import SignatureDemo from '../../src/components/SignatureDemo.vue' +import ToastDemo from '../../src/components/ToastDemo.vue' +import WatermarkDemo from '../../src/components/WatermarkDemo.vue' import DocsLayout from './DocsLayout.vue' import '@varo-ui/h5/source/style.css' import './tailwind.css' @@ -52,16 +56,19 @@ const theme: Theme = { enhanceApp({ app }) { app.component('AgentComponentsDemo', AgentComponentsDemo) app.component('AgentComponentDemo', AgentComponentDemo) + app.component('DateFieldDemo', DateFieldDemo) app.component('FormComponentDemo', FormComponentDemo) app.component('InteractivePreview', InteractivePreview) - app.component('ComponentCatalog', ComponentCatalog) + app.component('ListDemo', ListDemo) app.component('MiniProgramBlocksGallery', MiniProgramBlocksGallery) app.component('MapDemo', MapDemo) app.component('RobotChatDemo', RobotChatDemo) app.component('PlatformTabsDemo', PlatformTabsDemo) - app.component('PrimitiveCatalog', PrimitiveCatalog) + app.component('PullRefreshDemo', PullRefreshDemo) app.component('PrimitiveExample', PrimitiveExample) - app.component('RegistryInstallStrip', RegistryInstallStrip) + app.component('SignatureDemo', SignatureDemo) + app.component('WatermarkDemo', WatermarkDemo) + app.component('ToastDemo', ToastDemo) app.component('RegistryCoverageEvidence', RegistryCoverageEvidence) app.component('PrimitiveInteractionDemo', PrimitiveInteractionDemo) app.component('VCalendar', VCalendar) @@ -69,6 +76,7 @@ const theme: Theme = { app.component('VCascader', VCascader) app.component('VCheckbox', VCheckbox) app.component('VCheckboxGroup', VCheckboxGroup) + app.component('VDateField', VDateField) app.component('VDatePicker', VDatePicker) app.component('VForm', VForm) app.component('VFormItem', VFormItem) diff --git a/apps/docs/ai/activity.md b/apps/docs/ai/activity.md index 73fcefd2..c7925c64 100644 --- a/apps/docs/ai/activity.md +++ b/apps/docs/ai/activity.md @@ -6,16 +6,6 @@ -## 安装 - -```bash -pnpm add @varo-ui/ai -pnpm dlx @varo-ui/cli add --target h5 components/agent-ui -pnpm dlx @varo-ui/cli add --target weapp components/agent-ui -``` - -UI 组件由 Registry 安装到项目本地,因此从 `@/components/agent-ui` 导入;`@varo-ui/ai` 只提供事件协议、流控制和 Markdown 能力,不导出 Vue/Wevu UI 组件。 - ## 基础用法 ```vue @@ -39,11 +29,11 @@ import { AgentActivity } from '@/components/agent-ui' 无。 -## 平台差异 +::: info 平台差异 | Target | Import | | ------ | ---------------------------------------------------- | | H5 | Named export from `@/components/agent-ui` | | weapp | 默认导出自 `@/components/agent-ui/AgentActivity.vue` | -组件 API 在两个目标保持一致;DOM/WXML、调度和原生事件由目标实现负责。 +::: diff --git a/apps/docs/ai/agent-chat.md b/apps/docs/ai/agent-chat.md index f1a79e15..0021821e 100644 --- a/apps/docs/ai/agent-chat.md +++ b/apps/docs/ai/agent-chat.md @@ -6,16 +6,6 @@ -## 安装 - -```bash -pnpm add @varo-ui/ai -pnpm dlx @varo-ui/cli add --target h5 blocks/agent-chat -pnpm dlx @varo-ui/cli add --target weapp blocks/agent-chat -``` - -UI 组件由 Registry 安装到项目本地,因此从 `@/components/agent-ui` 导入;`@varo-ui/ai` 只提供事件协议、流控制和 Markdown 能力,不导出 Vue/Wevu UI 组件。 - ## 基础用法 ```vue @@ -52,11 +42,11 @@ import AgentChat from '@/components/blocks/agent-chat.vue' | `submit` | `string` | 提交 | | `update:modelValue` | `string` | 更新提示词 | -## 平台差异 +::: info 平台差异 | Target | Import | | ------ | ------------------------------------ | | H5 | `@/components/blocks/agent-chat.vue` | | weapp | `@/components/blocks/agent-chat.vue` | -组件 API 在两个目标保持一致;DOM/WXML、调度和原生事件由目标实现负责。 +::: diff --git a/apps/docs/ai/agent-workspace.md b/apps/docs/ai/agent-workspace.md new file mode 100644 index 00000000..a763b99d --- /dev/null +++ b/apps/docs/ai/agent-workspace.md @@ -0,0 +1,82 @@ +# AgentWorkspace + +组合来源授权、会话版本、执行区和输入框的双端 Agent Block。 + +## 基础用法 + +```vue + + + +``` + +## Props + +| Prop | 类型 | 默认值 | 说明 | +| ----------------- | ------------------------------- | -------------------------------- | -------------- | +| `activeVersionId` | `string` | `undefined` | 当前会话版本 | +| `busy` | `boolean` | `false` | 执行中状态 | +| `contextUsage` | `number` | `0` | 上下文占用比例 | +| `messages` | `AgentConversationMessage[]` | `[]` | 对话消息 | +| `open` | `boolean` | `true` | 是否显示 | +| `placement` | `'page' \| 'docked' \| 'sheet'` | `'page'` | 布局模式 | +| `prompt` | `string` | `''` | 输入内容 | +| `receipts` | `AgentSourceReceiptItem[]` | `[]` | 来源回执 | +| `retrieval` | `AgentRetrievalItem[]` | `[]` | 检索进度 | +| `sources` | `AgentContextSource[]` | `[]` | 可用来源 | +| `subtitle` | `string` | `'先确认可访问来源,再提交任务'` | 副标题 | +| `tasks` | `AgentTask[]` | `[]` | 执行任务 | +| `title` | `string` | `'Agent 工作区'` | 标题 | +| `versions` | `readonly AgentThreadVersion[]` | `[]` | 会话版本 | + +## Events + +| Event | Payload | 说明 | +| ---------------- | ------------------------------- | ------------ | +| `submit` | `string` | 提交输入 | +| `update:prompt` | `string` | 同步输入内容 | +| `close` | `void` | 关闭工作区 | +| `toggleSource` | `(AgentContextSource, boolean)` | 切换来源 | +| `connectSource` | `AgentContextSource` | 连接来源 | +| `retryRetrieval` | `AgentRetrievalItem` | 重试检索 | +| `retryTask` | `AgentTask` | 重试任务 | +| `approveTask` | `AgentTask` | 批准任务 | +| `cancelTask` | `void` | 取消任务 | +| `selectVersion` | `AgentThreadVersion` | 选择版本 | +| `branchVersion` | `AgentThreadVersion` | 创建分支 | +| `pinVersion` | `AgentThreadVersion` | 固定版本 | +| `openReceipt` | `AgentSourceReceiptItem` | 打开回执 | +| `connectReceipt` | `AgentSourceReceiptItem` | 连接回执来源 | + +## Slots + +| Slot | 说明 | +| ----------- | -------------------------------- | +| `execution` | 替换默认对话、检索、任务和回执区 | + +::: warning Weapp 插槽配置 +使用无参数 `#execution` 时,在 `weapp-vite` 中设置 `weapp.vue.template.scopedSlotsRequireProps: true`,避免父级状态被泛型插槽转换遗漏。 +::: + +::: info 平台导入 +H5 使用 `vue`;小程序将示例中的 `vue` 替换为 `wevu`。两端都默认导入安装后的 `@/components/blocks/agent-workspace.vue`。 +::: diff --git a/apps/docs/ai/approval.md b/apps/docs/ai/approval.md index 043cdf71..cda20e5b 100644 --- a/apps/docs/ai/approval.md +++ b/apps/docs/ai/approval.md @@ -6,16 +6,6 @@ -## 安装 - -```bash -pnpm add @varo-ui/ai -pnpm dlx @varo-ui/cli add --target h5 components/agent-ui -pnpm dlx @varo-ui/cli add --target weapp components/agent-ui -``` - -UI 组件由 Registry 安装到项目本地,因此从 `@/components/agent-ui` 导入;`@varo-ui/ai` 只提供事件协议、流控制和 Markdown 能力,不导出 Vue/Wevu UI 组件。 - ## 基础用法 ```vue @@ -53,11 +43,11 @@ import { AgentApproval } from '@/components/agent-ui' | --------- | -------- | | `default` | 补充内容 | -## 平台差异 +::: info 平台差异 | Target | Import | | ------ | ----------------------------------------- | | H5 | Named export from `@/components/agent-ui` | | weapp | `@/components/agent-ui/AgentApproval.vue` | -组件 API 在两个目标保持一致;DOM/WXML、调度和原生事件由目标实现负责。 +::: diff --git a/apps/docs/ai/artifact.md b/apps/docs/ai/artifact.md index d0354fd7..62d171b3 100644 --- a/apps/docs/ai/artifact.md +++ b/apps/docs/ai/artifact.md @@ -6,16 +6,6 @@ -## 安装 - -```bash -pnpm add @varo-ui/ai -pnpm dlx @varo-ui/cli add --target h5 components/agent-ui -pnpm dlx @varo-ui/cli add --target weapp components/agent-ui -``` - -UI 组件由 Registry 安装到项目本地,因此从 `@/components/agent-ui` 导入;`@varo-ui/ai` 只提供事件协议、流控制和 Markdown 能力,不导出 Vue/Wevu UI 组件。 - ## 基础用法 ```vue @@ -40,11 +30,11 @@ import { AgentArtifact } from '@/components/agent-ui' | ------ | ------------------- | -------- | | `open` | `AgentArtifactItem` | 打开产物 | -## 平台差异 +::: info 平台差异 | Target | Import | | ------ | ----------------------------------------- | | H5 | Named export from `@/components/agent-ui` | | weapp | `@/components/agent-ui/AgentArtifact.vue` | -组件 API 在两个目标保持一致;DOM/WXML、调度和原生事件由目标实现负责。 +::: diff --git a/apps/docs/ai/attachments.md b/apps/docs/ai/attachments.md index 8b3096b2..6f8b8eed 100644 --- a/apps/docs/ai/attachments.md +++ b/apps/docs/ai/attachments.md @@ -6,16 +6,6 @@ -## 安装 - -```bash -pnpm add @varo-ui/ai -pnpm dlx @varo-ui/cli add --target h5 components/agent-ui -pnpm dlx @varo-ui/cli add --target weapp components/agent-ui -``` - -UI 组件由 Registry 安装到项目本地,因此从 `@/components/agent-ui` 导入;`@varo-ui/ai` 只提供事件协议、流控制和 Markdown 能力,不导出 Vue/Wevu UI 组件。 - ## 基础用法 ```vue @@ -40,11 +30,11 @@ import { AgentAttachmentList } from '@/components/agent-ui' | -------- | --------------------- | -------- | | `remove` | `AgentAttachmentItem` | 移除附件 | -## 平台差异 +::: info 平台差异 | Target | Import | | ------ | ----------------------------------------------- | | H5 | Named export from `@/components/agent-ui` | | weapp | `@/components/agent-ui/AgentAttachmentList.vue` | -组件 API 在两个目标保持一致;DOM/WXML、调度和原生事件由目标实现负责。 +::: diff --git a/apps/docs/ai/citations.md b/apps/docs/ai/citations.md index 4283ce49..411776f8 100644 --- a/apps/docs/ai/citations.md +++ b/apps/docs/ai/citations.md @@ -6,16 +6,6 @@ -## 安装 - -```bash -pnpm add @varo-ui/ai -pnpm dlx @varo-ui/cli add --target h5 components/agent-ui -pnpm dlx @varo-ui/cli add --target weapp components/agent-ui -``` - -UI 组件由 Registry 安装到项目本地,因此从 `@/components/agent-ui` 导入;`@varo-ui/ai` 只提供事件协议、流控制和 Markdown 能力,不导出 Vue/Wevu UI 组件。 - ## 基础用法 ```vue @@ -43,11 +33,11 @@ import { AgentCitations } from '@/components/agent-ui' | `open` | `AgentCitationItem` | 打开引用 | | `update:open` | `boolean` | 展开变化 | -## 平台差异 +::: info 平台差异 | Target | Import | | ------ | ----------------------------------------------------- | | H5 | Named export from `@/components/agent-ui` | | weapp | 默认导出自 `@/components/agent-ui/AgentCitations.vue` | -组件 API 在两个目标保持一致;DOM/WXML、调度和原生事件由目标实现负责。 +::: diff --git a/apps/docs/ai/code-block.md b/apps/docs/ai/code-block.md index aeefc4c5..0d043ca6 100644 --- a/apps/docs/ai/code-block.md +++ b/apps/docs/ai/code-block.md @@ -6,16 +6,6 @@ -## 安装 - -```bash -pnpm add @varo-ui/ai -pnpm dlx @varo-ui/cli add --target h5 components/agent-ui -pnpm dlx @varo-ui/cli add --target weapp components/agent-ui -``` - -UI 组件由 Registry 安装到项目本地,因此从 `@/components/agent-ui` 导入;`@varo-ui/ai` 只提供事件协议、流控制和 Markdown 能力,不导出 Vue/Wevu UI 组件。 - ## 基础用法 ```vue @@ -51,11 +41,11 @@ import { AgentCodeBlock } from '@/components/agent-ui' | -------- | -------- | | `footer` | 底部扩展 | -## 平台差异 +::: info 平台差异 | Target | Import | | ------ | ----------------------------------------------------- | | H5 | Named export from `@/components/agent-ui` | | weapp | 默认导出自 `@/components/agent-ui/AgentCodeBlock.vue` | -组件 API 在两个目标保持一致;DOM/WXML、调度和原生事件由目标实现负责。 +::: diff --git a/apps/docs/ai/command-search.md b/apps/docs/ai/command-search.md index 067193d8..3763bee1 100644 --- a/apps/docs/ai/command-search.md +++ b/apps/docs/ai/command-search.md @@ -6,16 +6,6 @@ -## 安装 - -```bash -pnpm add @varo-ui/ai -pnpm dlx @varo-ui/cli add --target h5 components/agent-ui -pnpm dlx @varo-ui/cli add --target weapp components/agent-ui -``` - -UI 组件由 Registry 安装到项目本地,因此从 `@/components/agent-ui` 导入;`@varo-ui/ai` 只提供事件协议、流控制和 Markdown 能力,不导出 Vue/Wevu UI 组件。 - ## 基础用法 ```vue @@ -44,11 +34,11 @@ import { AgentCommandSearch } from '@/components/agent-ui' | `select` | `AgentSearchItem` | 选择命令 | | `update:modelValue` | `string` | 更新搜索词 | -## 平台差异 +::: info 平台差异 | Target | Import | | ------ | --------------------------------------------------------- | | H5 | Named export from `@/components/agent-ui` | | weapp | 默认导出自 `@/components/agent-ui/AgentCommandSearch.vue` | -组件 API 在两个目标保持一致;DOM/WXML、调度和原生事件由目标实现负责。 +::: diff --git a/apps/docs/ai/composer.md b/apps/docs/ai/composer.md index 657b53bc..91102ba2 100644 --- a/apps/docs/ai/composer.md +++ b/apps/docs/ai/composer.md @@ -6,16 +6,6 @@ -## 安装 - -```bash -pnpm add @varo-ui/ai -pnpm dlx @varo-ui/cli add --target h5 components/agent-ui -pnpm dlx @varo-ui/cli add --target weapp components/agent-ui -``` - -UI 组件由 Registry 安装到项目本地,因此从 `@/components/agent-ui` 导入;`@varo-ui/ai` 只提供事件协议、流控制和 Markdown 能力,不导出 Vue/Wevu UI 组件。 - ## 基础用法 ```vue @@ -54,11 +44,11 @@ import { AgentComposer } from '@/components/agent-ui' | `leading` | 前置操作;H5 | | `trailing` | 后置操作;H5 | -## 平台差异 +::: info 平台差异 | Target | Import | | ------ | ----------------------------------------- | | H5 | Named export from `@/components/agent-ui` | | weapp | `@/components/agent-ui/AgentComposer.vue` | -组件 API 在两个目标保持一致;DOM/WXML、调度和原生事件由目标实现负责。 +::: diff --git a/apps/docs/ai/context-card.md b/apps/docs/ai/context-card.md index 5f53704b..111d6f17 100644 --- a/apps/docs/ai/context-card.md +++ b/apps/docs/ai/context-card.md @@ -6,16 +6,6 @@ -## 安装 - -```bash -pnpm add @varo-ui/ai -pnpm dlx @varo-ui/cli add --target h5 components/agent-ui -pnpm dlx @varo-ui/cli add --target weapp components/agent-ui -``` - -UI 组件由 Registry 安装到项目本地,因此从 `@/components/agent-ui` 导入;`@varo-ui/ai` 只提供事件协议、流控制和 Markdown 能力,不导出 Vue/Wevu UI 组件。 - ## 基础用法 ```vue @@ -41,11 +31,11 @@ import { AgentContextCard } from '@/components/agent-ui' | ------ | ------------------- | -------- | | `open` | `AgentContextChunk` | 打开来源 | -## 平台差异 +::: info 平台差异 | Target | Import | | ------ | ------------------------------------------------------- | | H5 | Named export from `@/components/agent-ui` | | weapp | 默认导出自 `@/components/agent-ui/AgentContextCard.vue` | -组件 API 在两个目标保持一致;DOM/WXML、调度和原生事件由目标实现负责。 +::: diff --git a/apps/docs/ai/conversation.md b/apps/docs/ai/conversation.md index 5393f794..f9d88272 100644 --- a/apps/docs/ai/conversation.md +++ b/apps/docs/ai/conversation.md @@ -6,16 +6,6 @@ -## 安装 - -```bash -pnpm add @varo-ui/ai -pnpm dlx @varo-ui/cli add --target h5 components/agent-ui -pnpm dlx @varo-ui/cli add --target weapp components/agent-ui -``` - -UI 组件由 Registry 安装到项目本地,因此从 `@/components/agent-ui` 导入;`@varo-ui/ai` 只提供事件协议、流控制和 Markdown 能力,不导出 Vue/Wevu UI 组件。 - ## 基础用法 ```vue @@ -38,11 +28,11 @@ import { AgentConversation } from '@/components/agent-ui' 无。 -## 平台差异 +::: info 平台差异 | Target | Import | | ------ | --------------------------------------------- | | H5 | Named export from `@/components/agent-ui` | | weapp | `@/components/agent-ui/AgentConversation.vue` | -组件 API 在两个目标保持一致;DOM/WXML、调度和原生事件由目标实现负责。 +::: diff --git a/apps/docs/ai/diff-table.md b/apps/docs/ai/diff-table.md index 3e60f111..4997a09d 100644 --- a/apps/docs/ai/diff-table.md +++ b/apps/docs/ai/diff-table.md @@ -6,16 +6,6 @@ -## 安装 - -```bash -pnpm add @varo-ui/ai -pnpm dlx @varo-ui/cli add --target h5 components/agent-ui -pnpm dlx @varo-ui/cli add --target weapp components/agent-ui -``` - -UI 组件由 Registry 安装到项目本地,因此从 `@/components/agent-ui` 导入;`@varo-ui/ai` 只提供事件协议、流控制和 Markdown 能力,不导出 Vue/Wevu UI 组件。 - ## 基础用法 ```vue @@ -44,11 +34,11 @@ import { AgentDiffTable } from '@/components/agent-ui' | `reject` | `void` | 拒绝变更 | | `select` | `AgentTableRow` | 选择行 | -## 平台差异 +::: info 平台差异 | Target | Import | | ------ | ----------------------------------------------------- | | H5 | Named export from `@/components/agent-ui` | | weapp | 默认导出自 `@/components/agent-ui/AgentDiffTable.vue` | -组件 API 在两个目标保持一致;DOM/WXML、调度和原生事件由目标实现负责。 +::: diff --git a/apps/docs/ai/event-renderer.md b/apps/docs/ai/event-renderer.md index a4f6db15..510c40bd 100644 --- a/apps/docs/ai/event-renderer.md +++ b/apps/docs/ai/event-renderer.md @@ -6,16 +6,6 @@ -## 安装 - -```bash -pnpm add @varo-ui/ai -pnpm dlx @varo-ui/cli add --target h5 components/agent-ui -pnpm dlx @varo-ui/cli add --target weapp components/agent-ui -``` - -UI 组件由 Registry 安装到项目本地,因此从 `@/components/agent-ui` 导入;`@varo-ui/ai` 只提供事件协议、流控制和 Markdown 能力,不导出 Vue/Wevu UI 组件。 - ## 基础用法 ```vue @@ -49,11 +39,11 @@ import { AgentEventRenderer } from '@/components/agent-ui' | `actions` | 回答完成操作 | | `default` | 后置扩展 | -## 平台差异 +::: info 平台差异 | Target | Import | | ------ | ---------------------------------------------- | | H5 | Named export from `@/components/agent-ui` | | weapp | `@/components/agent-ui/AgentEventRenderer.vue` | -组件 API 在两个目标保持一致;DOM/WXML、调度和原生事件由目标实现负责。 +::: diff --git a/apps/docs/ai/file-diff.md b/apps/docs/ai/file-diff.md index 1c6fe290..c58066aa 100644 --- a/apps/docs/ai/file-diff.md +++ b/apps/docs/ai/file-diff.md @@ -6,16 +6,6 @@ -## 安装 - -```bash -pnpm add @varo-ui/ai -pnpm dlx @varo-ui/cli add --target h5 components/agent-ui -pnpm dlx @varo-ui/cli add --target weapp components/agent-ui -``` - -UI 组件由 Registry 安装到项目本地,因此从 `@/components/agent-ui` 导入;`@varo-ui/ai` 只提供事件协议、流控制和 Markdown 能力,不导出 Vue/Wevu UI 组件。 - ## 基础用法 ```vue @@ -89,17 +79,11 @@ const lines: AgentDiffLine[] = [ | ------ | ----------------------- | ------------------------------------------- | | `line` | `{ line, index, side }` | 覆盖代码内容渲染;用于接入已有 token 高亮器 | -## 设计边界 - -视觉和交互参考 [@pierre/diffs](https://github.com/pierrecomputer/pierre/tree/main/packages/diffs):中性代码面、低饱和新增/删除层、边栏指示、单栏/并排布局、行内变化和可展开 hunk。 - -Varo 不是其移植版。`@pierre/diffs` 的 Shadow DOM、Shiki、Worker Pool 和大规模虚拟化针对浏览器代码审阅;这些能力不能直接运行在小程序。`AgentFileDiff` 保留适合 Agent 输出的轻量数据契约和双端一致交互。只做 H5 且需要超大 Diff、语法高亮、注释或编辑时,应直接使用 `@pierre/diffs`。 - -## 平台差异 +::: info 平台差异 | Target | Import | | ------ | ------------------------------------------------------------------------------------------------ | | H5 | Named export from `@/components/agent-ui` | | weapp | 默认导出自 `@/components/agent-ui/AgentFileDiff.vue`;类型来自 `@/components/agent-ui/file-diff` | -组件 API 在两个目标保持一致;DOM/WXML、调度和原生事件由目标实现负责。 +::: diff --git a/apps/docs/ai/filter-table.md b/apps/docs/ai/filter-table.md index 19f173e9..cca45ab4 100644 --- a/apps/docs/ai/filter-table.md +++ b/apps/docs/ai/filter-table.md @@ -6,16 +6,6 @@ -## 安装 - -```bash -pnpm add @varo-ui/ai -pnpm dlx @varo-ui/cli add --target h5 components/agent-ui -pnpm dlx @varo-ui/cli add --target weapp components/agent-ui -``` - -UI 组件由 Registry 安装到项目本地,因此从 `@/components/agent-ui` 导入;`@varo-ui/ai` 只提供事件协议、流控制和 Markdown 能力,不导出 Vue/Wevu UI 组件。 - ## 基础用法 ```vue @@ -46,11 +36,11 @@ import { AgentFilterTable } from '@/components/agent-ui' | `select` | `AgentTableRow` | 选择行 | | `update:filter` | `string` | 更新筛选 | -## 平台差异 +::: info 平台差异 | Target | Import | | ------ | ----------------------------------------------------------------------------------------------------- | | H5 | Named export from `@/components/agent-ui` | | weapp | 默认导出自 `@/components/agent-ui/AgentFilterTable.vue`;类型来自 `@/components/agent-ui/agent-table` | -组件 API 在两个目标保持一致;DOM/WXML、调度和原生事件由目标实现负责。 +::: diff --git a/apps/docs/ai/fine-tune.md b/apps/docs/ai/fine-tune.md index 09ead0c2..4435b48c 100644 --- a/apps/docs/ai/fine-tune.md +++ b/apps/docs/ai/fine-tune.md @@ -6,16 +6,6 @@ Agent 生成设计的属性检查器和调优面板。 -## 安装 - -```bash -pnpm add @varo-ui/ai -pnpm dlx @varo-ui/cli add --target h5 components/agent-ui -pnpm dlx @varo-ui/cli add --target weapp components/agent-ui -``` - -UI 组件由 Registry 安装到项目本地,因此从 `@/components/agent-ui` 导入;`@varo-ui/ai` 只提供事件协议、流控制和 Markdown 能力,不导出 Vue/Wevu UI 组件。 - ## 基础用法 ```vue @@ -42,11 +32,11 @@ import { AgentFineTune } from '@/components/agent-ui' | `apply` | `AgentFineTuneControl[]` | 应用 | | `update:controls` | `AgentFineTuneControl[]` | 更新控制项 | -## 平台差异 +::: info 平台差异 | Target | Import | | ------ | ---------------------------------------------------- | | H5 | Named export from `@/components/agent-ui` | | weapp | 默认导出自 `@/components/agent-ui/AgentFineTune.vue` | -组件 API 在两个目标保持一致;DOM/WXML、调度和原生事件由目标实现负责。 +::: diff --git a/apps/docs/ai/flowchart.md b/apps/docs/ai/flowchart.md index 31b7d708..480cf31c 100644 --- a/apps/docs/ai/flowchart.md +++ b/apps/docs/ai/flowchart.md @@ -6,16 +6,6 @@ -## 安装 - -```bash -pnpm add @varo-ui/ai -pnpm dlx @varo-ui/cli add --target h5 components/agent-ui -pnpm dlx @varo-ui/cli add --target weapp components/agent-ui -``` - -UI 组件由 Registry 安装到项目本地,因此从 `@/components/agent-ui` 导入;`@varo-ui/ai` 只提供事件协议、流控制和 Markdown 能力,不导出 Vue/Wevu UI 组件。 - ## 基础用法 ```vue @@ -42,11 +32,11 @@ import { AgentFlowchart } from '@/components/agent-ui' | `add` | `string \| undefined` | 添加步骤 | | `select` | `AgentFlowNode` | 选择节点 | -## 平台差异 +::: info 平台差异 | Target | Import | | ------ | ----------------------------------------------------- | | H5 | Named export from `@/components/agent-ui` | | weapp | 默认导出自 `@/components/agent-ui/AgentFlowchart.vue` | -组件 API 在两个目标保持一致;DOM/WXML、调度和原生事件由目标实现负责。 +::: diff --git a/apps/docs/ai/image-generation.md b/apps/docs/ai/image-generation.md index 648beb53..dc7dfe32 100644 --- a/apps/docs/ai/image-generation.md +++ b/apps/docs/ai/image-generation.md @@ -6,16 +6,6 @@ -## 安装 - -```bash -pnpm add @varo-ui/ai -pnpm dlx @varo-ui/cli add --target h5 components/agent-ui -pnpm dlx @varo-ui/cli add --target weapp components/agent-ui -``` - -UI 组件由 Registry 安装到项目本地,因此从 `@/components/agent-ui` 导入;`@varo-ui/ai` 只提供事件协议、流控制和 Markdown 能力,不导出 Vue/Wevu UI 组件。 - ## 基础用法 ```vue @@ -46,11 +36,11 @@ import { AgentImageGeneration } from '@/components/agent-ui' | `retry` | `void` | 重试 | | `download` | `string` | 下载 | -## 平台差异 +::: info 平台差异 | Target | Import | | ------ | ----------------------------------------------------------- | | H5 | Named export from `@/components/agent-ui` | | weapp | 默认导出自 `@/components/agent-ui/AgentImageGeneration.vue` | -组件 API 在两个目标保持一致;DOM/WXML、调度和原生事件由目标实现负责。 +::: diff --git a/apps/docs/ai/index.md b/apps/docs/ai/index.md index 0d4c19b8..d85c31c5 100644 --- a/apps/docs/ai/index.md +++ b/apps/docs/ai/index.md @@ -1,151 +1,38 @@ # AI Agent 组件 -Varo Agent UI 的基础 surface 按 **组件案例 → 基础用法 → Props → Events → Slots → 平台差异** 提供独立文档;本页同时记录 Agent Workspace contract。组件、Blocks 与两者合计的 surface 数量由下方 Registry inventory 统一计算,所有界面统一消费 `@varo-ui/ai` 事件与会话版本协议。 +`@varo-ui/ai` 提供事件、流式控制和 Markdown 协议;UI 通过 Registry 安装为可编辑源码。 -## 安装 Agent UI - -先安装无界面的事件协议,再选择目标端通过 Registry 写入可编辑 UI 源码: +## 安装 ```bash pnpm add @varo-ui/ai pnpm dlx @varo-ui/cli add --target h5 components/agent-ui pnpm dlx @varo-ui/cli add --target weapp components/agent-ui + +# Blocks pnpm dlx @varo-ui/cli add --target h5 blocks/agent-chat pnpm dlx @varo-ui/cli add --target weapp blocks/agent-chat pnpm dlx @varo-ui/cli add --target h5 blocks/agent-workspace pnpm dlx @varo-ui/cli add --target weapp blocks/agent-workspace ``` -[浏览全部 Agent 组件](#agent-component-inventory) +::: info 导入 +H5 从 `@/components/agent-ui` 命名导入;小程序从对应 `.vue` 文件导入。 +::: -## 完整对话演示 +## 演示 - - -## 对话与流式内容 - -| 组件 | 用途 | -| ------------------------------------------ | ---------------------------- | -| [AgentLoading](./loading) | 加载、耗时和运行中反馈 | -| [AgentThinking](./thinking) | 推理、搜索和执行轨迹 | -| [AgentMarkdown](./markdown) | 安全增量 Markdown AST | -| [AgentStream](./stream) | 流式回答、错误、光标和操作区 | -| [AgentMessage](./message) | 用户、助手和系统消息 | -| [AgentConversation](./conversation) | 消息历史组合 | -| [AgentMessageScroller](./message-scroller) | 感知阅读位置的会话视口 | - -## 执行、工具与审批 - -| 组件 | 用途 | -| --------------------------------------- | ---------------------------- | -| [AgentToolChip](./tool-chip) | 紧凑工具状态 | -| [AgentToolResult](./tool-result) | 可折叠终端与请求结果 | -| [AgentTaskList](./task-list) | Agent 计划与进度 | -| `AgentTaskRunner` | 可重试、审批和取消的执行控制 | -| [AgentActivity](./activity) | 混合推理、搜索、工具活动流 | -| [AgentApproval](./approval) | 通用人工审批 | -| [AgentToolApproval](./tool-approval) | 工具权限审批 | -| [AgentRecommendation](./recommendation) | 带置信度的 Agent 建议 | -| [AgentEventRenderer](./event-renderer) | 快照到完整回答 UI 的状态投影 | - -## 输入与回答操作 - -| 组件 | 用途 | -| ---------------------------------------------- | ---------------------------- | -| [AgentRadioGroup](./radio-group) | 带动效指示器的单选决策 | -| [AgentPromptSuggestions](./prompt-suggestions) | 提示词建议 | -| [AgentComposer](./composer) | Agent 输入和发送状态 | -| `AgentComposerScope` | 提交前的来源授权与上下文预算 | -| [AgentResponseActions](./response-actions) | 复制、重试、赞、踩 | -| [AgentSelectionActions](./selection-actions) | 针对选中文本的 AI 操作 | -| [AgentCommandSearch](./command-search) | Agent 命令搜索 | - -## 上下文、引用与产物 - -| 组件 | 用途 | -| ------------------------------------------ | ------------------------------------ | -| [AgentArtifact](./artifact) | 代码、文档、文件和图片产物 | -| [AgentAttachmentList](./attachments) | 附件预览与移除 | -| [AgentSourceList](./sources) | 来源列表 | -| [AgentCitations](./citations) | 可折叠引用集合 | -| `AgentRetrievalProgress` | 可见检索队列与失败重试 | -| [AgentRagPipeline](./rag-pipeline) | 五阶段 RAG、上下文组装与流式引用联动 | -| `AgentSourceReceipt` | 回答完成后的来源读取回执 | -| [AgentContextCard](./context-card) | 检索知识块 | -| [AgentCodeBlock](./code-block) | 独立流式代码块 | -| [AgentFileDiff](./file-diff) | 文件级差异 | -| [AgentImageGeneration](./image-generation) | 图片生成生命周期 | - -## 结构化数据与工作区 - -| 组件 | 用途 | -| ------------------------------------ | ------------------------------- | -| [AgentSidebar](./sidebar) | AI 工作区侧栏 | -| `AgentThreadVersions` | 会话分支与版本选择 | -| `AgentShell` | page / docked / sheet placement | -| [AgentInsightCard](./insight-card) | 可翻页 Agent 洞察 | -| [AgentDiffTable](./diff-table) | AI 表格修改建议 | -| [AgentRecordsTable](./records-table) | 可排序记录表格 | -| [AgentFilterTable](./filter-table) | 状态过滤表格 | -| [AgentFlowchart](./flowchart) | Agent 工作流 | -| [AgentFineTune](./fine-tune) | 设计属性调优面板 | - -## Agent Workspace contract - -| 组件 | 关键输入 | 用户事件 | -| ------------------------ | ------------------------------------- | ---------------------------------------------------- | -| `AgentComposerScope` | `sources`、`usagePercent`、`disabled` | `toggle(source, enabled)`、`connect(source)` | -| `AgentRetrievalProgress` | `items` | `retry(item)` | -| `AgentRagPipeline` | `query`、`steps`、`sources`、`answer` | `run`、`cancel`、`selectSource(source)` | -| `AgentSourceReceipt` | `items`、`summary` | `open(item)`、`connect(item)` | -| `AgentTaskRunner` | `tasks`、`busy` | `retry(task)`、`approve(task)`、`cancel` | -| `AgentThreadVersions` | `versions`、`activeId` | `select(version)`、`branch(version)`、`pin(version)` | -| `AgentShell` | `placement`、`open`、`title` | `close` | - -`createAgentThreadController()` 在 `@varo-ui/ai` 中拥有不可变、无环的版本图;组件只渲染 snapshot 并转发决策。`AgentWorkspace` 使用 `toggleSource`、`retryRetrieval`、`retryTask`、`selectVersion` 等 qualified events,避免不同 surface 的 `retry` / `connect` 冲突。 - -### RAG 流程与动效 - -`AgentRagPipeline` 随 `components/agent-ui` 安装。它只投影受控快照,不执行检索、模型请求或来源授权。业务层按实际进度替换输入: - -- `steps`:固定 `query`、`embed`、`retrieve`、`assemble`、`generate` 五个阶段;状态为 `waiting`、`running`、`completed` 或 `failed`。可提供 `detail` 与 `durationMs`。仍有阶段运行时,整体保持运行状态并允许停止;没有运行阶段后再呈现失败结果。 -- `sources`:稳定 `id` 与 `title`,可附带 `excerpt`、0–1 的 `score`、上下文 `tokens` 和 `blue/violet/rose` 色调。仅当所有来源都有有限正数 `tokens` 时按权重分配片段,否则等分;片段保留可读的最小宽度。 -- `answer`:带稳定 `id` 的文本片段 `{ type: 'text', text }` 或引用 `{ type: 'citation', sourceId }`。引用通过来源 ID 关联,不依赖数组位置。删除或更换引用映射会清理已失效的来源反馈,不重播未变化的引用。 -- `title`、`elapsedMs`、`className` 控制标题、总耗时与容器;`reducedMotion` 关闭非必要动效。 - -新引用出现时,对应来源与上下文片段短暂高亮;H5 的悬停、键盘聚焦及点击均能联动来源,小程序使用点击选择。来源缺失时,H5 显示禁用引用按钮,小程序显示不可交互的 `[?]` 文本,并通过可访问标签说明来源不可用;正文仍可阅读。停止、重播与卸载会清理演示定时器;重播沿用当前查询,组件的业务状态不等待动画结束。 - -H5 自动遵循 `prefers-reduced-motion`,小程序同时提供 `reducedMotion` 属性与媒体查询样式。动效使用主题中的 `--varo-agent-motion-*` 变量以及 transform/opacity,不引入动画运行时依赖。 - -`AgentWorkspace` 的 `execution` 插槽可放入此组件,替换默认的对话、检索、任务与回执区域;来源授权、版本与输入区仍由 Workspace 组合。Weapp 的 `weapp-vite` 配置应设置 `weapp.vue.template.scopedSlotsRequireProps: true`,让没有插槽参数的 `#execution` 保持普通命名插槽,避免泛型插槽自动 `setData.pick` 遗漏父级状态。两端 playground 提供可取消、重播的演示数据流程。 - -## 完整 Block - -- [AgentChat](./agent-chat):组合消息历史、流式回答、推理、工具、审批和输入区。 -- `AgentWorkspace`:组合来源授权、检索进度、任务控制、版本分支、对话和三种 placement。 - -## Beautiful UI / beUI / ReUI 对标 - -Varo 没有直接复制 React/Framer Motion 源码,而是把交互能力重写为 Vue 3、`weapp-vite`、`wevu` 和 `weapp-tailwindcss` 可运行的双端组件。 - -- Beautiful UI 的 20 类 Agent surface 已映射:Loading、Thinking、Streaming、Approval、Tool Chips、Task Rows、Chat、Prompt Bar、Recommendation、Context、Diff Table、Records Table、Filter Table、Sidebar、Search、Flowchart、Insight、Code Block、Fine-tune、Selection Actions。 -- beUI 的 Agent 能力已映射:Message / Bubble、Message Scroller、Prompt Input、Todo List、Code Block、Approval Card、File Diff、Tool Result、Streaming Response、Image Generation、Tool Approval、Citations、Agent Activity、Loading States、AI Sidebar、Chat App。 -- ReUI AI Chat 1 / 6 / 9 / 12 的关键闭环已映射为 `AgentComposerScope`、`AgentRetrievalProgress`、`AgentSourceReceipt`、`AgentTaskRunner`、`AgentThreadVersions`、`AgentShell` 与 `AgentWorkspace`;只借鉴交互结构,不复制 React/Radix 源码或桌面视觉壳。 -- React 专属的 `motion/layoutId`、DOM selection 和 browser clipboard 不原样带入小程序;对应能力使用 WXML 状态、CSS 动效、受控事件和业务回调实现。 - -## 事件协议 - -流式 surface 共享以下 transport 事件: +::: warning RAG 边界 +`AgentRagPipeline` 只渲染受控状态并触发 `run`、`cancel`、`selectSource`;检索、模型请求和来源授权由业务层实现。 +::: -- `message.start` / `message.end` -- `text.delta` -- `reasoning.*` -- `tool.*` -- `approval.*` -- `data` / `error` / `done` +## Blocks -会话分支不进入流式 transport event:业务层通过 `createAgentThreadController()` 执行 `append`、`fork` 与 `select`,再把只读 versions snapshot 传给 `AgentThreadVersions`。来源授权、重试、审批和 shell close 同样是受控 UI callbacks。 +- [AgentChat](./agent-chat):对话、流式回答、工具、审批和输入。 +- [AgentWorkspace](./agent-workspace):来源、检索、任务、版本和多种布局。 -H5 使用 Markstream Core RAF 调度;小程序使用定时帧调度。两端共用安全 Markdown AST。 +::: info 平台 +H5 使用 RAF 调度;小程序使用定时帧调度。两端共用安全 Markdown AST。 +::: diff --git a/apps/docs/ai/insight-card.md b/apps/docs/ai/insight-card.md index 50442e23..2db7003a 100644 --- a/apps/docs/ai/insight-card.md +++ b/apps/docs/ai/insight-card.md @@ -6,16 +6,6 @@ -## 安装 - -```bash -pnpm add @varo-ui/ai -pnpm dlx @varo-ui/cli add --target h5 components/agent-ui -pnpm dlx @varo-ui/cli add --target weapp components/agent-ui -``` - -UI 组件由 Registry 安装到项目本地,因此从 `@/components/agent-ui` 导入;`@varo-ui/ai` 只提供事件协议、流控制和 Markdown 能力,不导出 Vue/Wevu UI 组件。 - ## 基础用法 ```vue @@ -43,11 +33,11 @@ import { AgentInsightCard } from '@/components/agent-ui' | `action` | `AgentInsightItem` | 执行建议 | | `update:current` | `number` | 更新当前页 | -## 平台差异 +::: info 平台差异 | Target | Import | | ------ | ------------------------------------------------------- | | H5 | Named export from `@/components/agent-ui` | | weapp | 默认导出自 `@/components/agent-ui/AgentInsightCard.vue` | -组件 API 在两个目标保持一致;DOM/WXML、调度和原生事件由目标实现负责。 +::: diff --git a/apps/docs/ai/loading.md b/apps/docs/ai/loading.md index 1a124218..a05977d7 100644 --- a/apps/docs/ai/loading.md +++ b/apps/docs/ai/loading.md @@ -6,16 +6,6 @@ -## 安装 - -```bash -pnpm add @varo-ui/ai -pnpm dlx @varo-ui/cli add --target h5 components/agent-ui -pnpm dlx @varo-ui/cli add --target weapp components/agent-ui -``` - -UI 组件由 Registry 安装到项目本地,因此从 `@/components/agent-ui` 导入;`@varo-ui/ai` 只提供事件协议、流控制和 Markdown 能力,不导出 Vue/Wevu UI 组件。 - ## 基础用法 ```vue @@ -41,11 +31,11 @@ import { AgentLoading } from '@/components/agent-ui' 无。 -## 平台差异 +::: info 平台差异 | Target | Import | | ------ | ----------------------------------------- | | H5 | Named export from `@/components/agent-ui` | | weapp | `@/components/agent-ui/AgentLoading.vue` | -组件 API 在两个目标保持一致;DOM/WXML、调度和原生事件由目标实现负责。 +::: diff --git a/apps/docs/ai/markdown.md b/apps/docs/ai/markdown.md index 0799873a..e596f17b 100644 --- a/apps/docs/ai/markdown.md +++ b/apps/docs/ai/markdown.md @@ -6,16 +6,6 @@ -## 安装 - -```bash -pnpm add @varo-ui/ai -pnpm dlx @varo-ui/cli add --target h5 components/agent-ui -pnpm dlx @varo-ui/cli add --target weapp components/agent-ui -``` - -UI 组件由 Registry 安装到项目本地,因此从 `@/components/agent-ui` 导入;`@varo-ui/ai` 只提供事件协议、流控制和 Markdown 能力,不导出 Vue/Wevu UI 组件。 - ## 基础用法 ```vue @@ -45,15 +35,15 @@ const markdownContent = '## Result\n\n**Ready**' | ------ | -------- | -------- | | `link` | `string` | 链接点击 | -## 小程序渲染 - +::: warning 小程序渲染 小程序继续使用平台无关的 `stream-markdown-parser` 生成安全 AST。普通行内节点会转换为微信 `rich-text nodes`,标题、列表、代码块、表格、图片和引用继续使用原生小程序节点。链接不会交给 `rich-text`,仍通过 `link` 事件由业务决定如何打开;原始 HTML 不会直接注入。 +::: -## 平台差异 +::: info 平台差异 | Target | Import | | ------ | ----------------------------------------- | | H5 | Named export from `@/components/agent-ui` | | weapp | `@/components/agent-ui/AgentMarkdown.vue` | -组件 API 在两个目标保持一致;DOM/WXML、调度和原生事件由目标实现负责。 +::: diff --git a/apps/docs/ai/message-scroller.md b/apps/docs/ai/message-scroller.md index 91adf36f..0304a623 100644 --- a/apps/docs/ai/message-scroller.md +++ b/apps/docs/ai/message-scroller.md @@ -6,16 +6,6 @@ -## 安装 - -```bash -pnpm add @varo-ui/ai -pnpm dlx @varo-ui/cli add --target h5 components/agent-ui -pnpm dlx @varo-ui/cli add --target weapp components/agent-ui -``` - -UI 组件由 Registry 安装到项目本地,因此从 `@/components/agent-ui` 导入;`@varo-ui/ai` 只提供事件协议、流控制和 Markdown 能力,不导出 Vue/Wevu UI 组件。 - ## 基础用法 ```vue @@ -51,11 +41,11 @@ import { AgentMessageScroller } from '@/components/agent-ui' | --------- | -------- | | `default` | 会话内容 | -## 平台差异 +::: info 平台差异 | Target | Import | | ------ | ----------------------------------------------------------- | | H5 | Named export from `@/components/agent-ui` | | weapp | 默认导出自 `@/components/agent-ui/AgentMessageScroller.vue` | -组件 API 在两个目标保持一致;DOM/WXML、调度和原生事件由目标实现负责。 +::: diff --git a/apps/docs/ai/message.md b/apps/docs/ai/message.md index 4ec2848d..c22131b4 100644 --- a/apps/docs/ai/message.md +++ b/apps/docs/ai/message.md @@ -6,16 +6,6 @@ -## 安装 - -```bash -pnpm add @varo-ui/ai -pnpm dlx @varo-ui/cli add --target h5 components/agent-ui -pnpm dlx @varo-ui/cli add --target weapp components/agent-ui -``` - -UI 组件由 Registry 安装到项目本地,因此从 `@/components/agent-ui` 导入;`@varo-ui/ai` 只提供事件协议、流控制和 Markdown 能力,不导出 Vue/Wevu UI 组件。 - ## 基础用法 ```vue @@ -48,11 +38,11 @@ import { AgentMessage } from '@/components/agent-ui' | --------- | -------- | | `default` | 消息内容 | -## 平台差异 +::: info 平台差异 | Target | Import | | ------ | ----------------------------------------- | | H5 | Named export from `@/components/agent-ui` | | weapp | `@/components/agent-ui/AgentMessage.vue` | -组件 API 在两个目标保持一致;DOM/WXML、调度和原生事件由目标实现负责。 +::: diff --git a/apps/docs/ai/prompt-suggestions.md b/apps/docs/ai/prompt-suggestions.md index 421e9691..460ba404 100644 --- a/apps/docs/ai/prompt-suggestions.md +++ b/apps/docs/ai/prompt-suggestions.md @@ -6,16 +6,6 @@ -## 安装 - -```bash -pnpm add @varo-ui/ai -pnpm dlx @varo-ui/cli add --target h5 components/agent-ui -pnpm dlx @varo-ui/cli add --target weapp components/agent-ui -``` - -UI 组件由 Registry 安装到项目本地,因此从 `@/components/agent-ui` 导入;`@varo-ui/ai` 只提供事件协议、流控制和 Markdown 能力,不导出 Vue/Wevu UI 组件。 - ## 基础用法 ```vue @@ -41,11 +31,11 @@ import { AgentPromptSuggestions } from '@/components/agent-ui' | -------- | -------- | ---------- | | `select` | `string` | 选中建议词 | -## 平台差异 +::: info 平台差异 | Target | Import | | ------ | -------------------------------------------------- | | H5 | Named export from `@/components/agent-ui` | | weapp | `@/components/agent-ui/AgentPromptSuggestions.vue` | -组件 API 在两个目标保持一致;DOM/WXML、调度和原生事件由目标实现负责。 +::: diff --git a/apps/docs/ai/radio-group.md b/apps/docs/ai/radio-group.md index 564dde19..0f62752a 100644 --- a/apps/docs/ai/radio-group.md +++ b/apps/docs/ai/radio-group.md @@ -6,16 +6,6 @@ -## 安装 - -```bash -pnpm add @varo-ui/ai -pnpm dlx @varo-ui/cli add --target h5 components/agent-ui -pnpm dlx @varo-ui/cli add --target weapp components/agent-ui -``` - -UI 组件由 Registry 安装到项目本地,因此从 `@/components/agent-ui` 导入;`@varo-ui/ai` 只提供事件协议、流控制和 Markdown 能力,不导出 Vue/Wevu UI 组件。 - ## 基础用法 ```vue @@ -43,11 +33,11 @@ import { AgentRadioGroup } from '@/components/agent-ui' | `update:value` | `string` | 更新选中值 | | `change` | `string` | 选择变化 | -## 平台差异 +::: info 平台差异 | Target | Import | | ------ | ------------------------------------------- | | H5 | Named export from `@/components/agent-ui` | | weapp | `@/components/agent-ui/AgentRadioGroup.vue` | -组件 API 在两个目标保持一致;DOM/WXML、调度和原生事件由目标实现负责。 +::: diff --git a/apps/docs/ai/rag-pipeline.md b/apps/docs/ai/rag-pipeline.md index 7c51fed4..339424f2 100644 --- a/apps/docs/ai/rag-pipeline.md +++ b/apps/docs/ai/rag-pipeline.md @@ -6,16 +6,6 @@ -## 安装 - -```bash -pnpm add @varo-ui/ai -pnpm dlx @varo-ui/cli add --target h5 components/agent-ui -pnpm dlx @varo-ui/cli add --target weapp components/agent-ui -``` - -UI 组件由 Registry 安装到项目本地,因此从 `@/components/agent-ui` 导入;`@varo-ui/ai` 只提供事件协议、流控制和 Markdown 能力,不导出 Vue/Wevu UI 组件。`AgentRagPipeline` 只投影受控快照,不执行检索、模型请求或来源授权。 - ## 基础用法 ```vue @@ -38,15 +28,16 @@ import { AgentRagPipeline } from '@/components/agent-ui' ## Props -| Prop | Type | Default | 说明 | -| --------------- | ---------------------- | -------------- | ------------------ | -| `query` | `string` | `''` | 当前查询 | -| `steps` | `AgentRagStep[]` | `[]` | 五阶段进度 | -| `sources` | `AgentRagSource[]` | `[]` | 检索来源 | -| `answer` | `AgentRagAnswerPart[]` | `[]` | 文本片段与引用来源 | -| `title` | `string` | `检索增强生成` | 标题 | -| `elapsedMs` | `number` | `undefined` | 总耗时 | -| `reducedMotion` | `boolean` | `false` | 关闭非必要动效 | +| Prop | Type | Default | 说明 | +| --------------- | ------------------------------- | ---------------- | ------------------ | +| `className` | `ClassValue` | `undefined` | 根节点样式 | +| `query` | `string` | `''` | 当前查询 | +| `steps` | `readonly AgentRagStep[]` | `[]` | 五阶段进度 | +| `sources` | `readonly AgentRagSource[]` | `[]` | 检索来源 | +| `answer` | `readonly AgentRagAnswerPart[]` | `[]` | 文本片段与引用来源 | +| `title` | `string` | `'检索增强生成'` | 标题 | +| `elapsedMs` | `number` | `undefined` | 总耗时 | +| `reducedMotion` | `boolean` | `false` | 关闭非必要动效 | ## Events @@ -56,11 +47,12 @@ import { AgentRagPipeline } from '@/components/agent-ui' | `cancel` | `void` | 停止当前流程 | | `selectSource` | `AgentRagSource` | 选中某个来源 | -## 平台差异 +::: info 平台差异 | Target | Import | | ------ | ------------------------------------------------------- | | H5 | Named export from `@/components/agent-ui` | | weapp | 默认导出自 `@/components/agent-ui/AgentRagPipeline.vue` | -组件 API 在两个目标保持一致;DOM/WXML、调度和原生事件由目标实现负责。文档演示使用本地快照,不调用模型或检索服务。 +文档演示使用本地快照,不调用模型或检索服务。 +::: diff --git a/apps/docs/ai/recommendation.md b/apps/docs/ai/recommendation.md index 1643610b..6ac2f80f 100644 --- a/apps/docs/ai/recommendation.md +++ b/apps/docs/ai/recommendation.md @@ -6,16 +6,6 @@ -## 安装 - -```bash -pnpm add @varo-ui/ai -pnpm dlx @varo-ui/cli add --target h5 components/agent-ui -pnpm dlx @varo-ui/cli add --target weapp components/agent-ui -``` - -UI 组件由 Registry 安装到项目本地,因此从 `@/components/agent-ui` 导入;`@varo-ui/ai` 只提供事件协议、流控制和 Markdown 能力,不导出 Vue/Wevu UI 组件。 - ## 基础用法 ```vue @@ -50,11 +40,11 @@ import { AgentRecommendation } from '@/components/agent-ui' | `default` | 扩展内容 | | `secondary` | 次要操作 | -## 平台差异 +::: info 平台差异 | Target | Import | | ------ | ----------------------------------------------- | | H5 | Named export from `@/components/agent-ui` | | weapp | `@/components/agent-ui/AgentRecommendation.vue` | -组件 API 在两个目标保持一致;DOM/WXML、调度和原生事件由目标实现负责。 +::: diff --git a/apps/docs/ai/records-table.md b/apps/docs/ai/records-table.md index 715a7c19..32569950 100644 --- a/apps/docs/ai/records-table.md +++ b/apps/docs/ai/records-table.md @@ -6,16 +6,6 @@ -## 安装 - -```bash -pnpm add @varo-ui/ai -pnpm dlx @varo-ui/cli add --target h5 components/agent-ui -pnpm dlx @varo-ui/cli add --target weapp components/agent-ui -``` - -UI 组件由 Registry 安装到项目本地,因此从 `@/components/agent-ui` 导入;`@varo-ui/ai` 只提供事件协议、流控制和 Markdown 能力,不导出 Vue/Wevu UI 组件。 - ## 基础用法 ```vue @@ -44,11 +34,11 @@ import { AgentRecordsTable } from '@/components/agent-ui' | `select` | `AgentTableRow` | 选择记录 | | `sort` | `AgentTableColumn` | 排序 | -## 平台差异 +::: info 平台差异 | Target | Import | | ------ | -------------------------------------------------------- | | H5 | Named export from `@/components/agent-ui` | | weapp | 默认导出自 `@/components/agent-ui/AgentRecordsTable.vue` | -组件 API 在两个目标保持一致;DOM/WXML、调度和原生事件由目标实现负责。 +::: diff --git a/apps/docs/ai/response-actions.md b/apps/docs/ai/response-actions.md index 2c2e80b4..2c7a87c5 100644 --- a/apps/docs/ai/response-actions.md +++ b/apps/docs/ai/response-actions.md @@ -6,16 +6,6 @@ -## 安装 - -```bash -pnpm add @varo-ui/ai -pnpm dlx @varo-ui/cli add --target h5 components/agent-ui -pnpm dlx @varo-ui/cli add --target weapp components/agent-ui -``` - -UI 组件由 Registry 安装到项目本地,因此从 `@/components/agent-ui` 导入;`@varo-ui/ai` 只提供事件协议、流控制和 Markdown 能力,不导出 Vue/Wevu UI 组件。 - ## 基础用法 ```vue @@ -44,11 +34,11 @@ import { AgentResponseActions } from '@/components/agent-ui' | `like` | `void` | 有帮助 | | `dislike` | `void` | 需改进 | -## 平台差异 +::: info 平台差异 | Target | Import | | ------ | ------------------------------------------------ | | H5 | Named export from `@/components/agent-ui` | | weapp | `@/components/agent-ui/AgentResponseActions.vue` | -组件 API 在两个目标保持一致;DOM/WXML、调度和原生事件由目标实现负责。 +::: diff --git a/apps/docs/ai/selection-actions.md b/apps/docs/ai/selection-actions.md index 0dd58d80..8b035d25 100644 --- a/apps/docs/ai/selection-actions.md +++ b/apps/docs/ai/selection-actions.md @@ -6,16 +6,6 @@ -## 安装 - -```bash -pnpm add @varo-ui/ai -pnpm dlx @varo-ui/cli add --target h5 components/agent-ui -pnpm dlx @varo-ui/cli add --target weapp components/agent-ui -``` - -UI 组件由 Registry 安装到项目本地,因此从 `@/components/agent-ui` 导入;`@varo-ui/ai` 只提供事件协议、流控制和 Markdown 能力,不导出 Vue/Wevu UI 组件。 - ## 基础用法 ```vue @@ -41,11 +31,11 @@ import { AgentSelectionActions } from '@/components/agent-ui' | -------- | ------------------ | -------- | | `select` | `{ action; text }` | 选择操作 | -## 平台差异 +::: info 平台差异 | Target | Import | | ------ | ------------------------------------------------------------ | | H5 | Named export from `@/components/agent-ui` | | weapp | 默认导出自 `@/components/agent-ui/AgentSelectionActions.vue` | -组件 API 在两个目标保持一致;DOM/WXML、调度和原生事件由目标实现负责。 +::: diff --git a/apps/docs/ai/sidebar.md b/apps/docs/ai/sidebar.md index e504e9ea..3ddb4a4c 100644 --- a/apps/docs/ai/sidebar.md +++ b/apps/docs/ai/sidebar.md @@ -6,16 +6,6 @@ AI 工作区侧栏,支持分组、折叠、创建和选中状态。 -## 安装 - -```bash -pnpm add @varo-ui/ai -pnpm dlx @varo-ui/cli add --target h5 components/agent-ui -pnpm dlx @varo-ui/cli add --target weapp components/agent-ui -``` - -UI 组件由 Registry 安装到项目本地,因此从 `@/components/agent-ui` 导入;`@varo-ui/ai` 只提供事件协议、流控制和 Markdown 能力,不导出 Vue/Wevu UI 组件。 - ## 基础用法 ```vue @@ -52,11 +42,11 @@ import { AgentSidebar } from '@/components/agent-ui' | -------- | -------- | | `footer` | 底部内容 | -## 平台差异 +::: info 平台差异 | Target | Import | | ------ | --------------------------------------------------- | | H5 | Named export from `@/components/agent-ui` | | weapp | 默认导出自 `@/components/agent-ui/AgentSidebar.vue` | -组件 API 在两个目标保持一致;DOM/WXML、调度和原生事件由目标实现负责。 +::: diff --git a/apps/docs/ai/sources.md b/apps/docs/ai/sources.md index 74572dcc..9488b358 100644 --- a/apps/docs/ai/sources.md +++ b/apps/docs/ai/sources.md @@ -6,16 +6,6 @@ -## 安装 - -```bash -pnpm add @varo-ui/ai -pnpm dlx @varo-ui/cli add --target h5 components/agent-ui -pnpm dlx @varo-ui/cli add --target weapp components/agent-ui -``` - -UI 组件由 Registry 安装到项目本地,因此从 `@/components/agent-ui` 导入;`@varo-ui/ai` 只提供事件协议、流控制和 Markdown 能力,不导出 Vue/Wevu UI 组件。 - ## 基础用法 ```vue @@ -41,11 +31,11 @@ import { AgentSourceList } from '@/components/agent-ui' | ------ | ----------------- | -------- | | `open` | `AgentSourceItem` | 打开来源 | -## 平台差异 +::: info 平台差异 | Target | Import | | ------ | ------------------------------------------- | | H5 | Named export from `@/components/agent-ui` | | weapp | `@/components/agent-ui/AgentSourceList.vue` | -组件 API 在两个目标保持一致;DOM/WXML、调度和原生事件由目标实现负责。 +::: diff --git a/apps/docs/ai/stream.md b/apps/docs/ai/stream.md index ac2a2620..b1a5a4e7 100644 --- a/apps/docs/ai/stream.md +++ b/apps/docs/ai/stream.md @@ -6,16 +6,6 @@ -## 安装 - -```bash -pnpm add @varo-ui/ai -pnpm dlx @varo-ui/cli add --target h5 components/agent-ui -pnpm dlx @varo-ui/cli add --target weapp components/agent-ui -``` - -UI 组件由 Registry 安装到项目本地,因此从 `@/components/agent-ui` 导入;`@varo-ui/ai` 只提供事件协议、流控制和 Markdown 能力,不导出 Vue/Wevu UI 组件。 - ## 基础用法 ```vue @@ -51,15 +41,15 @@ import { AgentStream } from '@/components/agent-ui' | --------- | ------------ | | `actions` | 完成后的操作 | -## 流式调度 - +::: info 流式调度 `@varo-ui/ai` 对齐 `markstream-core 2.0.7` 和 `stream-markdown-parser 1.2.13`。H5 使用 RAF 调度;小程序使用定时帧调度,但保持 grapheme 边界、代码围栏原子提交、追赶延迟、启动延迟、burst reveal、暂停、恢复、flush 和 dispose 契约。 +::: -## 平台差异 +::: info 平台差异 | Target | Import | | ------ | ----------------------------------------- | | H5 | Named export from `@/components/agent-ui` | | weapp | `@/components/agent-ui/AgentStream.vue` | -组件 API 在两个目标保持一致;DOM/WXML、调度和原生事件由目标实现负责。 +::: diff --git a/apps/docs/ai/task-list.md b/apps/docs/ai/task-list.md index 94b5b23f..2c4b0a53 100644 --- a/apps/docs/ai/task-list.md +++ b/apps/docs/ai/task-list.md @@ -6,16 +6,6 @@ Agent 计划、任务进度和完成计数。 -## 安装 - -```bash -pnpm add @varo-ui/ai -pnpm dlx @varo-ui/cli add --target h5 components/agent-ui -pnpm dlx @varo-ui/cli add --target weapp components/agent-ui -``` - -UI 组件由 Registry 安装到项目本地,因此从 `@/components/agent-ui` 导入;`@varo-ui/ai` 只提供事件协议、流控制和 Markdown 能力,不导出 Vue/Wevu UI 组件。 - ## 基础用法 ```vue @@ -39,11 +29,11 @@ import { AgentTaskList } from '@/components/agent-ui' 无。 -## 平台差异 +::: info 平台差异 | Target | Import | | ------ | ----------------------------------------- | | H5 | Named export from `@/components/agent-ui` | | weapp | `@/components/agent-ui/AgentTaskList.vue` | -组件 API 在两个目标保持一致;DOM/WXML、调度和原生事件由目标实现负责。 +::: diff --git a/apps/docs/ai/thinking.md b/apps/docs/ai/thinking.md index a0bcbb09..4164595a 100644 --- a/apps/docs/ai/thinking.md +++ b/apps/docs/ai/thinking.md @@ -6,16 +6,6 @@ -## 安装 - -```bash -pnpm add @varo-ui/ai -pnpm dlx @varo-ui/cli add --target h5 components/agent-ui -pnpm dlx @varo-ui/cli add --target weapp components/agent-ui -``` - -UI 组件由 Registry 安装到项目本地,因此从 `@/components/agent-ui` 导入;`@varo-ui/ai` 只提供事件协议、流控制和 Markdown 能力,不导出 Vue/Wevu UI 组件。 - ## 基础用法 ```vue @@ -44,11 +34,11 @@ import { AgentThinking } from '@/components/agent-ui' | ------------- | --------- | ------------ | | `update:open` | `boolean` | 展开状态变化 | -## 平台差异 +::: info 平台差异 | Target | Import | | ------ | ----------------------------------------- | | H5 | Named export from `@/components/agent-ui` | | weapp | `@/components/agent-ui/AgentThinking.vue` | -组件 API 在两个目标保持一致;DOM/WXML、调度和原生事件由目标实现负责。 +::: diff --git a/apps/docs/ai/tool-approval.md b/apps/docs/ai/tool-approval.md index 3c05ab33..b73ac008 100644 --- a/apps/docs/ai/tool-approval.md +++ b/apps/docs/ai/tool-approval.md @@ -6,16 +6,6 @@ -## 安装 - -```bash -pnpm add @varo-ui/ai -pnpm dlx @varo-ui/cli add --target h5 components/agent-ui -pnpm dlx @varo-ui/cli add --target weapp components/agent-ui -``` - -UI 组件由 Registry 安装到项目本地,因此从 `@/components/agent-ui` 导入;`@varo-ui/ai` 只提供事件协议、流控制和 Markdown 能力,不导出 Vue/Wevu UI 组件。 - ## 基础用法 ```vue @@ -45,11 +35,11 @@ import { AgentToolApproval } from '@/components/agent-ui' | `deny` | `void` | 拒绝 | | `update:remember` | `boolean` | 更新记忆选项 | -## 平台差异 +::: info 平台差异 | Target | Import | | ------ | -------------------------------------------------------- | | H5 | Named export from `@/components/agent-ui` | | weapp | 默认导出自 `@/components/agent-ui/AgentToolApproval.vue` | -组件 API 在两个目标保持一致;DOM/WXML、调度和原生事件由目标实现负责。 +::: diff --git a/apps/docs/ai/tool-chip.md b/apps/docs/ai/tool-chip.md index 06ef02eb..af4d793c 100644 --- a/apps/docs/ai/tool-chip.md +++ b/apps/docs/ai/tool-chip.md @@ -6,16 +6,6 @@ -## 安装 - -```bash -pnpm add @varo-ui/ai -pnpm dlx @varo-ui/cli add --target h5 components/agent-ui -pnpm dlx @varo-ui/cli add --target weapp components/agent-ui -``` - -UI 组件由 Registry 安装到项目本地,因此从 `@/components/agent-ui` 导入;`@varo-ui/ai` 只提供事件协议、流控制和 Markdown 能力,不导出 Vue/Wevu UI 组件。 - ## 基础用法 ```vue @@ -39,11 +29,11 @@ import { AgentToolChip } from '@/components/agent-ui' 无。 -## 平台差异 +::: info 平台差异 | Target | Import | | ------ | ----------------------------------------- | | H5 | Named export from `@/components/agent-ui` | | weapp | `@/components/agent-ui/AgentToolChip.vue` | -组件 API 在两个目标保持一致;DOM/WXML、调度和原生事件由目标实现负责。 +::: diff --git a/apps/docs/ai/tool-result.md b/apps/docs/ai/tool-result.md index a1387d27..1444ab43 100644 --- a/apps/docs/ai/tool-result.md +++ b/apps/docs/ai/tool-result.md @@ -6,16 +6,6 @@ -## 安装 - -```bash -pnpm add @varo-ui/ai -pnpm dlx @varo-ui/cli add --target h5 components/agent-ui -pnpm dlx @varo-ui/cli add --target weapp components/agent-ui -``` - -UI 组件由 Registry 安装到项目本地,因此从 `@/components/agent-ui` 导入;`@varo-ui/ai` 只提供事件协议、流控制和 Markdown 能力,不导出 Vue/Wevu UI 组件。 - ## 基础用法 ```vue @@ -52,11 +42,11 @@ import { AgentToolResult } from '@/components/agent-ui' | --------- | ---------- | | `default` | 自定义输出 | -## 平台差异 +::: info 平台差异 | Target | Import | | ------ | ------------------------------------------------------ | | H5 | Named export from `@/components/agent-ui` | | weapp | 默认导出自 `@/components/agent-ui/AgentToolResult.vue` | -组件 API 在两个目标保持一致;DOM/WXML、调度和原生事件由目标实现负责。 +::: diff --git a/apps/docs/components/badge.md b/apps/docs/components/badge.md index 89b5fdf8..c02e96ba 100644 --- a/apps/docs/components/badge.md +++ b/apps/docs/components/badge.md @@ -1,7 +1,5 @@ # Badge 徽标 - - ## 演示 diff --git a/apps/docs/components/breadcrumb.md b/apps/docs/components/breadcrumb.md index bb6854cf..4b1d16eb 100644 --- a/apps/docs/components/breadcrumb.md +++ b/apps/docs/components/breadcrumb.md @@ -1,7 +1,5 @@ # Breadcrumb 面包屑 - - ## 基础用法 ```vue diff --git a/apps/docs/components/button.md b/apps/docs/components/button.md index 5819f3d9..23ec69e0 100644 --- a/apps/docs/components/button.md +++ b/apps/docs/components/button.md @@ -1,11 +1,13 @@ # Button - - ## 演示 +::: info 交互 +按钮保留 44px 默认命中高度和现有语义色。按压使用 140ms 的轻量缩放与内阴影反馈;Ghost 默认透明,仅在 hover 或按压时出现弱背景。减少动态效果时不执行空间缩放。 +::: + ## 基础用法 ```vue diff --git a/apps/docs/components/calendar-card.md b/apps/docs/components/calendar-card.md index 62832163..5b8356b0 100644 --- a/apps/docs/components/calendar-card.md +++ b/apps/docs/components/calendar-card.md @@ -1,7 +1,5 @@ # CalendarCard 日历卡片 - - ## 演示 diff --git a/apps/docs/components/calendar.md b/apps/docs/components/calendar.md index 361315d4..e409ee3e 100644 --- a/apps/docs/components/calendar.md +++ b/apps/docs/components/calendar.md @@ -1,7 +1,5 @@ # Calendar 日历 - - ## 演示 diff --git a/apps/docs/components/cascader.md b/apps/docs/components/cascader.md index 02184eff..0866dcbf 100644 --- a/apps/docs/components/cascader.md +++ b/apps/docs/components/cascader.md @@ -1,7 +1,5 @@ # Cascader 级联选择器 - - ## 演示 diff --git a/apps/docs/components/cell.md b/apps/docs/components/cell.md index f3bd6555..87ae0779 100644 --- a/apps/docs/components/cell.md +++ b/apps/docs/components/cell.md @@ -1,7 +1,5 @@ # Cell - - ## 演示 diff --git a/apps/docs/components/checkbox.md b/apps/docs/components/checkbox.md index 4a64474f..0dd29d92 100644 --- a/apps/docs/components/checkbox.md +++ b/apps/docs/components/checkbox.md @@ -1,7 +1,5 @@ # Checkbox 复选按钮 - - ## 演示 diff --git a/apps/docs/components/date-field.md b/apps/docs/components/date-field.md new file mode 100644 index 00000000..b13781fc --- /dev/null +++ b/apps/docs/components/date-field.md @@ -0,0 +1,32 @@ +# DateField 日期字段 + +年 / 月 / 日三列选择,底层复用 `VPicker`。月历网格继续用 [Calendar](/components/calendar),不要把 DateField 当成日历。 + +## 演示 + + + +## Props + +| Prop | 类型 | 默认值 | 描述 | +| ------------- | --------- | --------------- | --------------------- | +| `visible` | `boolean` | `false` | Picker 是否展示 | +| `value` | `string` | `undefined` | 当前日期 `YYYY-MM-DD` | +| `placeholder` | `string` | `'Select date'` | 空值文案 | +| `disabled` | `boolean` | `false` | 禁用字段 | +| `readonly` | `boolean` | `false` | 只读字段 | +| `minYear` | `number` | `1970` | 起始年份 | +| `maxYear` | `number` | `2100` | 结束年份 | +| `title` | `string` | `undefined` | Picker 标题 | +| `confirmText` | `string` | `'Confirm'` | 确认文案 | +| `cancelText` | `string` | `'Cancel'` | 取消文案 | + +## Events + +| Event | Payload | 描述 | +| ---------------- | --------- | -------------- | +| `update:value` | `string` | 确认后提交日期 | +| `update:visible` | `boolean` | Picker 显隐 | +| `change` | `string` | 草稿日期变化 | +| `confirm` | `string` | 确认并提交 | +| `cancel` | `void` | 取消并保留原值 | diff --git a/apps/docs/components/date-picker.md b/apps/docs/components/date-picker.md index 8b058794..c4372688 100644 --- a/apps/docs/components/date-picker.md +++ b/apps/docs/components/date-picker.md @@ -1,7 +1,5 @@ # DatePicker 日期选择器 - - ## 演示 diff --git a/apps/docs/components/dialog.md b/apps/docs/components/dialog.md index 909b78f5..0765fb63 100644 --- a/apps/docs/components/dialog.md +++ b/apps/docs/components/dialog.md @@ -1,75 +1,12 @@ # Dialog -Varo 的 Dialog 采用 parts 暴露方式:`VDialogRoot`、`VDialogTrigger`、`VDialogOverlay`、`VDialogContent` 与 `VDialogClose`。 - - +由 `VDialogRoot`、`VDialogTrigger`、`VDialogOverlay`、`VDialogContent` 和 `VDialogClose` 组合。 ## 演示 -## 何时使用 - -- 需要模态确认或补充信息展示 -- 需要通过 parts 方式做企业内部二次封装 -- 需要统一 overlay click / escape close 等行为 - -## Anatomy - -
- Dialog 不是单个大组件,而是一组可组合 parts。 -
    -
  • VDialogRoot 持有 open 状态与受控逻辑。
  • -
  • VDialogTrigger 负责打开或切换状态。
  • -
  • VDialogOverlay 负责遮罩与点击关闭。
  • -
  • VDialogContent 承载弹层内容。
  • -
  • VDialogClose 负责显式关闭动作。
  • -
-
- -## 小程序运行时说明 - -微信小程序原生运行时没有浏览器 `document` 键盘事件,也不提供 DOM 焦点陷阱、`inert` 或 portal 语义。因此 Weapp 使用 `VDialogClose` 与 overlay 点击作为关闭入口。weapp Registry 安装的是 wevu SFC parts(`v-dialog-root.vue` 等),不依赖 `document`。reason/cancel 状态契约与 H5 保持一致。 - -## Root Props - -| Prop | 类型 | 默认值 | 说明 | -| ------------- | ---------------------- | ----------- | ---------------------- | -| `open` | `boolean \| undefined` | `undefined` | 受控打开状态 | -| `defaultOpen` | `boolean` | `false` | 非受控初始状态 | -| `disabled` | `boolean \| undefined` | `undefined` | 禁止触发打开或关闭行为 | - -## Root Events - -| Event | Payload | 说明 | -| ------------- | --------------------------------------------------- | ------------------------------------------------- | -| `openChange` | `(open: boolean, details: DialogOpenChangeDetails)` | 状态写入前同步触发的变更请求,可通过 details 取消 | -| `update:open` | `boolean` | 仅在请求未取消时于 `openChange` 之后触发 | - -```ts -type DialogOpenChangeReason - = | 'trigger-press' - | 'outside-press' - | 'escape-key' - | 'close-press' - | 'imperative-action' - -interface DialogOpenChangeDetails { - readonly reason: DialogOpenChangeReason - readonly canceled: boolean - cancel: () => void -} -``` - -| `reason` | 来源 | -| ------------------- | --------------------------------------------- | -| `trigger-press` | Trigger,以及 core 的 `open` / `toggle` 事件 | -| `outside-press` | Overlay 点击 | -| `escape-key` | H5 的 `Escape` 键或 core 的 Escape 事件 | -| `close-press` | `VDialogClose` | -| `imperative-action` | `useDialogRoot().api.setOpen(...)` 的默认原因 | - -`cancel()` 只在 `openChange` handler 返回前同步调用时生效: +## 基础用法 ```vue ``` -传入 `open` 后,受控 prop 始终是最终事实来源。未取消的请求会依次发出 `openChange`、`update:open`,但视图只在上层应用新 prop 后变化;取消会阻止内部非受控写入与 `update:open`。如果上层随后自行改变 `open`,组件仍遵循该 prop。 - -## Parts 说明 - -| Part | 作用 | -| ---------------- | ------------------ | -| `VDialogTrigger` | 触发打开或切换 | -| `VDialogOverlay` | 蒙层,点击时可关闭 | -| `VDialogContent` | 弹层主体内容 | -| `VDialogClose` | 显式关闭动作 | +::: warning 小程序运行时 +Weapp 没有 DOM 焦点陷阱、`inert`、portal 或 `Escape` 键语义;使用 `VDialogClose` 或点击 overlay 关闭。 +::: -## 行为说明 +## Root Props -- 支持受控与非受控两种模式 -- 未取消的状态转换只写入并发出一次 `update:open` -- H5 支持 overlay、`Escape`、焦点陷阱、背景 `inert` 与关闭后的 Trigger 焦点恢复 -- Weapp 使用 wevu SFC parts 与显式 Close/overlay;不绑定 `document`,也不承诺原生运行时不存在的 DOM 键盘或焦点行为 -- parts 设计更适合企业内部继续收敛成统一 Modal API +| Prop | 类型 | 默认值 | 说明 | +| ------------- | ---------------------- | ----------- | -------------- | +| `open` | `boolean \| undefined` | `undefined` | 受控打开状态 | +| `defaultOpen` | `boolean` | `false` | 非受控初始状态 | +| `disabled` | `boolean \| undefined` | `undefined` | 禁止状态切换 | -## 组合建议 +## Root Events -
- 推荐组合方式 -
    -
  • 先在业务侧确定 open 状态是否需要外部控制,再决定是否传入 open
  • -
  • 复杂弹层最好把标题区、内容区、底部操作区做成自己的 wrapper,而不是直接在业务里重复拼装。
  • -
  • 不同端的 portal 策略可以留在适配层处理,不要把平台分支写进核心交互模型。
  • -
-
+| Event | Payload | 说明 | +| ------------- | --------------------------------------------------- | ------------------------------------------ | +| `openChange` | `(open: boolean, details: DialogOpenChangeDetails)` | 变更前触发,可通过 `details.cancel()` 取消 | +| `update:open` | `boolean` | 未取消时触发 | -## 无障碍与关闭约定 +`details.reason` 为 `trigger-press`、`outside-press`、`escape-key`、`close-press` 或 `imperative-action`。 -- overlay、`Escape`、Close 与 Trigger 都进入同一 pre-change reason/cancel 契约 -- 取消关闭时 Dialog 内容、H5 modal layer 与焦点归属保持不变 -- 显式关闭动作统一走 `VDialogClose` -- 受控模式由 `open` prop 决定最终可见状态 +## Parts -## 相关文档 +| Part | 作用 | +| ---------------- | -------------- | +| `VDialogRoot` | 状态与上下文 | +| `VDialogTrigger` | 打开或切换 | +| `VDialogOverlay` | 遮罩与点击关闭 | +| `VDialogContent` | 弹层内容 | +| `VDialogClose` | 显式关闭 | -- [Button](/components/button) -- [Input](/components/input) -- [主题配置](/guide/theme) -- [跨端演示](/examples/) +::: info 关闭约定 +受控模式以 `open` 为准;overlay、`Escape`、Close 和 Trigger 都进入同一 `openChange` / cancel 契约。 +::: diff --git a/apps/docs/components/divider.md b/apps/docs/components/divider.md index 98aede92..834f2407 100644 --- a/apps/docs/components/divider.md +++ b/apps/docs/components/divider.md @@ -1,7 +1,5 @@ # Divider - - ## 演示 diff --git a/apps/docs/components/elevator.md b/apps/docs/components/elevator.md index 3e4b1518..6c08c72d 100644 --- a/apps/docs/components/elevator.md +++ b/apps/docs/components/elevator.md @@ -2,8 +2,6 @@ `VElevator` 会在内容滚动时根据当前分组标题同步右侧索引;滚动到底部时固定到最后一组,点击索引只滚动组件内部列表,不移动浏览器页面。 - - ## 演示 diff --git a/apps/docs/components/fixed-nav.md b/apps/docs/components/fixed-nav.md index bf8c67cc..1686f049 100644 --- a/apps/docs/components/fixed-nav.md +++ b/apps/docs/components/fixed-nav.md @@ -1,7 +1,5 @@ # FixedNav 悬浮导航 - - ## 演示 diff --git a/apps/docs/components/form.md b/apps/docs/components/form.md index 73d2e1f9..7d9aeaf0 100644 --- a/apps/docs/components/form.md +++ b/apps/docs/components/form.md @@ -1,7 +1,5 @@ # Form 表单 - - ## 演示 diff --git a/apps/docs/components/grid.md b/apps/docs/components/grid.md index 74ac4c7b..6b81218f 100644 --- a/apps/docs/components/grid.md +++ b/apps/docs/components/grid.md @@ -1,7 +1,5 @@ # Grid - - ## 演示 diff --git a/apps/docs/components/image.md b/apps/docs/components/image.md index bf524f9b..4a640f3a 100644 --- a/apps/docs/components/image.md +++ b/apps/docs/components/image.md @@ -1,7 +1,5 @@ # Image - - ## 演示 @@ -74,6 +72,6 @@ | `loading` | 自定义加载占位 | | `error` | 自定义失败占位 | -## Primitives - +::: info Primitives `ImageRoot` 分别由 `@varo-ui/h5/primitives` 与 `@varo-ui/weapp/primitives` 提供;`@varo-ui/headless` 只承载共享状态契约,UI 包的 `VImage` 负责 Varo 类名和 API 包装。 +::: diff --git a/apps/docs/components/index.md b/apps/docs/components/index.md index 0d21604f..af1df935 100644 --- a/apps/docs/components/index.md +++ b/apps/docs/components/index.md @@ -1,18 +1,9 @@ --- -title: 组件总览 -description: 按任务类型浏览 Varo 的 H5 与小程序组件,并在同一页面检查双端行为和代码。 +title: 组件 +description: Varo H5 与小程序组件的演示、用法和 API。 outline: false --- -# 组件总览 +# 组件 -按任务类型找到组件,再进入同一页面检查 H5 与小程序的演示、代码和平台差异。需要直接定位时,使用顶部文档搜索。 - - - -## 继续探索 - -- [AI Agent 组件](/ai/):流式回答、工具、审批、产物与工作区界面。 -- [Primitives](/primitives/):无样式行为、受控状态与可访问交互。 -- [Blocks](/blocks/build-your-own):面向业务场景的可复制页面切片。 -- [跨端示例](/examples/):查看组件组合后的 H5 与小程序效果。 +选择组件查看双端演示、用法和 API。 diff --git a/apps/docs/components/indicator.md b/apps/docs/components/indicator.md index e9148ba8..2a4ef62b 100644 --- a/apps/docs/components/indicator.md +++ b/apps/docs/components/indicator.md @@ -1,7 +1,5 @@ # Indicator 指示器 - - ## 演示 diff --git a/apps/docs/components/input-number.md b/apps/docs/components/input-number.md index 06b2228a..4f78a18f 100644 --- a/apps/docs/components/input-number.md +++ b/apps/docs/components/input-number.md @@ -1,23 +1,26 @@ # InputNumber 数字输入框 - - ## 演示 +InputNumber 默认使用紧凑的 128px 最小宽度,不会在横向商品行中挤压相邻内容;需要铺满容器时可通过 `class` 或父级布局显式设置宽度。 + ## 步进与精度 通过 `step` 控制步进,通过 `precision` 控制小数精度。 ## Props -| Prop | 类型 | 默认值 | 描述 | -| ----------- | --------- | ----------- | -------- | -| `value` | `number` | `0` | 当前值 | -| `min` | `number` | `-Infinity` | 最小值 | -| `max` | `number` | `Infinity` | 最大值 | -| `step` | `number` | `1` | 步进 | -| `precision` | `number` | `undefined` | 小数精度 | -| `disabled` | `boolean` | `false` | 禁用 | -| `readonly` | `boolean` | `false` | 只读 | +| Prop | 类型 | 默认值 | 描述 | +| ------------------- | --------- | ------------------ | ---------------------- | +| `decreaseAriaLabel` | `string` | `'Decrease value'` | 减少按钮的可访问名称 | +| `increaseAriaLabel` | `string` | `'Increase value'` | 增加按钮的可访问名称 | +| `inputAriaLabel` | `string` | `'Numeric value'` | 数值输入框的可访问名称 | +| `value` | `number` | `0` | 当前值 | +| `min` | `number` | `-Infinity` | 最小值 | +| `max` | `number` | `Infinity` | 最大值 | +| `step` | `number` | `1` | 步进 | +| `precision` | `number` | `undefined` | 小数精度 | +| `disabled` | `boolean` | `false` | 禁用 | +| `readonly` | `boolean` | `false` | 只读 | diff --git a/apps/docs/components/input.md b/apps/docs/components/input.md index 0d3e50b5..0cb840c4 100644 --- a/apps/docs/components/input.md +++ b/apps/docs/components/input.md @@ -1,7 +1,5 @@ # Input - - ## 演示 @@ -94,9 +92,13 @@ const digits = (value: string) => value.replace(/\D/g, '') | `suffixIcon` | `string` | `undefined` | 后缀内容 | | `errorMessage` | `string` | `undefined` | 错误文案 | -> Weapp 的 property 系统无法区分省略 `value` 与显式传入 `:value="undefined"`;两者都会使用非受控 `defaultValue`。需要受控空值时请传入 `value=""`。`VTextarea` 遵循同一规则。 +::: warning Weapp 受控空值 +Weapp 无法区分省略 `value` 与 `:value="undefined"`,两者都会使用 `defaultValue`。受控空值请传入 `value=""`。 +::: -Weapp 原生控件桥接使用显式 props:`name` 参与表单提交,`inputId` 设置内部 ``/`', 'label': '', + 'canvas': '', 'image': '', 'scroll-view': '', 'rich-text': '', diff --git a/packages/weapp-web/src/runtime/wx-host.ts b/packages/weapp-web/src/runtime/wx-host.ts index 137a06e9..ef849054 100644 --- a/packages/weapp-web/src/runtime/wx-host.ts +++ b/packages/weapp-web/src/runtime/wx-host.ts @@ -1,3 +1,5 @@ +import { createPreviewCanvasContext, findPreviewSelectorElement } from './native-elements.ts' + export interface WxHostOptions { pagePath: string getPage: () => Record | undefined @@ -5,6 +7,24 @@ export interface WxHostOptions { apis?: Record } +interface PreviewSelectorRect { + bottom: number + dataset: DOMStringMap + height: number + id: string + left: number + right: number + top: number + width: number +} + +interface PreviewSelectorQuery { + boundingClientRect: (callback: (result: PreviewSelectorRect | null) => void) => PreviewSelectorQuery + exec: (callback?: (results: Array) => void) => void + in: (owner?: unknown) => PreviewSelectorQuery + select: (selector: string) => PreviewSelectorQuery +} + function asRecord(value: unknown): Record | undefined { return value !== null && typeof value === 'object' && !Array.isArray(value) ? value as Record : undefined } @@ -45,11 +65,45 @@ export function createWxHost({ pagePath, getPage, enqueue, apis }: WxHostOptions }, }) const resize = listeners(resizeListeners) - const invokePage = (method: string, args: unknown[]) => { - const page = getPage() - const handler = page?.[method] - if (!page || typeof handler !== 'function') { throw new Error(`当前预览页面无法提供 wx.${method}`) } - return Reflect.apply(handler, page, args) + const createSelectorQuery = (): PreviewSelectorQuery => { + let selector = '' + let owner: unknown + let rectCallback: ((result: PreviewSelectorRect | null) => void) | undefined + const query: PreviewSelectorQuery = { + boundingClientRect(handler) { + rectCallback = handler + return query + }, + exec(handler) { + enqueue(() => { + const element = selector ? findPreviewSelectorElement(selector, owner) : null + const bounds = element?.getBoundingClientRect() + const result = bounds && element + ? { + bottom: bounds.bottom, + dataset: element.dataset, + height: bounds.height, + id: element.id, + left: bounds.left, + right: bounds.right, + top: bounds.top, + width: bounds.width, + } + : null + rectCallback?.(result) + handler?.([result]) + }) + }, + in(value) { + owner = value + return query + }, + select(value) { + selector = value + return query + }, + } + return query } const supported: Record = { getWindowInfo: windowInfo, @@ -74,7 +128,11 @@ export function createWxHost({ pagePath, getPage, enqueue, apis }: WxHostOptions callback(options, 'complete', result) }) }, - createSelectorQuery: () => invokePage('createSelectorQuery', []), + createCanvasContext: (canvasId: unknown, owner?: unknown) => { + if (typeof canvasId !== 'string' || !canvasId) { throw new TypeError('wx.createCanvasContext 需要 canvasId') } + return createPreviewCanvasContext(canvasId, owner) + }, + createSelectorQuery, onWindowResize: resize.add, offWindowResize: resize.remove, } diff --git a/packages/weapp-web/tests/wx-host.test.ts b/packages/weapp-web/tests/wx-host.test.ts new file mode 100644 index 00000000..58859aac --- /dev/null +++ b/packages/weapp-web/tests/wx-host.test.ts @@ -0,0 +1,62 @@ +// @vitest-environment jsdom + +import { afterEach, describe, expect, it, vi } from 'vitest' +import { createWxHost } from '../src/runtime/wx-host' + +afterEach(() => { + document.body.replaceChildren() +}) + +describe('wx host selector query', () => { + it('measures a selected native control through the queued callback contract', () => { + const target = document.createElement('div') + target.id = 'varo-signature-1' + target.dataset.surface = 'signature' + target.getBoundingClientRect = vi.fn(() => ({ + bottom: 188, + height: 168, + left: 20, + right: 351, + top: 20, + width: 331, + x: 20, + y: 20, + toJSON: () => ({}), + })) + document.body.append(target) + + const queued: Array<() => void> = [] + const { dispose, wx } = createWxHost({ + enqueue: callback => queued.push(callback), + getPage: () => undefined, + pagePath: 'pages/web-preview/index', + }) + const measure = vi.fn() + const complete = vi.fn() + const createSelectorQuery = wx.createSelectorQuery as () => { + boundingClientRect: (callback: typeof measure) => unknown + exec: (callback: typeof complete) => void + in: (owner: unknown) => unknown + select: (selector: string) => unknown + } + const query = createSelectorQuery() + + query.in({}) + query.select('#varo-signature-1') + query.boundingClientRect(measure) + query.exec(complete) + expect(measure).not.toHaveBeenCalled() + + queued.shift()?.() + expect(measure).toHaveBeenCalledWith(expect.objectContaining({ + dataset: target.dataset, + height: 168, + id: 'varo-signature-1', + width: 331, + })) + expect(complete).toHaveBeenCalledWith([ + expect.objectContaining({ height: 168, width: 331 }), + ]) + dispose() + }) +}) diff --git a/registry/component-tiers.v0.1.json b/registry/component-tiers.v0.1.json index 1e5f9439..097085a6 100644 --- a/registry/component-tiers.v0.1.json +++ b/registry/component-tiers.v0.1.json @@ -1,13 +1,13 @@ { "version": "0.2", "runtimeCatalog": { - "h5": 57, - "weappVite": 57 + "h5": 61, + "weappVite": 60 }, "registryCatalog": { - "h5": 58, - "weappVite": 48, - "weappSfc": 47, + "h5": 62, + "weappVite": 53, + "weappSfc": 52, "weappSfcBaseKit": 15 }, "registryExtensions": [ @@ -24,6 +24,7 @@ "cell", "checkbox", "collapse", + "date-field", "dialog", "divider", "empty", @@ -42,14 +43,17 @@ "notice-bar", "overlay", "pagination", + "picker", "popover", "popup", "progress", + "pull-refresh", "radio", "rate", "safe-area", "searchbar", "select", + "signature", "skeleton", "space", "steps", @@ -60,7 +64,8 @@ "tabs", "tag", "textarea", - "toast" + "toast", + "watermark" ], "weappSpecializedPendingRegistry": [ "calendar", @@ -69,7 +74,6 @@ "elevator", "fixed-nav", "number-keyboard", - "picker", "range", "short-password", "side-navbar", diff --git a/registry/components/agent-ui/AgentRagPipeline.vue b/registry/components/agent-ui/AgentRagPipeline.vue index 5d89aa90..29935dc2 100644 --- a/registry/components/agent-ui/AgentRagPipeline.vue +++ b/registry/components/agent-ui/AgentRagPipeline.vue @@ -314,14 +314,14 @@ const answerParts = computed(() => { }) }) -const footerActionLabel = computed(() => { +const actionLabel = computed(() => { if (anyRunning.value) { return '停止' } if (hasFailure.value) { return '重试流程' } if (allCompleted.value) { return '重新运行' } return '运行流程' }) -const footerStatusLabel = computed(() => { +const statusLabel = computed(() => { if (anyRunning.value) { return `流程运行中,已完成 ${completedCount.value}/5` } if (hasFailure.value) { return `流程失败,已完成 ${completedCount.value}/5` } if (allCompleted.value) { return '流程已完成,5/5' } @@ -394,16 +394,39 @@ onBeforeUnmount(clearPing) diff --git a/registry/components/agent-ui/h5/AgentRagPipeline.vue b/registry/components/agent-ui/h5/AgentRagPipeline.vue index 83179b2d..358a5500 100644 --- a/registry/components/agent-ui/h5/AgentRagPipeline.vue +++ b/registry/components/agent-ui/h5/AgentRagPipeline.vue @@ -202,7 +202,7 @@ const actionClass = computed(() => ), ) -const footerStatusLabel = computed(() => { +const statusLabel = computed(() => { if (isRunning.value) { return `处理中,${completedCount.value}/5 已完成` } if (hasFailed.value) { return '流程失败,可重试' } if (isCompleted.value) { return '流程已完成' } @@ -218,7 +218,7 @@ const liveStatus = computed(() => { return '检索增强生成流程等待运行' }) -const footerDotClass = computed(() => { +const statusDotClass = computed(() => { if (overallStatus.value === 'running') { return 'bg-[var(--varo-agent-primary)]' } if (overallStatus.value === 'failed') { return 'bg-[var(--varo-agent-danger)]' } if (overallStatus.value === 'completed') { return 'bg-[var(--varo-agent-success)]' } @@ -393,26 +393,39 @@ onBeforeUnmount(clearAllPings)
-
-

- {{ title }} -

- - {{ elapsedLabel }} - -

- {{ liveStatus }} -

+
+
+

+ {{ title }} +

+ + +
+
+ + {{ elapsedLabel }} + + +
-
    +
    - -
    - - - -
diff --git a/registry/components/button/weapp-vite.vue b/registry/components/button/weapp-vite.vue index b0a7babc..a8542b6a 100644 --- a/registry/components/button/weapp-vite.vue +++ b/registry/components/button/weapp-vite.vue @@ -13,6 +13,7 @@ type ButtonShape = 'default' | 'square' | 'round' const props = withDefaults( defineProps<{ + ariaLabel?: string block?: boolean className?: ClassValue color?: string @@ -31,6 +32,7 @@ const props = withDefaults( variant?: ButtonVariant }>(), { + ariaLabel: '', block: false, disabled: false, hairline: false, @@ -127,6 +129,7 @@ function pressCancel() {