Primitiveaction

Swipe Actions

Stable

Uma linha de lista que se arrasta para revelar ações na borda esquerda ou direita. A faixa de ações vive fora da linha, encostada na borda, e viaja com ela — quem recorta é a própria linha, então as ações saem de baixo em vez de entrar em cena. O arraste é um atalho: tudo que ele alcança precisa estar alcançável de outro jeito.

Instalação

npx up-web-ds add swipe-actions

Preview

Basic

dialog-stackKibo UI · MIT

Both Sides

dialog-stackKibo UI · MIT · aguardando revisão de arquitetura
lensMagic UI · MIT · aguardando revisão de acessibilidade

Full Swipe

Arraste até o fim para descartarA ação da ponta cobre as outras quando arma

Disabled

Item publicado no registryNão pode ser descartado daqui

All states

Basic

dialog-stackKibo UI · MIT

Both Sides

dialog-stackKibo UI · MIT · aguardando revisão de arquitetura
lensMagic UI · MIT · aguardando revisão de acessibilidade

Full Swipe

Arraste até o fim para descartarA ação da ponta cobre as outras quando arma

Disabled

Item publicado no registryNão pode ser descartado daqui

Usage

Imports de Swipe Actions
import {
  SwipeAction,
  SwipeActions,
  SwipeContent,
  SwipeItem,
  SwipeRoot,
} from '@/components/ui/swipe-actions'
import { Button } from '@/components/ui/button'
import { CloseIcon, EllipsisIcon } from '@/lib/up-web-icons'
Swipe Actions
<SwipeRoot className="w-full max-w-md divide-y divide-border overflow-hidden rounded-xl border border-border">
  <SwipeItem>
    <SwipeActions side="right">
      <SwipeAction className="bg-destructive-subtle text-destructive-subtle-foreground">
        <CloseIcon />
        Descartar
      </SwipeAction>
    </SwipeActions>

    <SwipeContent className="flex items-center justify-between gap-3 p-4">
      <span className="flex flex-col">
        <span className="type-small font-medium">dialog-stack</span>
        <span className="type-caption text-muted-foreground">
          Kibo UI · MIT
        </span>
      </span>

      <Button variant="ghost" size="icon-sm" aria-label="Mais ações">
        <EllipsisIcon />
      </Button>
    </SwipeContent>
  </SwipeItem>
</SwipeRoot>

Props

SwipeRoot

Estende React.ComponentProps<'div'>. Aceita também os atributos padrão de um elemento React (280 não listados).

SwipeItem

Props de SwipeItem
PropTypeDefaultDescription
closeOnScrollbooleanfalseClose the row on any scroll on the page.
disabledbooleanfalse
fullSwipeThresholdnumber0.5Fraction of the row width the drag must pass for the side's `fullSwipe` action to arm, firing on release instead of opening the row.
onOpenChange((state: SwipeState) => void)sem valor padrãoCalled once per real change of which side is open.
thresholdnumber0.5Fraction of the action strip the drag must pass to snap open.
velocityFactornumber0.2Seconds of velocity projected onto the release position, so a quick flick opens the row without dragging all the way.

Estende React.ComponentProps<'div'>. Aceita também os atributos padrão de um elemento React (280 não listados).

SwipeActions

Props de SwipeActions
PropTypeDefaultDescription
side, obrigatóriaSwipeSidesem valor padrãoWhich edge the strip belongs to.
fullSwipebooleanfalseLet a drag past `fullSwipeThreshold` run the outermost action, the way Mail does on iOS. The takeover works by that action covering the others, so it is always the outermost one, as it is on the platform.

Estende React.ComponentProps<'div'>. Aceita também os atributos padrão de um elemento React (280 não listados).

SwipeAction

Props de SwipeAction
PropTypeDefaultDescription
closeOnClickbooleantrueClose the row once the click handler has run.

Estende React.ComponentProps<'button'>. Aceita também os atributos padrão de um elemento React (290 não listados).

SwipeActionContent

Estende React.ComponentProps<'span'>. Aceita também os atributos padrão de um elemento React (280 não listados).

SwipeContent

Estende React.ComponentProps<'div'>. Aceita também os atributos padrão de um elemento React (280 não listados).

prop obrigatória.

Composition

O SwipeRoot guarda as linhas e deixa só uma aberta por vez. Dentro de cada SwipeItem, as faixas de ação vêm antes do conteúdo — elas ficam fora da linha, encostadas na borda que declaram.

Composição de SwipeActions

SwipeActions

  • SwipeItem
    • SwipeActions
      • SwipeAction
    • SwipeContent

Metadata

Notas de acessibilidade

Verificado em tests/e2e/swipe-actions.spec.ts no Chromium desktop e mobile, em light e dark, com Axe sem violações WCAG 2.2 AA. Teclado: com o foco dentro da linha, ArrowLeft e ArrowRight abrem e fecham os lados e Escape fecha — verificado em navegador e por teste. A linha não é um controle: não tem role próprio, não é parada de tabulação, e o atalho é ligado ao elemento em vez de declarado como onKeyDown no JSX, justamente para não fingir que o container é o que está sendo operado. IMPORTANTE, e é obrigação de quem usa: o arraste é um atalho, então as mesmas ações precisam existir em outro caminho na linha; os examples trazem um botão “Mais ações” exatamente por isso, e é ele que dá ao teclado um lugar de onde usar as setas. Leitor de tela verificado por teste e pela árvore do navegador: uma faixa fechada é `inert`, então suas ações não são anunciadas nem alcançadas por Tab — sem isso uma lista de vinte linhas esconderia quarenta paradas invisíveis —, e ela sai do inert assim que aquele lado abre. Cada ação é um `<button type="button">` de verdade. Touch verificado em viewport de 375px com emulação de toque: `touch-pan-y` deixa a rolagem vertical com a página e só o eixo horizontal com a linha, um gesto vertical é devolvido à página, e cada ação tem pelo menos 80x44 — acima do mínimo de 24x24 da WCAG 2.2 SC 2.5.8. Reduced motion verificado em navegador com prefers-reduced-motion: reduce e por teste: o movimento é calculado em JavaScript, então `motion-safe:` não o alcança e a política é a media query — sob reduce o encaixe tem duração zero, a linha aparece aberta ou fechada sem percorrer o caminho, e nenhum estado se perde. O arraste em si segue o dedo nos dois modos, porque ele é o gesto e não uma animação.

Classificação

Layer
Primitive
Domínio
Domain-free (compartilhado)
Categoria
action
Status
Stable

Origem e distribuição

Fonte
ncdai registry / swipe-actions
Licença
MIT
Distribuição
Interna

Acessibilidade

  • Teclado: revisado
  • Leitor de tela: revisado
  • Touch: revisado
  • Reduced motion: revisado

Dependências

Pacotes
Nenhuma
Ícones
Nenhum
Construído sobre
Nenhum
Usado por
Nenhum ainda