---
title: MotionControl
description: A set of animated controls ported from the Amicro UIkit.
category: Advanced
status: beta
since: 0.6.3
tags: [motion, controls, uikit, pro]
syncStatus: reviewed
---

## Usage

### All Variants
`variant` picks the control; the caller supplies every option and command.
:::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: 'Design' },
    { value: 'dev', label: 'Development' },
  ]
  </script>

  <template>
    <TxMotionControl v-model="saved" variant="yui-save-pill" />
    <TxMotionControl
      v-model="category"
      variant="yui-category-select"
      :options="options"
      label="Category"
    />
  </template>
---
:::

### Best Practices

- Keep business results in the application: a menu command is not a backend success, a PiP state is not a platform switch, and `download` is only a request.
- Use stable `value` keys and localize labels separately; supply categories, dates, frequencies, tabs, and commands yourself.
- Bind both `v-model` and `v-model:items` for closeable tabs. Set `minItems="1"` to keep the last tab, and allocate real IDs from `add`.
- Keep the `item` slot non-interactive; put independent actions outside the native buttons and rich content in the `panel` slot.
- Drive `status` and `progress` from the real transfer, and handle cancellation and errors there.

## API Reference

### Props

| Prop | Type | Default | Meaning |
| --- | --- | --- | --- |
| `variant` | `MotionControlVariant` | `yui-category-select` | One of 34 variants; the 21 catalog IDs match upstream. |
| `modelValue` | `string \| number \| boolean` | Variant-dependent | Controlled value. Without it, state stays local and selections default to the first enabled choice. |
| `options` | `MotionControlItem[]` | `[]` | Choices for selection variants; win over `items`, but closeable tabs read only `items`. |
| `items` | `MotionControlItem[]` | `[]` | Menu commands or closeable tabs, bound with `v-model:items`. |
| `count` | `number` | `3` for step bar/stepper, otherwise `4` | Segments, pages, or generated steps when there are no `options`. |
| `min` | `number` | `0` | Counter minimum; also the uncontrolled starting value. |
| `max` | `number` | — | Counter maximum. |
| `step` | `number` | `1` | Counter and radial-progress increment; `25` gives the source's quarter steps. |
| `disabled` | `boolean` | `false` | Blocks selection, commands, value changes, closing, adding, and download requests. |
| `size` | `xs \| sm \| md \| lg` | `md` | Control height and inset. |
| `status` | `idle \| loading \| success \| error` | `idle` | Host-owned download state; `loading` blocks repeats, and only `success` shows the check. |
| `progress` | `number` | `0` | Host-owned download percentage, shown while `loading`. |
| `open` | `boolean` | — | Controlled menu, tooltip, or frequency expansion; the category select ignores it. |
| `animated` | `boolean` | `true` | Enables motion; it still stops offscreen, when hidden, or under reduced motion. |
| `label` | `string` | `''` | Visible label, or the group or trigger's accessible name, depending on the variant. |
| `tooltip` | `string` | `''` | Tooltip or glance text; the hover link falls back to `href`. |
| `href` | `string` | `''` | Hover-link destination; without it, the trigger is a button that emits `action`. |
| `target` | `_self \| _blank` | `_self` | Link target; `_blank` adds `noopener noreferrer`. |
| `newItem` | `MotionControlItem` | — | A tab the caller prepared; duplicate values are not added. |
| `maxItems` | `number` | — | Maximum tab count. |
| `minItems` | `number` | `0` | Tabs that must remain; `1` matches upstream's undeletable last tab. |
| `canBack` | `boolean` | `true` | Allows the back request. |
| `canForward` | `boolean` | `true` | Allows the forward request. |
| `labels` | `Partial<MotionControlLabels>` | English labels | Overrides default strings without a library message catalog. |

### Events

| Event | Payload | When |
| --- | --- | --- |
| `update:modelValue` | `MotionControlValue` | A permitted operation changes the value. |
| `change` | `MotionControlValue` | With `update:modelValue`; not for an unchanged value. |
| `select` | `MotionControlItem` | An option, step, tab, or command is chosen, including a repeat. |
| `update:items` | `MotionControlItem[]` | A tab closes or `newItem` is added. |
| `update:open` | `boolean` | A menu, tooltip, or frequency expansion changes. |
| `close` | `MotionControlItem` | A tab closes. |
| `add` | `MotionControlItem \| undefined` | `newItem` is added, or, without one, the host is asked to create a tab. |
| `action` | `{ variant, value, item? }` | An action, link, hint, toggle, menu command, or frequency confirmation runs. |
| `navigate` | `'back' \| 'forward'` | A permitted back or forward request; browser history is untouched. |
| `download` | — | A download request for the application; not a completion event. |

### Slots

| Slot | Scope | Purpose |
| --- | --- | --- |
| `default` | — | Label of the hover link, magnetic button, or morph button. |
| `item` | `{ item, active }` | Tab and step content; keep it non-interactive. |
| `icon` | `{ item, active }` | Tab icon; renders only for items with `icon` set. |
| `panel` | `{ item, active? }` | Content for a tab; reserves no space when omitted. |
| `menu` | `{ items, select }` | Replaces the menu content; call `select(item)` to emit the command. |
| `preview` | — | Tooltip or glance preview content. |
| `value` | `{ value, item }` | Host-rendered value, count, or selection beside the control. |

### Types

#### MotionControlItem

| Field | Type | Description |
| --- | --- | --- |
| `value` | `string \| number` | Unique key, also after string conversion. |
| `label` | `string` | Display text. |
| `disabled` | `boolean` | Disables the item. |
| `icon` | `string` | Text glyph; use the `icon` slot for SVG or components. |
| `description` | `string` | Description, passed to `TxSelect`. |
| `closable` | `boolean` | `false` makes the tab uncloseable. |
| `danger` | `boolean` | Destructive command style. |
| `children` | `MotionControlItem[]` | Submenu, rendered recursively as dropdown or context submenus. |

#### MotionControlLabels

Keys and defaults of `labels`, exported as `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',
}
```

## Source Mapping

Paths are relative to upstream `src/components/css-animations/`. `MOTION_CONTROL_SOURCES` exports each entry's full path, line range, upstream export, and model domain; `MOTION_CONTROL_VARIANTS` exports every variant ID.

### Catalog Variants

| Variant | Upstream export | Source | Structure and model |
| --- | --- | --- | --- |
| `yui-category-select` | `CategorySelect` | `yui-components/YuiUiKit1.tsx:9–63` | Rounded select with dropdown menu; option key. |
| `yui-filter-tag-pill` | `FilterTagPill` | `yui-components/UiKitTrios.tsx:10–38` | Segmented filter with travelling pill; option key. |
| `yui-submenu-flyout` | `SubmenuFlyout` | `yui-components/UiKitTrios.tsx:41–74` | Sideways submenu flyout; commands. |
| `yui-hover-link` | `HoverLinkCard` | `yui-components/YuiUiKit1.tsx:66–107` | Lifted link pill with floating URL; `href` or `action`. |
| `yui-magnetic-icon-btn` | `MagneticIconButton` | `yui-components/UiKitTrios.tsx:81–94` | Arrow button with horizontal travel; `action`. |
| `yui-morph-action-pill` | `MorphActionPill` | `yui-components/UiKitTrios.tsx:97–124` | Pill that expands on hover or focus; `action`. |
| `yui-plus-minus-toggle` | `PlusMinusToggle` | `yui-components/YuiUiKit1.tsx:110–142` | Two square buttons with press bounce; `plus` / `minus`. |
| `yui-light-dark-toggle` | `LightDarkMorphToggle` | `yui-components/YuiUiKit1.tsx:145–169` | Sun/moon rotation; boolean. |
| `yui-ab-tabs` | `SegmentedABTabs` | `yui-components/YuiUiKit2.tsx:202–238` | Wide segmented tabs with sliding pill; A/B choices. |
| `yui-progress-stepper` | `ProgressStepper` | `yui-components/YuiUiKit1.tsx:172–216` | Connected steps with filled track; option key or one-based step. |
| `yui-segmented-arc-meter` | `SegmentedArcMeter` | `yui-components/RedesignedUiTrios.tsx:10–30` | Discrete bars with percentage; `0..count`. |
| `yui-segmented-step-bar` | `SegmentedStepBar` | `yui-components/UiKitTrios.tsx:159–174` | Battery segments; click cycles the level. |
| `yui-multi-tab-close` | `MultiTabCloseBar` | `yui-components/YuiUiKit1.tsx:219–287` | Closeable tabs, shrink/fade exits, add request; selection and items. |
| `yui-date-position` | `DatePositionSelector` | `yui-components/YuiUiKit1.tsx:290–328` | Consecutive dates with sliding highlight; option key. |
| `yui-stepper-dots` | `SegmentedStepperDots` | `yui-components/RedesignedUiTrios.tsx:35–61` | Active dot expands to a pill; one-based page. |
| `yui-context-menu` | `ContextMenuEditDelete` | `yui-components/YuiUiKit2.tsx:9–56` | Scale/fade action popup; edit/delete or supplied commands. |
| `yui-glance-preview` | `CardGlancePreview` | `yui-components/RedesignedUiTrios.tsx:66–100` | Floating preview with status dot; hover/focus. |
| `yui-download-icons` | `DownloadAnimatedIcons` | `yui-components/YuiUiKit2.tsx:99–138` | Bouncing arrow while loading; check on success. |
| `yui-wheel-counter` | `VerticalWheelCounter` | `yui-components/RedesignedUiTrios.tsx:105–143` | Vertical number morph with up/down buttons; bounded number. |
| `yui-perspective-layout` | `PerspectiveLayoutSwitcher` | `yui-components/RedesignedUiTrios.tsx:148–170` | Grid/stack icons rotate and scale in; `grid` / `stack`. |
| `yui-save-pill` | `BookmarkSavePill` | `yui-components/RedesignedUiTrios.tsx:175–193` | Bookmark/check pill with changing label; boolean. |

### Additional Exports

| Variant | Upstream export | Source | Structure and model |
| --- | --- | --- | --- |
| `frequency-selector` | `FrequencySelector` | `FrequencySelector.tsx:12–126` | Blurred label, option pills, and a confirm button. |
| `tab-bar` | `TabBar` | `TabBar.tsx:16–72` | Icon tabs whose active label expands; option key. |
| `radial-progress-ring` | `RadialProgressRing` | `yui-components/UiKitTrios.tsx:131–156` | SVG ring with percentage; click advances by `step`. |
| `pagination-numbered-bubble` | `PaginationNumberedBubble` | `yui-components/YuiUiKit1.tsx:331–366` | Active page bubble lifts; one-based page. |
| `back-forward-nav` | `BackForwardNav` | `yui-components/YuiUiKit1.tsx:369–397` | Two direction buttons; `navigate`. |
| `question-tooltip` | `QuestionTooltip` | `yui-components/YuiUiKit2.tsx:59–97` | Round question trigger with anchored hint; hover/focus. |
| `pip-mode-icons` | `PipModeIcons` | `yui-components/YuiUiKit2.tsx:141–168` | Layer icon with entering mini-window; boolean and `action`. |
| `simple-plus-minus-btn` | `SimplePlusMinusBtn` | `yui-components/YuiUiKit2.tsx:171–199` | Two small buttons without a display; bounded count. |
| `quantity-counter` | `QuantityCounter` | `yui-components/YuiUiKit2.tsx:241–274` | Round pill with minus, animated number, and plus. |
| `list-column-toggle` | `ListColumnToggle` | `yui-components/YuiUiKit2.tsx:277–301` | Grid/list icon rotation with changing label; `grid` / `list`. |
| `follow-check-button` | `FollowCheckButton` | `yui-components/YuiUiKit2.tsx:304–322` | Plus/check follow pill; boolean. |
| `menu-dots-expand` | `MenuDotsExpand` | `yui-components/YuiUiKit2.tsx:325–347` | Dots trigger that opens supplied commands. |
| `compact-mode-switch` | `CompactModeSwitch` | `yui-components/YuiUiKit2.tsx:350–386` | Icon-only grid/list segments with active pill. |

## Overview

- Composes `TxSelect`, `TxTabs`, `TxDropdownMenu`, `TxContextMenu`, `TxTooltip`, `TxPagination`, and `TxTextMorph`; focus, arrow keys, Escape, outside clicks, and anchoring follow those primitives.
- On a focused counter, Up/Down step the value and Home/End jump to the bounds. The frequency selector returns focus to its trigger when it collapses.
- In `yui-multi-tab-close`, closing the active tab selects the nearest enabled tab; closing another tab keeps the selection. Model events don't wait for the exit animation.
- Close buttons sit in a separate strip beside the tab navigation, never inside a tab button.
- Menu commands keep the primitives' `select` timing: a confirmation beat before closing, or immediate under reduced motion.
- Motion stops offscreen, in hidden documents, in inactive KeepAlive instances, on unmount, and under reduced motion.

## Technologies

- Upstream: [Amicro commit 43c29ce](https://github.com/Subhan-code/Amicro--Micro-transitions-/tree/43c29ce9cdd16459e3eab4992381b8d35b38776a), MIT, Copyright (c) 2026 SYED  SUBHAN UDDIN.
- Source: `packages/tuffex/packages/components/src/motion-control/`.
