Sortable
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:
- Container: list ou grid reordenável.
- Item: componente individual (card, tag, row).
- Handler de movimento: ícone ou área visível para iniciar o drag.
- 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
Name | Type | Default | Description |
---|---|---|---|
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' | 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
Name | Type | Default | Description |
---|---|---|---|
id* | 'string' | 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
Name | Type | Default | Description |
---|---|---|---|
children | React.ReactNode | The content of the SortableItemHandle component |