Usage
Use a Button or any other component in the default slot of the Slideover.
Then, use the #content slot to add the content displayed when the Slideover is open.
<template>
<B24Slideover
:b24ui="{
content: 'light bg-(--ui-color-base-7) sm:top-[300px] sm:max-h-[calc(100%-300px)]'
}"
>
<B24Button label="Open" />
<template #content>
<Placeholder class="edge-light h-full m-4" />
</template>
</B24Slideover>
</template>
You can also use the #header, #body and #footer slots to customize the Slideover's content.
Title
Use the title prop to set the title of the Slideover's header.
<template>
<B24Slideover title="Slideover with title">
<B24Button label="Open" />
<template #body>
<Placeholder class="h-full" />
</template>
</B24Slideover>
</template>
Description
Use the description prop to set the description of the Slideover's header.
<template>
<B24Slideover
title="Slideover with description"
description="Lorem ipsum dolor sit amet, consectetur adipiscing elit."
>
<B24Button label="Open" />
<template #body>
<Placeholder class="h-full" />
</template>
</B24Slideover>
</template>
Close
Use the close prop to customize or hide the close button (with false value) displayed in the Slideover's header.
You can pass any property from the Button component to customize it.
<template>
<B24Slideover
title="Slideover with close button"
:close="{
color: 'air-secondary-accent-2'
}"
>
<B24Button label="Open" />
<template #body>
<Placeholder class="h-full" />
</template>
</B24Slideover>
</template>
#content slot is used as it's a part of the header.Close Icon
Use the close-icon prop to customize the close button Icon.
<script setup lang="ts">
import RocketIcon from '@bitrix24/b24icons-vue/main/RocketIcon'
</script>
<template>
<B24Slideover title="Slideover with close button" :close-icon="RocketIcon">
<B24Button label="Open" />
</B24Slideover>
</template>
Side
Use the side prop to set the side of the screen where the Slideover will slide in from. Defaults to bottom.
<template>
<B24Slideover side="bottom" title="Slideover with side">
<B24Button label="Open" />
</B24Slideover>
</template>
Transition
Use the transition prop to control whether the Slideover is animated or not. Defaults to true.
<template>
<B24Slideover :transition="false" title="Slideover without transition">
<B24Button label="Open" />
</B24Slideover>
</template>
Overlay
Use the overlay prop to control whether the Slideover has an overlay or not. Defaults to true.
<template>
<B24Slideover :overlay="false" title="Slideover without overlay">
<B24Button label="Open" />
</B24Slideover>
</template>
Overlay blur
If you want to disable background blur, you should use the overlayBlur prop.
The overlayBlur prop has 3 options:
auto: when the user has not requested reduced motionon: always use bluroff: (default) do not use blur
<template>
<B24Slideover overlay-blur="auto" title="Overlay blur">
<B24Button label="Open" />
<template #body>
<Placeholder class="h-full" />
</template>
</B24Slideover>
</template>
Modal
Use the modal prop to control whether the Slideover blocks interaction with outside content. Defaults to true.
modal is set to false, the overlay is automatically disabled and outside content becomes interactive.<template>
<B24Slideover :modal="false" title="Slideover interactive">
<B24Button label="Open" />
<template #body>
<Placeholder class="h-full" />
</template>
</B24Slideover>
</template>
Dismissible
Use the dismissible prop to control whether the Slideover is dismissible when clicking outside of it or pressing escape. Defaults to true.
close:prevent event will be emitted when the user tries to close it.modal: false with dismissible: false to make the Slideover's background interactive without closing it.<template>
<B24Slideover :dismissible="false" title="Slideover non-dismissible">
<B24Button label="Open" />
</B24Slideover>
</template>
Examples
Control open state
You can control the open state by using the default-open prop or the v-model:open directive.
defineShortcuts, you can toggle the Slideover by pressing O.Programmatic usage
You can use the useOverlay composable to open a Slideover programmatically.
App component which uses the OverlayProvider component.First, create a slideover component that will be opened programmatically:
close event when the slideover is closed or dismissed here. You can emit any data through the close event, however, the event must be emitted in order to capture the return value.Then, use it in your app:
emit('close').Nested slideovers
You can nest slideovers within each other.
With footer slot
Use the #footer slot to add content after the Slideover's body.
Simple list of elements
playground and also seen in the demo version.API
Props
Slots
Emits
Theme
export default defineAppConfig({
b24ui: {
slideover: {
slots: {
overlay: 'fixed inset-0 bg-linear-to-b from-[#00204e]/52 to-[#00204e]',
content: 'fixed sm:shadow-lg flex flex-col focus:outline-none h-full',
sidebarLayoutRoot: 'relative',
sidebarLayoutHeaderWrapper: 'relative',
sidebarLayoutPageWrapper: 'min-h-full pb-[calc(53px_+_10px)] px-[20px] ps-[20px] pe-[20px] pb-[20px]',
sidebarLayoutContainer: 'gap-[22px]',
sidebarLayoutPageBottomWrapper: 'relative',
sidebarLayoutLoadingWrapper: '',
sidebarLayoutLoadingIcon: '',
header: 'pt-[24px] flex-1 flex items-center gap-x-[12px] gap-y-1.5',
wrapper: 'min-h-[30px]',
title: 'font-[family-name:var(--ui-font-family-primary)] text-(--b24ui-typography-label-color) font-(--ui-font-weight-semi-bold) mb-0 text-(length:--ui-font-size-4xl)/[calc(var(--ui-font-size-4xl)+2px)]',
description: 'mt-1 text-(--b24ui-typography-description-color) text-(length:--ui-font-size-sm)',
close: 'absolute',
body: 'size-full flex-1',
footer: 'absolute inset-x-0 bottom-0 bg-(--ui-color-bg-content-primary) flex items-center justify-center gap-3 border-t border-t-1 border-t-(--ui-color-divider-less) shadow-top-md py-[9px] px-2 pr-(--scrollbar-width)',
safeList: 'group-hover:rounded-full group-hover:border-1 group-hover:border-current'
},
variants: {
useFooter: {
true: {
sidebarLayoutPageWrapper: 'pb-[calc(53px+20px)]'
}
},
overlayBlur: {
auto: {
overlay: 'motion-safe:backdrop-blur-sm'
},
on: {
overlay: 'backdrop-blur-sm'
},
off: {
overlay: ''
}
},
side: {
right: {
content: 'right-0 inset-y-0 w-[calc(100%-60px)] sm:w-[calc(100%-150px)] sm:rounded-t-none',
sidebarLayoutRoot: 'sm:rounded-t-none'
},
left: {
content: 'left-0 inset-y-0 w-[calc(100%-60px)] sm:w-[calc(100%-150px)] sm:rounded-t-none',
sidebarLayoutRoot: 'sm:rounded-t-none'
},
top: {
content: 'inset-x-0 top-0 max-h-full sm:rounded-t-none',
sidebarLayoutRoot: 'sm:rounded-t-none'
},
bottom: {
content: 'right-[5px] top-0 sm:top-[18px] bottom-0 w-[calc(100%-60px-5px)] sm:w-[calc(100%-150px-70px)] sm:max-h-[calc(100%-18px)] sm:rounded-t-[18px]',
sidebarLayoutRoot: 'sm:rounded-t-[18px]'
}
},
transition: {
true: {
overlay: 'motion-safe:data-[state=open]:animate-[fade-in_200ms_ease-out] motion-safe:data-[state=closed]:animate-[fade-out_200ms_ease-in]'
}
}
},
compoundVariants: [
{
side: [
'right',
'bottom'
],
class: {
close: 'pl-1.5 pr-[4px] top-[17px] -translate-x-full left-[1px] rounded-l-full'
}
},
{
side: 'left',
class: {
close: 'pr-1.5 pl-[4px] top-[17px] translate-x-full right-[1px] rounded-r-full [&>div]:flex-row-reverse'
}
},
{
side: 'top',
class: {
close: 'top-4 end-4'
}
},
{
transition: true,
side: 'top',
class: {
content: 'motion-safe:data-[state=open]:animate-[slide-in-from-top_200ms_ease-in-out] motion-safe:data-[state=closed]:animate-[slide-out-to-top_200ms_ease-in-out]'
}
},
{
transition: true,
side: 'right',
class: {
content: 'motion-safe:data-[state=open]:animate-[slide-in-from-right_200ms_ease-in-out] motion-safe:data-[state=closed]:animate-[slide-out-to-right_200ms_ease-in-out]'
}
},
{
transition: true,
side: 'bottom',
class: {
content: 'motion-safe:data-[state=open]:animate-[slide-in-from-bottom_200ms_ease-in-out] motion-safe:data-[state=closed]:animate-[slide-out-to-bottom_200ms_ease-in-out]'
}
},
{
transition: true,
side: 'left',
class: {
content: 'motion-safe:data-[state=open]:animate-[slide-in-from-left_200ms_ease-in-out] motion-safe:data-[state=closed]:animate-[slide-out-to-left_200ms_ease-in-out]'
}
}
],
defaultVariants: {
side: 'bottom',
overlayBlur: 'off'
}
}
}
})
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import bitrix24UIPluginVite from '@bitrix24/b24ui-nuxt/vite'
export default defineConfig({
plugins: [
vue(),
bitrix24UIPluginVite({
b24ui: {
slideover: {
slots: {
overlay: 'fixed inset-0 bg-linear-to-b from-[#00204e]/52 to-[#00204e]',
content: 'fixed sm:shadow-lg flex flex-col focus:outline-none h-full',
sidebarLayoutRoot: 'relative',
sidebarLayoutHeaderWrapper: 'relative',
sidebarLayoutPageWrapper: 'min-h-full pb-[calc(53px_+_10px)] px-[20px] ps-[20px] pe-[20px] pb-[20px]',
sidebarLayoutContainer: 'gap-[22px]',
sidebarLayoutPageBottomWrapper: 'relative',
sidebarLayoutLoadingWrapper: '',
sidebarLayoutLoadingIcon: '',
header: 'pt-[24px] flex-1 flex items-center gap-x-[12px] gap-y-1.5',
wrapper: 'min-h-[30px]',
title: 'font-[family-name:var(--ui-font-family-primary)] text-(--b24ui-typography-label-color) font-(--ui-font-weight-semi-bold) mb-0 text-(length:--ui-font-size-4xl)/[calc(var(--ui-font-size-4xl)+2px)]',
description: 'mt-1 text-(--b24ui-typography-description-color) text-(length:--ui-font-size-sm)',
close: 'absolute',
body: 'size-full flex-1',
footer: 'absolute inset-x-0 bottom-0 bg-(--ui-color-bg-content-primary) flex items-center justify-center gap-3 border-t border-t-1 border-t-(--ui-color-divider-less) shadow-top-md py-[9px] px-2 pr-(--scrollbar-width)',
safeList: 'group-hover:rounded-full group-hover:border-1 group-hover:border-current'
},
variants: {
useFooter: {
true: {
sidebarLayoutPageWrapper: 'pb-[calc(53px+20px)]'
}
},
overlayBlur: {
auto: {
overlay: 'motion-safe:backdrop-blur-sm'
},
on: {
overlay: 'backdrop-blur-sm'
},
off: {
overlay: ''
}
},
side: {
right: {
content: 'right-0 inset-y-0 w-[calc(100%-60px)] sm:w-[calc(100%-150px)] sm:rounded-t-none',
sidebarLayoutRoot: 'sm:rounded-t-none'
},
left: {
content: 'left-0 inset-y-0 w-[calc(100%-60px)] sm:w-[calc(100%-150px)] sm:rounded-t-none',
sidebarLayoutRoot: 'sm:rounded-t-none'
},
top: {
content: 'inset-x-0 top-0 max-h-full sm:rounded-t-none',
sidebarLayoutRoot: 'sm:rounded-t-none'
},
bottom: {
content: 'right-[5px] top-0 sm:top-[18px] bottom-0 w-[calc(100%-60px-5px)] sm:w-[calc(100%-150px-70px)] sm:max-h-[calc(100%-18px)] sm:rounded-t-[18px]',
sidebarLayoutRoot: 'sm:rounded-t-[18px]'
}
},
transition: {
true: {
overlay: 'motion-safe:data-[state=open]:animate-[fade-in_200ms_ease-out] motion-safe:data-[state=closed]:animate-[fade-out_200ms_ease-in]'
}
}
},
compoundVariants: [
{
side: [
'right',
'bottom'
],
class: {
close: 'pl-1.5 pr-[4px] top-[17px] -translate-x-full left-[1px] rounded-l-full'
}
},
{
side: 'left',
class: {
close: 'pr-1.5 pl-[4px] top-[17px] translate-x-full right-[1px] rounded-r-full [&>div]:flex-row-reverse'
}
},
{
side: 'top',
class: {
close: 'top-4 end-4'
}
},
{
transition: true,
side: 'top',
class: {
content: 'motion-safe:data-[state=open]:animate-[slide-in-from-top_200ms_ease-in-out] motion-safe:data-[state=closed]:animate-[slide-out-to-top_200ms_ease-in-out]'
}
},
{
transition: true,
side: 'right',
class: {
content: 'motion-safe:data-[state=open]:animate-[slide-in-from-right_200ms_ease-in-out] motion-safe:data-[state=closed]:animate-[slide-out-to-right_200ms_ease-in-out]'
}
},
{
transition: true,
side: 'bottom',
class: {
content: 'motion-safe:data-[state=open]:animate-[slide-in-from-bottom_200ms_ease-in-out] motion-safe:data-[state=closed]:animate-[slide-out-to-bottom_200ms_ease-in-out]'
}
},
{
transition: true,
side: 'left',
class: {
content: 'motion-safe:data-[state=open]:animate-[slide-in-from-left_200ms_ease-in-out] motion-safe:data-[state=closed]:animate-[slide-out-to-left_200ms_ease-in-out]'
}
}
],
defaultVariants: {
side: 'bottom',
overlayBlur: 'off'
}
}
}
})
]
})