Sortable

1.0.0

O componente Sortable fornece funcionalidade de arrastar e soltar para criar listas ordenáveis, com suporte para orientação vertical e horizontal, navegação por teclado e manipuladores de arrastar personalizáveis.

import React, { useState } from "react";
import { Sortable } from "@nimbus-ds/patterns";
import { Box, Card, Text } from "@nimbus-ds/components";
import { mockSortableItems as defaultItems } from "lib/mocks/mock-items";

const Example: React.FC = () => {
  const [items, setItems] = useState(defaultItems);

  return (
    <Sortable items={items} onReorder={setItems} orientation="vertical">
      <Box
        display="flex"
        flexDirection="column"
        width="100%"
        padding="2"
        overflow="hidden"
      >
        {items.map((item) => (
          <Sortable.Item key={item.id} id={item.id}>
            <Box as="div" width="100%" marginY="2" cursor="grab">
              <Card>
                <Card.Body>
                  <Text>{item.content}</Text>
                </Card.Body>
              </Card>
            </Box>
          </Sortable.Item>
        ))}
      </Box>
    </Sortable>
  );
};

export default Example;

Instale o componente via terminal.

npm install @nimbus-ds/sortable

Sortable

O padrão Sortable permite reorganizar elementos dentro de uma lista ou grid através de interações de drag and drop. Seu propósito é oferecer controle direto ao usuário sobre a ordem dos elementos, facilitando a personalização e hierarquização visual da informação em fluxos onde a ordem é relevante.

É ideal para experiências onde a ordem dos itens tem impacto funcional ou visual, como listas de produtos em destaque, categorias, módulos de conteúdo, entre outros.


  • Quando o usuário precisa definir a ordem de itens segundo prioridade ou hierarquia.
  • Em fluxos onde os itens têm uma ordem preestabelecida mas editável (ex. passos, listas de prioridade).

  • Quando a ordem dos elementos não tem consequências visíveis ou funcionais.
    Exemplo: Uma lista com mais de 20 itens onde a ordem não modifica a funcionalidade do sistema.
  • Em listas onde o conteúdo é extenso ou a reordenação pode afetar dados relacionados sem validação.
  • Se os elementos precisam de confirmação adicional para serem movidos (drag and drop não é ótimo nesses casos).

  • Ação direta: Reordenar através de drag and drop sem necessidade de confirmação adicional.
  • Feedback visual imediato: Ao arrastar, destacam-se zonas válidas de inserção.
  • Persistência automática: Mudanças de ordem são salvas automaticamente ou ao sair do fluxo.
  • Reordenação parcial: O usuário pode modificar apenas alguns itens sem ter que reorganizar toda a lista.

  • Navegação com teclado: assegurar foco e uso de teclas (Enter, Space, Arrow keys) para mover itens.
  • Suporte ARIA: usar aria-roledescription="sortable" no container da lista, aria-describedby combinado com uma live region para anúncios, e aria-live="polite" para anunciar mudanças.
  • Orientação da lista: usar aria-orientation="vertical" ou aria-orientation="horizontal" no container conforme apropriado.
  • Controles de arrastar: se usar botões como handles, aplicar aria-pressed para indicar estado ativo durante a operação de arrastar.
  • Roles adequados: usar role="list" e role="listitem" onde aplicável.
  • Feedback textual visível para screen readers ao mover itens.
  • Zonas de tap de mínimo 44×44 px.

O padrão Sortable pode incluir:

  1. Container: list ou grid reordenável.
  2. Item: componente individual (card, tag, row).
  3. Handler de movimento: ícone ou área visível para iniciar o drag.
  4. Indicador de posição: linha ou sombra onde o item será solto.
  • #Card
  • #Icon
  • #IconButton
  • #List ou #Grid
  • Event handlers de drag and drop (onDragStart, onDragOver, onDrop, etc.)
  • Vertical: Ideal para listas simples.
  • Horizontal: Útil para displays visuais como carrosséis.
  • Com Handler: Ícone ou zona específica para iniciar o movimento.
  • Scroll vertical: Múltiplos itens dentro de container com scroll.
  • Renderização personalizada: O item pode ter um layout específico.

✅ Do

  • Usar drag and drop para facilitar ao usuário controlar a ordem de uma lista de itens.
  • Permitir salvar automaticamente ou validar ao finalizar a reordenação.

❌ Don't

  • Não ocultar o estado do item durante o drag (usar opacidade ou sombra).
  • Não bloquear acessibilidade ao teclado ou screen readers.
  • Não permitir reordenar se os itens estão desabilitados ou são dependentes entre si sem validação prévia.

As props adicionais são passadas ao elemento <Sortable>. Consulte a documentação de div para ver a lista de props aceitas pelo elemento <Sortable>.

Sortable

NameTypeDefaultDescription

children

React.ReactNode

The children components

disabled

boolean

Whether to disable sorting functionality

items*

array

The items to be sorted

onReorder*

object

Callback fired when items are reordered

onDragStart

object

Callback fired when drag starts

onDragOver

object

Callback fired during drag

onDragEnd

object

Callback fired when drag ends

orientation

'horizontal'
'vertical'

The orientation of the sortable list

sensorOptions

object

Custom sensor options for drag detection

overlaySettings

object

Configuration for the drag overlay appearance and behavior

dndContextSettings

object

Settings for the DndContext

renderOverlay

object

Render function for the dragged item overlay

Sortable.Item

NameTypeDefaultDescription

id*

'string'
'number'

The unique identifier for the item

disabled

boolean

Whether the item is disabled from being dragged

handle

boolean

Custom drag handle selector

children

React.ReactNode

The children components

renderItem

object

Optional render function that receives drag state and handlers, useful for fully customizing the item

Sortable.ItemHandle

NameTypeDefaultDescription

children

React.ReactNode

The content of the SortableItemHandle component