Dashboard-Seitenleiste

GitHub
Eine skalierbare und zusammenklappbare Seitenleiste, die in einem Dashboard angezeigt wird.

Bearbeiten

Die DashboardSidebar-Komponente wird verwendet, um eine Seitenleiste in einem Dashboard-Layout anzuzeigen. Es unterstützt Drag-to-Size, State-Persistenz und integriert sich mit DashboardGroup, DashboardPanel und DashboardNavbar.

DashboardSidebar vs Sidebar: Diese Komponente wurde für Dashboard-Layouts mit Drag-to-Size, State-Persistenz und DashboardGroup-Integration entwickelt. Für eine einfache, eigenständige Seitenleiste (Chat-Panel, Einstellungen, Navigation) verwenden Sie stattdessen Sidebar.

Sein Status (Größe, zusammengeklappt usw.) wird basierend auf den storage-und storage-key-Props gespeichert, die Sie der DashboardGroup-Komponente zur Verfügung stellen.

Verwenden Sie es innerhalb des Standardsteckplatzes der Komponente DashboardGroup:

layouts/dashboard.vue
<template>
  <UDashboardGroup>
    <UDashboardSidebar />

    <slot />
  </UDashboardGroup>
</template>
Diese Komponente hat kein einziges Root-Element, wenn Sie die resizable-Prop verwenden, also wickeln Sie es in einen Container (z. B. <div class="flex flex-1">), wenn Sie Seitenübergänge verwenden oder eine einzelne Root für das Layout benötigen.

Verwenden Sie die Slots header, default und footer, um die Seitenleiste und die Slots body oder content anzupassen, um das Menü der Seitenleiste anzupassen.

<script setup lang="ts">
import type { NavigationMenuItem } from '@nuxt/ui'

const items: NavigationMenuItem[][] = [[{
  label: 'Home',
  icon: 'i-lucide-house',
  active: true
}, {
  label: 'Inbox',
  icon: 'i-lucide-inbox',
  badge: '4'
}, {
  label: 'Contacts',
  icon: 'i-lucide-users'
}, {
  label: 'Settings',
  icon: 'i-lucide-settings',
  defaultOpen: true,
  children: [{
    label: 'General'
  }, {
    label: 'Members'
  }, {
    label: 'Notifications'
  }]
}], [{
  label: 'Feedback',
  icon: 'i-lucide-message-circle',
  to: 'https://github.com/nuxt-ui-templates/dashboard',
  target: '_blank'
}, {
  label: 'Help & Support',
  icon: 'i-lucide-info',
  to: 'https://github.com/nuxt/ui',
  target: '_blank'
}]]
</script>

<template>
  <UDashboardSidebar collapsible resizable :ui="{ footer: 'border-t border-default' }">
    <template #header="{ collapsed }">
      <Logo v-if="!collapsed" class="h-5 w-auto shrink-0" />
      <UIcon v-else name="i-simple-icons-nuxtdotjs" class="size-5 text-primary mx-auto" />
    </template>

    <template #default="{ collapsed }">
      <UButton
        :label="collapsed ? undefined : 'Search...'"
        icon="i-lucide-search"
        color="neutral"
        variant="outline"
        block
        :square="collapsed"
      >
        <template v-if="!collapsed" #trailing>
          <div class="flex items-center gap-0.5 ms-auto">
            <UKbd value="meta" variant="subtle" />
            <UKbd value="K" variant="subtle" />
          </div>
        </template>
      </UButton>

      <UNavigationMenu
        :collapsed="collapsed"
        :items="items[0]"
        orientation="vertical"
      />

      <UNavigationMenu
        :collapsed="collapsed"
        :items="items[1]"
        orientation="vertical"
        class="mt-auto"
      />
    </template>

    <template #footer="{ collapsed }">
      <UButton
        :avatar="{
          src: 'https://github.com/benjamincanac.png',
          loading: 'lazy' as const
        }"
        :label="collapsed ? undefined : 'Benjamin'"
        color="neutral"
        variant="ghost"
        class="w-full"
        :block="collapsed"
      />
    </template>
  </UDashboardSidebar>
</template>
Ziehen Sie die Seitenleiste in die Nähe des linken Randes des Bildschirms, um sie zu reduzieren.

Resizable (nicht verfügbar)

Verwenden Sie die resizable-Prop, um die Seitenleiste in der Größe anzupassen.

<template>
  <UDashboardSidebar resizable>
    <Placeholder class="h-96" />
  </UDashboardSidebar>
</template>

Collapsible (nicht verfügbar)

Verwenden Sie die collapsible-Stütze, um die Seitenleiste zusammenklappbar zu machen, wenn Sie sie in die Nähe des Bildschirmrandes ziehen.

Die Komponente DashboardSidebarCollapse hat keine Auswirkungen, wenn die Seitenleiste nicht collapsible ist.
<template>
  <UDashboardSidebar resizable collapsible>
    <Placeholder class="h-96" />
  </UDashboardSidebar>
</template>
Sie können auf den collapsed-Status in den Slot-Requisiten zugreifen, um den Inhalt der Seitenleiste anzupassen, wenn sie zusammengeklappt wird.

Größe

Verwenden Sie die min-size, max-size, default-size und collapsed-size Requisiten, um die Größe der Seitenleiste anzupassen.

<template>
  <UDashboardSidebar
    resizable
    collapsible
    :min-size="22"
    :default-size="35"
    :max-size="40"
    :collapsed-size="0"
  >
    <Placeholder class="h-96" />
  </UDashboardSidebar>
</template>
Größen werden standardmäßig als Prozentsätze berechnet. Sie können dies mit der unit-Prop auf der DashboardGroup-Komponente ändern.
Die collapsed-size prop ist standardmäßig auf 0 eingestellt, aber die Seitenleiste hat eine min-w-16, um sicherzustellen, dass sie sichtbar ist.

Side Seite

Verwenden Sie die side-Prop, um die Seite der Seitenleiste zu ändern. Standardmäßig left.

<template>
  <UDashboardSidebar side="right" resizable collapsible>
    <Placeholder class="h-96" />
  </UDashboardSidebar>
</template>

Mode Bearbeiten

Verwenden Sie die mode-Prop, um den Modus des Sidebar-Menüs zu ändern. Standardmäßig slideover.

Verwenden Sie den body-Steckplatz, um den Menükörper (unter der Kopfzeile) oder den content-Steckplatz zu füllen, um das gesamte Menü zu füllen.

Sie können die menu prop verwenden, um das Menü der Seitenleiste anzupassen, es wird je nach dem von Ihnen gewählten Modus angepasst.
<script setup lang="ts">
import type { NavigationMenuItem } from '@nuxt/ui'

defineProps<{
  mode: 'drawer' | 'slideover' | 'modal'
}>()

const items: NavigationMenuItem[] = [{
  label: 'Home',
  icon: 'i-lucide-house',
  active: true
}, {
  label: 'Inbox',
  icon: 'i-lucide-inbox'
}, {
  label: 'Contacts',
  icon: 'i-lucide-users'
}]
</script>

<template>
  <UDashboardGroup>
    <UDashboardSidebar :mode="mode">
      <template #header="{ collapsed }">
        <Logo v-if="!collapsed" class="h-5 w-auto" />
        <UIcon v-else name="i-simple-icons-nuxtdotjs" class="size-5 text-primary mx-auto" />
      </template>

      <UNavigationMenu
        :items="items"
        orientation="vertical"
      />
    </UDashboardSidebar>

    <UDashboardPanel>
      <template #header>
        <UDashboardNavbar title="Dashboard" />
      </template>
    </UDashboardPanel>
  </UDashboardGroup>
</template>
Diese Beispiele enthalten die Komponenten DashboardGroup, DashboardPanel und [DashboardNavbar](](/docs/components/dashboard-navbar), da sie zur Demonstration der Seitenleiste auf Mobilgeräten erforderlich sind.

Toggle

Verwenden Sie die toggle-Prop, um die DashboardSidebarToggle-Komponente anzupassen, die auf dem Handy angezeigt wird.

Sie können jede Eigenschaft aus der Komponente Button übergeben, um sie anzupassen.

<script setup lang="ts">
import type { NavigationMenuItem } from '@nuxt/ui'

const items: NavigationMenuItem[] = [{
  label: 'Home',
  icon: 'i-lucide-house',
  active: true
}, {
  label: 'Inbox',
  icon: 'i-lucide-inbox'
}, {
  label: 'Contacts',
  icon: 'i-lucide-users'
}]
</script>

<template>
  <UDashboardGroup>
    <UDashboardSidebar
      open
      :toggle="{
        color: 'primary',
        variant: 'subtle',
        class: 'rounded-full'
      }"
    >
      <template #header>
        <Logo class="h-5 w-auto" />
      </template>

      <UNavigationMenu
        :items="items"
        orientation="vertical"
      />
    </UDashboardSidebar>

    <UDashboardPanel>
      <template #header>
        <UDashboardNavbar title="Dashboard" />
      </template>
    </UDashboardPanel>
  </UDashboardGroup>
</template>

Toggle Side Seite

Verwenden Sie die toggle-side-Stütze, um die Seite der Toggle-Taste zu wechseln. Standardmäßig ist left.

<script setup lang="ts">
import type { NavigationMenuItem } from '@nuxt/ui'

const items: NavigationMenuItem[] = [{
  label: 'Home',
  icon: 'i-lucide-house',
  active: true
}, {
  label: 'Inbox',
  icon: 'i-lucide-inbox'
}, {
  label: 'Contacts',
  icon: 'i-lucide-users'
}]
</script>

<template>
  <UDashboardGroup>
    <UDashboardSidebar
      open
      toggle-side="right"
    >
      <template #header>
        <Logo class="h-5 w-auto" />
      </template>

      <UNavigationMenu
        :items="items"
        orientation="vertical"
      />
    </UDashboardSidebar>

    <UDashboardPanel>
      <template #header>
        <UDashboardNavbar title="Dashboard" />
      </template>
    </UDashboardPanel>
  </UDashboardGroup>
</template>

Examples Bearbeiten

Control im offenen Zustand

Sie können den offenen Zustand mit der open-prop-oder der v-model:open-Direktive steuern.

<script setup lang="ts">
import type { NavigationMenuItem } from '@nuxt/ui'

const items: NavigationMenuItem[] = [{
  label: 'Home',
  icon: 'i-lucide-house',
  active: true
}, {
  label: 'Inbox',
  icon: 'i-lucide-inbox'
}, {
  label: 'Contacts',
  icon: 'i-lucide-users'
}]

const open = ref(true)

defineShortcuts({
  o: () => open.value = !open.value
})
</script>

<template>
  <UDashboardSidebar v-model:open="open">
    <template #header="{ collapsed }">
      <Logo v-if="!collapsed" class="h-5 w-auto" />
      <UIcon v-else name="i-simple-icons-nuxtdotjs" class="size-5 text-primary mx-auto" />
    </template>

    <UNavigationMenu
      :items="items"
      orientation="vertical"
    />
  </UDashboardSidebar>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { NavigationMenuItem } from '@nuxt/ui'

const items: NavigationMenuItem[] = [{
  label: 'Home',
  icon: 'i-lucide-house',
  active: true
}, {
  label: 'Inbox',
  icon: 'i-lucide-inbox'
}, {
  label: 'Contacts',
  icon: 'i-lucide-users'
}]

const open = ref(true)

defineShortcuts({
  o: () => open.value = !open.value
})
</script>

<template>
  <UDashboardSidebar v-model:open="open">
    <template #header="{ collapsed }">
      <Logo v-if="!collapsed" class="h-5 w-auto" />
      <UIcon v-else name="i-simple-icons-nuxtdotjs" class="size-5 text-primary mx-auto" />
    </template>

    <UNavigationMenu
      :items="items"
      orientation="vertical"
    />
  </UDashboardSidebar>
</template>
In diesem Beispiel können Sie unter Nutzung von defineShortcuts den offenen Status der DashboardSidebar umschalten, indem Sie: kbd{value="O"} drücken.

Control kollabiert

Sie können den kollabierten Zustand mit der collapsed-prop-oder der v-model:collapsed-Direktive steuern.

<script setup lang="ts">
import type { NavigationMenuItem } from '@nuxt/ui'

const items: NavigationMenuItem[] = [{
  label: 'Home',
  icon: 'i-lucide-house',
  active: true
}, {
  label: 'Inbox',
  icon: 'i-lucide-inbox'
}, {
  label: 'Contacts',
  icon: 'i-lucide-users'
}]

const collapsed = ref(false)

defineShortcuts({
  c: () => collapsed.value = !collapsed.value
})
</script>

<template>
  <UDashboardSidebar v-model:collapsed="collapsed" collapsible>
    <template #header>
      <Logo v-if="!collapsed" class="h-5 w-auto" />
      <UIcon v-else name="i-simple-icons-nuxtdotjs" class="size-5 text-primary mx-auto" />
    </template>

    <UNavigationMenu
      :collapsed="collapsed"
      :items="items"
      orientation="vertical"
    />
  </UDashboardSidebar>
</template>
<script setup lang="ts">
import { ref } from 'vue'
import type { NavigationMenuItem } from '@nuxt/ui'

const items: NavigationMenuItem[] = [{
  label: 'Home',
  icon: 'i-lucide-house',
  active: true
}, {
  label: 'Inbox',
  icon: 'i-lucide-inbox'
}, {
  label: 'Contacts',
  icon: 'i-lucide-users'
}]

const collapsed = ref(false)

defineShortcuts({
  c: () => collapsed.value = !collapsed.value
})
</script>

<template>
  <UDashboardSidebar v-model:collapsed="collapsed" collapsible>
    <template #header>
      <Logo v-if="!collapsed" class="h-5 w-auto" />
      <UIcon v-else name="i-simple-icons-nuxtdotjs" class="size-5 text-primary mx-auto" />
    </template>

    <UNavigationMenu
      :collapsed="collapsed"
      :items="items"
      orientation="vertical"
    />
  </UDashboardSidebar>
</template>
In diesem Beispiel können Sie unter Nutzung von defineShortcuts den zusammengebrochenen Zustand der DashboardSidebar durch Drücken von kbd{value="C"} umschalten.

API ist

Props Bearbeiten

Prop Default Type
mode
'slideover'
T

The mode of the sidebar menu.

menu
DashboardSidebarMenu<T>

The props for the sidebar menu component.

toggle
true
boolean | Omit<ButtonProps, LinkPropsKeys>

Customize the toggle button to open the sidebar. { color: 'neutral', variant: 'ghost' }

toggleSide
'left'
"left" | "right"

The side to render the toggle button on.

autoClose
true
boolean

Automatically close when route changes.

id
useId()
string

The id of the panel.

side
'left'
"left" | "right"

The side to render the panel on.

minSize
10
number

The minimum size of the panel.

maxSize
20
number

The maximum size of the panel.

defaultSize
15
number

The default size of the panel.

resizable
false
boolean

Whether to allow the user to resize the panel.

collapsible
false
boolean

Whether to allow the user to collapse the panel.

collapsedSize
0
number

The size of the panel when collapsed.

open
false
boolean
collapsed
false
boolean
ui
{ root?: SlotClass; header?: SlotClass; body?: SlotClass; footer?: SlotClass; toggle?: SlotClass; handle?: SlotClass; content?: SlotClass; overlay?: SlotClass; }

Slots Bearbeiten

Slot Type
header
{ collapsed: boolean; collapse: (value: boolean) => void; }
default
{ collapsed: boolean; collapse: (value: boolean) => void; }
footer
{ collapsed: boolean; collapse: (value: boolean) => void; }
toggle
{ open: boolean; toggle: () => void; ui: object; }
content
{ close?: (() => void) | undefined; }
resize-handle
{ onMouseDown: (e: MouseEvent) => void; onTouchStart: (e: TouchEvent) => void; onDoubleClick: (e: MouseEvent) => void; ui: object; }

Theme Bearbeiten

app.config.ts
export default defineAppConfig({
  ui: {
    dashboardSidebar: {
      slots: {
        root: 'relative hidden lg:flex flex-col min-h-svh min-w-16 w-(--width) shrink-0',
        header: 'h-(--ui-header-height) shrink-0 flex items-center gap-1.5 px-4',
        body: 'flex flex-col gap-4 flex-1 overflow-y-auto px-4 py-2',
        footer: 'shrink-0 flex items-center gap-1.5 px-4 py-2',
        toggle: '',
        handle: '',
        content: 'lg:hidden',
        overlay: 'lg:hidden'
      },
      variants: {
        menu: {
          true: {
            header: 'sm:px-6',
            body: 'sm:px-6',
            footer: 'sm:px-6'
          }
        },
        side: {
          left: {
            root: 'border-e border-default'
          },
          right: {
            root: ''
          }
        },
        toggleSide: {
          left: {
            toggle: ''
          },
          right: {
            toggle: 'ms-auto'
          }
        }
      }
    }
  }
})
vite.config.ts
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nuxt/ui/vite'

export default defineConfig({
  plugins: [
    vue(),
    ui({
      ui: {
        dashboardSidebar: {
          slots: {
            root: 'relative hidden lg:flex flex-col min-h-svh min-w-16 w-(--width) shrink-0',
            header: 'h-(--ui-header-height) shrink-0 flex items-center gap-1.5 px-4',
            body: 'flex flex-col gap-4 flex-1 overflow-y-auto px-4 py-2',
            footer: 'shrink-0 flex items-center gap-1.5 px-4 py-2',
            toggle: '',
            handle: '',
            content: 'lg:hidden',
            overlay: 'lg:hidden'
          },
          variants: {
            menu: {
              true: {
                header: 'sm:px-6',
                body: 'sm:px-6',
                footer: 'sm:px-6'
              }
            },
            side: {
              left: {
                root: 'border-e border-default'
              },
              right: {
                root: ''
              }
            },
            toggleSide: {
              left: {
                toggle: ''
              },
              right: {
                toggle: 'ms-auto'
              }
            }
          }
        }
      }
    })
  ]
})

Changelog (englisch)

No recent changes