pull/3806/merge
Henry Bley-Vroman 10 months ago committed by GitHub
commit f3cb820e44
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -5,7 +5,8 @@ describe('test multi sidebar sort root', () => {
test('using / sidebar', async () => {
const sidebarLocator = page.locator(
'.VPSidebarItem.level-0 > .item > .text'
'.VPSidebarItem.level-0 > .item > summary > .text, \
.VPSidebarItem.level-0 > .item > .text'
)
const sidebarContent = await sidebarLocator.allTextContents()

@ -16,7 +16,7 @@ const {
isActiveLink,
hasActiveLink,
hasChildren,
toggle
handleToggle,
} = useSidebarControl(computed(() => props.item))
const sectionTag = computed(() => (hasChildren.value ? 'section' : `div`))
@ -31,41 +31,61 @@ const textTag = computed(() => {
: `h${props.depth + 2}`
})
const itemRole = computed(() => (isLink.value ? undefined : 'button'))
const classes = computed(() => [
[`level-${props.depth}`],
{ collapsible: collapsible.value },
{ collapsed: collapsed.value },
{ 'is-link': isLink.value },
{ 'is-active': isActiveLink.value },
{ 'has-active': hasActiveLink.value }
])
function onItemInteraction(e: MouseEvent | Event) {
if ('key' in e && e.key !== 'Enter') {
return
}
!props.item.link && toggle()
}
function onCaretClick() {
props.item.link && toggle()
function onToggle(payload: ToggleEvent): void {
handleToggle(payload.newState)
}
</script>
<template>
<component :is="sectionTag" class="VPSidebarItem" :class="classes">
<details
v-if="item.text && collapsible && hasChildren"
class="item"
:open="!collapsed"
@toggle="onToggle"
>
<summary>
<div class="indicator" />
<VPLink
v-if="item.link"
:tag="linkTag"
class="link"
:href="item.link"
:rel="item.rel"
:target="item.target"
>
<component :is="textTag" class="text" v-html="item.text" />
</VPLink>
<component v-else :is="textTag" class="text" v-html="item.text" />
<div class="caret">
<span class="vpi-chevron-right caret-icon" />
</div>
</summary>
<div class="items">
<template v-if="depth < 5">
<VPSidebarItem
v-for="i in item.items"
:key="i.text"
:item="i"
:depth="depth + 1"
/>
</template>
</div>
</details>
<div
v-if="item.text"
v-else
:is="item.text"
class="item"
:role="itemRole"
v-on="
item.items
? { click: onItemInteraction, keydown: onItemInteraction }
: {}
"
:tabindex="item.items && 0"
>
<div class="indicator" />
@ -80,21 +100,9 @@ function onCaretClick() {
<component :is="textTag" class="text" v-html="item.text" />
</VPLink>
<component v-else :is="textTag" class="text" v-html="item.text" />
<div
v-if="item.collapsed != null && item.items && item.items.length"
class="caret"
role="button"
aria-label="toggle section"
@click="onCaretClick"
@keydown.enter="onCaretClick"
tabindex="0"
>
<span class="vpi-chevron-right caret-icon" />
</div>
</div>
<div v-if="item.items && item.items.length" class="items">
<div v-if="(!collapsible || !item.text) && hasChildren" class="items">
<template v-if="depth < 5">
<VPSidebarItem
v-for="i in item.items"
@ -112,7 +120,7 @@ function onCaretClick() {
padding-bottom: 24px;
}
.VPSidebarItem.collapsed.level-0 {
.VPSidebarItem.level-0:has(> details:not([open])) {
padding-bottom: 10px;
}
@ -122,8 +130,24 @@ function onCaretClick() {
width: 100%;
}
.VPSidebarItem.collapsible > .item {
.VPSidebarItem details summary {
cursor: pointer;
display: flex;
justify-content: space-between;
position: relative;
}
.VPSidebarItem details summary .link {
flex-grow: 0;
}
.VPSidebarItem details summary::-webkit-details-marker {
display: none;
}
.VPSidebarItem details summary::marker {
content: '';
}
.indicator {
@ -136,10 +160,8 @@ function onCaretClick() {
transition: background-color 0.25s;
}
.VPSidebarItem.level-2.is-active > .item > .indicator,
.VPSidebarItem.level-3.is-active > .item > .indicator,
.VPSidebarItem.level-4.is-active > .item > .indicator,
.VPSidebarItem.level-5.is-active > .item > .indicator {
.VPSidebarItem:is(.level-2, .level-3, .level-4, .level-5).is-active > .item > .indicator,
.VPSidebarItem:is(.level-2, .level-3, .level-4, .level-5).is-active > details > summary .indicator {
background-color: var(--vp-c-brand-1);
}
@ -162,45 +184,15 @@ function onCaretClick() {
color: var(--vp-c-text-1);
}
.VPSidebarItem.level-1 .text,
.VPSidebarItem.level-2 .text,
.VPSidebarItem.level-3 .text,
.VPSidebarItem.level-4 .text,
.VPSidebarItem.level-5 .text {
.VPSidebarItem:is(.level-1, .level-2, .level-3, .level-4, .level-5) .text {
font-weight: 500;
color: var(--vp-c-text-2);
}
.VPSidebarItem.level-0.is-link > .item > .link:hover .text,
.VPSidebarItem.level-1.is-link > .item > .link:hover .text,
.VPSidebarItem.level-2.is-link > .item > .link:hover .text,
.VPSidebarItem.level-3.is-link > .item > .link:hover .text,
.VPSidebarItem.level-4.is-link > .item > .link:hover .text,
.VPSidebarItem.level-5.is-link > .item > .link:hover .text {
color: var(--vp-c-brand-1);
}
.VPSidebarItem.level-0.has-active > .item > .text,
.VPSidebarItem.level-1.has-active > .item > .text,
.VPSidebarItem.level-2.has-active > .item > .text,
.VPSidebarItem.level-3.has-active > .item > .text,
.VPSidebarItem.level-4.has-active > .item > .text,
.VPSidebarItem.level-5.has-active > .item > .text,
.VPSidebarItem.level-0.has-active > .item > .link > .text,
.VPSidebarItem.level-1.has-active > .item > .link > .text,
.VPSidebarItem.level-2.has-active > .item > .link > .text,
.VPSidebarItem.level-3.has-active > .item > .link > .text,
.VPSidebarItem.level-4.has-active > .item > .link > .text,
.VPSidebarItem.level-5.has-active > .item > .link > .text {
color: var(--vp-c-text-1);
}
.VPSidebarItem.level-0.is-active > .item .link > .text,
.VPSidebarItem.level-1.is-active > .item .link > .text,
.VPSidebarItem.level-2.is-active > .item .link > .text,
.VPSidebarItem.level-3.is-active > .item .link > .text,
.VPSidebarItem.level-4.is-active > .item .link > .text,
.VPSidebarItem.level-5.is-active > .item .link > .text {
.VPSidebarItem.is-active:is(.level-0, .level-1, .level-2, .level-3, .level-4, .level-5) > .item > summary .text,
.VPSidebarItem.is-active:is(.level-0, .level-1, .level-2, .level-3, .level-4, .level-5) > .item > .link > .text,
.VPSidebarItem:is(.level-0, .level-1, .level-2, .level-3, .level-4, .level-5) .link:hover >.text,
.VPSidebarItem:is(.level-0, .level-1, .level-2, .level-3, .level-4, .level-5) .link:focus >.text {
color: var(--vp-c-brand-1);
}
@ -217,12 +209,8 @@ function onCaretClick() {
flex-shrink: 0;
}
.item:hover .caret {
color: var(--vp-c-text-2);
}
.item:hover .caret:hover {
color: var(--vp-c-text-1);
.item summary:hover .caret {
color: var(--vp-c-text-1)
}
.caret-icon {
@ -231,20 +219,12 @@ function onCaretClick() {
transition: transform 0.25s;
}
.VPSidebarItem.collapsed .caret-icon {
.VPSidebarItem > details:not([open]) > summary .caret-icon {
transform: rotate(0);
}
.VPSidebarItem.level-1 .items,
.VPSidebarItem.level-2 .items,
.VPSidebarItem.level-3 .items,
.VPSidebarItem.level-4 .items,
.VPSidebarItem.level-5 .items {
.VPSidebarItem:is(.level-1, .level-2, .level-3, .level-4, .level-5) .items {
border-left: 1px solid var(--vp-c-divider);
padding-left: 16px;
}
.VPSidebarItem.collapsed .items {
display: none;
}
</style>

@ -26,7 +26,7 @@ export interface SidebarControl {
isActiveLink: Ref<boolean>
hasActiveLink: ComputedRef<boolean>
hasChildren: ComputedRef<boolean>
toggle(): void
handleToggle(newState: string): void
}
export function useSidebar() {
@ -176,13 +176,12 @@ export function useSidebarControl(
})
watchPostEffect(() => {
console.log(item.value.text, isActiveLink.value, hasActiveLink.value)
;(isActiveLink.value || hasActiveLink.value) && (collapsed.value = false)
})
function toggle() {
if (collapsible.value) {
collapsed.value = !collapsed.value
}
function handleToggle(newState: string) {
collapsed.value = newState === 'closed'
}
return {
@ -192,6 +191,6 @@ export function useSidebarControl(
isActiveLink,
hasActiveLink,
hasChildren,
toggle
handleToggle
}
}

Loading…
Cancel
Save