Dashboardsavoir

GitHub à
Une barre latérale redimensionnable et pliable à afficher dans un tableau de bord.

Utilisation

Il prend en charge le glisser-redimensionner, la persistance de l'état et s'intègre avec DashboardGroup, [DashboardPanelxph006/docs/components/dashboard-panel) et DashboardNavbar.

DashboardSidebar vs Sidebar: Ce composant est conçu pour les mises en page de tableau de bord avec glisser-redimensionner, persistance d'état et intégration DashboardGroup.Pour une barre latérale simple et autonome (panneau de discussion, paramètres, navigation), utilisez plutôt Sidebar.

Son état (taille, effondré, etc.) sera enregistré en fonction des props storage et storage-key que vous fournissez au composant xDashboardGroup.

Utilisez-le dans l'emplacement par défaut du composant DashboardGroup:

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

    <slot />
  </UDashboardGroup>
</template>
Ce composant n'a pas un seul élément racine lorsque vous utilisez la prop resizable, donc enveloppez-le dans un conteneur (par exemple <div class="flex flex-1">) si vous utilisez des transitions de page ou si vous avez besoin d'une seule racine pour la mise en page.

Utilisez les slots header, default et footer pour personnaliser la barre latérale et les slots body ou content pour personnaliser le menu de la barre latérale.

<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>
Faites glisser la barre latérale près du bord gauche de l'écran pour l'effondrer.

Redimensionnable

Utilisez la prop resizable pour redimensionner la barre latérale.

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

Collapsible

Utilisez le prop collapsible pour rendre la barre latérale pliable lorsque vous la faites glisser près du bord de l'écran.

Le composant DashboardSidebarCollapse n'aura aucun effet si la barre latérale n'est pas collapsible.
<template>
  <UDashboardSidebar resizable collapsible>
    <Placeholder class="h-96" />
  </UDashboardSidebar>
</template>
Vous pouvez accéder à l'état collapsed dans les accessoires de l'emplacement pour personnaliser le contenu de la barre latérale lorsqu 'elle est réduite.

Size électrique

Utilisez les props min-size, max-size, default-size et collapsed-size pour personnaliser la taille de la barre latérale.

<template>
  <UDashboardSidebar
    resizable
    collapsible
    :min-size="22"
    :default-size="35"
    :max-size="40"
    :collapsed-size="0"
  >
    <Placeholder class="h-96" />
  </UDashboardSidebar>
</template>
Les tailles sont calculées en pourcentage par défaut. Vous pouvez modifier cela en utilisant la prop unit sur le composant DashboardGroup.
La prop collapsed-size est définie sur 0 par défaut, mais la barre latérale a un min-w-16 pour s'assurer qu 'elle est visible.

Side

Utilisez la prop side pour changer le côté de la barre latérale. Par défaut, left.

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

mode

Utilisez la prop mode pour changer le mode du menu de la barre latérale. Par défaut, slideover.

Utilisez l'emplacement body pour remplir le corps du menu (sous l'en-tête) ou l'emplacement content pour remplir le menu entier.

Vous pouvez utiliser le prop menu pour personnaliser le menu de la barre latérale, il s'adaptera en fonction du mode que vous choisissez.
<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>
Ces exemples contiennent les composants DashboardGroup, DashboardPanel et DashboardNavbar, car ils sont nécessaires pour montrer la barre latérale sur mobile.

Toggle

Utilisez la prop toggle pour personnaliser le composant DashboardSidebarToggle affiché sur mobile.

Vous pouvez passer n'importe quelle propriété du composant Button pour la personnaliser.

<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 côté

Utilisez la prop toggle-side pour changer le côté du bouton bascule. Par défaut, 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>

Exemples

Control état ouvert

Vous pouvez contrôler l'état ouvert à l'aide de la prop open ou de la directive v-model:open.

<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>
Dans cet exemple, en utilisant defineShortcuts, vous pouvez basculer l'état ouvert de la barre latérale du tableau de bord en appuyant sur: kbd{value="O"}.

Control État effondré

Vous pouvez contrôler l'état effondré en utilisant la prop collapsed ou la directive v-model:collapsed.

<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>
Dans cet exemple, en utilisant defineShortcuts, vous pouvez basculer l'état réduit de la barre latérale du tableau de bord en appuyant sur: kbd{value="C"}.

API

Props is

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

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; }

Thème

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

No recent changes