---
title: MotionControl
description: 移植自 Amicro UIkit 的动效控件集
category: Advanced
status: beta
since: 0.6.3
tags: [motion, controls, uikit, pro]
syncStatus: reviewed
---

## 用法

### 全部变体
`variant` 选择控件；选项与命令都由调用方提供。
:::TuffDemoWrapper{demo="MotionControlDemo" code-lang="vue"}
---
code: |
  <script setup lang="ts">
  import { ref } from 'vue'
  import { TxMotionControl } from '@talex-touch/tuffex/motion-control'

  const saved = ref(false)
  const category = ref('design')
  const options = [
    { value: 'design', label: '设计' },
    { value: 'dev', label: '开发' },
  ]
  </script>

  <template>
    <TxMotionControl
      v-model="saved"
      variant="yui-save-pill"
      :labels="{ save: '保存项目', saved: '已保存' }"
    />
    <TxMotionControl
      v-model="category"
      variant="yui-category-select"
      :options="options"
      label="分类"
    />
  </template>
---
:::

### 最佳实践

- 业务结果由应用持有：菜单命令不代表后端成功，PiP 状态不代表平台已切换，`download` 只是请求。
- 使用稳定的 `value` 键，文案单独本地化；分类、日期、频率、标签与命令由调用方提供。
- 可关闭标签同时绑定 `v-model` 与 `v-model:items`；要保留最后一项时设 `minItems="1"`，用 `add` 分配真实 ID。
- `item` 插槽内不放交互元素；独立操作放在原生按钮之外，丰富内容用 `panel` 插槽。
- `status` 与 `progress` 来自真实传输，取消与错误也在传输层处理。

## API 参考

### 属性

| 属性 | 类型 | 默认值 | 说明 |
| --- | --- | --- | --- |
| `variant` | `MotionControlVariant` | `yui-category-select` | 34 个变体之一；21 个目录 ID 与上游一致。 |
| `modelValue` | `string \| number \| boolean` | 由变体决定 | 受控值；省略时状态留在组件内，选择类默认首个可用选项。 |
| `options` | `MotionControlItem[]` | `[]` | 选择类选项，优先于 `items`；可关闭标签只读 `items`。 |
| `items` | `MotionControlItem[]` | `[]` | 菜单命令或可关闭标签，配合 `v-model:items`。 |
| `count` | `number` | 分段条/步骤器为 `3`，其他为 `4` | 分段数、页数，或无 `options` 时生成的步骤数。 |
| `min` | `number` | `0` | 计数下限，也是非受控时的初始值。 |
| `max` | `number` | — | 计数上限。 |
| `step` | `number` | `1` | 计数器与径向进度的增量；`25` 对应源码的四分之一进度。 |
| `disabled` | `boolean` | `false` | 阻止选择、命令、取值、关闭、添加与下载请求。 |
| `size` | `xs \| sm \| md \| lg` | `md` | 控件高度与内边距。 |
| `status` | `idle \| loading \| success \| error` | `idle` | 宿主提供的下载状态；`loading` 阻止重复请求，仅 `success` 显示勾。 |
| `progress` | `number` | `0` | 宿主提供的下载百分比，仅 `loading` 时显示。 |
| `open` | `boolean` | — | 受控的菜单、提示或频率选择展开状态；分类选择不受它控制。 |
| `animated` | `boolean` | `true` | 启用动效；离屏、隐藏或减少动态效果时仍会停止。 |
| `label` | `string` | `''` | 可见文案，或组与触发器的无障碍名称，视变体而定。 |
| `tooltip` | `string` | `''` | 提示或 glance 文案；悬停链接缺省时显示 `href`。 |
| `href` | `string` | `''` | 悬停链接的目标；省略时触发器改为派发 `action` 的按钮。 |
| `target` | `_self \| _blank` | `_self` | 链接目标；`_blank` 自动加 `noopener noreferrer`。 |
| `newItem` | `MotionControlItem` | — | 调用方准备好的新标签；值重复时不添加。 |
| `maxItems` | `number` | — | 标签数量上限。 |
| `minItems` | `number` | `0` | 最少保留的标签数；`1` 对应上游「最后一项不可关闭」。 |
| `canBack` | `boolean` | `true` | 允许后退请求。 |
| `canForward` | `boolean` | `true` | 允许前进请求。 |
| `labels` | `Partial<MotionControlLabels>` | 英文默认文案 | 覆盖默认文案，不依赖组件库消息目录。 |

### 事件

| 事件 | 参数 | 时机 |
| --- | --- | --- |
| `update:modelValue` | `MotionControlValue` | 允许的操作改变值时触发。 |
| `change` | `MotionControlValue` | 与 `update:modelValue` 同步；值未变时不触发。 |
| `select` | `MotionControlItem` | 选中选项、步骤、标签或命令时触发，重复选择也触发。 |
| `update:items` | `MotionControlItem[]` | 关闭标签或添加 `newItem` 后触发。 |
| `update:open` | `boolean` | 菜单、提示或频率选择展开状态变化时触发。 |
| `close` | `MotionControlItem` | 标签被关闭时触发。 |
| `add` | `MotionControlItem \| undefined` | 添加 `newItem`；未提供时请求宿主创建标签。 |
| `action` | `{ variant, value, item? }` | 操作、链接、提示、切换、菜单命令或频率确认时触发。 |
| `navigate` | `'back' \| 'forward'` | 允许的后退或前进请求；不读写浏览器历史。 |
| `download` | — | 下载请求，由应用处理；不是完成事件。 |

### 插槽

| 插槽 | 作用域 | 用途 |
| --- | --- | --- |
| `default` | — | 悬停链接、磁性按钮或展开按钮的文案。 |
| `item` | `{ item, active }` | 标签与步骤内容；不要放交互控件。 |
| `icon` | `{ item, active }` | 标签图标；条目设置了 `icon` 才渲染。 |
| `panel` | `{ item, active? }` | 标签对应的内容；省略时不占位。 |
| `menu` | `{ items, select }` | 替换菜单内容；调用 `select(item)` 派发命令事件。 |
| `preview` | — | 提示或 glance 的预览内容。 |
| `value` | `{ value, item }` | 控件旁由宿主渲染的值、数量或选中项。 |

### 类型

#### MotionControlItem

| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `value` | `string \| number` | 唯一键；转为字符串后也不能重复。 |
| `label` | `string` | 显示文案。 |
| `disabled` | `boolean` | 禁用该项。 |
| `icon` | `string` | 文本字形；SVG 或组件用 `icon` 插槽。 |
| `description` | `string` | 说明，透传给 `TxSelect`。 |
| `closable` | `boolean` | 设为 `false` 时该标签不可关闭。 |
| `danger` | `boolean` | 危险命令样式。 |
| `children` | `MotionControlItem[]` | 子菜单，递归渲染为下拉或右键子菜单。 |

#### MotionControlLabels

`labels` 的键与默认值，导出为 `MOTION_CONTROL_DEFAULT_LABELS`：

```ts
{
  control: 'Motion control', choose: 'Choose an option', frequency: 'Frequency',
  confirm: 'Confirm selection', add: 'Add tab', close: 'Close',
  increase: 'Increase', decrease: 'Decrease', back: 'Back', forward: 'Forward',
  actions: 'Actions', details: 'View details', action: 'Action', launch: 'Launch',
  link: 'Open link', preview: 'Preview', help: 'Help', download: 'Download',
  downloading: 'Downloading', downloaded: 'Downloaded', downloadError: 'Download failed',
  pip: 'Enter picture in picture', pipOff: 'Exit picture in picture',
  save: 'Save item', saved: 'Saved', follow: 'Follow', following: 'Following',
  grid: 'Grid view', list: 'List view', stack: 'Stack view', light: 'Light mode',
  dark: 'Dark mode', progress: 'Progress', page: 'Page',
}
```

## 源码映射

源码路径相对于上游 `src/components/css-animations/`。`MOTION_CONTROL_SOURCES` 导出每项的完整路径、行号、上游导出名与模型类型，`MOTION_CONTROL_VARIANTS` 导出全部变体 ID。

### 目录变体

| 变体 | 上游导出 | 源码 | 结构与模型 |
| --- | --- | --- | --- |
| `yui-category-select` | `CategorySelect` | `yui-components/YuiUiKit1.tsx:9–63` | 圆角选择器与下拉菜单；选项键。 |
| `yui-filter-tag-pill` | `FilterTagPill` | `yui-components/UiKitTrios.tsx:10–38` | 分段筛选与移动 pill；选项键。 |
| `yui-submenu-flyout` | `SubmenuFlyout` | `yui-components/UiKitTrios.tsx:41–74` | 横向展开的子菜单；命令。 |
| `yui-hover-link` | `HoverLinkCard` | `yui-components/YuiUiKit1.tsx:66–107` | 抬升的链接 pill 与悬浮 URL；`href` 或 `action`。 |
| `yui-magnetic-icon-btn` | `MagneticIconButton` | `yui-components/UiKitTrios.tsx:81–94` | 横向位移的箭头按钮；`action`。 |
| `yui-morph-action-pill` | `MorphActionPill` | `yui-components/UiKitTrios.tsx:97–124` | 悬停或聚焦时展开的操作 pill；`action`。 |
| `yui-plus-minus-toggle` | `PlusMinusToggle` | `yui-components/YuiUiKit1.tsx:110–142` | 两个带按压回弹的方形按钮；`plus` / `minus`。 |
| `yui-light-dark-toggle` | `LightDarkMorphToggle` | `yui-components/YuiUiKit1.tsx:145–169` | 日/月图标旋转；布尔值。 |
| `yui-ab-tabs` | `SegmentedABTabs` | `yui-components/YuiUiKit2.tsx:202–238` | 宽分段标签与滑动 pill；A/B 选项。 |
| `yui-progress-stepper` | `ProgressStepper` | `yui-components/YuiUiKit1.tsx:172–216` | 相连步骤节点与填充轨道；选项键或从 1 开始的步骤。 |
| `yui-segmented-arc-meter` | `SegmentedArcMeter` | `yui-components/RedesignedUiTrios.tsx:10–30` | 离散竖条与百分比；`0..count`。 |
| `yui-segmented-step-bar` | `SegmentedStepBar` | `yui-components/UiKitTrios.tsx:159–174` | 电池式分段，点击循环；数字等级。 |
| `yui-multi-tab-close` | `MultiTabCloseBar` | `yui-components/YuiUiKit1.tsx:219–287` | 可关闭标签、收缩淡出与添加请求；选中值与条目。 |
| `yui-date-position` | `DatePositionSelector` | `yui-components/YuiUiKit1.tsx:290–328` | 连续日期与滑动高亮；选项键。 |
| `yui-stepper-dots` | `SegmentedStepperDots` | `yui-components/RedesignedUiTrios.tsx:35–61` | 选中圆点扩成 pill；从 1 开始的页码。 |
| `yui-context-menu` | `ContextMenuEditDelete` | `yui-components/YuiUiKit2.tsx:9–56` | 缩放淡入的操作弹层；编辑/删除或调用方命令。 |
| `yui-glance-preview` | `CardGlancePreview` | `yui-components/RedesignedUiTrios.tsx:66–100` | 悬浮预览与状态点；hover/focus。 |
| `yui-download-icons` | `DownloadAnimatedIcons` | `yui-components/YuiUiKit2.tsx:99–138` | loading 时箭头弹跳，success 时显示勾。 |
| `yui-wheel-counter` | `VerticalWheelCounter` | `yui-components/RedesignedUiTrios.tsx:105–143` | 纵向数字变换与上下按钮；有界数字。 |
| `yui-perspective-layout` | `PerspectiveLayoutSwitcher` | `yui-components/RedesignedUiTrios.tsx:148–170` | 网格/堆叠图标旋转缩放；`grid` / `stack`。 |
| `yui-save-pill` | `BookmarkSavePill` | `yui-components/RedesignedUiTrios.tsx:175–193` | 书签/勾图标与变化文案；布尔值。 |

### 额外导出

| 变体 | 上游导出 | 源码 | 结构与模型 |
| --- | --- | --- | --- |
| `frequency-selector` | `FrequencySelector` | `FrequencySelector.tsx:12–126` | 模糊标签、横向选项 pill 与确认按钮。 |
| `tab-bar` | `TabBar` | `TabBar.tsx:16–72` | 选中项展开文案的图标标签；选项键。 |
| `radial-progress-ring` | `RadialProgressRing` | `yui-components/UiKitTrios.tsx:131–156` | SVG 进度环与百分比；点击按 `step` 推进。 |
| `pagination-numbered-bubble` | `PaginationNumberedBubble` | `yui-components/YuiUiKit1.tsx:331–366` | 选中页码气泡上抬；从 1 开始的页码。 |
| `back-forward-nav` | `BackForwardNav` | `yui-components/YuiUiKit1.tsx:369–397` | 两个方向按钮；`navigate`。 |
| `question-tooltip` | `QuestionTooltip` | `yui-components/YuiUiKit2.tsx:59–97` | 圆形问号与锚定提示；hover/focus。 |
| `pip-mode-icons` | `PipModeIcons` | `yui-components/YuiUiKit2.tsx:141–168` | 层叠图标与小窗入场；布尔值与 `action`。 |
| `simple-plus-minus-btn` | `SimplePlusMinusBtn` | `yui-components/YuiUiKit2.tsx:171–199` | 两个独立小按钮，不显示数值；有界计数。 |
| `quantity-counter` | `QuantityCounter` | `yui-components/YuiUiKit2.tsx:241–274` | 减号、动态数字与加号组成的圆角 pill。 |
| `list-column-toggle` | `ListColumnToggle` | `yui-components/YuiUiKit2.tsx:277–301` | 网格/列表图标旋转与变化文案；`grid` / `list`。 |
| `follow-check-button` | `FollowCheckButton` | `yui-components/YuiUiKit2.tsx:304–322` | 加号/勾图标的关注 pill；布尔值。 |
| `menu-dots-expand` | `MenuDotsExpand` | `yui-components/YuiUiKit2.tsx:325–347` | 省略号按钮打开调用方命令。 |
| `compact-mode-switch` | `CompactModeSwitch` | `yui-components/YuiUiKit2.tsx:350–386` | 纯图标网格/列表分段与选中 pill。 |

## 概述

- 内部组合 `TxSelect`、`TxTabs`、`TxDropdownMenu`、`TxContextMenu`、`TxTooltip`、`TxPagination` 与 `TxTextMorph`；焦点、方向键、Escape、外部点击与锚定沿用这些原语。
- 计数器聚焦后 `↑` / `↓` 增减，`Home` / `End` 跳到边界；频率选择器收起后焦点回到触发器。
- `yui-multi-tab-close` 关闭当前标签时选中最近的可用标签，关闭其他标签不改变选择；模型事件不等待退场动画。
- 关闭按钮位于标签导航旁的独立操作条，不嵌套在标签按钮内。
- 菜单命令沿用原语的 `select` 时序：关闭前保留确认节奏，减少动态效果时立即执行。
- 离屏、文档隐藏、KeepAlive 失活、卸载或减少动态效果时停止动效。

## 技术实现

- 上游：[Amicro 提交 43c29ce](https://github.com/Subhan-code/Amicro--Micro-transitions-/tree/43c29ce9cdd16459e3eab4992381b8d35b38776a)，MIT，Copyright (c) 2026 SYED  SUBHAN UDDIN。
- 源码：`packages/tuffex/packages/components/src/motion-control/`。
