DXDashboard

DXDashboard

Complete dashboard layout component that combines sidebar navigation, top navbar, and content area. Handles all state management and provides extensive customisation through slots.

Live Examples

Props

NameTypeRequiredDefaultDescription
navigationNavigationNorequiredNavigation structure with groups and items
currentUrlstringNorequiredCurrent URL path for active state detection
titlestringNo'Dashboard'Dashboard title shown in sidebar brand
pageTitlestringNo''Page title shown in navbar
user{ name: string; email: string } | nullNonullUser object for navbar dropdown
logoutUrlstringNo'/logout'Logout URL for navbar dropdown
storageKeystringNo'dashboard-sidebar-hidden'LocalStorage key for sidebar state persistence

Slots

NameDescriptionScoped Props
defaultMain page content rendered in the content area-
sidebar-brandCustom brand/logo content for sidebar header-
sidebar-linkCustom link rendering in sidebar navigation-
navbar-menu-iconCustom hamburger menu icon for navbar-
navbar-searchCustom search component for navbar-
navbar-user-iconCustom user icon/avatar in navbar dropdown-
navbar-user-menuCustom user dropdown menu content-

Features

  • Combined Layout - Integrates DXDashboardSidebar and DXDashboardNavbar
  • State Management - Handles sidebar toggle and localStorage persistence
  • Responsive - Works on mobile and desktop
  • Customisable - Extensive slot system for customisation
  • Type-Safe - Full TypeScript support with proper types

Usage Example

Basic Usage

<template>
  <DXDashboard
    :navigation="navigation"
    :current-url="route.path"
    title="My Application"
    :page-title="pageTitle"
    :user="authUser"
  >
    <!-- Your page content here -->
    <h1>Welcome to the Dashboard</h1>
  </DXDashboard>
</template>

<script setup lang="ts">
import { DXDashboard } from '@omnitend/dashboard-for-laravel';

const navigation = [
  {
    label: 'Main',
    items: [
      { label: 'Dashboard', url: '/dashboard' },
      { label: 'Customers', url: '/customers' },
    ],
  },
];

const authUser = { name: 'John Doe', email: 'john@example.com' };
const pageTitle = 'Dashboard';
</script>

With Icons

Navigation items can include icons using unplugin-icons or any Vue component:

<script setup lang="ts">
import { DXDashboard } from '@omnitend/dashboard-for-laravel';
import IconHome from '~icons/lucide/home';
import IconUsers from '~icons/lucide/users';
import IconSettings from '~icons/lucide/settings';

const navigation = [
  {
    items: [
      { label: 'Dashboard', url: '/dashboard', icon: IconHome },
      { label: 'Customers', url: '/customers', icon: IconUsers },
    ],
  },
  {
    label: 'Settings',
    items: [
      { label: 'Preferences', url: '/settings', icon: IconSettings },
    ],
  },
];
</script>

Icon Setup (unplugin-icons):

Install packages:

npm install --save-dev unplugin-icons @iconify-json/lucide

Configure in vite.config.ts:

import Icons from 'unplugin-icons/vite';

export default defineConfig({
  plugins: [
    Icons({
      compiler: 'vue3',
    }),
  ],
});

Then import icons using the ~icons/ prefix:

import IconName from '~icons/lucide/icon-name';

Custom Branding

<DXDashboard :navigation="navigation" current-url="/dashboard">
  <template #sidebar-brand="{ collapsed }">
    <div class="d-flex align-items-center">
      <img v-if="!collapsed" src="/logo.svg" alt="Logo" />
      <span v-else>L</span>
    </div>
  </template>

  <!-- content -->
</DXDashboard>

Notes

This component requires CSS for sidebar visibility control. Add this to your global styles or layout:

.dashboard-sidebar {
  display: none !important;
}

html.sidebar-visible .dashboard-sidebar {
  display: block !important;
}

For Astro projects with SSR, add an inline script to prevent flicker:

<script is:inline>
  (function() {
    try {
      const hidden = localStorage.getItem('dashboard-sidebar-hidden');
      if (hidden === 'false') {
        document.documentElement.classList.add('sidebar-visible');
      }
    } catch (e) {}
  })();
</script>