DashboardPanel

A resizable panel to display in a dashboard.

Usage

The DashboardPanel component is used to display a panel. Its state (size, collapsed, etc.) will be saved based on the storage and storage-key props you provide to the DashboardGroup component.

Use it inside the default slot of the DashboardGroup component, you can put multiple panels next to each other:

pages/index.vue
<script setup lang="ts">
definePageMeta({
  layout: 'dashboard'
})
</script>

<template>
  <UDashboardPanel id="inbox-1" resizable />

  <UDashboardPanel id="inbox-2" class="hidden lg:flex" />
</template>
It is recommended to set an id when using multiple panels in different pages to avoid conflicts.

Use the header, body and footer slots to customize the panel or the default slot if you don't want a scrollable body with padding.

Inbox

<template>
  <UDashboardPanel resizable>
    <template #header>
      <UDashboardNavbar title="Inbox">
        <template #leading>
          <UDashboardSidebarCollapse />
        </template>
      </UDashboardNavbar>
    </template>

    <template #body>
      <Placeholder class="h-full" />
    </template>
  </UDashboardPanel>
</template>
Most of the time, you will use the DashboardNavbar component in the header slot.

Resizable

Use the resizable prop to make the panel resizable.

<template>
  <UDashboardPanel resizable>
    <template #body>
      <Placeholder class="h-96" />
    </template>
  </UDashboardPanel>
</template>

Size

Use the min-size, max-size and default-size props to customize the size of the panel.

<template>
  <UDashboardPanel resizable>
    <template #body>
      <Placeholder class="h-96" />
    </template>
  </UDashboardPanel>
</template>

API

Props

Prop Default Type
id

useId()

string

The id of the panel.

maxSize

100

number

The maximum size of the panel.

minSize

15

number

The minimum size of the panel.

defaultSize

0

number

The default size of the panel.

resizable

false

boolean

Whether to allow the user to resize the panel.

ui

Partial<{ root: string; body: string; handle: string; }>

Slots

Slot Type
default

{}

header

{}

body

{}

footer

{}

resize-handle

{ onMouseDown: (e: MouseEvent) => void; onTouchStart: (e: TouchEvent) => void; }

Theme

app.config.ts
export default defineAppConfig({
  uiPro: {
    dashboardPanel: {
      slots: {
        root: 'flex flex-col min-w-0 min-h-svh lg:border-r lg:border-(--ui-border) shrink-0',
        body: 'flex flex-col gap-4 sm:gap-6 flex-1 overflow-y-auto p-4 sm:p-6',
        handle: ''
      },
      variants: {
        size: {
          true: {
            root: 'w-full lg:w-(--width)'
          },
          false: {
            root: 'flex-1'
          }
        }
      }
    }
  }
})
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({
      uiPro: {
        dashboardPanel: {
          slots: {
            root: 'flex flex-col min-w-0 min-h-svh lg:border-r lg:border-(--ui-border) shrink-0',
            body: 'flex flex-col gap-4 sm:gap-6 flex-1 overflow-y-auto p-4 sm:p-6',
            handle: ''
          },
          variants: {
            size: {
              true: {
                root: 'w-full lg:w-(--width)'
              },
              false: {
                root: 'flex-1'
              }
            }
          }
        }
      }
    })
  ]
})