Files
bookorbit/client/src/components/ui/sidebar/Sidebar.vue
T
neon af8f55976f feat(client): add the Nostalgia appearance style
Add a Style setting beside mode, accent, radius and background. Nostalgia restyles the app through
tokens only (neutral surface palettes, system type, flat shell, top glow) and pins background,
opacity and brightness. Add a top glow reach slider for both styles. Tidy the theme layer first:
charts read live tokens, bare `rounded` follows the radius scale, one shared sign-in toolbar.
Also carries the settings page header redesign.
2026-10-09 01:01:57 +00:00

92 lines
3.2 KiB
Vue

<script setup lang="ts">
import type { SidebarProps } from '.'
import { useI18n } from 'vue-i18n'
import { cn } from '@/lib/utils'
import { Sheet, SheetContent } from '@/components/ui/sheet'
import SheetDescription from '@/components/ui/sheet/SheetDescription.vue'
import SheetHeader from '@/components/ui/sheet/SheetHeader.vue'
import SheetTitle from '@/components/ui/sheet/SheetTitle.vue'
import { SIDEBAR_WIDTH_MOBILE, useSidebar } from './utils'
defineOptions({
inheritAttrs: false,
})
const props = withDefaults(defineProps<SidebarProps>(), {
side: 'left',
variant: 'sidebar',
collapsible: 'offcanvas',
})
const { isMobile, state, openMobile, setOpenMobile } = useSidebar()
const { t } = useI18n()
</script>
<template>
<div
v-if="collapsible === 'none'"
data-slot="sidebar"
:class="cn('bg-sidebar text-sidebar-foreground saturate-150 flex h-full w-(--sidebar-width) flex-col', props.class)"
v-bind="$attrs"
>
<slot />
</div>
<Sheet v-else-if="isMobile" :open="openMobile" v-bind="$attrs" @update:open="setOpenMobile">
<SheetContent
data-sidebar="sidebar"
data-slot="sidebar"
data-mobile="true"
:side="side"
class="bg-sidebar text-sidebar-foreground saturate-150 w-(--sidebar-width) p-0 [&>button]:hidden"
:style="{
'--sidebar-width': SIDEBAR_WIDTH_MOBILE,
}"
>
<SheetHeader class="sr-only">
<SheetTitle>{{ t('components.ui.sidebar.title') }}</SheetTitle>
<SheetDescription>{{ t('components.ui.sidebar.mobileDescription') }}</SheetDescription>
</SheetHeader>
<div class="flex h-full w-full flex-col">
<slot />
</div>
</SheetContent>
</Sheet>
<div
v-else
class="group peer text-sidebar-foreground hidden md:block"
data-slot="sidebar"
:data-state="state"
:data-collapsible="state === 'collapsed' ? collapsible : ''"
:data-variant="variant"
:data-side="side"
>
<!-- Zero-width sentinel — keeps the peer element in the DOM for CSS selectors -->
<div aria-hidden="true" class="w-0 shrink-0" />
<div
:class="
cn(
'fixed inset-y-0 z-10 hidden h-svh w-(--sidebar-width) transition-[left,right,width] duration-200 ease-linear md:flex',
side === 'left'
? 'left-0 group-data-[collapsible=offcanvas]:left-[calc(var(--sidebar-width)*-1)]'
: 'right-0 group-data-[collapsible=offcanvas]:right-[calc(var(--sidebar-width)*-1)]',
// Adjust the padding for floating and inset variants.
variant === 'floating' || variant === 'inset'
? 'p-(--shell-gap) group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+2*var(--shell-gap)+2px)]'
: 'group-data-[collapsible=icon]:w-(--sidebar-width-icon)',
props.class,
)
"
v-bind="$attrs"
>
<div
data-sidebar="sidebar"
class="relative z-0 flex h-full w-full flex-col border-r border-(--shell-border) bg-(--shell-surface) shell-backdrop group-data-[variant=floating]:rounded-(--shell-radius) group-data-[variant=floating]:border group-data-[variant=floating]:shadow-(--shell-shadow)"
>
<slot />
</div>
</div>
</div>
</template>