Search by

vkm-apps / x-theme

vmphobos

Theme layout and sidebar package for Laravel 13+, Livewire 4+, and Tailwind 4+

Package info

github.com/vkm-apps/x-theme

Language:Blade

pkg:composer/vkm-apps/x-theme

Statistics

Installs: 19

Dependents: 0

Suggesters: 0

Stars: 0

v1.0.7 2026-07-14 17:48 UTC

This package is auto-updated.

Last update: 2026-10-20 03:16:36 UTC


README

Latest Version on Packagist Total Downloads Software License

A modern, highly polished, utility-driven Theme layout, responsive sidebar, and beautiful authentication layout component system built for Laravel 13+, Livewire 4+, and Tailwind CSS v4+ with Alpine.js.

🌟 Key Features

  • Three Specialized Layouts: Choose between a Base empty layout, a Hero landing-page layout, or a full Sidebar dashboard layout.
  • Responsive Sidebar Layout: Seamlessly switches between Full Width, Mini Sidebar, and Mobile Drawer modes with smooth transitions.
  • FOUC Prevention & Sync: Built-in lightweight javascript to apply Light/Dark modes instantly before the first paint, matching browser preferences or saved localStorage configurations.
  • Dynamic User Resolution: Automatically resolves names, initials, role titles, and Gravatars for authenticated Laravel users in the Sidebar.
  • SEO Best Practices: Configurable meta tags, descriptions, keywords, canonical URLs, robot crawl tags (noindex), and favicon loading built directly into the layout.
  • Auth Flow Layouts: Clean, responsive, and stunning authorization screen templates supporting Centered Card and Split-Screen layouts with mesh/radial gradients and background parallax scaling.
  • Tailwind v4 Optimized: Uses cutting-edge Tailwind CSS v4 properties (such as HSL palettes, smooth backdrop filters, and CSS variables) for maximum style flexibility.
  • Adaptive Rounded Overrides: Allows overriding app-wide rounding aesthetics (none, sm, lg) dynamically from layout parameters.
  • Importable JavaScript: All layout JS logic is in resources/js/theme.js so you can import it into your own JS bundles.

🚀 Installation

1. Require the Package via Composer

Install the package using Composer:

composer require vkm-apps/x-theme

2. Publish Views and Assets

To publish the package's customizable Blade views or its CSS/JS assets, run:

# Publish both views & assets
php artisan vendor:publish --provider="VkmApps\XTheme\XThemeServiceProvider"

# Or publish them selectively using tags
php artisan vendor:publish --tag=x-theme-views
php artisan vendor:publish --tag=x-theme-assets

Published files will be copied to:

  • Views: resources/views/vendor/x-theme/
  • CSS: public/vendor/x-theme/css/theme.css
  • JS: public/vendor/x-theme/js/theme.js

🎨 Styling & Asset Integration

CSS (Tailwind CSS v4)

The package uses custom styles in resources/css/theme.css for advanced transitions, scrollbars, and teleported menus.

Method A: Direct CSS Import (Recommended)

Add the following line to your host application's main CSS entry point (usually resources/css/app.css):

@import "../../public/vendor/x-theme/css/theme.css";

Note: Make sure you publish the assets tag x-theme-assets so this file is available in the public directory.

Method B: Layout CSS Stack

Include the CSS file dynamically inside the layout's stylesheet stack:

@push('css')
    <link rel="stylesheet" href="{{ asset('vendor/x-theme/css/theme.css') }}">
@endpush

JavaScript

The package's AlpineJS layout state and Theme controller are externalized to resources/js/theme.js.

Method A: Direct Import (Recommended)

Import the JS file in your application's main JS entry point (usually resources/js/app.js):

// Import directly from the vendor package
import '../../vendor/vkm-apps/x-theme/resources/js/theme.js';

// Or if you published the assets:
// import '../../public/vendor/x-theme/js/theme.js';

Method B: Published Asset Script Tag

If not using a bundler, include the published JS file via a <script> tag:

@push('page-js')
    <script src="{{ asset('vendor/x-theme/js/theme.js') }}"></script>
@endpush

🎨 Theme Variables & Body Customization

The layout's body background and text colors are powered by CSS variables in theme.css. You can customize these variables in your host application's CSS entry point:

:root {
    --theme-light-bg: #f9fafb;     /* Custom light background */
    --theme-light-text: #111827;   /* Custom light text color */
    --theme-dark-bg: #0f172a;      /* Custom dark background */
    --theme-dark-text: #f8fafc;    /* Custom dark text color */
}

Any class attribute passed directly to <x-layout... class="..."> (e.g. class="bg-zinc-100 font-sans") will merge into the <body> element and take precedence over these variables.

🛠️ Component Catalog & Usage Guide

1. Base Layout (<x-layout>)

An empty layout wrapper with no sidebar or navigation by default. If a menu slot is provided, it renders a responsive top navigation bar with a mobile drawer.

When to Use

  • Simple content pages with optional top navigation.
  • Pages that need a clean, minimal wrapper.

Available Properties

Property Type Default Description
title string null Appends page title ahead of your app.name configuration.
metaDescription string null Custom description for SEO meta tag.
metaKeywords string null Custom keywords for SEO.
noIndex boolean false Injects <meta name="robots" content="noindex, nofollow"> when set to true.
canonicalUrl string current url Canonical URL element. Defaults to the current request path.
favicon string null Path to favicon asset file.
mobile boolean true Allows enabling/disabling the drawer viewport toggle logic on smaller screens.
bottom boolean false Switches the sticky navigation bar to the bottom of the viewport.
rounded string 'lg' Overrides UI component corners. Allowed options: 'none', 'sm', 'lg'.
defaultTheme string 'light' The default landing theme if no selection is saved in localStorage (e.g. 'dark').
themeToggle boolean true Show or hide the theme toggle buttons (and user switcher in sidebar).

Code Example: With Menu

<x-layout title="Home">
    <x-slot:logoLarge>
        <span class="text-xl font-bold text-indigo-600">My App</span>
    </x-slot:logoLarge>

    <x-slot:menu>
        <a href="/docs" class="text-sm font-semibold hover:text-indigo-600">Docs</a>
        <a href="/support" class="text-sm font-semibold hover:text-indigo-600">Support</a>
    </x-slot:menu>

    <div class="py-6 px-4 sm:px-6 lg:px-8">
        <h1 class="text-2xl font-bold">Welcome!</h1>
    </div>
</x-layout>

Code Example: Without Menu (Bare Layout)

<x-layout title="Landing Page">
    <div class="flex items-center justify-center min-h-screen">
        <h1 class="text-4xl font-bold">Hello World</h1>
    </div>
</x-layout>

2. Hero Layout (<x-layout.hero>)

A minimal layout with a transparent top bar containing the logo on the left and a dark/light mode toggle on the right. No sidebar or menus.

When to Use

  • Landing pages and marketing pages.
  • Hero sections with custom backgrounds.
  • Pages where you want full control over the body styling.

Code Example

<x-layout.hero title="Welcome" class="bg-zinc-50 dark:bg-zinc-950">
    <x-slot:logoLarge>
        <span class="text-xl font-bold text-indigo-600">Brand</span>
    </x-slot:logoLarge>

    <div class="m-auto container bg-white dark:bg-zinc-900 rounded-2xl p-8 mt-4">
        <h1 class="text-4xl font-bold">Hero Section</h1>
        <p class="mt-4 text-zinc-600 dark:text-zinc-400">
            Style the body and content however you need.
        </p>
    </div>

    <x-slot:footer>
        <footer class="py-6 text-center text-sm text-zinc-500">
            © 2026 My Company
        </footer>
    </x-slot:footer>
</x-layout.hero>

Tip: The hero layout does not apply default background colors to the <body>. Pass your own classes directly on the component (e.g. class="bg-white dark:bg-zinc-950") to control the page background.

3. Sidebar Layout (<x-layout.sidebar>)

The full responsive sidebar dashboard layout. Supports collapsible sidebar, top navigation bar with hamburger toggle, and dark/light mode switching.

When to Use

  • Admin dashboards and panels.
  • Application layouts with sidebar navigation.

Code Example

<x-layout.sidebar 
    title="Dashboard" 
    meta-description="Management panel overview page"
    rounded="lg"
>
    <!-- Logo Slots -->
    <x-slot:logoSmall>
        <img src="/logo-small.svg" alt="Logo Icon" class="size-6">
    </x-slot:logoSmall>
    
    <x-slot:logoLarge>
        <span class="text-xl font-bold tracking-tight text-indigo-600">Phobos Panel</span>
    </x-slot:logoLarge>

    <!-- Top Right Navbar Links -->
    <x-slot:navbarMenu>
        <a href="/docs" class="text-sm font-semibold hover:text-indigo-600">Documentation</a>
        <a href="/support" class="text-sm font-semibold hover:text-indigo-600">Help Desk</a>
    </x-slot:navbarMenu>

    <!-- Sidebar Wrapper Placement -->
    <x-slot:sidebar>
        <x-sidebar>
            <!-- Navigation Links -->
            <x-slot:nav>
                <x-sidebar-item href="/dashboard" icon="fa-solid fa-house" :active="request()->is('dashboard')">
                    Overview
                </x-sidebar-item>

                <!-- Accordion Menu Section -->
                <x-sidebar-group title="Administration" icon="fa-solid fa-users-gear" :active="request()->is('admin/*')">
                    <x-sidebar-item href="/admin/users" :active="request()->is('admin/users')">
                        User Directory
                    </x-sidebar-item>
                    <x-sidebar-item href="/admin/roles" :active="request()->is('admin/roles')">
                        Roles & Permissions
                    </x-sidebar-item>
                </x-sidebar-group>
            </x-slot:nav>
        </x-sidebar>
    </x-slot:sidebar>

    <!-- Main Content -->
    <div class="py-6 px-4 sm:px-6 lg:px-8">
        <h1 class="text-2xl font-bold text-zinc-900 dark:text-white">Welcome back!</h1>
        <p class="text-zinc-500 mt-1">Here is what is happening with your projects today.</p>
    </div>
</x-layout.sidebar>

4. The Sidebar Component (<x-sidebar>)

Builds the collapsible navigation structure. Displays brand logo options, scrollable links, user profiles, and dropdown options.

Automatic User Resolving

If a user is logged in via Laravel's Auth facade, the component will:

  • Parse auth()->user()->name for the display title.
  • Auto-generate name initials (e.g. "John Doe" $\rightarrow$ "JD") if no image is available.
  • Scan for common profile image fields (like avatar or profile_photo_url) and fall back to Gravatar profile photos.
  • Auto-resolve roles from properties (e.g. role_name, role->title, role->name).

Available Properties

Property Type Default Description
photo string null Overrides the profile picture source URL.
title string null Overrides user name display.
role string null Overrides user subtitle/role field.
showUserMenu boolean true Show or hide the bottom user panel card.
homeUrl string '/' Target redirect URL for the brand logos.

Customizing User Dropdown Actions

You can define slots to appear inside the Alpine-anchored popup profile menu:

<x-sidebar>
    <x-slot:nav>
        <!-- Sidebar items -->
    </x-slot:nav>

    <!-- Bottom User Menu Dropdown Actions -->
    <x-slot:userMenu>
        <a href="/profile" class="dropdown-item">
            <i class="fa-solid fa-user-gear"></i>
            <span>My Profile</span>
        </a>
        <form method="POST" action="/logout" class="w-full">
            @csrf
            <button type="submit" class="dropdown-item text-red-600 dark:text-red-400">
                <i class="fa-solid fa-power-off"></i>
                <span>Sign Out</span>
            </button>
        </form>
    </x-slot:userMenu>
</x-sidebar>

5. Sidebar Navigation Group & Item (<x-sidebar-group>, <x-sidebar-item>)

These structural utility components build the menu lists.

SVG Icon Injection Support

Both sidebar-group and sidebar-item allow you to inject standard icon class definitions (like FontAwesome, Bootstrap, or Lucide Icons) or custom raw <svg> tags directly:

<!-- Font Icon Usage -->
<x-sidebar-item href="/stats" icon="fa-solid fa-chart-line">
    Statistics
</x-sidebar-item>

<!-- Inline SVG Injection Usage -->
<x-sidebar-item href="/billing" :active="request()->is('billing')">
    <x-slot:icon>
        <svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor">
            <path stroke-linecap="round" stroke-linejoin="round" d="M2.5 8.5h19m-19 4h19m-19 4h19" />
        </svg>
    </x-slot:icon>
    Billing Panel
</x-sidebar-item>

6. Auth Card Components

Provides responsive layouts with full theme switcher support. Supports split-screen backgrounds or simple centered forms with blur overlays.

<x-auth.card> Layout Options

  • Centered Card Mode (Default): A layout with glassmorphic backdrop filters, tech grids, and animated pulsing radial light blobs.
  • Split-Screen Mode: Left visual panel supporting customizable hero images or mesh-gradient loops; Right panel housing input fields. Enable this by passing the split-screen attribute.

Components List

  • <x-auth.login>
  • <x-auth.register>
  • <x-auth.forgot-password>
  • <x-auth.reset-password>

Configuration Properties

Property Type Default Description
image string null Background image asset URL for the visual hero section.
action string null Action URL for the <form> POST. Automatically loads a loading indicator.
btnStyles string null Add custom utility overrides to style the submit button.
splitScreen boolean false Toggle between centered-glass card and modern split screens.
title string 'Welcome back' Header title text.
subtitle string null Header instructions subtitle.
submitText string 'Sign in' Label inside the submission button.

Code Example (Split-Screen Login View)

<x-auth.login
    action="/login"
    image="/images/auth-backdrop.jpg"
    split-screen="true"
    title="Sign In to System"
    subtitle="Please enter your authentication details below."
    submit-text="Authenticate"
>
    <!-- Logo Slot -->
    <x-slot:logo>
        <span class="font-extrabold text-2xl tracking-wider text-white">MY APP</span>
    </x-slot:logo>

    <!-- Form Input Fields -->
    <div class="space-y-1">
        <label for="email" class="block text-xs font-bold text-zinc-500 uppercase">Email Address</label>
        <input type="email" name="email" id="email" required class="w-full px-3 py-2 border rounded-xl dark:bg-zinc-900 border-zinc-200 dark:border-zinc-800 focus:outline-indigo-500">
    </div>

    <div class="space-y-1">
        <label for="password" class="block text-xs font-bold text-zinc-500 uppercase">Password</label>
        <input type="password" name="password" id="password" required class="w-full px-3 py-2 border rounded-xl dark:bg-zinc-900 border-zinc-200 dark:border-zinc-800 focus:outline-indigo-500">
    </div>

    <!-- Optional Custom Footers -->
    <x-slot:footer>
        <div class="flex items-center justify-between text-xs font-semibold text-zinc-400">
            <a href="/register" class="hover:underline">Create Account</a>
            <a href="/password/reset" class="hover:underline">Forgot Password?</a>
        </div>
    </x-slot:footer>
</x-auth.login>

🔒 Security

If you discover any security-related issues, please email instead of using the issue tracker.

📄 License

The MIT License (MIT). Please see License File for more information.