Modal
Sayfanın üstünde açılan, arkasını karartan pencere. Kısa formlar, ayrıntı görünümleri ve kullanıcının dikkatini bir işe toplaması gereken durumlar için kullanılır; aynı anda yalnızca bir modal açık kalır.
Temel kullanım
Her modalın benzersiz bir name değeri vardır. Pencere bu adla acun:modal.trigger, acun:modal:open olayı ya da JavaScript'te AcunUI.modal.open('catalog-customer') ile açılır. Başlıktaki X, Esc tuşu ve arka plana tıklama pencereyi kapatır. Açılınca odak ilk etkileşimli öğeye geçer, Tab tuşu pencerenin içinde döner, kapanınca odak açan düğmeye geri döner.
<acun:modal.trigger name="catalog-customer"><acun:button>Müşteri özetini aç</acun:button></acun:modal.trigger>
<acun:modal name="catalog-customer" title="Müşteri özeti">
<dl class="space-y-3 text-sm">
<div class="flex justify-between"><dt class="text-gray-500 dark:text-zinc-400">Müşteri</dt><dd>Ayşe Yılmaz</dd></div>
<div class="flex justify-between"><dt class="text-gray-500 dark:text-zinc-400">Üyelik</dt><dd>Premium</dd></div>
<div class="flex justify-between"><dt class="text-gray-500 dark:text-zinc-400">Son sipariş</dt><dd>12 Eylül 2026</dd></div>
</dl>
</acun:modal>
| Prop | Değerler |
|---|---|
name | Benzersiz ad; olaylar bu adı taşır |
title | Başlık satırı (X düğmesiyle) |
Genişlikler
Pencerenin en fazla genişliği max-width ile seçilir; varsayılan md. Onay ve kısa mesajlar için sm, iki sütunlu formlar ya da tablolar için xl veya 2xl kullanın. Dar ekranlarda pencere her zaman tam genişliktedir.
<div class="flex flex-wrap gap-2" x-data>
<acun:modal.trigger name="catalog-width-sm"><acun:button variant="white">sm</acun:button></acun:modal.trigger>
<acun:modal.trigger name="catalog-width-lg"><acun:button variant="white">lg</acun:button></acun:modal.trigger>
<acun:modal.trigger name="catalog-width-2xl"><acun:button variant="white">2xl</acun:button></acun:modal.trigger>
</div>
<acun:modal name="catalog-width-sm" title="Dar pencere" max-width="sm"><p class="text-sm">Kısa bir onay ya da mesaj için.</p></acun:modal>
<acun:modal name="catalog-width-lg" title="Geniş pencere" max-width="lg"><p class="text-sm">Tek sütunlu formlar için.</p></acun:modal>
<acun:modal name="catalog-width-2xl" title="En geniş pencere" max-width="2xl"><p class="text-sm">İki sütunlu formlar ve küçük tablolar için.</p></acun:modal>
| Prop | Değerler |
|---|---|
max-width | sm | md | lg | xl | 2xl |
Alt çubuk ve form
footer slot'u pencerenin altına sağa hizalı bir düğme çubuğu ekler. Slot'ların içinde close() ile pencereyi kapatabilirsiniz. İçerik uzarsa yalnızca gövde kayar, başlık ve alt çubuk yerinde kalır.
<acun:modal.trigger name="catalog-product-form"><acun:button>Yeni Ürün</acun:button></acun:modal.trigger>
<acun:modal name="catalog-product-form" title="Yeni Ürün" max-width="lg">
<div class="space-y-4">
<acun:input name="urun_adi" label="Ürün adı" />
<acun:input name="stok_kodu" label="Stok kodu" />
</div>
<acun:slot:footer>
<acun:modal.close><acun:button variant="white">Vazgeç</acun:button></acun:modal.close>
<acun:modal.close><acun:button x-on:click="$dispatch('toast', { type: 'success', message: 'Ürün kaydedildi.' })">Kaydet</acun:button></acun:modal.close>
</acun:slot:footer>
</acun:modal>
| Prop | Değerler |
|---|---|
footer | Slot: alt düğme çubuğu |
close() | Slot içinden pencereyi kapatır |
Başlıksız pencere
title verilmezse başlık satırı ve X düğmesi çizilmez; içerik pencereyi tamamen kullanır. Bu durumda ekran okuyucunun pencereyi adlandırabilmesi için aria-label verin (boşsa "Pencere" okunur).
<acun:modal.trigger name="catalog-done"><acun:button variant="white">Aktarımı bitir</acun:button></acun:modal.trigger>
<acun:modal name="catalog-done" max-width="sm" aria-label="Aktarım tamamlandı">
<div class="flex flex-col items-center gap-3 py-4 text-center">
<acun:icon name="check-circle" size="12" stroke="1.4" class="text-emerald-600" />
<p class="text-base font-semibold text-gray-900 dark:text-zinc-100">Aktarım tamamlandı</p>
<p class="text-sm text-gray-500 dark:text-zinc-400">148 ürün Elektronik kategorisine eklendi.</p>
<acun:modal.close><acun:button class="mt-2">Tamam</acun:button></acun:modal.close>
</div>
</acun:modal>
| Prop | Değerler |
|---|---|
aria-label | Başlık yokken pencerenin erişilebilir adı |
Dışarı tıklayınca kapanmasın
Uzun bir form yanlışlıkla kaybolmasın diye :closable-on-backdrop="false" ile arka plana tıklamayı kapatın; X ve Esc çalışmaya devam eder. Değeri iki nokta üst üste ile verin: closable-on-backdrop="false" yazılırsa "false" metni gelir ve özellik açık kalır.
<acun:modal.trigger name="catalog-sticky"><acun:button variant="white">Talep formunu aç</acun:button></acun:modal.trigger>
<acun:modal name="catalog-sticky" title="Destek talebi" :closable-on-backdrop="false">
<acun:textarea name="talep_notu" label="Talep notu" rows="4" />
<acun:slot:footer>
<acun:modal.close><acun:button variant="white">Kapat</acun:button></acun:modal.close>
</acun:slot:footer>
</acun:modal>
| Prop | Değerler |
|---|---|
closable-on-backdrop | true | false |
Kapatmayı onaya bağlamak
request-close-event verildiğinde X, Esc ve arka plan pencereyi doğrudan kapatmaz, bu adla bir olay yayar. Olayı dinleyen kod (ör. kaydedilmemiş değişiklik kontrolü) karar verir ve pencereyi kapatır: dinleyici pencerenin üstündeyse close(), başka bir yerdeyse AcunUI.modal.close('catalog-note'). Alt çubuktaki close() bu kontrolü atlar.
<acun:modal.trigger name="catalog-note"><acun:button variant="white">Not ekle</acun:button></acun:modal.trigger>
<acun:modal
name="catalog-note"
title="Not ekle"
request-close-event="catalog-note-close-requested"
x-on:catalog-note-close-requested.window="if (confirm('Yazdığınız not kaydedilmeyecek. Kapatılsın mı?')) close()"
>
<acun:textarea name="musteri_notu" label="Not" rows="3" />
</acun:modal>
| Prop | Değerler |
|---|---|
request-close-event | Kapatma isteğinde yayılacak olayın adı |
Livewire ile
Sunucudan acun:modal:open ve acun:modal:close olaylarını gönderin. close-action kullanıcı pencereyi kapattığında (X, Esc, arka plan, close()) çağrılacak Livewire metodudur; sunucudan gönderilen acun:modal:close bu metodu yeniden çağırmaz. Pencere açılınca acun:modal:opened, her kapanışta acun:modal:closed olayı { name } ile yayılır. İlk adlar (open-modal, close-modal ve yayılan modal-closed) de çalışmaya devam eder.
// <acun:modal name="urun-formu" title="Ürün" close-action="formuSifirla"> … </acun:modal>
public function duzenle(int $urunId): void
{
$this->urun = Urun::findOrFail($urunId);
$this->dispatch('acun:modal:open', name: 'urun-formu');
}
public function kaydet(): void
{
$this->urun->save();
$this->dispatch('acun:modal:close', name: 'urun-formu');
}
public function formuSifirla(): void
{
$this->reset('urun');
}
| Prop | Değerler |
|---|---|
close-action | Kullanıcı kapatınca çağrılan Livewire metodu |
Parçalı kullanım
Modalı açan düğmeyi acun:modal.trigger ile sarın; JavaScript yazmanız gerekmez. Pencereyi acun:modal.header (başlık, açıklama ve X), acun:modal.body (kayan gövde) ve acun:modal.footer parçalarıyla kurun; acun:modal.close içindeki düğme pencereyi kapatır. İçerik bir parçayla başlamalıdır; gövde ile alt çubuğu bir form ile sarmak için formu başlıktan sonra koyun.
<acun:modal.trigger name="gorev-ekle">
<acun:button>Yeni görev</acun:button>
</acun:modal.trigger>
<acun:modal name="gorev-ekle" max-width="lg">
<acun:modal.header title="Yeni görev" description="Görevin şubesini ve sorumlusunu seçin." />
<acun:modal.body class="space-y-4">
<acun:input name="gorev_adi" label="Görev adı" placeholder="Kadıköy – stok sayımı" />
<acun:select name="sube" label="Şube" :options="['kadikoy' => 'Kadıköy', 'uskudar' => 'Üsküdar', 'atasehir' => 'Ataşehir']" placeholder="Şube seçin" />
<acun:select name="sorumlu" label="Sorumlu" :options="['ahmet' => 'Ahmet Yılmaz', 'elif' => 'Elif Kaya']" placeholder="Ekip üyesi seçin" />
</acun:modal.body>
<acun:modal.footer>
<acun:modal.close>
<acun:button variant="white">Vazgeç</acun:button>
</acun:modal.close>
<acun:modal.close>
<acun:button x-on:click="$dispatch('toast', { type: 'success', message: 'Görev kaydedildi.' })">Kaydet</acun:button>
</acun:modal.close>
</acun:modal.footer>
</acun:modal>
| Prop | Değerler |
|---|---|
acun:modal.trigger | name (açılacak modal) |
acun:modal.header | title, description; slot: başlık içeriği |
acun:modal.body · footer | Gövde ve alt çubuk |
acun:modal.close | İçindeki öğe modalı kapatır |
Klasik modalda kapatma düğmesi
title ve footer slot'lu klasik kullanımda da acun:modal.close çalışır.
<acun:modal.trigger name="teslimat-notu">
<acun:button variant="white">Teslimat notu</acun:button>
</acun:modal.trigger>
<acun:modal name="teslimat-notu" title="Teslimat notu">
<p class="text-sm text-gray-600 dark:text-zinc-400">Müşteri adreste yoksa paketi kapıcıya bırakın ve fotoğrafını çekin.</p>
<acun:slot:footer>
<acun:modal.close><acun:button variant="white">Kapat</acun:button></acun:modal.close>
</acun:slot:footer>
</acun:modal>
Prop'lar ve slot'lar
Bileşenin kabul ettiği değerler.
| Prop | Varsayılan | Açıklama |
|---|---|---|
name | — | Zorunlu. acun:modal:open / acun:modal:close olaylarındaki ve AcunUI.modal.open('…') / close('…') çağrılarındaki ad; ad olmadan kapatma tüm modalları kapatır. Açılınca acun:modal:opened, kapanınca acun:modal:closed yayılır ({ name }) |
title | null | Başlık satırı ve X düğmesi; boşsa çizilmez |
max-width | md | sm · md · lg · xl · 2xl |
aria-label | null | Başlık yokken erişilebilir ad; boşsa "Pencere" |
closable-on-backdrop | true | Arka plana tıklayınca kapanır |
close-action | null | Kullanıcı kapatınca çağrılan Livewire metodu |
request-close-event | null | X / Esc / arka plan kapatmak yerine bu olayı yayar |
modal.trigger: name | — | Zorunlu; tıklanınca bu adlı modalı açar (confirmation-dialog dahil) |
modal.header: title · description | null | Başlık, açıklama ve X; title verilmezse slot başlığın kendisidir |
modal.body · modal.footer | — | Kayan gövde ve sağa hizalı alt çubuk |
modal.close | — | İçindeki öğeye tıklanınca modal kapanır |