mirror of
https://github.com/bookorbit/bookorbit.git
synced 2026-11-03 00:11:37 -06:00
af8f55976f
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.
92 lines
3.2 KiB
Vue
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>
|