fix(theme): sidebar scrollbar is cropped by nav bar

pull/1820/head
Kia Ishii 2 years ago
parent 48f0b01569
commit bd36224b45

@ -1,26 +1,16 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed, provide } from 'vue' import { provide } from 'vue'
import { useWindowScroll } from '@vueuse/core'
import { useNav } from '../composables/nav.js' import { useNav } from '../composables/nav.js'
import { useSidebar } from '../composables/sidebar.js'
import VPNavBar from './VPNavBar.vue' import VPNavBar from './VPNavBar.vue'
import VPNavScreen from './VPNavScreen.vue' import VPNavScreen from './VPNavScreen.vue'
const { y } = useWindowScroll()
const { isScreenOpen, closeScreen, toggleScreen } = useNav() const { isScreenOpen, closeScreen, toggleScreen } = useNav()
const { hasSidebar } = useSidebar()
provide('close-screen', closeScreen) provide('close-screen', closeScreen)
const classes = computed(() => ({
'no-sidebar': !hasSidebar.value,
'fill-bg': y.value > 0
}))
</script> </script>
<template> <template>
<header class="VPNav" :class="classes"> <header class="VPNav">
<VPNavBar :is-screen-open="isScreenOpen" @toggle-screen="toggleScreen"> <VPNavBar :is-screen-open="isScreenOpen" @toggle-screen="toggleScreen">
<template #nav-bar-title-before><slot name="nav-bar-title-before" /></template> <template #nav-bar-title-before><slot name="nav-bar-title-before" /></template>
<template #nav-bar-title-after><slot name="nav-bar-title-after" /></template> <template #nav-bar-title-after><slot name="nav-bar-title-after" /></template>
@ -42,19 +32,10 @@ const classes = computed(() => ({
left: 0; left: 0;
z-index: var(--vp-z-index-nav); z-index: var(--vp-z-index-nav);
width: 100%; width: 100%;
background-color: var(--vp-nav-bg-color);
pointer-events: none; pointer-events: none;
transition: background-color 0.5s; transition: background-color 0.5s;
} }
.VPNav.no-sidebar {
background-color: transparent;
}
.VPNav.fill-bg {
background-color: var(--vp-nav-bg-color);
}
@media (min-width: 960px) { @media (min-width: 960px) {
.VPNav { .VPNav {
position: fixed; position: fixed;

@ -1,4 +1,6 @@
<script lang="ts" setup> <script lang="ts" setup>
import { computed } from 'vue'
import { useWindowScroll } from '@vueuse/core'
import { useSidebar } from '../composables/sidebar.js' import { useSidebar } from '../composables/sidebar.js'
import VPNavBarTitle from './VPNavBarTitle.vue' import VPNavBarTitle from './VPNavBarTitle.vue'
import VPNavBarSearch from './VPNavBarSearch.vue' import VPNavBarSearch from './VPNavBarSearch.vue'
@ -17,11 +19,17 @@ defineEmits<{
(e: 'toggle-screen'): void (e: 'toggle-screen'): void
}>() }>()
const { y } = useWindowScroll()
const { hasSidebar } = useSidebar() const { hasSidebar } = useSidebar()
const classes = computed(() => ({
'has-sidebar': hasSidebar.value,
fill: y.value > 0
}))
</script> </script>
<template> <template>
<div class="VPNavBar" :class="{ 'has-sidebar' : hasSidebar }"> <div class="VPNavBar" :class="classes">
<div class="container"> <div class="container">
<div class="title"> <div class="title">
<VPNavBarTitle> <VPNavBarTitle>
@ -32,6 +40,7 @@ const { hasSidebar } = useSidebar()
<div class="content"> <div class="content">
<div class="curtain" /> <div class="curtain" />
<div class="content-body">
<slot name="nav-bar-content-before" /> <slot name="nav-bar-content-before" />
<VPNavBarSearch class="search" /> <VPNavBarSearch class="search" />
<VPNavBarMenu class="menu" /> <VPNavBarMenu class="menu" />
@ -44,18 +53,24 @@ const { hasSidebar } = useSidebar()
</div> </div>
</div> </div>
</div> </div>
</div>
</template> </template>
<style scoped> <style scoped>
.VPNavBar { .VPNavBar {
position: relative; position: relative;
border-bottom: 1px solid var(--vp-c-gutter); border-bottom: 1px solid transparent;
padding: 0 8px 0 24px; padding: 0 8px 0 24px;
height: var(--vp-nav-height); height: var(--vp-nav-height);
transition: border-color 0.5s, background-color 0.5s; transition: border-color 0.5s, background-color 0.5s;
pointer-events: none; pointer-events: none;
} }
.VPNavBar.has-sidebar,
.VPNavBar.fill {
border-bottom-color: var(--vp-c-gutter);
}
@media (min-width: 768px) { @media (min-width: 768px) {
.VPNavBar { .VPNavBar {
padding: 0 32px; padding: 0 32px;
@ -78,6 +93,10 @@ const { hasSidebar } = useSidebar()
pointer-events: none; pointer-events: none;
} }
.container :deep(*) {
pointer-events: auto;
}
@media (min-width: 960px) { @media (min-width: 960px) {
.VPNavBar.has-sidebar .container { .VPNavBar.has-sidebar .container {
max-width: 100%; max-width: 100%;
@ -86,6 +105,12 @@ const { hasSidebar } = useSidebar()
.title { .title {
flex-shrink: 0; flex-shrink: 0;
height: calc(var(--vp-nav-height) - 1px);
transition: background-color 0.5s;
}
.VPNavBar.fill .title {
background-color: var(--vp-nav-bg-color);
} }
@media (min-width: 960px) { @media (min-width: 960px) {
@ -97,7 +122,7 @@ const { hasSidebar } = useSidebar()
padding: 0 32px; padding: 0 32px;
width: var(--vp-sidebar-width); width: var(--vp-sidebar-width);
height: var(--vp-nav-height); height: var(--vp-nav-height);
background-color: var(--vp-c-bg-alt); background-color: transparent;
} }
} }
@ -108,14 +133,7 @@ const { hasSidebar } = useSidebar()
} }
} }
.container :deep(*) {
pointer-events: auto;
}
.content { .content {
display: flex;
justify-content: flex-end;
align-items: center;
flex-grow: 1; flex-grow: 1;
} }
@ -135,6 +153,25 @@ const { hasSidebar } = useSidebar()
} }
} }
.content-body {
display: flex;
justify-content: flex-end;
align-items: center;
height: calc(var(--vp-nav-height) - 1px);
transition: background-color 0.5s;
}
.VPNavBar.fill .content-body {
background-color: var(--vp-nav-bg-color);
}
@media (min-width: 960px) {
.VPNavBar.has-sidebar .content-body {
position: relative;
background-color: var(--vp-nav-bg-color);
}
}
.menu + .translations::before, .menu + .translations::before,
.menu + .appearance::before, .menu + .appearance::before,
.menu + .social-links::before, .menu + .social-links::before,
@ -165,7 +202,7 @@ const { hasSidebar } = useSidebar()
.VPNavBar.has-sidebar .curtain { .VPNavBar.has-sidebar .curtain {
position: absolute; position: absolute;
right: 0; right: 0;
bottom: -32px; bottom: -31px;
width: calc(100% - var(--vp-sidebar-width)); width: calc(100% - var(--vp-sidebar-width));
height: 32px; height: 32px;
} }

@ -39,6 +39,8 @@ watchPostEffect(async () => {
ref="navEl" ref="navEl"
@click.stop @click.stop
> >
<div class="curtain" />
<nav class="nav" id="VPSidebarNav" aria-labelledby="sidebar-aria-label" tabindex="-1"> <nav class="nav" id="VPSidebarNav" aria-labelledby="sidebar-aria-label" tabindex="-1">
<span class="visually-hidden" id="sidebar-aria-label"> <span class="visually-hidden" id="sidebar-aria-label">
Sidebar Navigation Sidebar Navigation
@ -113,6 +115,20 @@ watchPostEffect(async () => {
} }
} }
@media (min-width: 960px) {
.curtain {
position: sticky;
top: -64px;
left: 0;
z-index: 1;
margin-top: calc(var(--vp-nav-height) * -1);
margin-right: -32px;
margin-left: -32px;
height: var(--vp-nav-height);
background-color: var(--vp-sidebar-bg-color);
}
}
.nav { .nav {
outline: 0; outline: 0;
} }

Loading…
Cancel
Save