Seitenleiste

Das Offcanvas-Panel ist Teil der App-Shell von nfgarching/core. Die Demo zeigt hier das aktuelle Konto.

Demo-Konto

ENV: production · Package-Version 1.0.0


App-Shell

Die App-Shell von core besteht aus dem Grundlayout layout::main mit Navbar, einklappbarer Sidebar, Offcanvas-Panel und Toasts. Diese Seite ist selbst in dieser Shell gerendert – die nummerierten Bereiche unten sind die echten Bausteine rund um diesen Text.
  1. 1 Navbar – layout::parts.navbar – Brand, Einträge aus der NavbarNavigation-Registry; klappt unter 992 px in den Hamburger ein.
  2. 2 Sidebar-Toggler – Schaltet die Alpine-Variable sidebarOpen am body-Element um; die Sidebar wird ein- und ausgeblendet, main füllt dann die volle Breite.
  3. 3 Sidebar – layout::parts.sidebar – rendert nur die Bereiche der SidebarNavigation-Registry (hier: Packages und Beispiel-Package).
  4. 4 Offcanvas – layout::parts.offcanvas – Panel am rechten Rand, Toggler bleibt außerhalb der Navbar-Collapse immer sichtbar.
  5. 5 Toasts – layout::parts.toasts – reagieren auf die Browser-Events show-toast und show-message (z. B. aus Livewire per dispatch).
  6. 6 Hauptbereich – Das main-Element mit den Slots header, slot und footer von x-app-layout.

Toasts und Offcanvas auslösen

Die Toasts hören auf die Browser-Events show-toast und show-message – aus Livewire genügt ein dispatch() mit message.
resources/views/demo/core/examples/layout/toasts.blade.php
<div class="d-flex flex-wrap gap-2">
    <button type="button" class="btn btn-success"
        @click="$dispatch('show-toast', { title: 'Erfolg', subtitle: 'gerade eben', message: 'Der Datensatz wurde gespeichert.' })">
        <i class="bi bi-check-circle"></i> Toast: Erfolg
    </button>
    <button type="button" class="btn btn-warning"
        @click="$dispatch('show-toast', { title: 'Warnung', subtitle: 'bitte prüfen', message: 'Es fehlen noch Angaben.' })">
        <i class="bi bi-exclamation-triangle"></i> Toast: Warnung
    </button>
    <button type="button" class="btn btn-danger"
        @click="$dispatch('show-message', { message: 'Speichern fehlgeschlagen.' })">
        <i class="bi bi-x-octagon"></i> Meldung: Fehler
    </button>
    <button type="button" class="btn btn-outline-secondary" data-bs-toggle="offcanvas" data-bs-target="#offcanvasNavbarDark">
        <i class="bi bi-layout-sidebar-reverse"></i> Offcanvas öffnen
    </button>
</div>

Override-Pattern

Jeder Teil der Shell wird per @include eingebunden. Vorher prüft das Layout, ob die Anwendung eine eigene Variante unter resources/views/layouts/… mitbringt. So lässt sich jeder Teil überschreiben, ohne das Package zu forken.

Im Package, layouts/main.blade.php:

@if(file_exists(resource_path('views/layouts/parts/navbar.blade.php')))
    @include('layouts.parts.navbar')
@else
    @include('layout::parts.navbar')
@endif

Diese Demo überschreibt so:

  • layouts/parts/head.blade.php – Bootstrap per Vite statt CDN, Favicon je Umgebung
  • layouts/parts/script.blade.php – ohne Bootstrap-CDN, mit Demo-Banner
  • layouts/parts/navbar.blade.php – ohne Platzhalter-Suche und -Links
  • layouts/parts/sidebar.blade.php – nur Registry-Bereiche
  • layouts/parts/offcanvas.blade.php – Demo-Konto statt Server-Informationen

In der App, resources/views/layouts/parts/navbar.blade.php:

{{-- Override von layout::parts.navbar: ohne Platzhalter-Suche und Platzhalter-Links
     des Packages. Sidebar-Toggler, Brand, NavbarNavigation-Registry und
     Offcanvas-Toggler sind unverändert. --}}
<nav class="navbar navbar-expand-lg bg-body-secondary sticky-top">

    <div class="container-fluid">

        <button class="navbar-toggler collapsed" type="button" data-bs-toggle="collapse" data-bs-target="#navbarNav"
            aria-controls="navbarNav" aria-expanded="false" aria-label="{{ __('Navigation umschalten') }}">
            <span class="navbar-toggler-icon"></span>
        </button>

        <button class="btn btn-link nav-link px-2" type="button" @click="sidebarOpen = !sidebarOpen"
            aria-label="{{ __('Sidebar umschalten') }}" data-demo-hint="sidebar-toggle">
            <i class="bi fs-6" :class="sidebarOpen ? 'bi-layout-sidebar' : 'bi-layout-sidebar-inset'"></i>
        </button>

        <a class="navbar-brand col-md-3 col-lg-2 me-0 px-3 fs-6" href="{{ route('demo.home') }}">
            {{ config('app.name') }}
        </a>

        <div class="collapse navbar-collapse" id="navbarNav">
            <ul class="navbar-nav ms-auto align-items-lg-center gap-lg-2">
                @foreach (app(\Nfgarching\Core\Navigation\NavbarNavigation::class)->visibleItems() as $item)
                    @includeIf($item)
                @endforeach
            </ul>
        </div>

        <ul class="navbar-nav flex-row ms-auto ms-lg-2">
            <li class="nav-item">
                <a class="nav-link" role="button" data-bs-toggle="offcanvas" data-bs-target="#offcanvasNavbarDark"
                    aria-label="{{ __('Offcanvas öffnen') }}">
                    <span class="bi bi-three-dots-vertical"></span>
                </a>
            </li>
        </ul>

    </div>

</nav>

@if (file_exists(resource_path('views/layouts/parts/offcanvas.blade.php')))
    @include('layouts.parts.offcanvas')
@else
    @include('layout::parts.offcanvas')
@endif

Favicons

Das Package liefert mehrere Favicon-Varianten mit. Ein eigenes Icon je Umgebung zeigt schon im Browser-Tab, ob man in Produktion, Staging oder lokal arbeitet. Diese Demo wählt die Variante anhand von APP_ENV (aktuell: production).

default
favicon.ico
Produktion (neutral)
Green
faviconGreen.ico
Lokale Entwicklung
Yellow
faviconYellow.ico
Staging / Abnahme
Blue
faviconBlue.ico
Testumgebung
Red
faviconRed.ico
Wartung oder Störung
Black
faviconBlack.ico
Archiv / schreibgeschützt

Dokumentation auf GitHub (docs/layout.md)

Demo – alle Daten werden täglich zurückgesetzt.