Fix collapsible sidebar.

main
fandi.susanto.bts 1 month ago
parent 1e702a0f58
commit bad6e8cb75

@ -9,7 +9,7 @@ const props = withDefaults(
tag?: string
placement?: CSideBarPlacement
width?: string
collapsible?: boolean
collapseButton?: boolean
collapsed?: boolean
collapsedWidth?: string
ariaLabel?: string
@ -18,7 +18,7 @@ const props = withDefaults(
tag: 'aside',
placement: 'start',
width: 'var(--c-side-bar-width, 240px)',
collapsible: false,
collapseButton: false,
collapsed: undefined,
collapsedWidth: '38px',
ariaLabel: undefined,
@ -30,9 +30,7 @@ const emit = defineEmits<{
}>()
const internalCollapsed = ref(false)
const isCollapsed = computed(() =>
props.collapsible ? (props.collapsed ?? internalCollapsed.value) : false,
)
const isCollapsed = computed(() => props.collapsed ?? internalCollapsed.value)
const sideBarStyle = computed(() => ({
'--c-side-bar-current-width': isCollapsed.value ? props.collapsedWidth : props.width,
@ -60,9 +58,9 @@ function toggleCollapsed() {
:style="sideBarStyle"
:aria-label="ariaLabel"
>
<div v-if="$slots.header || collapsible" class="header">
<div v-if="$slots.header || collapseButton" class="header">
<CButton
v-if="collapsible"
v-if="collapseButton"
class="toggle"
icon="☰"
:aria-expanded="!isCollapsed"

@ -2,7 +2,7 @@
import { ref } from 'vue'
import CCodeBlock from '@/documentation/CCodeBlock.vue'
import { CMenu, CSeparator, CSideBar } from '@/index'
import { CButton, CMenu, CSeparator, CSideBar } from '@/index'
import type { CMenuEntry, CMenuSelectEvent } from '@/index'
const lastAction = ref('No item selected')
@ -39,7 +39,7 @@ const navigation: CMenuEntry[] = [
const sidebarUsage = `<CSideBar
v-model:collapsed="sidebarCollapsed"
collapsible
collapse-button
width="250px"
aria-label="Application navigation"
>
@ -56,7 +56,7 @@ const sidebarUsage = `<CSideBar
<template #footer>Administrator</template>
</CSideBar>`
const collapsibleUsage = `<script setup>
const collapseUsage = `<script setup>
import { ref } from 'vue'
const sidebarCollapsed = ref(false)
@ -64,7 +64,7 @@ const sidebarCollapsed = ref(false)
<template>
<CSideBar
collapsible
collapse-button
v-model:collapsed="sidebarCollapsed"
collapsed-width="38px"
aria-label="Application navigation"
@ -77,6 +77,14 @@ const sidebarCollapsed = ref(false)
</CSideBar>
</template>`
const externalCollapseUsage = `<CButton @click="sidebarCollapsed = !sidebarCollapsed">
Toggle sidebar
</CButton>
<CSideBar v-model:collapsed="sidebarCollapsed">
Externally controlled content
</CSideBar>`
const placementUsage = `<div class="workspace">
<CSideBar placement="start" width="180px" aria-label="Navigation">
<template #header><strong>Navigation</strong></template>
@ -189,10 +197,15 @@ function recordSelection(event: CMenuSelectEvent) {
</p>
</div>
<div class="external-control">
<CButton @click="sidebarCollapsed = !sidebarCollapsed">Toggle from outside</CButton>
<span>Collapsed: {{ sidebarCollapsed }}</span>
</div>
<div class="preview">
<CSideBar
v-model:collapsed="sidebarCollapsed"
collapsible
collapse-button
width="250px"
aria-label="Example sidebar"
>
@ -228,31 +241,34 @@ function recordSelection(event: CMenuSelectEvent) {
<div class="description">
<h2>Collapsible sidebar</h2>
<p>
Add <code>collapsible</code> to show a boxed menu button before the header content. The
sidebar slides between its expanded and collapsed widths and keeps its menu state,
including expanded menu branches.
Bind <code>collapsed</code> to control whether the sidebar is open, independently of how
that state is changed. Add <code>collapse-button</code> only when the sidebar should render
its own boxed toggle before the header content. The sidebar preserves its menu state while
collapsed, including expanded menu branches.
</p>
</div>
<dl class="property-list">
<div>
<dt><code>collapsible</code></dt>
<dd>Enables the header toggle. Without it, the sidebar always remains expanded.</dd>
<dt><code>collapse-button</code></dt>
<dd>Shows the built-in header toggle. It does not enable or disable collapse behavior.</dd>
</div>
<div>
<dt><code>collapsed</code></dt>
<dd>
Controls the collapsed state through <code>v-model:collapsed</code>. The model is
optional; without it, <code>CSideBar</code> manages its own state.
Controls the collapsed state. Use <code>v-model:collapsed</code> with either the built-in
button or an external control. The built-in button can also manage its own state when no
model is supplied.
</dd>
</div>
<div>
<dt><code>collapsed-width</code></dt>
<dd>Sets the width of the collapsed toggle strip. The default is <code>38px</code>.</dd>
<dd>Sets the width of the collapsed sidebar. The default is <code>38px</code>.</dd>
</div>
</dl>
<CCodeBlock class="code-sample" :code="collapsibleUsage" />
<CCodeBlock class="code-sample" :code="collapseUsage" />
<CCodeBlock class="code-sample" :code="externalCollapseUsage" />
</section>
<section class="example">
@ -421,6 +437,18 @@ function recordSelection(event: CMenuSelectEvent) {
margin-top: 8px;
}
.external-control {
display: flex;
align-items: center;
margin-bottom: 6px;
gap: 8px;
span {
color: var(--c-muted-text-color, #626a75);
font-size: 12px;
}
}
.property-list {
margin: 0;
border: 1px solid var(--c-border-color, #d5d9df);

Loading…
Cancel
Save