# MoveHandle

```tsx
import { MoveHandle } from '@tangible/ui';
```

Interactive docs and examples: [MoveHandle in Storybook](https://storybook-tangible-ui.pages.dev/?path=/docs/components-movehandle--docs).

## MoveHandle props

| Prop | Type | Default | Description |
| - | - | - | - |
| `aria-label?` | `string` | | Accessible label for the control group. Required if aria-labelledby is not set. |
| `aria-labelledby?` | `string` | | ID of element labelling this group. Required if aria-label is not set. |
| `canMoveDown?` | `boolean` | `true` | When false, disables the move-down button without hiding it. Default: true. |
| `canMoveUp?` | `boolean` | `true` | When false, disables the move-up button without hiding it. Default: true. |
| `className?` | `string` | | |
| `dragHandleProps?` | `HTMLAttributes<HTMLButtonElement>` | | Props to spread on the drag handle button (e.g., from dnd-kit useSortable). |
| `index?` | `number` | | Position index. In 'full' mode, shows the number at rest and swaps to the drag handle on hover/focus-within. In 'arrows' mode, shows the number between the chevrons with no swap — there is no handle to swap to. Ignored in 'handle' mode. |
| `labels?` | `MoveHandleLabels` | | Override internal button labels for i18n. |
| `locked?` | `boolean` | `false` | When true, shows lock icon and disables all interaction. |
| `mode?` | `"arrows" \| "full" \| "handle"` | `'full'` | Structural mode. 'full' (default) shows background panel with arrows/index. 'handle' shows only the bare drag icon button. 'arrows' shows the panel with the up/down chevron buttons and no drag handle — for items reordered exclusively by explicit moves (top-level containers, lists without a drag library). Pass `index` to show the position between the chevrons. |
| `onMoveDown?` | `() => void` | | Called when the "move down" button is clicked. Button not rendered when omitted. Consumers should announce the result via a live region (e.g. "Item moved to position 4 of 5") since the DOM reorder is not conveyed to screen readers automatically. |
| `onMoveUp?` | `() => void` | | Called when the "move up" button is clicked. Button not rendered when omitted. Consumers should announce the result via a live region (e.g. "Item moved to position 2 of 5") since the DOM reorder is not conveyed to screen readers automatically. |
| `size?` | `"md" \| "sm"` | `'md'` | Component scale. Full mode: sm = 32px, md = 40px. Handle mode: sm = 24px, md = 32px. |

## Examples

- [Arrows With Index](https://storybook-tangible-ui.pages.dev/?path=/story/components-movehandle--arrows-with-index): `mode="arrows"` with `index`: the position badge sits between the chevrons and never swaps to a
  drag handle — there is none. This is the "full mode look without the grip" for lists reordered by
  explicit moves only (no drag library). Locked keeps the index and disables the chevrons; when both
  chevrons disable while one holds focus, the group itself catches focus rather than dropping it.

- [Arrows Only](https://storybook-tangible-ui.pages.dev/?path=/story/components-movehandle--arrows-only): `mode="arrows"` without an index: the two chevrons fill the panel and there is no center at all.

Other stories: Default, With Index, Locked, Boundary Disabled, Sizes, No Arrows, Drag Only (In List), Handle Mode, In List, Keyboard Reorder, Index + No Arrows, Syllabus Demo, i18n Labels ([interactive page](https://storybook-tangible-ui.pages.dev/?path=/docs/components-movehandle--docs)).

## Component API tokens

Read via fallback, never declared. Set one on an ancestor to restyle every instance under it.

- `--tui-move-handle-size`
- `--tui-move-handle-icon-size`
- `--tui-move-handle-fg`
- `--tui-move-handle-bg`
- `--tui-move-handle-fg-interact`
- `--tui-move-handle-bg-interact`

---

Interactive version: https://storybook-tangible-ui.pages.dev/?path=/docs/components-movehandle--docs
