Skip to content

Sidebar

The Sidebar component can be toggled to appear from the left, right, top, or bottom edge of the viewport. The component can be used to show an overlay for navigation, shopping carts, and more.

Examples

Base

The sidebar can be positioned go appear from each side of the viewport using the position prop. Using fullwidth or fullheight, the sidebar overlaps the entire viewport width or height.

html
<section>
    <o-field grouped>
        <o-switch v-model="overlay" label="Overlay" />
        <o-switch v-model="fullheight" label="Fullheight" />
        <o-switch v-model="fullwidth" label="Fullwidth" />
        <o-field label="Position">
            <o-select v-model="position">
                <option value="left">Left</option>
                <option value="right">Right</option>
                <option value="top">Top</option>
                <option value="bottom">Bottom</option>
            </o-select>
        </o-field>
        <o-field label="Override layout for small screens">
            <o-select v-model="mobile">
                <option :value="undefined"></option>
                <option value="reduced">Reduced</option>
                <option value="expanded">Expanded</option>
                <option value="fullwidth">Fullwidth</option>
                <option value="fullheight">Fullheight</option>
                <option value="hidden">Hidden</option>
            </o-select>
        </o-field>
    </o-field>

    <o-button label="Show Sidebar" @click="active = true" />

    <o-sidebar
        v-slot="{ close }"
        v-model:active="active"
        :fullheight="fullheight"
        :fullwidth="fullwidth"
        :overlay="overlay"
        :position="position"
        :mobile="mobile">
        <o-button
            v-if="fullwidth || fullheight || !overlay || mobile"
            icon-left="times"
            label="Close"
            @click="close($event)" />
        <img
            width="128"
            src="https://avatars2.githubusercontent.com/u/66300512?s=200&v=4"
            alt="Lightweight UI components for Vue.js" />
        <h3>Example</h3>
    </o-sidebar>
</section>
javascript
import { ref } from "vue";

const active = ref(false);
const overlay = ref(true);
const fullheight = ref(true);
const fullwidth = ref(false);
const position = ref<"left" | "top" | "bottom" | "right">("left");
const mobile = ref<
    "reduced" | "expanded" | "fullwidth" | "fullheight" | "hidden"
>("fullwidth");

Inline

When the property inline is set, the component will be rendered in place. The appearance can be triggered with the active prop as usual.

html
<section>
    <o-sidebar inline active>
        <img
            width="128"
            src="https://avatars2.githubusercontent.com/u/66300512?s=200&v=4"
            alt="Lightweight UI components for Vue.js" />
        <section style="padding: 1em">
            <h5>Example 1</h5>
            <h5>Example 2</h5>
            <h5>Example 3</h5>
            <h5>Example 4</h5>
            <h5>Example 5</h5>
        </section>
    </o-sidebar>
</section>

Teleport

The teleport prop allows the sidebar to be "teleported" into any DOM node outside the DOM hierarchy of that component. By default, if only a boolean is passed, the sidebar will be teleported to the document body. In addition, any other destination can be passed as a value to the teleport prop.

html
<section>
    <o-button
        label="Open Sidebar"
        size="medium"
        variant="primary"
        @click="isActive = true" />

    <o-sidebar
        v-slot="{ close }"
        v-model:active="isActive"
        fullheight
        overlay
        teleport>
        <o-button icon-left="times" label="Close" @click="close($event)" />
        <p>
            Lorem ipsum dolor sit amet, consectetur adipiscing elit. Etiam
            sodales leo nec convallis rutrum. Vivamus pharetra molestie arcu
            at dictum. Nulla faucibus leo eget enim egestas, in tempus justo
            venenatis. Duis dictum suscipit erat, a dapibus eros lobortis
            ac. Praesent tempor rhoncus convallis. Nullam in ipsum
            convallis, rutrum elit eget, dictum ipsum. Nunc sagittis aliquet
            massa. Etiam lacus sapien, eleifend non eros quis, finibus
            ornare nisl. Ut laoreet sit amet lacus non dignissim. Sed
            convallis mattis enim, sed interdum risus molestie ut. Praesent
            vel ex hendrerit, cursus lectus a, blandit felis. Nam luctus
            orci nec varius commodo.
        </p>
    </o-sidebar>
</section>
javascript
import { ref } from "vue";

const isActive = ref(false);

Dynamic Component

Instead of using the default slot, the component prop allows to pass any component that will be programmatically rendered inside the sidebar. Furthermore, an inline component created with a render function can also be passed. Props and events can be passed to the component with props and events props too.

html
<section>
    <o-button
        label="Open Sidebar"
        size="medium"
        variant="primary"
        @click="isSidebarActive = true" />

    <o-sidebar
        v-model:active="isSidebarActive"
        :component="Form"
        :fullheight="true"
        :overlay="true" />
</section>
javascript
import { ref } from "vue";
import Form from "./_sidebar-form.vue";

const isSidebarActive = ref(false);

Programmatically

This component provides a programmatic interface that can be accessed by the useOruga() composable. composable. The composable can be used from outside the Vue instance. For example, it can be used in Pinia or Vue Router with this syntax:

    import { useOruga } from "@oruga-ui/oruga-next";
    const oruga = useOruga();
    oruga.sidebar.open({...});
        
html
<section class="odocs-spaced">
    <p>
        <o-button
            label="Open Sidebar (HTML)"
            size="medium"
            variant="primary"
            @click="imageSidebar()" />

        <o-button
            label="Open Sidebar (Component)"
            size="medium"
            variant="primary"
            @click="formSidebar()" />
    </p>
</section>
javascript
import { h } from "vue";
import { useOruga } from "@oruga-ui/oruga-next";
import Form from "./_sidebar-form.vue";

const oruga = useOruga();

function imageSidebar(): void {
    const vnode = h("p", { style: { "text-align": "center" } }, [
        h("img", {
            src: "https://avatars2.githubusercontent.com/u/66300512?s=200&v=4",
        }),
    ]);
    oruga.sidebar.open({
        component: vnode,
        fullheight: true,
        overlay: true,
    });
}

function formSidebar(): void {
    oruga.sidebar.open({
        component: Form,
        fullheight: true,
        overlay: true,
    });
}

A sidebar to use as overlay.

html
<o-sidebar></o-sidebar>

Props

Prop nameDescriptionTypeValuesDefault
activeWhether siedbar is active or not, use v-model:active to make it two-way bindingboolean-false
animationCustom animation (transition name)string-
From config:
sidebar: {
  animation: undefined
}
clipScrollSet true to remove the body scrollbar.
When false, a non-scrollable scrollbar will be kept to avoid moving the background,
but will set the body to a fixed position, which may break some layouts.
boolean-
From config:
sidebar: {
  clipScroll: false
}
closeOnEscapeClose when pressing escape keyboolean-
From config:
sidebar: {
  closeOnEscape: true
}
closeOnOutsideClose when clicked outside of the panelboolean-
From config:
sidebar: {
  closeOnOutside: true
}
componentComponent to be injected.
Close the component by emitting a 'close' event — $emit('close')
C-
eventsEvents to be binded to the injected componentEmitsToProps<ComponentEmit<C>>-
fullheightShow sidebar in fullheightboolean-
From config:
sidebar: {
  fullheight: false
}
fullwidthShow sidebar in fullwidthboolean-
From config:
sidebar: {
  fullwidth: false
}
inlineDisplay the Sidebear inlineboolean-false
mobileOverride layout for small screens"expanded" | "fullheight" | "fullwidth" | "hidden" | "reduced"expanded, reduced, fullwidth, fullheight, hidden
From config:
sidebar: {
  mobile: undefined
}
mobileBreakpointMobile breakpoint as max-width valuestring-
From config:
sidebar: {
  mobileBreakpoint: undefined
}
overlayShow an overlay backgroundboolean-
From config:
sidebar: {
  overlay: false
}
overrideOverride existing theme classes completelyboolean-
positionSidebar position"bottom" | "left" | "right" | "top"top, right, bottom, left
From config:
sidebar: {
  position: "left"
}
propsProps to be binded to the injected componentComponentProps<C>-
teleportAppend the component to another part of the DOM.
Set true to append the component to the body.
In addition, any CSS selector string or an actual DOM node can be used.
boolean | object | string-
From config:
sidebar: {
  teleport: false
}
trapFocusTrap focus inside the sidebarboolean-
From config:
sidebar: {
  trapFocus: true
}

Events

Event namePropertiesDescription
update:activevalue boolean - updated active propactive prop two-way binding
closeevent Event - native eventon active state changes to false

Slots

NameDescriptionBindings
defaultSidebar default content, default is component propclose (...args: [] | [Event]): void - function to close the component

Class Inspector

Classes applied to the element:
Want to know how does the Class Inspector work?
Class propDescriptionPropsSuffixes
rootClass
Class of the root element.
mobileClass
Class of the root element when on mobile.
👉 Switch to mobile view to see it in action!
activeClass
Class of the root element when active.
active
teleportClass
Class of the root element when teleported.
teleport
inlineClass
Class of the root element when inlined.
inline
overlayClass
Class of the overlay element.
contentClass
Class of the content element.
visibleClass
Class of the content element when visible.
active
hiddenClass
Class of the content element when hidden.
active
positionClass
Class of the content element with position.
position
fullheightClass
Class of the content element when fullheight.
fullheight
fullwidthClass
Class of the content element when fullwidth.
fullwidth
contentMobileClass
Class of the content element with small screen modifier.
mobile
scrollClipClass
Class of the body when is visible and scroll is clipped.
clipScroll
scrollKeepClass
Class of the body when is visible and scroll is keeped.
clipScroll

Sass Variables

Current theme ➜ Oruga

SASS VariableDefault
$sidebar-zindexmap.get(vars.$zindex, "fixed")
$sidebar-overlay-background-colorh.useVar( "overlay-background-color")
$sidebar-overlay-zindexmap.get(vars.$zindex, "overlay")
$sidebar-content-zindexmap.get(vars.$zindex, "sidebar")
$sidebar-content-max-width50vw
$sidebar-content-max-height50vh
$sidebar-content-box-shadowh.useVar("overlay-box-shadow")
$sidebar-content-background-colorh.useVar( "control-brackground-color")
$sidebar-content-border-radiush.useVar("border-radius")
$sidebar-content-border-widthh.useVar("control-border-width")
$sidebar-content-border-stylesolid
$sidebar-content-border-colorh.useVar("control-border-color")

See ➜ 📄 SCSS file

Current theme ➜ Bulma

SASS VariableDefault
$sidebar-z40
$sidebar-width260px
$sidebar-height260px
$sidebar-mobile-width80px
$sidebar-colorsdv.$colors
$sidebar-background-background-colorhsla( #{css.getVar("scheme-h")}, #{css.getVar("scheme-s")}, #{css.getVar("scheme-invert-l")}, 0.86)
$sidebar-shadowcss.getVar("shadow")

See ➜ 📄 SCSS file

Current theme ➜ Bootstrap

SASS VariableDefault
$sidebar-reduced-width10rem
$sidebar-reduced-height10vh

See ➜ 📄 SCSS file

Released under the MIT License.