# All files / js/components/ui/sidebar Sidebar.vue

0% Statements 0/9
0% Branches 0/20
0% Functions 0/5
0% Lines 0/8

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97

     <script setup lang="ts">
    import type { SidebarProps } from '.'
    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()
    </script>

    <template>
      <div
        v-if="collapsible === 'none'"
        data-slot="sidebar"
        :class="cn('bg-sidebar text-sidebar-foreground 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 w-(--sidebar-width) p-0 [&>button]:hidden"
          :style="{
            '--sidebar-width': SIDEBAR_WIDTH_MOBILE,
          }"
        >
          <SheetHeader class="sr-only">
            <SheetTitle>Sidebar</SheetTitle>
            <SheetDescription>Displays the mobile sidebar.</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"
      >
        <!-- This is what handles the sidebar gap on desktop  -->
        <div
          :class="cn(
            'relative w-(--sidebar-width) bg-transparent transition-[width] duration-200 ease-linear',
            'group-data-[collapsible=offcanvas]:w-0',
            'group-data-[side=right]:rotate-180',
            variant === 'floating' || variant === 'inset'
              ? 'group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4)))]'
              : 'group-data-[collapsible=icon]:w-(--sidebar-width-icon)',
          )"
        />
        <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-2 group-data-[collapsible=icon]:w-[calc(var(--sidebar-width-icon)+(--spacing(4))+2px)]'
              : 'group-data-[collapsible=icon]:w-(--sidebar-width-icon) group-data-[side=left]:border-r group-data-[side=right]:border-l',
            props.class,
          )"
          v-bind="$attrs"
        >
          <div
            data-sidebar="sidebar"
            class="bg-sidebar group-data-[variant=floating]:border-sidebar-border flex h-full w-full flex-col group-data-[variant=floating]:rounded-lg group-data-[variant=floating]:border group-data-[variant=floating]:shadow-sm"
          >
            <slot />
          </div>
        </div>
      </div>
    </template>