Skip to content

Slideover ​

A dialog that slides in from any side of the screen.

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.

vue
<template>
  <B24Slideover>
    <B24Button label="Open" color="link" depth="dark" />

    <template #content>
      <Placeholder class="h-full" />
    </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.

Details
vue
<script setup lang="ts">
export interface ExampleProps {
  title?: string
}

withDefaults(defineProps<ExampleProps>(), {
  title: 'Heads up!'
})
</script>

<template>
  <B24Slideover
    :title="title"
  >
    <B24Button label="Open" color="link" depth="dark" />

    <template #body>
      <Placeholder class="h-full" />
    </template>
  </B24Slideover>
</template>

Description ​

Use the description prop to set the description of the Slideover's header.

Details
vue
<script setup lang="ts">
export interface ExampleProps {
  title?: string
  description?: string
}

withDefaults(defineProps<ExampleProps>(), {
  title: 'Heads up!',
  description: 'Let\'s signal the manager that the deal is not moving.'
})
</script>

<template>
  <B24Slideover
    :title="title"
    :description="description"
  >
    <B24Button label="Open" color="link" depth="dark" />

    <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.

TIP

The close button is not displayed if the #content slot is used as it's a part of the header.

Details
vue
<template>
  <B24Slideover
    title="Slideover with custom close button"
    description="The `close` prop inherits from the Button props."
    :close="{ color: 'danger', depth: 'dark', size: 'xs', rounded: true }"
    :b24ui="{ close: 'rounded-full py-4 px-2 -left-2' }"
  >
    <B24Button label="Open with custom close button" color="link" depth="dark" />

    <template #body>
      <Placeholder class="h-full w-full" />
    </template>
  </B24Slideover>

  <B24Slideover
    title="Slideover with ai close button"
    description="The `close` prop inherits from the Button props."
    :close="{ label: 'Test', color: 'ai' }"
  >
    <B24Button label="Open with ai close button" color="link" depth="dark" />

    <template #body>
      <Placeholder class="h-full w-full" />
    </template>
  </B24Slideover>
</template>

Close Icon ​

Use the close-icon prop to customize the close button @bitrix24/b24icons. Defaults to Cross30Icon.

Details
vue
<script setup lang="ts">
import EyeClosedIcon from '@bitrix24/b24icons-vue/button/EyeClosedIcon'
</script>

<template>
  <B24Slideover
    title="Slideover with custom close button"
    description="The `close-icon` prop use"
    :close-icon="EyeClosedIcon"
  >
    <B24Button label="Open" color="link" depth="dark" />

    <template #body>
      <Placeholder class="h-full w-full" />
    </template>
  </B24Slideover>
</template>

Side ​

Use the side prop to set the side of the screen where the Slideover will slide in from. Defaults to right.

Details
vue
<script setup lang="ts">
import type { SlideoverProps } from '@bitrix24/b24ui-nuxt/types/index.ts'

export interface ExampleProps {
  side?: SlideoverProps['side']
}

withDefaults(defineProps<ExampleProps>(), {
  side: 'right' as const
})
</script>

<template>
  <B24Slideover
    :side="side"
    title="Slideover with side"
    :description="`This slideover has \`side: '${side}'\` prop.`"
  >
    <B24Button label="Open" color="link" depth="dark" />

    <template #body>
      <Placeholder class="h-full min-h-48" />
    </template>
  </B24Slideover>
</template>

Overlay ​

Use the overlay prop to control whether the Modal has an overlay or not. Defaults to true.

Details
vue
<script setup lang="ts">
export interface ExampleProps {
  isOverlay?: boolean
}

withDefaults(defineProps<ExampleProps>(), {
  isOverlay: true
})
</script>

<template>
  <B24Slideover
    :overlay="isOverlay"
    :title="`Slideover ${isOverlay ? 'with' : 'without'} overlay`"
    description="The `overlay` prop use"
  >
    <B24Button label="Open" color="link" depth="dark" />

    <template #body>
      <Placeholder class="h-full w-full" />
    </template>
  </B24Slideover>
</template>

If you want to disable background blur, you should use the overlayBlur prop. The overlayBlur prop has 3 options:

  • auto: (default) when the user has not requested reduced motion
  • on: always use blur
  • off: do not use blur
Details
vue
<script setup lang="ts">
import type { ModalProps } from '@bitrix24/b24ui-nuxt/types/index.ts'

export interface ExampleProps {
  overlayBlur?: ModalProps['overlayBlur']
}

withDefaults(defineProps<ExampleProps>(), {
  overlayBlur: 'auto' as const
})
</script>

<template>
  <B24Modal
    :overlay-blur="overlayBlur"
    :title="`Modal overlay blur ${overlayBlur}`"
    description="The `overlay-blur` prop use"
  >
    <B24Button label="Open" color="link" depth="dark" />

    <template #body>
      <Placeholder class="h-48" />
    </template>
  </B24Modal>
</template>

Transition ​

Use the transition prop to control whether the Slideover is animated or not. Defaults to true.

INFO

Reduced movement is taken into account

Details
vue
<script setup lang="ts">
export interface ExampleProps {
  isTransition?: boolean
}

withDefaults(defineProps<ExampleProps>(), {
  isTransition: true
})
</script>

<template>
  <B24Slideover
    :transition="isTransition"
    :title="`Slideover ${isTransition ? 'with' : 'without'} transition`"
    description="The `transition` prop use"
  >
    <B24Button label="Open" color="link" depth="dark" />

    <template #body>
      <Placeholder class="h-full w-full" />
    </template>
  </B24Slideover>
</template>

Examples ​

Control open state ​

You can control the open state by using the default-open prop or the v-model:open directive.

INFO

In this example, leveraging defineShortcuts, you can toggle the Slideover by pressing O.

TIP

This allows you to move the trigger outside of the Slideover or remove it entirely.

Details
vue
<script setup lang="ts">
import { ref } from 'vue'

const open = ref(false)

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

<template>
  <B24Slideover
    v-model:open="open"
  >
    <B24Button label="Open" color="link" depth="dark" />

    <template #content>
      <Placeholder class="h-full w-full" />
    </template>
  </B24Slideover>
</template>

Prevent closing ​

Set the dismissible prop to false to prevent the Slideover from being closed when clicking outside of it or pressing escape.

Details
vue
<template>
  <B24Slideover
    :dismissible="false"
    title="Slideover non-dismissible"
    description="`Esc` also doesn't work"
  >
    <B24Button label="Open" color="link" depth="dark" />

    <template #body>
      <Placeholder class="h-full w-full" />
    </template>
  </B24Slideover>
</template>

Programmatic usage ​

You can use the useOverlay composable to open a Slideover programatically.

WARNING

Make sure to wrap your app with the App component which uses the OverlayProvider component.

First, create a slideover component that will be opened programatically:

vue
<script setup lang="ts">
defineProps<{
  count: number
}>()

const emit = defineEmits<{ close: [boolean] }>()
</script>

<template>
  <B24Slideover
    :close="{ onClick: () => emit('close', false) }"
    :title="`This Slideover was opened programmatically ${count} times`"
  >
    <template #body>
      <Placeholder class="h-full" />
    </template>

    <template #footer>
      <div class="flex gap-2">
        <B24Button
          color="success"
          label="Success"
          rounded
          size="sm"
          @click="emit('close', true)"
        />
        <B24Button
          rounded
          label="Close"
          color="link"
          depth="dark"
          size="sm"
          @click="emit('close', false)"
        />
      </div>
    </template>
  </B24Slideover>
</template>

INFO

We are emitting a 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:

TIP

You can close the slideover within the slideover component by emitting emit('close').

Details
vue
<script setup lang="ts">
import { ref } from 'vue'
import LazySlideover from './LazySlideover.vue'

const count = ref(0)

const toast = useToast()
const overlay = useOverlay()

const slideover = overlay.create(LazySlideover, {
  props: {
    count: count.value
  }
})

async function open() {
  const shouldIncrement = await slideover.open()

  if (shouldIncrement) {
    count.value++

    toast.add({
      title: `Success: ${shouldIncrement}`,
      color: 'success',
      id: 'slideover-success'
    })

    // Update the count
    slideover.patch({
      count: count.value
    })
    return
  }

  toast.add({
    title: `Dismissed: ${shouldIncrement}`,
    color: 'danger',
    id: 'slideover-dismiss'
  })
}
</script>

<template>
  <B24Button
    label="Open"
    color="link"
    depth="dark"
    @click="open"
  />
</template>

Nested slideovers ​

You can nest slideovers within each other.

Details
vue
<script setup lang="ts">
import { ref } from 'vue'

const first = ref(false)
const second = ref(false)
</script>

<template>
  <B24Slideover
    v-model:open="first"
    title="First Slideover"
    :b24ui="{ content: 'sm:max-w-1/2' }"
  >
    <B24Button label="Open" color="link" depth="dark" />

    <template #body>
      <B24Container class="h-full w-full pb-4">
        <Placeholder class="h-full w-full" />
      </B24Container>
    </template>

    <template #footer>
      <B24Button
        rounded
        label="Close"
        color="link"
        depth="dark"
        size="sm"
        @click="first = false"
      />
      <B24Slideover
        v-model:open="second"
        title="Second Slideover"
      >
        <B24Button
          color="default"
          label="Open second"
          rounded
          size="sm"
        />

        <template #body>
          <B24Container class="h-full w-full pb-4">
            <Placeholder class="h-full w-full" />
          </B24Container>
        </template>

        <template #footer>
          <B24Button
            rounded
            label="Close"
            color="link"
            depth="dark"
            size="sm"
            @click="second = false"
          />
        </template>
      </B24Slideover>
    </template>
  </B24Slideover>
</template>

Use the #footer slot to add content after the Slideover's body.

TIP

You can also close the dialog box using the B24ModalDialogClose component.

Details
vue
<template>
  <B24Slideover
    title="Slideover with footer"
    description="This is useful when you want a form in a Slideover."
    :b24ui="{ footer: 'flex-row-reverse justify-start' }"
  >
    <B24Button label="Open" color="link" depth="dark" />

    <template #body>
      <Placeholder class="h-full w-full" />
    </template>
    <template #footer>
      <B24ModalDialogClose>
        <B24Button rounded label="Send" color="primary" size="sm" />
      </B24ModalDialogClose>
      <B24ModalDialogClose>
        <B24Button rounded label="Cancel" color="link" depth="dark" size="sm" />
      </B24ModalDialogClose>
    </template>
  </B24Slideover>
</template>

API ​

Props ​

Prop Default Type
titlestring
descriptionstring
contentOmit<DialogContentProps, "as" | "asChild" | "forceMount"> & Partial<EmitsToProps<DialogContentImplEmits>>
The content of the slideover
overlaytrueboolean
Render an overlay behind the slideover.
overlayBlur"auto""off" | "auto" | "on"
Render an overlay blur behind the slideover. `auto` use `motion-safe`.
transitiontrueboolean
Animate the slideover when opening or closing.
side"right""bottom" | "top" | "left" | "right"
The side of the slideover.
portaltrueboolean
Render the slideover in a portal.
closetrueboolean | Partial<ButtonProps>
Display a close button to dismiss the slideover. `{ color: 'primary' }`{lang="ts"} for `left`, `right` `{ color: 'link' }`{lang="ts"} for `top`, `bottom`
closeIconicons.close(props: HTMLAttributes & VNodeProps & {}, ctx: Omit<{ attrs: Data; slots: Readonly<InternalSlots>; emit: (event: string, ...args: any[]) => void; expose: <Exposed extends Record<string, any> = Record<...>>(exposed?: Exposed) => void; }, "expose">): any
The icon displayed in the close button.
dismissibletrueboolean
When `false`, the slideover will not close when clicking outside or pressing escape.
scrollbarThintrueboolean
b24ui{ overlay?: ClassNameValue; content?: ClassNameValue; header?: ClassNameValue; wrapper?: ClassNameValue; body?: ClassNameValue; ... 4 more ...; safeList?: ClassNameValue; }
openboolean
The controlled open state of the dialog. Can be binded as `v-model:open`.
defaultOpenboolean
The open state of the dialog when it is initially rendered. Use when you do not need to control its open state.
modaltrueboolean
The modality of the dialog When set to `true`, <br> interaction with outside elements will be disabled and only dialog content will be visible to screen readers.

Slots ​

Slot Type
default{ open: boolean; }
content{}
header{}
title{}
description{}
close{ b24ui: { overlay: (props?: Record<string, any>) => string; content: (props?: Record<string, any> | undefined) => string; header: (props?: Record<string, any> | undefined) => string; ... 6 more ...; safeList: (props?: Record<...> | undefined) => string; }; }
body{}
footer{}

Emits ​

Event Type

Released under the MIT License.