TR
Başlangıç
14 · Menü

JSON menü

Uygulama menüsü tek bir JSON dosyasında tanımlanır; dikey menü, yatay menü, mobil çekmece ve komut paleti araması aynı tanımdan üretilir. Aktif sayfa, rozet, dış bağlantı ve üç seviyeye kadar alt menü desteklenir; menü yetki denetimi yapmaz, hangi öğelerin görüneceğine uygulama karar verir.

acun:menu
01

Temel kullanım

acun:menu tanımı menu prop'undan alır: resources/menu altındaki bir dosyanın adı, tam dosya yolu, PHP dizisi ya da Menu nesnesi. Örnekte tanım dizi olarak verildi; uygulamada JSON dosyası kullanın. Düzenlerin nav slot'u menüyü zaten sarar; tek başına kullanırken bir <nav> içine koyun.

CANLI ÖRNEK
<nav class="flex flex-col gap-0.5">
    <acun:menu :menu="[
        ['section' => 'Genel'],
        ['title' => 'Pano', 'icon' => 'squares-2x2', 'url' => '#'],
        ['title' => 'Siparişler', 'icon' => 'shopping-bag', 'url' => '#siparisler'],
        ['title' => 'Raporlar', 'icon' => 'chart-bar', 'children' => [
            ['title' => 'Satış raporu', 'url' => '#satis'],
            ['title' => 'Müşteri raporu', 'url' => '#musteri'],
        ]],
        ['section' => 'Destek'],
        ['title' => 'Yardım merkezi', 'icon' => 'lifebuoy', 'url' => 'https://destek.ornek.com', 'target' => '_blank'],
    ]" />
</nav>
PropDeğerler
menuDosya adı | tam yol | dizi | Menu nesnesi
02

JSON dosyası

Dosya resources/menu/ altında durur ve öğeleri menu anahtarında listeler. Her öğe ya bir bölüm başlığıdır (section) ya da title taşıyan bir bağlantı veya gruptur. icon yalnızca en üst seviyedeki öğelerde gösterilir.

JSON
{
    "menu": [
        { "section": "Genel" },
        { "title": "Anasayfa", "icon": "home", "route": "anasayfa" },
        { "title": "Siparişler", "icon": "shopping-bag", "route": "siparisler.index", "active": "siparisler.*" },
        { "title": "Raporlar", "icon": "chart-bar", "badge": true, "children": [
            { "title": "Satış", "route": "raporlar.satis" },
            { "title": "Arşiv", "children": [
                { "title": "2025", "url": "/raporlar/arsiv/2025" }
            ] }
        ] },
        { "section": "Destek" },
        { "title": "Yardım merkezi", "icon": "lifebuoy", "url": "https://destek.ornek.com", "target": "_blank" }
    ]
}
PropDeğerler
sectionBölüm başlığı; altında öğe kalmazsa gizlenir
titleGörünen ad
iconacun:icon adı
03

Bağlantılar

route bir Laravel rota adıdır, parametreleri params ile verilir; rota tanımlı değilse bağlantı # olur. url göreli bir yol ya da tam adres alır. Menü verisi veritabanından da gelebileceği için yalnızca http, https, mailto ve tel adresleri ile göreli yollar kabul edilir; diğerleri (ör. javascript:) # olarak çizilir. "target": "_blank" bağlantıyı yeni sekmede açar ve wire:navigate kullanmaz.

JSON
{
    "menu": [
        { "title": "Anasayfa", "icon": "home", "route": "anasayfa" },
        { "title": "Müşteri kartı", "icon": "identification", "route": "musteriler.show", "params": { "musteri": 42 } },
        { "title": "Arşiv", "icon": "archive-box", "url": "/raporlar/arsiv" },
        { "title": "Destek hattı", "icon": "phone", "url": "tel:+908500000000" },
        { "title": "Yardım merkezi", "icon": "lifebuoy", "url": "https://destek.ornek.com", "target": "_blank" }
    ]
}
PropDeğerler
routeRota adı
paramsRota parametreleri
urlGöreli yol | http(s) | mailto | tel
target_blank
04

Aktif sayfa

active verilmezse route öğesi o rota açıkken, url öğesi adres birebir eşleştiğinde aktif olur; dış adresler hiçbir zaman aktif sayılmaz. Alt sayfalarda da aktif kalması için active ile rota adları ya da / ile başlayan yol desenleri verin (* joker). Aktif öğe içeren grup açık çizilir.

JSON
{
    "menu": [
        { "title": "Siparişler", "icon": "shopping-bag", "route": "siparisler.index", "active": "siparisler.*" },
        { "title": "Raporlar", "icon": "chart-bar", "url": "/raporlar", "active": ["/raporlar", "/raporlar/*"] }
    ]
}
PropDeğerler
activeRota adı | /yol deseni | bunların dizisi
05

Rozet ve alt menüler

badge öğenin sağında bir sayı ya da kısa metin gösterir; grupta true verilirse görünen alt öğe sayısı yazılır. children ile en fazla üç seviye iç içe menü kurulur; üçüncü seviyedeki öğelerin children alanı yok sayılır. Rozetler dikey ve yatay menüde, alt gruplar dahil her seviyede gösterilir.

CANLI ÖRNEK
<nav class="flex flex-col gap-0.5">
    <acun:menu :menu="[
        ['title' => 'Bildirimler', 'icon' => 'bell', 'url' => '#', 'badge' => 6],
        ['title' => 'Aktarımlar', 'icon' => 'arrow-up-tray', 'url' => '#aktarim', 'badge' => 'Yeni'],
        ['title' => 'Raporlar', 'icon' => 'chart-bar', 'badge' => true, 'children' => [
            ['title' => 'Satış', 'url' => '#satis'],
            ['title' => 'Müşteriler', 'url' => '#musteriler'],
            ['title' => 'Arşiv', 'children' => [
                ['title' => '2025', 'url' => '#2025'],
                ['title' => '2024', 'url' => '#2024'],
            ]],
        ]],
    ]" />
</nav>
PropDeğerler
badgeSayı | metin | true (alt öğe sayısı)
childrenAlt öğeler; en fazla 3 seviye
06

Düzende kullanım

Menüyü düzenin nav slot'una koyun. horizontal yatay (üst) menü çizer: bölüm başlıkları atlanır, gruplar açılır panel olur. Yatay düzende mobil çekmece için aynı dosyayı mobileNav slot'una dikey olarak verin. searchItems() menüdeki her bağlantıyı komut paleti araması için döndürür; ayrı bir arama listesi gerekmez.

BLADE
{{-- Dikey düzen: menü ve arama aynı dosyadan --}}
<acun:layout.sidebar>
    <acun:slot:nav><acun:menu menu="dikey" /></acun:slot:nav>
    <acun:slot:search>
        <acun:command-palette :items="\Acun\Ui\Menu\Menu::fromFile('dikey')->searchItems()" />
    </acun:slot:search>
    …
</acun:layout.sidebar>

{{-- Yatay düzen: üstte yatay menü, mobil çekmecede dikey menü --}}
<acun:layout.horizontal>
    <acun:slot:nav><acun:menu menu="dikey" horizontal /></acun:slot:nav>
    <acun:slot:mobileNav><acun:menu menu="dikey" /></acun:slot:mobileNav>
    …
</acun:layout.horizontal>
PropDeğerler
horizontaltrue | false
07

PHP ile kurma

Menü PHP'de Menu sınıfıyla da kurulabilir; tanım bir diziden, örneğin veritabanından gelebilir. transform her öğeye çizilmeden önce uygulanır; isActive öğenin aktif olup olmadığına karar verir, null dönerse varsayılan kural işler. Bu dokümantasyon sitesinin menüsü de bu şekilde kurulur.

PHP
use Acun\Ui\Menu\Menu;

$menu = new Menu(
    $tanim,
    // Her öğe çizilmeden önce buradan geçer: kendi alanınızı bağlantıya çevirin.
    transform: fn (array $oge) => isset($oge['modul'])
        ? ['url' => '/moduller/'.$oge['modul']] + $oge
        : $oge,
    // true / false: öğe aktif mi; null: varsayılan kurala bırak.
    isActive: fn (array $oge) => isset($oge['modul']) ? $oge['modul'] === $aktifModul : null,
);

// Blade: <acun:menu :menu="$menu" />
// Komut paleti: $menu->searchItems()
PropDeğerler
transformfn (array $oge): array
isActivefn (array $oge): ?bool
API

Prop'lar ve slot'lar

Bileşenin kabul ettiği değerler.

PropVarsayılanAçıklama
menu — Zorunlu; dosya adı (resources/menu/…json), tam yol, dizi ya da Menu nesnesi
horizontalfalseYatay (üst) menü; bölüm başlıkları gösterilmez
sectionsautoYatay menüde true her bölümü tek bir açılır menü yapar (içindeki gruplar yana açılır); false öğeleri yan yana dizer; auto 6 öğeden fazlasında bölümler
section — JSON: bölüm başlığı; yalnızca en üst seviyede
title — JSON: görünen ad
iconnullJSON: acun:icon adı; en üst seviyede gösterilir
routenullJSON: rota adı; tanımlı değilse bağlantı #
params[]JSON: rota parametreleri
urlnullJSON: göreli yol ya da http, https, mailto, tel adresi; diğerleri #
activenullJSON: rota adı ya da /yol deseni (dizi olabilir, * joker)
badgenullJSON: sayı ya da metin; grupta true = alt öğe sayısı
targetnullJSON: _blank = yeni sekme, wire:navigate kullanılmaz
children — JSON: alt öğeler; en fazla 3 seviye
Acun UI · JSON menüDetaylı kullanım ve örnekler