Skip to content

Stacking Sidepanel

The StackingSidepanel component provides a powerful way to display multiple sidepanels that stack horizontally next to each other. This creates a visual hierarchy and navigation flow that's perfect for multi-step processes, drill-down interfaces, or master-detail views.

Overview

The Stacking Sidepanel is ideal for:

  • Multi-step workflows: Guide users through sequential steps without losing context
  • Master-detail views: Show a list in one panel and details in another
  • Nested navigation: Allow users to drill down into deeper levels of content
  • Related information: Display supplementary content while keeping the primary content visible

Key Features

  • Progressive Disclosure: Display information in a logical progression
  • Maintains Context: Users can see previous panels while working in current ones
  • Flexible Configuration: Customize width, animations, and transitions
  • Responsive Design: Works well on various screen sizes
  • Accessible: Designed with keyboard navigation and screen readers in mind

IMPORTANT

The StackingSidepanel component is designed to work with right-positioned side panels only. Ensure that all side panels within the stacking side panel are positioned to the right and have the is-stacking prop set to true.

Basic Usage

Active Panels: none

vue
<template>
  <spr-button @click="stackingSidepanel?.showPanel('sidepanel-1')">Show Panel 1</spr-button>
  <span class="spr-body-md">Active Panels: {{ activePanelText }}</span>

  <spr-stacking-sidepanel ref="stacking-sidepanel" v-model:stack="activePanel" @update:stack="activePanelsHandler">
    <template #sidepanel-1> <!-- Stacking sidepanel utilizes custom named slots. Make sure the slot names are unique. -->
      <!-- Stacking sidepanel is only supported for right positioned sidepanel. Also, set `is-stacking` to true. -->
      <spr-sidepanel
        size="sm"
        position="right"
        :is-stacking="true"
        header-title="Sidepanel 1"
        @close="stackingSidepanel?.hidePanel('sidepanel-1')"
      >
        <div class="spr-p-size-spacing-2xs">
          <spr-button @click="stackingSidepanel?.showPanel('sidepanel-2')">Show Panel 2</spr-button>
        </div>
      </spr-sidepanel>
    </template>
    <template #sidepanel-2>
      <spr-sidepanel
        size="md"
        position="right"
        :is-stacking="true"
        header-title="Sidepanel 2"
        @close="stackingSidepanel?.hidePanel('sidepanel-2')"
      >
        <div class="spr-p-size-spacing-2xs">
          <spr-button @click="stackingSidepanel?.showPanel('sidepanel-3')">Show Panel 3</spr-button>
        </div>
      </spr-sidepanel>
    </template>
    <template #sidepanel-3>
      <spr-sidepanel
        size="lg"
        position="right"
        :is-stacking="true"
        header-title="Sidepanel 2"
        @close="stackingSidepanel?.hidePanel('sidepanel-3')"
      >
        <div class="spr-p-size-spacing-2xs">
          <spr-button @click="stackingSidepanel?.hidePanel('sidepanel-3')">Close Panel 3</spr-button>
        </div>
      </spr-sidepanel>
    </template>
  </spr-stacking-sidepanel>
</template>

<script lang="ts" setup>
import { ref, useTemplateRef } from 'vue';

const activePanel = ref<string[]>([]);
const stackingSidepanel = useTemplateRef("stacking-sidepanel"); // Use component reference to access exposed methods

const activePanelText = ref("none");
const activePanelsHandler = (panel: string[]) => {
  activePanelText.value = panel.length > 0 ? panel.join(', ') : 'none';
}
</script>

API Reference

Props

NameDescriptionTypeDefault
stackArray of active panel names. Used with v-model:stack for two-way binding.string[][]

Events

NameDescriptionParameters
update:stackEmitted when the stack of panels changes(panels: string[])

Exposed Methods

NameDescriptionParameters
showPanelShows a panel by its slot name(name: string)
hidePanelHides a panel by its slot name(name: string)

Slots

NameDescription
named slotsEach panel is rendered in a named slot. Use the <template #panelName> syntax to define content for each panel. Make sure that slot names are unique to avoid conflicts.

Best Practices

GuidelineDescription
Maintain Context HierarchyDesign panels to show a clear hierarchy of information, with each new panel revealing more detailed or specific content.
Consistent Panel SizingConsider using consistent panel sizes or a logical progression of sizes (e.g., narrow to wide) to maintain visual harmony.
Clear Navigation PathsProvide obvious ways to navigate between panels, such as "Back" buttons or breadcrumbs.
Limit Stack DepthTo prevent excessive horizontal scrolling, limit the number of simultaneously open panels to 3-4 maximum.
Panel DependenciesWhen a parent panel is closed, consider whether child panels should automatically close as well to maintain logical relationships.
Performance ConsiderationsFor complex panel content, use lazy loading or conditional rendering to improve performance.
Responsive DesignEnsure the stacking behavior works well on different screen sizes, potentially collapsing to a single panel view on mobile devices.