Components/Motion dock

Motion dock

Caller-owned items with adjacent spring magnification, pointer dragging and keyboard reorder.

Since 0.6.3BETA

This component doc is in progress

This page is still being migrated. Demos and API details may change.

Overview

TxMotionDock renders actual caller-provided items. Pointer distance influences the item under the pointer and its neighbors; the source spring keeps width and height synchronized. Dragging changes a local preview, then returns a new ordered item array on release. It never replaces the caller's items with built-in demo colors or mutates the provided array.

The dock is a horizontal toolbar. Native buttons and links use roving focus, localized instructions and a polite announcement after an actual reorder. Pausing, reduced motion or visibility suspension stops size animation while leaving the items readable and operable.

Usage

Controlled items and slots

The demo shows the current order after every pointer or keyboard reorder. It also demonstrates selection, a disabled item, real icon/label slots and a native link to its help paragraph.

Loading demo...

Pointer and keyboard

Move along the dock to magnify adjacent items. The source uses a 28px resting size, 44px peak and an 80px influence radius at md. A primary pointer drag starts after 4px of horizontal movement, preserves pointer capture through local reorder, and emits the final order on release. Escape, pointer cancellation or lost capture restores the caller order without emitting a reorder. An external replacement of items cancels the stale drag snapshot.

Left/Right moves focus through enabled items with wrapping; Home/End reaches the first/last enabled item. Alt + Left/Right moves the focused item one position; Alt + Home/End moves it to an end. Enter or Space activates the focused item. Links retain native navigation, with Space providing the same toolbar activation as buttons. A drag does not activate its item, and subsequent keyboard activation is not suppressed.

API Reference

Props

PropTypeDefaultDescription
itemsreadonly MotionDockItem[]RequiredCaller-owned order and stable unique IDs. Synchronize update:items, normally with v-model:items.
activeIdstring | number—Selected identity; supports v-model:active-id. Selection does not modify the order.
reorderablebooleantrueEnable pointer drag and Alt-key reorder; normal navigation and activation remain available.
disabledbooleanfalseDisable all activation/reorder and stop size animation.
pausedbooleanfalseStop magnification and restore resting sizes without disabling item actions.
size'xs' | 'sm' | 'md' | 'lg''md'Resting sizes 20, 24, 28 and 36px. Peak size scales by the source 44/28 ratio.
itemSizenumberFrom sizeOverride resting size, minimum 16px; non-finite values use the size preset.
magnifiedSizenumberitemSize × 44 / 28Override peak, never smaller than the resting size.
distancenumber80Pointer influence radius in pixels; minimum 1px.
showLabelsbooleanfalseShow item label text below the dock. Accessible names always use item.label.
labelsPartial<MotionDockLabels>See belowLocalized toolbar name, keyboard instructions and reorder announcement.

Item and labels

MotionDockItem contains id: string | number, label: string, optional disabled: boolean and optional href: string. Without href, it is a native button. With href, it is a native link; disabled links cannot navigate. Reorder preserves the same item objects, including caller-owned additional fields.

LabelDefaultMeaning
dock'Application dock'Toolbar accessible name.
instructionsEnglish arrow/Home/End, Alt-reorder, Enter/Space and Escape instructionsAssociated with the toolbar through a stable Vue ID.
reordered'Moved {label} to position {position} of {total}.'Polite reorder announcement. Positions are one-based; event indexes are zero-based.

Events

EventPayloadDescription
update:itemsMotionDockItem[]A new array after a changed pointer or keyboard order. The caller must apply it.
reorder(items, detail)The same actual ordered array and MotionDockReorder describing the operation.
update:activeIdstring | numberA native activation requests selection.
select(item, index)Actual selected item and its current order index; not a fabricated business action.

MotionDockReorder is { id, from, to, source: 'pointer' | 'keyboard' }. from and to are zero-based. Releasing without an order change or cancelling a drag emits no reorder. The component does not write storage or navigate on behalf of a button item.

Slots

SlotScopeDescription
item{ item, index, active, dragging }Replace the content inside the native item control. Do not nest another interactive control.
icon{ item, index }Icon artwork. The fallback is the first character of the caller's label. Artwork is hidden from assistive technology.
label{ item, index }Visible label content when showLabels=true; does not replace the accessible name.

No imperative method is required. items, activeId, reorderable and paused drive the real state.

Exports

@talex-touch/tuffex/motion-dock exports TxMotionDock, installable MotionDock, TxMotionDockInstance, MotionDockProps, MotionDockEmits, MotionDockItem, MotionDockId, MotionDockLabels, MotionDockReorder and MOTION_DOCK_DEFAULT_LABELS.

CSS variables

VariableMeaning
--tx-motion-dock-base-sizeResting size, derived from size / itemSize.
--tx-motion-dock-item-sizePer-item size owned by the shared spring driver.

Surface, line, selected ring and icon fill use host --tx-* tokens. Hover fills change immediately rather than tweening color.

Source mapping

VariantOriginal symbolPinned sourceRetained behavior
dockDock / DockItemDock.tsxAdjacent pointer-distance magnification; synchronized width/height; mass 0.1, stiffness 220, damping 16; horizontal drag-to-reorder. Built-in color arrays become caller-owned items and slots.

Best Practices

  • Use stable unique IDs and apply update:items. Rendering a fixed array while ignoring the emitted order intentionally keeps the caller order unchanged.
  • Keep your own item objects and business actions. Listen to select for button actions; supply href for actual links.
  • Provide localized labels and nonempty item names. Icon content should remain decorative, not a second nested button.
  • Use reorderable=false for fixed app/navigation order. Disabled items remain part of the data but cannot activate, focus through the toolbar or start a drag.
  • Keep the dock compact enough for its host. Visible labels can be wider than icon cells; use concise names or keep showLabels=false on narrow surfaces.
  • Do not add a second hover timer or spring. The component owns motion activity and cancels the single RAF when it settles or suspends.

Technologies

The implementation uses native pointer capture and HTML toolbar semantics. Layout is measured on input events, not in spring frames. The existing liquid springSteps advances the source spring with carried velocity. A single demand-driven RAF writes item size custom properties and stops at rest. useMotionActivity owns SSR-safe visibility, hidden-document, reduced-motion and KeepAlive suspension. RAF ownership, pointer capture and pending drag state are released on deactivation/unmount. No observers or global listeners are duplicated by the dock.

Adapted under MIT. Copyright (c) 2026 SYED SUBHAN UDDIN. This page records implementation contracts; it does not claim a completed browser or package verification run.