Use a Button or any other component in the default slot of the Slideover.
Depois, use o slot #content para adicionar o conteúdo exibido quando o Slideover está aberto.
<template>
<NSlideover>
<NButton label="Open" color="neutral" variant="subtle" />
<template #content>
<Placeholder class="h-full m-4" />
</template>
</NSlideover>
</template>
Você também pode usar os slots #header, #body e #footer para personalizar o conteúdo do Slideover.
Use a prop title para definir o título do cabeçalho do Slideover.
<template>
<NSlideover title="Slideover with title">
<NButton label="Open" color="neutral" variant="subtle" />
<template #body>
<Placeholder class="h-full" />
</template>
</NSlideover>
</template>
Use a prop description para definir a descrição do cabeçalho do Slideover.
<template>
<NSlideover
title="Slideover with description"
description="Lorem ipsum dolor sit amet, consectetur adipiscing elit."
>
<NButton label="Open" color="neutral" variant="subtle" />
<template #body>
<Placeholder class="h-full" />
</template>
</NSlideover>
</template>
Use a prop close para personalizar ou ocultar o botão de fechar (com o valor false) exibido no cabeçalho do Slideover.
Você pode passar qualquer propriedade do componente Button para personalizá-lo.
<template>
<NSlideover
title="Slideover with close button"
:close="{
color: 'primary',
variant: 'outline',
class: 'rounded-full'
}"
>
<NButton label="Open" color="neutral" variant="subtle" />
<template #body>
<Placeholder class="h-full" />
</template>
</NSlideover>
</template>
#content for usado, pois ele faz parte do cabeçalho.Use a prop close-icon para personalizar o Icon do botão de fechar. O padrão é i-lucide-x.
<template>
<NSlideover title="Slideover with close button" close-icon="i-lucide-arrow-right">
<NButton label="Open" color="neutral" variant="subtle" />
<template #body>
<Placeholder class="h-full" />
</template>
</NSlideover>
</template>
Use a prop side para definir o lado da tela de onde o Slideover vai deslizar. O padrão é right.
<template>
<NSlideover side="left" title="Slideover with side">
<NButton label="Open" color="neutral" variant="subtle" />
<template #body>
<Placeholder class="h-full min-h-48" />
</template>
</NSlideover>
</template>
Use a prop inset para recuar o Slideover em relação às bordas.
<template>
<NSlideover side="right" inset title="Slideover with inset">
<NButton label="Open" color="neutral" variant="subtle" />
<template #body>
<Placeholder class="min-w-96 min-h-96 size-full" />
</template>
</NSlideover>
</template>
Use a prop transition para controlar se o Slideover é animado ou não. O padrão é true.
<template>
<NSlideover :transition="false" title="Slideover without transition">
<NButton label="Open" color="neutral" variant="subtle" />
<template #body>
<Placeholder class="h-full" />
</template>
</NSlideover>
</template>
Use a prop overlay para controlar se o Slideover tem um overlay ou não. O padrão é true.
<template>
<NSlideover :overlay="false" title="Slideover without overlay">
<NButton label="Open" color="neutral" variant="subtle" />
<template #body>
<Placeholder class="h-full" />
</template>
</NSlideover>
</template>
Use a prop modal para controlar se o Slideover bloqueia a interação com o conteúdo externo. O padrão é true.
modal é definido como false, o overlay é automaticamente desabilitado e o conteúdo externo se torna interativo.<template>
<NSlideover :modal="false" title="Slideover interactive">
<NButton label="Open" color="neutral" variant="subtle" />
<template #body>
<Placeholder class="h-full" />
</template>
</NSlideover>
</template>
Use a prop dismissible para controlar se o Slideover pode ser dispensado ao clicar fora dele ou pressionar escape. O padrão é true.
close:prevent será emitido quando o usuário tentar fechá-lo.modal: false com dismissible: false para tornar o fundo do Slideover interativo sem fechá-lo.<template>
<NSlideover :dismissible="false" title="Slideover non-dismissible">
<NButton label="Open" color="neutral" variant="subtle" />
<template #body>
<Placeholder class="h-full" />
</template>
</NSlideover>
</template>
Use a prop unmount-on-hide para evitar que o conteúdo do Slideover seja desmontado quando ele é fechado. O padrão é true.
<template>
<NSlideover :unmount-on-hide="false" title="Slideover">
<NButton label="Open" color="neutral" variant="subtle" />
<template #body>
<Placeholder class="h-full" />
</template>
</NSlideover>
</template>
portal é definida como false, o conteúdo também é renderizado no servidor. Isso é útil para renderizar um Slideover aberto durante o SSR sem uma piscada no carregamento da página, ou para expor seu conteúdo para SEO.Você pode controlar o estado de abertura usando a prop default-open ou a diretiva v-model:open.
defineShortcuts, você pode abrir e fechar o Slideover pressionando O.Você pode usar o composable useOverlay para abrir um Slideover programaticamente.
App, que usa o componente OverlayProvider.Primeiro, crie um componente de slideover que será aberto programaticamente:
close quando o slideover é fechado ou dispensado. Você pode emitir qualquer dado por meio do evento close, porém o evento precisa ser emitido para que o valor de retorno seja capturado.Depois, use-o no seu app:
emit('close').Você pode aninhar slideovers uns dentro dos outros.
Use o slot #footer para adicionar conteúdo após o corpo do Slideover.
| Prop | Default | Type |
|---|---|---|
title | string | |
description | string | |
content | DialogContentProps & Partial<EmitsToProps<DialogContentImplEmits>>The content of the slideover. | |
overlay | true | boolean Render an overlay behind the slideover. |
transition | true | boolean Animate the slideover when opening or closing. |
side | 'right' | "right" | "top" | "bottom" | "left"The side of the slideover. |
inset | false | boolean Whether to inset the slideover from the edges. |
portal | true | string | false | true | HTMLElementRender the slideover in a portal. |
close | true | boolean | Omit<ButtonProps, LinkPropsKeys> Display a close button to dismiss the slideover.
|
closeIcon | appConfig.ui.icons.close | anyThe icon displayed in the close button. |
dismissible | true | boolean When |
open | boolean The controlled open state of the dialog. Can be binded as | |
defaultOpen | boolean The open state of the dialog when it is initially rendered. Use when you do not need to control its open state. | |
modal | true | boolean The modality of the dialog When set to |
unmountOnHide | true | boolean When set to |
ui | { overlay?: SlotClass; content?: SlotClass; header?: SlotClass; wrapper?: SlotClass; body?: SlotClass; footer?: SlotClass; title?: SlotClass; description?: SlotClass; close?: SlotClass; loading?: SlotClass; } |
| Slot | Type |
|---|---|
default | { open: boolean; } |
content | { close: () => void; } |
header | { close: () => void; } |
title | {} |
description | {} |
actions | {} |
close | { ui: object; } |
body | { close: () => void; } |
footer | { close: () => void; } |
| Event | Type |
|---|---|
leave | [] |
after:leave | [] |
enter | [] |
after:enter | [] |
close:prevent | [] |
update:open | [value: boolean] |
export default defineAppConfig({
ui: {
slideover: {
slots: {
overlay: 'fixed inset-0 bg-secondary/75',
content: 'fixed bg-default divide-y divide-default sm:ring ring-default sm:shadow-lg flex flex-col focus:outline-none',
header: 'flex items-center gap-1.5 p-4 sm:px-6 min-h-(--ui-header-height)',
wrapper: '',
body: 'flex-1 overflow-y-auto p-4 sm:p-6',
footer: 'flex items-center gap-1.5 p-4 sm:px-6',
title: 'text-highlighted font-semibold',
description: 'mt-1 text-muted text-sm',
close: 'absolute top-4 end-4',
loading: 'w-full h-full flex justify-center items-center'
},
variants: {
side: {
top: {
content: ''
},
right: {
content: 'max-w-md'
},
bottom: {
content: ''
},
left: {
content: 'max-w-md'
}
},
inset: {
true: {
content: 'rounded-lg'
}
},
transition: {
true: {
overlay: 'data-[state=open]:animate-[fade-in_200ms_ease-out] data-[state=closed]:animate-[fade-out_200ms_ease-in]'
}
}
},
compoundVariants: [
{
side: 'top',
inset: true,
class: {
content: 'max-h-[calc(100%-2rem)] inset-x-4 top-4'
}
},
{
side: 'top',
inset: false,
class: {
content: 'max-h-full inset-x-0 top-0'
}
},
{
side: 'right',
inset: true,
class: {
content: 'w-[calc(100%-2rem)] inset-y-4 right-4'
}
},
{
side: 'right',
inset: false,
class: {
content: 'w-full inset-y-0 right-0'
}
},
{
side: 'bottom',
inset: true,
class: {
content: 'max-h-[calc(100%-2rem)] inset-x-4 bottom-4'
}
},
{
side: 'bottom',
inset: false,
class: {
content: 'max-h-full inset-x-0 bottom-0'
}
},
{
side: 'left',
inset: true,
class: {
content: 'w-[calc(100%-2rem)] inset-y-4 left-4'
}
},
{
side: 'left',
inset: false,
class: {
content: 'w-full inset-y-0 left-0'
}
},
{
transition: true,
side: 'top',
class: {
content: 'data-[state=open]:animate-[slide-in-from-top_200ms_ease-in-out] data-[state=closed]:animate-[slide-out-to-top_200ms_ease-in-out]'
}
},
{
transition: true,
side: 'right',
class: {
content: 'data-[state=open]:animate-[slide-in-from-right_200ms_ease-in-out] data-[state=closed]:animate-[slide-out-to-right_200ms_ease-in-out]'
}
},
{
transition: true,
side: 'bottom',
class: {
content: 'data-[state=open]:animate-[slide-in-from-bottom_200ms_ease-in-out] data-[state=closed]:animate-[slide-out-to-bottom_200ms_ease-in-out]'
}
},
{
transition: true,
side: 'left',
class: {
content: 'data-[state=open]:animate-[slide-in-from-left_200ms_ease-in-out] data-[state=closed]:animate-[slide-out-to-left_200ms_ease-in-out]'
}
}
]
}
}
})
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import ui from '@nitro/ui/vite'
export default defineConfig({
plugins: [
vue(),
ui({
ui: {
slideover: {
slots: {
overlay: 'fixed inset-0 bg-secondary/75',
content: 'fixed bg-default divide-y divide-default sm:ring ring-default sm:shadow-lg flex flex-col focus:outline-none',
header: 'flex items-center gap-1.5 p-4 sm:px-6 min-h-(--ui-header-height)',
wrapper: '',
body: 'flex-1 overflow-y-auto p-4 sm:p-6',
footer: 'flex items-center gap-1.5 p-4 sm:px-6',
title: 'text-highlighted font-semibold',
description: 'mt-1 text-muted text-sm',
close: 'absolute top-4 end-4',
loading: 'w-full h-full flex justify-center items-center'
},
variants: {
side: {
top: {
content: ''
},
right: {
content: 'max-w-md'
},
bottom: {
content: ''
},
left: {
content: 'max-w-md'
}
},
inset: {
true: {
content: 'rounded-lg'
}
},
transition: {
true: {
overlay: 'data-[state=open]:animate-[fade-in_200ms_ease-out] data-[state=closed]:animate-[fade-out_200ms_ease-in]'
}
}
},
compoundVariants: [
{
side: 'top',
inset: true,
class: {
content: 'max-h-[calc(100%-2rem)] inset-x-4 top-4'
}
},
{
side: 'top',
inset: false,
class: {
content: 'max-h-full inset-x-0 top-0'
}
},
{
side: 'right',
inset: true,
class: {
content: 'w-[calc(100%-2rem)] inset-y-4 right-4'
}
},
{
side: 'right',
inset: false,
class: {
content: 'w-full inset-y-0 right-0'
}
},
{
side: 'bottom',
inset: true,
class: {
content: 'max-h-[calc(100%-2rem)] inset-x-4 bottom-4'
}
},
{
side: 'bottom',
inset: false,
class: {
content: 'max-h-full inset-x-0 bottom-0'
}
},
{
side: 'left',
inset: true,
class: {
content: 'w-[calc(100%-2rem)] inset-y-4 left-4'
}
},
{
side: 'left',
inset: false,
class: {
content: 'w-full inset-y-0 left-0'
}
},
{
transition: true,
side: 'top',
class: {
content: 'data-[state=open]:animate-[slide-in-from-top_200ms_ease-in-out] data-[state=closed]:animate-[slide-out-to-top_200ms_ease-in-out]'
}
},
{
transition: true,
side: 'right',
class: {
content: 'data-[state=open]:animate-[slide-in-from-right_200ms_ease-in-out] data-[state=closed]:animate-[slide-out-to-right_200ms_ease-in-out]'
}
},
{
transition: true,
side: 'bottom',
class: {
content: 'data-[state=open]:animate-[slide-in-from-bottom_200ms_ease-in-out] data-[state=closed]:animate-[slide-out-to-bottom_200ms_ease-in-out]'
}
},
{
transition: true,
side: 'left',
class: {
content: 'data-[state=open]:animate-[slide-in-from-left_200ms_ease-in-out] data-[state=closed]:animate-[slide-out-to-left_200ms_ease-in-out]'
}
}
]
}
}
})
]
})