Tour experimental
Ark UI Tour 기반 wrapper입니다. backdrop, spotlight, positioner, content, title, description, progress-text, control, actions, action-trigger, close-trigger, arrow anatomy를 제공합니다.
Preview
<script lang="ts">
import * as Tour from '@odbd/svelte/tour'
import { Portal } from '@odbd/svelte/portal'
import { useTour } from '@odbd/svelte/tour'
import type { TourStepDetails } from '@odbd/svelte/tour'
const steps: TourStepDetails[] = [
{
id: 'welcome',
type: 'dialog',
title: '디자인 시스템 투어',
description: '핵심 흐름을 한 단계씩 안내해요.',
actions: [{ label: '다음', action: 'next' }],
},
{
// 실제 요소에 앵커되는 tooltip 스텝: spotlight가 대상을 비추고
// 다이얼로그가 화살표와 함께 그 옆에 붙는다.
id: 'trigger',
type: 'tooltip',
placement: 'bottom',
target: () => document.querySelector<HTMLElement>('#tour-demo-trigger'),
title: '투어 시작 버튼',
description: '이 버튼처럼 화면의 실제 요소를 spotlight로 비추며 안내해요.',
actions: [
{ label: '이전', action: 'prev' },
{ label: '다음', action: 'next' },
],
},
{
id: 'wrap-up',
type: 'dialog',
title: '준비 완료',
description: '이제 컴포넌트를 직접 사용해요.',
actions: [{ label: '끝내기', action: 'dismiss' }],
},
]
// id를 주지 않으면 part id가 'tour-content-undefined'로 렌더된다(중복 위험);
// 닫힐 때 포커스를 시작 버튼으로 되돌린다(2.4.3)
const tour = useTour({
id: 'docs-tour',
steps,
onStatusChange: (details: { status: string }) => {
if (details.status === 'dismissed' || details.status === 'completed') {
document.querySelector<HTMLButtonElement>('#tour-demo-trigger')?.focus()
}
},
})
</script>
<div class="tour-demo">
<button
id="tour-demo-trigger"
type="button"
class="odbd-button"
data-variant="solid"
data-size="md"
onclick={() => tour().start()}>투어 시작</button
>
</div>
<Tour.Root {tour}>
<Portal>
<Tour.Backdrop />
<Tour.Spotlight />
<Tour.Positioner>
<Tour.Content>
<Tour.Arrow>
<Tour.ArrowTip />
</Tour.Arrow>
<Tour.Title />
<Tour.Description />
<Tour.ProgressText />
<Tour.Control>
<Tour.Actions>
{#snippet children(actions)}
{#each actions() as action (action.label)}
<!-- zag 기본 aria-label("next step")이 한국어 가시 라벨과 어긋난다(2.5.3) -->
<Tour.ActionTrigger
{action}
aria-label={action.label}
class="odbd-button"
data-variant="solid"
data-size="sm"
/>
{/each}
{/snippet}
</Tour.Actions>
</Tour.Control>
<Tour.CloseTrigger aria-label="투어 닫기">✕</Tour.CloseTrigger>
</Tour.Content>
</Tour.Positioner>
</Portal>
</Tour.Root>
<style>
.tour-demo {
display: grid;
justify-items: center;
}
.tour-demo :global(.odbd-button) {
inline-size: fit-content;
min-inline-size: 12rem;
}
</style>
Import
Svelte와 React가 같은 anatomy 계약을 공유합니다. 선택한 프레임워크는 모든 페이지에서 유지됩니다. 패키지 설치는 Getting Started를 참고하세요.
import * as Tour from '@odbd/svelte/tour' import { Tour } from '@odbd/react/tour'