Skip to content
ARC UI ARC Reactive Components
Docs Components Tokens Synthesizer
v2.1.0
Getting Started Frameworks Design Tokens Theming Theme Synthesizer Accessibility Browser Support Changelog Contributing All Components App ShellAspect GridAuth ShellCenterClusterContainerDashboard GridDockFloat BarInsetMasonryPage HeaderPage LayoutResizableResponsive SwitcherSectionSettings LayoutSplit PaneStatus BarStickyToolbar Anchor NavBottom NavBreadcrumbBreadcrumb MenuCommand BarDrawerFooterLinkNavigation MenuPage IndicatorPaginationRailScroll IndicatorScroll SpyScroll To TopSidebarSkip LinkSpeed DialStepper NavTabsTop BarTree View AccordionAspect RatioAvatarAvatar GroupCalloutCardCarouselCollapsibleColor SwatchCTA BannerDividerEmpty StateFeature CardIconImageInfinite ScrollMarqueeScroll AreaSeparatorSkeletonSpinnerStackVirtual List Animated NumberBadgeComparisonCountdown TimerData TableDescription ListDiffKey ValueListMeterSparklineStatStepperTableTagTimelineValue Card BlockquoteCode BlockGradient TextHighlightKbdMarkdownNumber FormatProseTextTime AgoTruncateTypewriter ButtonButton GroupCalendarCheckboxChipColor PickerComboboxCopy ButtonDate PickerFieldsetFile UploadFormHotkeyIcon ButtonInputInput GroupLabelMulti SelectNumber InputOTP InputPin InputRadio GroupRange SliderRatingSearchSegmented ControlSelectSliderSortable ListSwitch GroupTextareaTheme ToggleTime PickerToggle AlertAnnouncementBannerCommand PaletteConfirmConnection StatusContext MenuDialogDropdown MenuGuided TourHover CardInline MessageLoading OverlayModalNotification PanelPopoverProgressProgress ToastSheetSnackbarSpotlightToastTooltip
Components Sortable List
input interactive
<arc-sortable-list>

Overview

Guidelines

When to use

  • Wrap plain elements (e.g. `<div>`) as direct children -- the component reads their `textContent` for display
  • Listen for `arc-change` to persist the new order back to your data store
  • Use Sortable List for short to medium lists (under ~50 items) where manual ordering matters
  • Provide clear, distinguishable text content for each item so users can identify what they are reordering
  • Test keyboard reordering to ensure your application handles the order array correctly

When not to use

  • Do not nest interactive elements (buttons, links) inside list items -- they conflict with drag handles and keyboard interaction
  • Do not use Sortable List for very long lists where search or filtering would be more efficient than manual reordering
  • Do not rely solely on the visual grip dots to communicate draggability -- ensure items have descriptive labels for screen readers
  • Do not place multiple Sortable Lists adjacent without clear visual separation between them
  • Avoid using Sortable List for single-item lists -- there is nothing to reorder

Features

  • Drag-and-drop reordering with HTML5 Drag and Drop API and visual insertion indicators
  • Six-dot grip handle icon rendered for each item as a drag affordance
  • Full keyboard reordering: Space to select, Enter to move, Arrow keys to shift, Escape to cancel
  • Blue border highlight for keyboard-selected items and elevated glow for items being moved
  • Dragged items fade to 50% opacity with an elevated box shadow for clear visual feedback
  • Fires `arc-change` with `detail.order` containing the new index mapping after every reorder
  • ARIA attributes including `role="listbox"`, `role="option"`, and `aria-grabbed` for accessibility
  • Disabled state at 40% opacity with pointer events blocked

Preview

Design tokens
Components
Patterns
Utilities

Usage

This component requires JavaScript. No pure HTML/CSS version is available — use the Web Component directly or a framework wrapper.

<arc-sortable-list>
  <div>First item</div>
  <div>Second item</div>
  <div>Third item</div>
</arc-sortable-list>

<script>
  document.querySelector('arc-sortable-list')
    .addEventListener('arc-change', e => {
      console.log('New order:', e.detail.order);
    });
</script>
import { SortableList } from '@arclux/arc-ui-react';

<SortableList onArcChange={(e) => console.log(e.detail.order)}>
  <div>First item</div>
  <div>Second item</div>
  <div>Third item</div>
</SortableList>
<script setup>
import { SortableList } from '@arclux/arc-ui-vue';

function onReorder(e) {
  console.log('New order:', e.detail.order);
}
</script>

<template>
  <SortableList @arc-change="onReorder">
    <div>First item</div>
    <div>Second item</div>
    <div>Third item</div>
  </SortableList>
</template>
<script>
  import { SortableList } from '@arclux/arc-ui-svelte';
</script>

<SortableList on:arc-change={(e) => console.log(e.detail.order)}>
  <div>First item</div>
  <div>Second item</div>
  <div>Third item</div>
</SortableList>
import { Component } from '@angular/core';
import { SortableList } from '@arclux/arc-ui-angular';

@Component({
  imports: [SortableList],
  template: `
    <SortableList (arc-change)="onReorder($event)">
      <div>First item</div>
      <div>Second item</div>
      <div>Third item</div>
    </SortableList>
  `,
})
export class MyComponent {
  onReorder(e: CustomEvent) {
    console.log('New order:', e.detail.order);
  }
}
import { SortableList } from '@arclux/arc-ui-solid';

<SortableList onArcChange={(e) => console.log(e.detail.order)}>
  <div>First item</div>
  <div>Second item</div>
  <div>Third item</div>
</SortableList>
import { SortableList } from '@arclux/arc-ui-preact';

<SortableList onArcChange={(e) => console.log(e.detail.order)}>
  <div>First item</div>
  <div>Second item</div>
  <div>Third item</div>
</SortableList>

API

Prop Type Default Description
disabled boolean false Disables all interaction, reducing opacity to 40% and blocking pointer events.

Events

Event Description
arc-change Fired when items are reordered, with updated order in detail

See Also