UNPKG

bootstrap-vue-next

Version:

BootstrapVueNext is an early and lovely component library for Vue 3 & Nuxt 3 based on Bootstrap 5 and Typescript.

1 lines 13.4 kB
{"version":3,"file":"BOffcanvas-DH1MW9Or.mjs","sources":["../src/components/BOffcanvas/BOffcanvas.vue"],"sourcesContent":["<template>\n <ConditionalTeleport\n :to=\"props.teleportTo\"\n :disabled=\"props.teleportDisabled || isOpenByBreakpoint\"\n >\n <Transition\n v-if=\"renderRef || contentShowing || isOpenByBreakpoint\"\n v-bind=\"transitionProps\"\n :appear=\"modelValue || props.visible\"\n >\n <div\n v-show=\"\n (showRef && ((backdropReady && props.backdropFirst) || !props.backdropFirst)) ||\n isOpenByBreakpoint\n \"\n :id=\"computedId\"\n ref=\"_element\"\n aria-modal=\"true\"\n role=\"dialog\"\n :class=\"computedClasses\"\n :style=\"computedStyles\"\n tabindex=\"-1\"\n :aria-labelledby=\"`${computedId}-offcanvas-label`\"\n data-bs-backdrop=\"false\"\n v-bind=\"$attrs\"\n >\n <template v-if=\"contentShowing || isOpenByBreakpoint\">\n <div v-if=\"!props.noHeader\" class=\"offcanvas-header\" :class=\"props.headerClass\">\n <slot name=\"header\" v-bind=\"sharedSlots\">\n <h5 :id=\"`${computedId}-offcanvas-label`\" class=\"offcanvas-title\">\n <slot name=\"title\" v-bind=\"sharedSlots\">\n {{ props.title }}\n </slot>\n </h5>\n <template v-if=\"!props.noHeaderClose\">\n <BButton\n v-if=\"hasHeaderCloseSlot\"\n ref=\"_close\"\n v-bind=\"headerCloseAttrs\"\n @click=\"hide('close')\"\n >\n <slot name=\"header-close\" v-bind=\"sharedSlots\" />\n </BButton>\n <BCloseButton\n v-else\n ref=\"_close\"\n :aria-label=\"props.headerCloseLabel\"\n v-bind=\"headerCloseAttrs\"\n @click=\"hide('close')\"\n />\n </template>\n </slot>\n </div>\n <div class=\"offcanvas-body\" :class=\"props.bodyClass\" v-bind=\"props.bodyAttrs\">\n <slot v-bind=\"sharedSlots\" />\n </div>\n <div v-if=\"hasFooterSlot\" :class=\"props.footerClass\">\n <slot name=\"footer\" v-bind=\"sharedSlots\" />\n </div>\n </template>\n <div\n v-if=\"needsFallback\"\n ref=\"_fallbackFocusElement\"\n :class=\"fallbackClassSelector\"\n tabindex=\"0\"\n style=\"width: 0; height: 0; overflow: hidden\"\n />\n </div>\n </Transition>\n <slot v-if=\"!props.noBackdrop\" name=\"backdrop\" v-bind=\"sharedSlots\">\n <Transition v-if=\"renderBackdropRef\" v-bind=\"backdropTransitionProps\">\n <div\n v-show=\"showBackdrop\"\n class=\"offcanvas-backdrop\"\n :class=\"{\n fade: !computedNoAnimation,\n show: backdropVisible || computedNoAnimation,\n }\"\n @click=\"hide('backdrop')\"\n />\n </Transition>\n </slot>\n </ConditionalTeleport>\n</template>\n\n<script setup lang=\"ts\">\nimport {breakpointsBootstrapV5, onKeyStroke, unrefElement, useBreakpoints} from '@vueuse/core'\nimport {useActivatedFocusTrap} from '../../composables/useActivatedFocusTrap'\nimport {computed, type EmitFn, nextTick, onMounted, ref, useTemplateRef, watch} from 'vue'\nimport {useDefaults} from '../../composables/useDefaults'\nimport {useId} from '../../composables/useId'\nimport type {BOffcanvasProps} from '../../types/ComponentProps'\nimport type {BOffcanvasEmits} from '../../types/ComponentEmits'\nimport type {BOffcanvasSlots, BOffcanvasSlotsData} from '../../types/ComponentSlots'\nimport BButton from '../BButton/BButton.vue'\nimport BCloseButton from '../BButton/BCloseButton.vue'\nimport ConditionalTeleport from '../ConditionalTeleport.vue'\nimport {useSafeScrollLock} from '../../composables/useSafeScrollLock'\nimport {isEmptySlot} from '../../utils/dom'\nimport {useShowHide} from '../../composables/useShowHide'\nimport {getElement} from '../../utils/getElement'\n\n// TODO once the responsive stuff may be implemented correctly,\n// What needs to occur is a fixing of the \"body scrolling\".\n// If the offcanvas is on the screen on a large screen, body scrolling is not disabled\n// Even though the modelValue is true\n// When it's a small screen and close, it works, as normal,\n// But then when it opens up on a small screen, it must disable again\n// This is implemented on Layout.vue, but is not officially supported.\n\ndefineOptions({\n inheritAttrs: false,\n})\n\nconst _props = withDefaults(defineProps<Omit<BOffcanvasProps, 'modelValue'>>(), {\n backdropFirst: false,\n bodyAttrs: undefined,\n bodyClass: undefined,\n bodyScrolling: false,\n focus: undefined,\n footerClass: undefined,\n headerClass: undefined,\n headerCloseClass: undefined,\n headerCloseLabel: 'Close',\n headerCloseVariant: 'secondary',\n id: undefined,\n initialAnimation: false,\n lazy: false,\n noAnimation: false,\n noBackdrop: false,\n noCloseOnBackdrop: false,\n noCloseOnEsc: false,\n noTrap: false,\n noHeader: false,\n noHeaderClose: false,\n unmountLazy: false,\n placement: 'start',\n shadow: false,\n teleportDisabled: false,\n teleportTo: 'body',\n title: undefined,\n show: false,\n width: undefined,\n visible: false,\n})\nconst props = useDefaults(_props, 'BOffcanvas')\n\nconst emit = defineEmits<BOffcanvasEmits>()\n\nconst slots = defineSlots<BOffcanvasSlots>()\n\nconst modelValue = defineModel<Exclude<BOffcanvasProps['modelValue'], undefined>>({\n default: false,\n})\n\nconst computedId = useId(() => props.id, 'offcanvas')\n\nconst element = useTemplateRef<HTMLElement>('_element')\nconst fallbackFocusElement = useTemplateRef<HTMLElement>('_fallbackFocusElement')\nconst closeButton = useTemplateRef<HTMLElement>('_close')\n\nconst pickFocusItem = () => {\n if (props.focus && typeof props.focus !== 'boolean') {\n if (props.focus === 'close') {\n return closeButton\n }\n return getElement(props.focus, element.value ?? undefined)\n }\n return element\n}\n\nconst onAfterEnter = () => {\n nextTick(() => {\n if (props.focus !== false && !isOpenByBreakpoint.value && props.noTrap) {\n const focusElement = unrefElement(pickFocusItem())\n focusElement?.focus()\n }\n })\n}\n\nconst {\n showRef,\n renderRef,\n renderBackdropRef,\n hide,\n show,\n toggle,\n computedNoAnimation,\n contentShowing,\n transitionProps,\n backdropReady,\n backdropTransitionProps,\n backdropVisible,\n isVisible,\n buildTriggerableEvent,\n localNoAnimation,\n isLeaving,\n trapActive,\n} = useShowHide(modelValue, props, emit as EmitFn, element, computedId, {\n transitionProps: {\n onAfterEnter,\n enterToClass: 'showing',\n leaveToClass: 'hiding',\n enterActiveClass: '',\n leaveActiveClass: '',\n enterFromClass: '',\n leaveFromClass: '',\n },\n})\n\nconst breakpoints = useBreakpoints(breakpointsBootstrapV5)\nconst smallerOrEqualToBreakpoint = breakpoints.smallerOrEqual(() => props.responsive ?? 'xs')\nconst isOpenByBreakpoint = ref(props.responsive !== undefined && !smallerOrEqualToBreakpoint.value)\nonMounted(() => {\n if (props.responsive !== undefined)\n emit('breakpoint', buildTriggerableEvent('breakpoint'), isOpenByBreakpoint.value)\n})\n\nuseSafeScrollLock(showRef, () => props.bodyScrolling || isOpenByBreakpoint.value)\n\nonKeyStroke(\n 'Escape',\n () => {\n hide('esc')\n },\n {target: element}\n)\n\nconst fallbackClassSelector = 'offcanvas-fallback-focus'\n\nconst {needsFallback} = useActivatedFocusTrap({\n element,\n isActive: trapActive,\n noTrap: () => props.noTrap || isOpenByBreakpoint.value,\n fallbackFocus: {\n classSelector: fallbackClassSelector,\n ref: fallbackFocusElement,\n },\n focus: () =>\n props.focus === false || isOpenByBreakpoint.value\n ? false\n : (unrefElement(pickFocusItem()) ?? undefined),\n})\n\nconst showBackdrop = computed(\n () =>\n (props.responsive === undefined || !isOpenByBreakpoint.value) &&\n props.noBackdrop === false &&\n (showRef.value === true ||\n (isLeaving.value && props.backdropFirst && !computedNoAnimation.value))\n)\n\nconst hasHeaderCloseSlot = computed(() => !isEmptySlot(slots['header-close']))\nconst headerCloseClasses = computed(() => [\n {'text-reset': !hasHeaderCloseSlot.value},\n props.headerCloseClass,\n])\nconst headerCloseAttrs = computed(() => ({\n variant: hasHeaderCloseSlot.value ? props.headerCloseVariant : undefined,\n class: headerCloseClasses.value,\n}))\n\nconst hasFooterSlot = computed(() => !isEmptySlot(slots.footer))\nconst computedClasses = computed(() => [\n props.responsive === undefined ? 'offcanvas' : `offcanvas-${props.responsive}`,\n `offcanvas-${props.placement}`,\n {\n 'show': isVisible.value,\n [`shadow-${props.shadow}`]: !!props.shadow,\n 'no-transition': computedNoAnimation.value,\n },\n])\n\nconst computedStyles = computed(() => ({\n width: props.width,\n}))\n\nconst sharedSlots = computed<BOffcanvasSlotsData>(() => ({\n visible: isVisible.value,\n placement: props.placement,\n hide,\n show,\n toggle,\n id: computedId.value,\n active: trapActive.value,\n}))\n\nwatch(smallerOrEqualToBreakpoint, (newValue) => {\n if (props.responsive === undefined) return\n if (newValue === true) {\n const opened = false\n localNoAnimation.value = true\n requestAnimationFrame(() => {\n isOpenByBreakpoint.value = opened\n })\n emit('breakpoint', buildTriggerableEvent('breakpoint'), opened)\n emit('hide', buildTriggerableEvent('hide'))\n } else {\n const opened = true\n localNoAnimation.value = true\n requestAnimationFrame(() => {\n isOpenByBreakpoint.value = opened\n })\n emit('breakpoint', buildTriggerableEvent('breakpoint'), opened)\n emit('show', buildTriggerableEvent('show'))\n }\n})\n\ndefineExpose({\n hide,\n show,\n toggle,\n isOpenByBreakpoint,\n})\n</script>\n\n<style lang=\"scss\" scoped>\n.no-transition {\n transition: none !important;\n}\n</style>\n"],"names":["_useSlots","_useModel"],"mappings":"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"}