---
title: "Steps"
description: "Sıralı bir akışta kullanıcının nerede olduğunu gösterir. Yatay, dikey ve kompakt düzenler; hatalı adım ve birden çok adım atlarken sırayla dolan bağlantılar."
---

<Callout type="info" title="Ne zaman kullanılır">
3–6 adımlı sihirbazlar: kampanya oluşturma, pazaryeri bağlantısı, ilk eşitleme. Adımların sırası önemliyse Steps, boyutu bilinen bir işin ilerlemesi için [Progress Bar](https://builders.ikas.com/tr/docs/app-development/ui-kit/components/progress-bar), kullanıcının istediği sırayla işaretlediği kurulum adımları için [Launchpad](https://builders.ikas.com/tr/docs/app-development/ui-kit/components/launchpad) kullanın.
</Callout>

## Kurulum

```bash
npx shadcn@latest add @ikas/steps
```

Registry tanımı yoksa önce [Kurulum](https://builders.ikas.com/tr/docs/app-development/ui-kit/installation) adımlarını tamamlayın.

## Örnekler

### Yatay

Beş adımlı bir sihirbaz. "Sona atla" ile birden çok adım atlandığında bağlantılar sırayla dolar, mevcut adımın halkası en son yerine oturur. "Hata" mevcut adıma `error` verir.

**Örnek: Yatay** (`steps/horizontal`) · [Canlı önizleme](https://builders.ikas.com/ui-preview/demo/steps/horizontal)

```tsx
import * as React from "react"

import { Button } from "@/components/ui/button"
import { SegmentedControl } from "@/components/ikas/segmented-control"
import { type StepMarkerShape } from "@/components/ikas/step-kit"
import { Steps, type StepsItem } from "@/components/ikas/steps"

const base: StepsItem[] = [
  { id: "goal", label: "Hedef", description: "Kampanyanın amacını seç." },
  { id: "audience", label: "Kitle", description: "Kimlere gösterileceğini belirle." },
  { id: "content", label: "İçerik", description: "Başlık ve görselleri ekleyin." },
  { id: "budget", label: "Bütçe", description: "Günlük harcama sınırını gir." },
  { id: "review", label: "Önizleme", description: "Yayından önce kontrol edin." },
]
const shapes: { value: StepMarkerShape; label: string }[] = [
  { value: "diamond", label: "Elmas" },
  { value: "circle", label: "Daire" },
  { value: "square", label: "Kare" },
  { value: "pill", label: "Hap" },
]

/** A wizard of five steps. "Sona atla" fills the connectors one after another; the current step's halo lands last. */
export default function StepsHorizontal() {
  const [current, setCurrent] = React.useState(1)
  const [failed, setFailed] = React.useState(false)
  const [shape, setShape] = React.useState<StepMarkerShape>("diamond")
  const go = (to: number) => (setFailed(false), setCurrent(Math.max(0, Math.min(base.length, to))))
  const steps = base.map((step, i) => (failed && i === current ? { ...step, error: "Kaydedilemedi, tekrar dene." } : step))

  return (
    <div className="flex w-full max-w-2xl flex-col gap-6">
      <Steps steps={steps} current={current} marker={shape} label="Kampanya adımları" />
      <div className="flex flex-col items-center gap-3 border-t pt-5">
        <div className="flex flex-wrap justify-center gap-2">
          <Button size="sm" variant="outline" onClick={() => go(current - 1)}>Geri</Button>
          <Button size="sm" onClick={() => go(current + 1)}>İleri</Button>
          <Button size="sm" variant="outline" onClick={() => go(base.length)}>Sona atla</Button>
          <Button size="sm" variant="outline" onClick={() => go(0)}>Başa dön</Button>
          <Button size="sm" variant="outline" disabled={current >= base.length} onClick={() => setFailed(true)}>Hata</Button>
        </div>
        <SegmentedControl aria-label="İşaret şekli" mode="radio" size="sm" value={shape} onValueChange={setShape} options={shapes} />
      </div>
    </div>
  )
}
```

### Dikey

Açıklamalı uzun akışlar için. Mevcut adım açıklamasıyla ve `actions` ile verilen butonla açılır; hata olduğunda açıklamanın yerini hata mesajı alır.

**Örnek: Dikey** (`steps/vertical`) · [Canlı önizleme](https://builders.ikas.com/ui-preview/demo/steps/vertical)

```tsx
import * as React from "react"

import { Button } from "@/components/ui/button"
import { SegmentedControl } from "@/components/ikas/segmented-control"
import { type StepMarkerShape } from "@/components/ikas/step-kit"
import { Steps, type StepsItem } from "@/components/ikas/steps"

const base: StepsItem[] = [
  { id: "connect", label: "Hesabı bağla", description: "Pazaryeri API anahtarını girin." },
  { id: "products", label: "Ürünleri seç", description: "Gönderilecek ürünleri filtreleyin." },
  { id: "price", label: "Fiyat kuralı", description: "Komisyonu fiyata yansıt." },
  { id: "preview", label: "Önizle", description: "İlk 10 ürünü kontrol edin." },
  { id: "publish", label: "Yayınla", description: "Ürünleri pazaryerine gönderin." },
]
const shapes: { value: StepMarkerShape; label: string }[] = [
  { value: "diamond", label: "Elmas" },
  { value: "circle", label: "Daire" },
  { value: "square", label: "Kare" },
  { value: "pill", label: "Hap" },
]

/** A long flow: the current step opens with its description and action; an error replaces the description. */
export default function StepsVertical() {
  const [current, setCurrent] = React.useState(1)
  const [failed, setFailed] = React.useState(false)
  const [shape, setShape] = React.useState<StepMarkerShape>("diamond")
  const steps = base.map((step, i) => (failed && i === current ? { ...step, error: "Anahtar reddedildi. Pazaryeri panelinden yeni bir anahtar al." } : step))

  return (
    <div className="flex w-full max-w-md flex-col gap-6">
      <Steps
        orientation="vertical"
        steps={steps}
        current={current}
        marker={shape}
        label="Pazaryeri bağlantısı"
        actions={
          current < base.length && (
            <Button size="sm" onClick={() => (setFailed(false), setCurrent(current + 1))}>
              {failed ? "Tekrar dene" : current === base.length - 1 ? "Yayınla" : "Devam et"}
            </Button>
          )
        }
      />
      <div className="flex flex-col items-center gap-3 border-t pt-5">
        <div className="flex flex-wrap justify-center gap-2">
          <Button size="sm" variant="outline" onClick={() => (setFailed(false), setCurrent(Math.max(0, current - 1)))}>Geri</Button>
          <Button size="sm" variant="outline" disabled={current >= base.length} onClick={() => setFailed(true)}>Hata</Button>
          <Button size="sm" variant="ghost" onClick={() => (setFailed(false), setCurrent(0))}>Baştan</Button>
        </div>
        <SegmentedControl aria-label="İşaret şekli" mode="radio" size="sm" value={shape} onValueChange={setShape} options={shapes} />
      </div>
    </div>
  )
}
```

### Kompakt

Sihirbazın başlığında adım adlarına yer yoksa: yalnızca işaretler, sayacın yanında mevcut adımın adı.

**Örnek: Kompakt** (`steps/compact`) · [Canlı önizleme](https://builders.ikas.com/ui-preview/demo/steps/compact)

```tsx
import * as React from "react"

import { Button } from "@/components/ui/button"
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"
import { SegmentedControl } from "@/components/ikas/segmented-control"
import { type StepMarkerShape } from "@/components/ikas/step-kit"
import { Steps } from "@/components/ikas/steps"

const steps = ["Hedef", "Kitle", "İçerik", "Bütçe", "Önizleme"].map((label) => ({ id: label, label }))
const shapes: { value: StepMarkerShape; label: string }[] = [
  { value: "diamond", label: "Elmas" },
  { value: "circle", label: "Daire" },
  { value: "square", label: "Kare" },
  { value: "pill", label: "Hap" },
]

/** A wizard's header when there is no room for step names: markers only, the current name beside the count. */
export default function StepsCompact() {
  const [current, setCurrent] = React.useState(2)
  const [shape, setShape] = React.useState<StepMarkerShape>("diamond")

  return (
    <div className="flex w-full max-w-sm flex-col gap-6">
      <Card>
        <CardHeader>
          <CardTitle>Kampanya oluştur</CardTitle>
        </CardHeader>
        <CardContent className="flex flex-col gap-5">
          <Steps orientation="compact" steps={steps} current={current} marker={shape} label="Kampanya sihirbazı" />
          <div className="flex justify-between gap-2">
            <Button size="sm" variant="outline" disabled={current === 0} onClick={() => setCurrent(current - 1)}>Geri</Button>
            <Button size="sm" disabled={current >= steps.length} onClick={() => setCurrent(current + 1)}>
              {current >= steps.length - 1 ? "Yayınla" : "İleri"}
            </Button>
          </div>
        </CardContent>
      </Card>
      <div className="flex justify-center border-t pt-5">
        <SegmentedControl aria-label="İşaret şekli" mode="radio" size="sm" value={shape} onValueChange={setShape} options={shapes} />
      </div>
    </div>
  )
}
```

### İşaret şekli

Kökte bir kez verilen `StepMarkerProvider`, uygulamadaki tüm Steps, Launchpad ve segmentli Progress Bar'ların işaret şeklini belirler. Varsayılan `diamond`, Launchpad ile aynıdır.

**Örnek: İşaret şekli** (`steps/markers`) · [Canlı önizleme](https://builders.ikas.com/ui-preview/demo/steps/markers)

```tsx
import * as React from "react"

import { SegmentedControl } from "@/components/ikas/segmented-control"
import { StepMarkerProvider, markerWidth, type StepMarkerShape } from "@/components/ikas/step-kit"
import { Steps } from "@/components/ikas/steps"

const steps = [
  { id: "goal", label: "Hedef" },
  { id: "audience", label: "Kitle" },
  { id: "content", label: "İçerik", error: "Görsel yüklenemedi." },
  { id: "budget", label: "Bütçe" },
]

/** One StepMarkerProvider sets the marker shape for every stepper and setup list in the app. Diamond matches Launchpad. */
export default function StepsMarkers() {
  const [shape, setShape] = React.useState<StepMarkerShape>("diamond")
  // The horizontal stepper's last column holds only its marker: centre what sits below under what it draws.
  const drawn = `calc(${((steps.length - 1) / steps.length) * 100}% + ${markerWidth(shape, "default")}px)`

  return (
    <div className="flex w-full max-w-2xl flex-col gap-6">
      <StepMarkerProvider shape={shape}>
        <div className="flex flex-col gap-8">
          <Steps steps={steps} current={2} label="Yatay" />
          <div style={{ width: drawn }}>
            <Steps orientation="compact" steps={steps} current={1} label="Kompakt" className="mx-auto w-full max-w-sm" />
          </div>
        </div>
      </StepMarkerProvider>
      <div className="flex justify-center border-t pt-5" style={{ width: drawn }}>
        <SegmentedControl
          aria-label="İşaret şekli"
          mode="radio"
          size="sm"
          value={shape}
          onValueChange={setShape}
          options={[
            { value: "diamond", label: "Elmas" },
            { value: "circle", label: "Daire" },
            { value: "square", label: "Kare" },
            { value: "pill", label: "Hap" },
          ]}
        />
      </div>
    </div>
  )
}
```

## Kullanım ilkeleri

**Yapın:**

- 3–6 adım kullanın; adım adları kısa ve fiil ya da isim olarak tutarlı olsun.
- Hatayı ilgili adımın error alanına yazın; ne olduğunu ve ne yapılacağını tek cümlede söyleyin.
- Uygulamada tek bir işaret şekli seçin ve kökte StepMarkerProvider ile verin.

**Yapmayın:**

- Daireleri elle numaralandırmayın.
- “Adım 2/5” yazısıyla yetinmeyin; adımların adını gösterin.
- Her Steps'e ayrı ayrı farklı bir marker şekli vermeyin.

## Erişilebilirlik

- Adımlar sıralı liste (`ol`) olarak okunur; mevcut adım `aria-current="step"` taşır.
- Her değişiklik `aria-live="polite"` ile duyurulur: "5 adımdan 2. adım: Kitle". Hatalı adımın sonuna ", hata" eklenir.
- Kompakt düzen `role="progressbar"` ile mevcut adımı ve toplamı bildirir.
- Dikey düzende hata mesajı `role="alert"` ile okunur.
- `prefers-reduced-motion` açıkken bağlantılar ve işaretler animasyonsuz değişir.

## API

### `Steps`

| Prop | Tip | Varsayılan | Açıklama |
| --- | --- | --- | --- |
| `steps` (zorunlu) | `StepsItem[]` | - | Sıralı adımlar. Boş dizide hiçbir şey çizilmez. Alanlar için aşağıdaki tabloya bakın. |
| `current` (zorunlu) | `number` | - | Mevcut adımın sırası (0'dan başlar). steps.length verildiğinde tüm adımlar tamamlanmış sayılır. |
| `orientation` | `"horizontal" \| "vertical" \| "compact"` | `"horizontal"` | horizontal sihirbazlar için (3–6 adım), vertical açıklamalı uzun akışlar için, compact sihirbaz başlığı için. |
| `marker` | `StepMarkerShape` | - | diamond (varsayılan), circle, square veya pill. Verilmezse StepMarkerProvider'ınkini kullanır. |
| `actions` | `React.ReactNode` | - | Dikey düzende mevcut adımın altında gösterilir, örn. adımın ana butonu. |
| `label` | `string` | `"Adımlar"` | Listenin erişilebilir adı. |
| `completeLabel` | `string` | `"Tüm adımlar tamamlandı"` | Tüm adımlar bittiğinde duyurulan ve gösterilen metin. |

### `StepsItem`

| Alan | Tip | Açıklama |
| --- | --- | --- |
| `id` | `string` | Adımın sabit kimliği. |
| `label` | `string` | Adımın adı. |
| `description` | `ReactNode` | Dikey düzende mevcut adımın altında, dar ekranlarda başlıkta gösterilir. Tek cümle. |
| `error` | `ReactNode` | Adım başarısız olduğunda verilir. İşaret kırmızıya döner ve açıklamanın yerini alır. |

İşaretleri ve bağlantıları kendi bileşeninizde kullanmak için [Step Kit](https://builders.ikas.com/tr/docs/app-development/ui-kit/components/step-kit) sayfasına bakın.
