---
title: "Launchpad"
description: "Uygulama ana sayfasının üstündeki ilk adımlar. Numaralı adımlar dikey bir hat üzerinde durur; açık adım yerinde genişler ve aksiyonlarını gösterir."
---

<Callout type="info" title="Ne zaman kullanılır">
Uygulama, mağaza sahibi birkaç işi yapmadan çalışmıyorsa: hesap bağlama, kategori eşleme, script kurulumu, ilk eşitleme. Kurulumdan sonraki ilk ekranda bir kez gösterin.
</Callout>

## Kurulum

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

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

## Örnekler

### İlk kurulum

Bir adımı bitirince sıradaki açık adıma geçilir. Herhangi bir satıra tıklayarak o adımı açabilirsiniz. `requires` ile bağlanan adım, önceki adım bitene kadar kilitli kalır ve sağda "02 bitince" yazar.

**Örnek: İlk kurulum** (`launchpad/first-run`) · [Canlı önizleme](https://builders.ikas.com/ui-preview/demo/launchpad/first-run)

```tsx
import * as React from "react"
import { toast } from "sonner"

import { Button } from "@/components/ui/button"
import { Launchpad, type LaunchpadStep } from "@/components/ikas/launchpad"

export default function LaunchpadFirstRun() {
  const [done, setDone] = React.useState<Record<string, boolean>>({ connect: true })
  const [visible, setVisible] = React.useState(true)
  const complete = (id: string) => setDone((d) => ({ ...d, [id]: true }))
  const status = (id: string): LaunchpadStep["status"] => (done[id] ? "done" : undefined)

  if (!visible)
    return (
      <Button variant="outline" onClick={() => (setDone({ connect: true }), setVisible(true))}>
        Adımları yeniden göster
      </Button>
    )

  const steps: LaunchpadStep[] = [
    {
      id: "connect",
      label: "Hesabı bağla",
      description: "API anahtarınızla pazaryeri satıcı hesabınızı bağlayın.",
      eta: "~1 dk",
      status: status("connect"),
      actions: <Button size="sm" onClick={() => complete("connect")}>Hesabı bağla</Button>,
    },
    {
      id: "categories",
      label: "Kategorileri eşle",
      description: "ikas kategorilerinizi pazaryeri kategorileriyle eşleyin. Otomatik eşleme çoğunu halleder.",
      eta: "~2 dk",
      status: status("categories"),
      requires: ["connect"],
      actions: (
        <>
          <Button size="sm" onClick={() => complete("categories")}>Otomatik eşle</Button>
          <Button size="sm" variant="ghost">Elle eşle</Button>
        </>
      ),
    },
    {
      id: "script",
      label: "Script'i kur",
      description: "Stok ve fiyat rozetleri ürün sayfalarında görünsün.",
      eta: "~1 dk",
      status: status("script"),
      actions: <Button size="sm" onClick={() => complete("script")}>{"Script'i kur"}</Button>,
    },
    {
      id: "sync",
      label: "İlk eşitlemeyi başlat",
      description: "Birkaç dakika sürer, bitince bildirim alırsınız.",
      status: status("sync"),
      requires: ["categories"],
      actions: <Button size="sm" onClick={() => (complete("sync"), toast.success("Eşitleme başladı"))}>Eşitlemeyi başlat</Button>,
    },
  ]

  return (
    <Launchpad
      className="w-full max-w-xl"
      steps={steps}
      onComplete={() => toast.success("Kurulum tamamlandı")}
      onDismiss={() => setVisible(false)}
    />
  )
}
```

### Küçültülmüş ve tamamlanmış

Küçültülen kart yalnızca başlığı ve sıradaki adımı gösterir. Bu örnekte açık adım ve küçültme durumu sayfa tarafından tutuluyor (`activeId`, `collapsed`). Tüm adımlar bitince kapatma butonu görünür.

**Örnek: Küçültülmüş ve tamamlanmış** (`launchpad/states`) · [Canlı önizleme](https://builders.ikas.com/ui-preview/demo/launchpad/states)

```tsx
import * as React from "react"
import { toast } from "sonner"

import { Button } from "@/components/ui/button"
import { Launchpad, type LaunchpadStep } from "@/components/ikas/launchpad"

const base: LaunchpadStep[] = [
  { id: "permissions", label: "İzinleri onayla", eta: "~1 dk" },
  { id: "settings", label: "Temel ayarları yap", eta: "~3 dk" },
  { id: "first", label: "İlk kaydı oluştur", requires: ["permissions"] },
]

export default function LaunchpadStates() {
  // Controlled: the page decides which step is open and whether the card is collapsed.
  const [collapsed, setCollapsed] = React.useState(true)
  const [activeId, setActiveId] = React.useState<string | null>("settings")
  const [dismissed, setDismissed] = React.useState(false)

  const inProgress = base.map((step) => ({
    ...step,
    status: step.id === "permissions" ? ("done" as const) : undefined,
    description: "Adım açıklaması burada görünür.",
    actions: <Button size="sm">Devam et</Button>,
  }))
  const finished = base.map((step) => ({ ...step, status: "done" as const }))

  return (
    <div className="flex w-full max-w-xl flex-col gap-4">
      <Launchpad
        title="Küçültülmüş"
        steps={inProgress}
        activeId={activeId}
        onActiveChange={setActiveId}
        collapsed={collapsed}
        onCollapsedChange={setCollapsed}
      />
      {dismissed ? (
        <Button variant="outline" className="self-start" onClick={() => setDismissed(false)}>
          Tamamlanan kartı geri getir
        </Button>
      ) : (
        <Launchpad
          title="Hepsi tamam"
          steps={finished}
          onDismiss={() => (setDismissed(true), toast("Kart kaldırıldı"))}
        />
      )}
    </div>
  )
}
```

## Anatomi

| Parça | Ne gösterir |
| --- | --- |
| Başlık | Kısa etiket (varsayılan "Başlangıç"), tamamlanan adım sayacı (`01/04`), adım başına bir parça olan ilerleme ve kartı küçülten / genişleten ok butonu. |
| Hat | Biten adımlar arasında düz, kalan adımlar arasında kesikli çizgi. |
| Düğüm | Dolu elmas: tamamlandı. İçi dolu çekirdekli elmas: açık adım. Boş elmas: sırada. Kesikli elmas: kilitli. |
| Sağ bilgi | `eta` ("~2 dk"), "tamamlandı" ya da kilitli adımda hangi adımın beklendiği. |

## Kullanım ilkeleri

**Yapın:**

- 3–5 adımla sınırlayın; her adımın tek bir işi olsun.
- Adım etiketini fiille yazın: “Hesabı bağla”, “Script'i kur”.
- Bir ana, en fazla bir ikincil aksiyon verin; ana aksiyon adımı bitirsin.
- Sıra gerçekten gerekiyorsa requires kullanın, gerekmiyorsa adımları serbest bırakın.

**Yapmayın:**

- Launchpad'i her sayfada göstermeyin; ana ekranın en üstünde bir kez yeter.
- Bitmemiş adımları gizlemek için kartı kaldırmayın; kullanıcı küçültebilir.
- Uzun açıklama veya form koymayın; adım, işin yapıldığı ekrana yönlendirsin.

## Erişilebilirlik

- Adımlar sıralı liste (`ol`) olarak okunur; açık adımın butonu `aria-current="step"` ve `aria-expanded` taşır.
- Adımlar arasında ↑ / ↓, ilk ve son adım için Home / End ile gezinilir.
- İlerleme `role="progressbar"` ile "4 adımdan 1 tanesi tamamlandı" olarak okunur.
- Küçült / Genişlet ok butonu, duruma göre "Küçült" ya da "Genişlet" etiketiyle okunur ve `aria-expanded` taşır.
- Kilitli adımın aksiyonları devre dışıdır; `prefers-reduced-motion` açıkken açılıp kapanma animasyonsuzdur.

## API

### `Launchpad`

| Prop | Tip | Varsayılan | Açıklama |
| --- | --- | --- | --- |
| `steps` (zorunlu) | `LaunchpadStep[]` | - | Sıralı adımlar. Alanlar için aşağıdaki tabloya bakın. |
| `activeId` | `string \| null` | - | Açık adım. Vermezseniz Launchpad kendisi tutar ve ilk açık adımla başlar. |
| `onActiveChange` | `(id: string) => void` | - | Bir adıma tıklanınca ve açık adım bitip sıradakine geçilince çağrılır. |
| `onComplete` | `() => void` | - | Son adım bittiğinde bir kez çağrılır. |
| `collapsed` | `boolean` | - | Yalnızca başlık ve sıradaki adım. Vermezseniz Launchpad kendisi tutar. |
| `onCollapsedChange` | `(collapsed: boolean) => void` | - | Başlıktaki Küçült / Genişlet ok butonuyla çağrılır. |
| `title` | `React.ReactNode` | `"Başlangıç"` | Sol üstteki kısa etiket. |
| `onDismiss` | `() => void` | - | Tüm adımlar bitince kapatma butonunu gösterir. |

### `LaunchpadStep`

| Alan | Tip | Açıklama |
| --- | --- | --- |
| `id` | `string` | Sabit kimlik; `activeId` ve `requires` bunu kullanır. |
| `label` | `ReactNode` | Adımın adı. |
| `description` | `ReactNode` | Adım açıkken görünen bir iki cümle. |
| `eta` | `ReactNode` | Sağdaki tahmini süre, örn. `"~2 dk"`. |
| `status` | `"todo" \| "done" \| "blocked"` | Varsayılan `todo`; `requires` içindeki bir adım bitmemişse `blocked` olur. |
| `requires` | `string[]` | Önce bitmesi gereken adımların id'leri. |
| `actions` | `ReactNode` | Adım açıkken görünen butonlar. Ana aksiyon önce. |
