# All files / js/components/ui/sheet SheetContent.vue

0% Statements 0/8
0% Branches 0/10
0% Functions 0/3
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

     <script setup lang="ts">
    import type { HTMLAttributes } from 'vue'
    import { cn } from '@/lib/utils'
    import { reactiveOmit } from '@vueuse/core'
    import { X } from 'lucide-vue-next'
    import {
      DialogClose,
      DialogContent,
      type DialogContentEmits,
      type DialogContentProps,
      DialogPortal,
      useForwardPropsEmits,
    } from 'reka-ui'
    import SheetOverlay from './SheetOverlay.vue'

    interface SheetContentProps extends DialogContentProps {
      class?: HTMLAttributes['class']
      side?: 'top' | 'right' | 'bottom' | 'left'
    }

    defineOptions({
      inheritAttrs: false,
    })

    const props = withDefaults(defineProps<SheetContentProps>(), {
      side: 'right',
    })
    const emits = defineEmits<DialogContentEmits>()

    const delegatedProps = reactiveOmit(props, 'class', 'side')

    const forwarded = useForwardPropsEmits(delegatedProps, emits)
    </script>

    <template>
      <DialogPortal>
        <SheetOverlay />
        <DialogContent
          data-slot="sheet-content"
          :class="cn(
            'bg-background data-[state=open]:animate-in data-[state=closed]:animate-out fixed z-50 flex flex-col gap-4 shadow-lg transition ease-in-out data-[state=closed]:duration-300 data-[state=open]:duration-500',
            side === 'right'
              && 'data-[state=closed]:slide-out-to-right data-[state=open]:slide-in-from-right inset-y-0 right-0 h-full w-3/4 border-l sm:max-w-sm',
            side === 'left'
              && 'data-[state=closed]:slide-out-to-left data-[state=open]:slide-in-from-left inset-y-0 left-0 h-full w-3/4 border-r sm:max-w-sm',
            side === 'top'
              && 'data-[state=closed]:slide-out-to-top data-[state=open]:slide-in-from-top inset-x-0 top-0 h-auto border-b',
            side === 'bottom'
              && 'data-[state=closed]:slide-out-to-bottom data-[state=open]:slide-in-from-bottom inset-x-0 bottom-0 h-auto border-t',
            props.class)"
          v-bind="{ ...forwarded, ...$attrs }"
        >
          <slot />

          <DialogClose
            class="ring-offset-background focus:ring-ring data-[state=open]:bg-secondary absolute top-4 right-4 rounded-xs opacity-70 transition-opacity hover:opacity-100 focus:ring-2 focus:ring-offset-2 focus:outline-hidden disabled:pointer-events-none"
          >
            <X class="size-4" />
            <span class="sr-only">Close</span>
          </DialogClose>
        </DialogContent>
      </DialogPortal>
    </template>