Pular para o conteúdo

Tour

Tour guiado com destaque de spotlight e navegação por passos.

import { Tour } from 'asterui'

Tour Básico

Um tour guiado simples com múltiplos passos.

import { Tour, Button, Input, Card } from 'asterui'
import { useState, useRef } from 'react'

function App() {
  const [open, setOpen] = useState(false);
  const searchRef = useRef<HTMLInputElement>(null);
  const profileRef = useRef<HTMLButtonElement>(null);
  const settingsRef = useRef<HTMLButtonElement>(null);
  
  const steps = [
    {
      target: searchRef,
      title: 'Search',
      description: 'Use the search bar to find content quickly.',
      placement: 'bottom' as const,
    },
    {
      target: profileRef,
      title: 'Profile',
      description: 'Click here to view and edit your profile.',
      placement: 'bottom' as const,
    },
    {
      target: settingsRef,
      title: 'Settings',
      description: 'Customize your experience in settings.',
      placement: 'left' as const,
    },
  ];
  
  return (
      <Card className="p-4">
        <div className="flex gap-4 items-center mb-4">
          <Input ref={searchRef} placeholder="Search..." className="flex-1" />
          <Button ref={profileRef}>Profile</Button>
          <Button ref={settingsRef}>Settings</Button>
        </div>
        <Button color="primary" onClick={() => setOpen(true)}>
          Start Tour
        </Button>
        <Tour
          open={open}
          steps={steps}
          onClose={() => setOpen(false)}
          onFinish={() => setOpen(false)}
        />
      </Card>
    )
}

export default App

Tour Sem Alvo

Passos sem alvo aparecem centralizados na tela.

import { Tour, Button } from 'asterui'
import { useState } from 'react'

function App() {
  const [open, setOpen] = useState(false);
  
  const steps = [
    {
      title: 'Welcome!',
      description: 'This tour will guide you through the main features.',
    },
    {
      title: 'Getting Started',
      description: 'Follow along to learn how to use this application.',
    },
    {
      title: 'All Done!',
      description: 'You are ready to start using the app.',
    },
  ];
  
  return (
      <Button color="primary" onClick={() => setOpen(true)}>
        Start Intro
      </Button>
      <Tour
        open={open}
        steps={steps}
        onClose={() => setOpen(false)}
        type="primary"
      />
    )
}

export default App

Com Imagem de Capa

Adicione imagens ou conteúdo personalizado acima do título do passo.

import { Tour, Button } from 'asterui'
import { useState, useRef } from 'react'

function App() {
  const [open, setOpen] = useState(false);
  const buttonRef = useRef<HTMLButtonElement>(null);
  
  const steps = [
    {
      target: buttonRef,
      title: 'New Feature',
      description: 'Check out this amazing new feature we just added!',
      cover: (
        <img
          src="https://picsum.photos/320/160"
          alt="Feature preview"
          className="w-full h-40 object-cover"
        />
      ),
      placement: 'right' as const,
    },
  ];
  
  return (
      <Button ref={buttonRef} color="primary" onClick={() => setOpen(true)}>
        View Feature
      </Button>
      <Tour
        open={open}
        steps={steps}
        onClose={() => setOpen(false)}
        showSkip={false}
      />
    )
}

export default App

Posições

Controle onde o popover aparece relativo ao alvo.

Target
import { Tour, Button, Space } from 'asterui'
import { useState, useRef } from 'react'

function App() {
  const [open, setOpen] = useState(false);
  const targetRef = useRef<HTMLDivElement>(null);
  const placements = ['top', 'right', 'bottom', 'left'] as const;
  const [placementIndex, setPlacementIndex] = useState(0);
  
  const steps = [
    {
      target: targetRef,
      title: `Placement: ${placements[placementIndex]}`,
      description: 'The popover can appear on any side of the target.',
      placement: placements[placementIndex],
    },
  ];
  
  return (
      <div className="flex flex-col items-center gap-4">
        <div
          ref={targetRef}
          className="w-24 h-24 bg-primary text-primary-content flex items-center justify-center rounded-lg"
        >
          Target
        </div>
        <Space>
          <Button onClick={() => setPlacementIndex((i) => (i + 1) % 4)}>
            Change Placement
          </Button>
          <Button color="primary" onClick={() => setOpen(true)}>
            Show Tour
          </Button>
        </Space>
        <Tour
          open={open}
          steps={steps}
          onClose={() => setOpen(false)}
          showIndicators={false}
        />
      </div>
    )
}

export default App
PropriedadeDescriçãoTipoPadrão
openSe o tour é visívelbooleanfalse
stepsConfiguração dos passos do tourTourStepProps[]-
currentÍndice do passo atual (controlado)number-
onChangeCallback quando o passo muda(current: number) => void-
onCloseCallback quando o tour fecha() => void-
onFinishCallback quando o tour termina() => void-
maskMostrar sobreposição de máscara com spotlightbooleantrue
typeTipo de estilo do botão'default' | 'primary''default'
gapEspaço entre spotlight e alvo [raio, deslocamento] ou númeronumber | [number, number]8
showSkipMostrar botão pularbooleantrue
showIndicatorsMostrar indicadores de passobooleantrue
closeOnMaskClickFechar ao clicar na máscarabooleantrue
closeOnEscapeFechar com tecla Escapebooleantrue
scrollIntoViewRolar alvo para a visualizaçãobooleantrue
prevButtonTextTexto para botão anteriorReact.ReactNode'Previous'
nextButtonTextTexto para botão próximoReact.ReactNode'Next'
finishButtonTextTexto para botão finalizarReact.ReactNode'Finish'
skipButtonTextTexto para botão pularReact.ReactNode'Skip'
zIndexz-index para sobreposição do tournumber1000
PropriedadeDescriçãoTipoPadrão
targetRef do elemento alvo ou função retornando elementoRefObject<HTMLElement> | (() => HTMLElement | null) | null-
titleTítulo do passoReact.ReactNode-
descriptionDescrição do passoReact.ReactNode-
coverImagem de capa ou conteúdo acima do títuloReact.ReactNode-
placementPosicionamento do popover relativo ao alvoTourPlacement'bottom'
classNameClasse personalizada para o popover do passostring-
onOpenChamado quando o passo se torna ativo() => void-
onCloseChamado ao sair do passo() => void-
  • Diálogo do tour tem role=“dialog” e aria-modal=“true”
  • Teclas de seta navegam entre passos
  • Tecla Escape fecha o tour
  • Indicadores de passo são acessíveis por teclado
  • Foco é aprisionado dentro do tour quando aberto