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
<template>
<mc-button @click="stackingSidepanel?.showPanel('sidepanel-1')">Show Panel 1</mc-button>
<span class="mc-body-md">Active Panels: {{ activePanelText }}</span>
<mc-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. -->
<mc-sidepanel
size="sm"
position="right"
:is-stacking="true"
header-title="Sidepanel 1"
@close="stackingSidepanel?.hidePanel('sidepanel-1')"
>
<div class="mc-p-size-spacing-2xs">
<mc-button @click="stackingSidepanel?.showPanel('sidepanel-2')">Show Panel 2</mc-button>
</div>
</mc-sidepanel>
</template>
<template #sidepanel-2>
<mc-sidepanel
size="md"
position="right"
:is-stacking="true"
header-title="Sidepanel 2"
@close="stackingSidepanel?.hidePanel('sidepanel-2')"
>
<div class="mc-p-size-spacing-2xs">
<mc-button @click="stackingSidepanel?.showPanel('sidepanel-3')">Show Panel 3</mc-button>
</div>
</mc-sidepanel>
</template>
<template #sidepanel-3>
<mc-sidepanel
size="lg"
position="right"
:is-stacking="true"
header-title="Sidepanel 2"
@close="stackingSidepanel?.hidePanel('sidepanel-3')"
>
<div class="mc-p-size-spacing-2xs">
<mc-button @click="stackingSidepanel?.hidePanel('sidepanel-3')">Close Panel 3</mc-button>
</div>
</mc-sidepanel>
</template>
</mc-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 stackingExpandableSidepanel = useTemplateRef("stacking-expandable-sidepanel");
const activePanelText = ref("none");
const activePanelsHandler = (panel: string[]) => {
activePanelText.value = panel.length > 0 ? panel.join(', ') : 'none';
}
</script>Expanding Sidepanels
IMPORTANT
To properly integrate expandable sidepanels within the Stacking Sidepanel component, These props are required:
is-stackingshould betrueon eachmc-sidepanel:is-expandableon eachmc-sidepanel.:is-expandedon eachmc-sidepanel:is-active-panelon eachmc-sidepanel.
For more details on these props, refer to the Sidepanel Props Documentation.
<template>
<mc-button @click="stackingExpandableSidepanel?.showPanel('expandable-sidepanel-1')">Show Panel 1</mc-button>
<span class="mc-body-md">Active Panels: {{ activePanelText }}</span>
<mc-stacking-sidepanel
ref="stacking-expandable-sidepanel"
v-model:stack="activePanel"
@update:stack="activePanelsHandler"
:expanded-panel="expandedPanel"
>
<template #sidepanel-1>
<mc-sidepanel
size="sm"
position="right"
:is-stacking="true"
header-title="Sidepanel 1"
:is-expandable="true"
:is-expanded="stackingExpandableSidepanel?.expandedPanel === 'expandable-sidepanel-1'"
:is-active-panel="stackingExpandableSidepanel?.activePanel === 'expandable-sidepanel-1'" // Remove pointer events when not active
@close="stackingExpandableSidepanel?.hidePanel('expandable-sidepanel-1')"
@expand="stackingExpandableSidepanel?.handleExpandPanel('expand', 'expandable-sidepanel-1')"
@shrink="stackingExpandableSidepanel?.handleExpandPanel('shrink', 'expandable-sidepanel-1')"
>
<div class="mc-p-size-spacing-2xs">
<mc-button @click="stackingExpandableSidepanel?.showPanel('expandable-sidepanel-2')">Show Panel 2</mc-button>
</div>
</mc-sidepanel>
</template>
<template #sidepanel-2>
<mc-sidepanel
size="md"
position="right"
:is-stacking="true"
:is-expandable="true"
:is-expanded="stackingExpandableSidepanel?.expandedPanel === 'expandable-sidepanel-2'"
:is-active-panel="stackingExpandableSidepanel?.activePanel === 'expandable-sidepanel-2'"
header-title="Sidepanel 2"
@close="stackingExpandableSidepanel?.hidePanel('expandable-sidepanel-2')"
@expand="stackingExpandableSidepanel?.handleExpandPanel('expand', 'expandable-sidepanel-2')"
@shrink="stackingExpandableSidepanel?.handleExpandPanel('shrink', 'expandable-sidepanel-2')"
>
<div class="mc-p-size-spacing-2xs">
<mc-button @click="stackingExpandableSidepanel?.showPanel('expandable-sidepanel-3')">Show Panel 3</mc-button>
</div>
</mc-sidepanel>
</template>
<template #sidepanel-3>
<mc-sidepanel
size="lg"
position="right"
:is-stacking="true"
header-title="Sidepanel 3"
:is-expandable="true"
:is-expanded="stackingExpandableSidepanel?.expandedPanel === 'expandable-sidepanel-3'"
:is-active-panel="stackingExpandableSidepanel?.activePanel === 'expandable-sidepanel-3'"
@close="stackingExpandableSidepanel?.hidePanel('expandable-sidepanel-3')"
@expand="stackingExpandableSidepanel?.handleExpandPanel('expand', 'expandable-sidepanel-3')"
@shrink="stackingExpandableSidepanel?.handleExpandPanel('shrink', 'expandable-sidepanel-3')"
>
<div class="mc-p-size-spacing-2xs">
<mc-button @click="stackingExpandableSidepanel?.hidePanel('expandable-sidepanel-3')">Close Panel 3</mc-button>
</div>
</mc-sidepanel>
</template>
</mc-stacking-sidepanel>
</template>
<script lang="ts" setup>
import { ref, useTemplateRef } from 'vue';
const activeExpandablePanel = ref<string[]>([]);
const stackingExpandableSidepanel = useTemplateRef("stacking-expandable-sidepanel"); // Use component reference to access exposed methods
const activePanelText = ref("none");
const activePanelsHandler = (panel: string[]) => {
activePanelText.value = panel.length > 0 ? panel.join(', ') : 'none';
}
const expandedPanel = ref('');
</script>API Reference
Props
| Name | Description | Type | Default |
|---|---|---|---|
stack | Array of active panel names. Used with v-model:stack for two-way binding. | string[] | [] |
Events
| Name | Description | Parameters |
|---|---|---|
update:stack | Emitted when the stack of panels changes | (panels: string[]) |
Exposed Methods
| Name | Description | Parameters |
|---|---|---|
showPanel | Shows a panel by its slot name | (name: string) |
hidePanel | Hides a panel by its slot name | (name: string) |
handleExpandPanel | Function to update expandedPanel variable. | (action: 'expand' | 'shrink' , name: string) |
Exposed Variables
| Name | Description |
|---|---|
expandedPanel | Sidepanel name that is currently expanded. |
activePanel | Sidepanel name that is currently shown. |
Slots
| Name | Description |
|---|---|
| named slots | Each 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
| Guideline | Description |
|---|---|
| Maintain Context Hierarchy | Design panels to show a clear hierarchy of information, with each new panel revealing more detailed or specific content. |
| Consistent Panel Sizing | Consider using consistent panel sizes or a logical progression of sizes (e.g., narrow to wide) to maintain visual harmony. |
| Clear Navigation Paths | Provide obvious ways to navigate between panels, such as "Back" buttons or breadcrumbs. |
| Limit Stack Depth | To prevent excessive horizontal scrolling, limit the number of simultaneously open panels to 3-4 maximum. |
| Panel Dependencies | When a parent panel is closed, consider whether child panels should automatically close as well to maintain logical relationships. |
| Performance Considerations | For complex panel content, use lazy loading or conditional rendering to improve performance. |
| Responsive Design | Ensure the stacking behavior works well on different screen sizes, potentially collapsing to a single panel view on mobile devices. |