@nextcloud/vue
Version:
Nextcloud vue components
1 lines • 36.3 kB
Source Map (JSON)
{"version":3,"file":"NcModal-MC_HktJd.mjs","sources":["../../src/composables/useScopeIdAttrs.ts","../../src/components/NcModal/NcModal.vue"],"sourcesContent":["/*!\n * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors\n * SPDX-License-Identifier: AGPL-3.0-or-later\n */\n\nimport type { ComponentInternalInstance } from 'vue'\n\nimport { getCurrentInstance, warn } from 'vue'\n\n/**\n * Get the parent instance of the instance only if the instance is the root node of the parent\n * - Parent > Child - same root node\n * - Parent > div > Child - different root node\n * - Parent > WrapperWithSlot > Child - different root node\n *\n * @param instance - Current instance (internal)\n */\nfunction getSameNodeParent(instance: ComponentInternalInstance): ComponentInternalInstance | null {\n\tif (!instance.parent) {\n\t\treturn null\n\t}\n\n\tif ('vapor' in instance || 'vapor' in instance.parent) {\n\t\twarn('Vapor instances are not supported in useScopeIdAttrs :(')\n\t\treturn null\n\t}\n\n\tif (instance.parent.subTree !== instance.vnode) {\n\t\treturn null\n\t}\n\n\treturn instance.parent\n}\n\n/**\n * Get all ancestor instances of the instance that are on the same root node\n *\n * @param instance - Current instance (internal)\n */\nfunction getSameNodeAncestors(instance: ComponentInternalInstance): ComponentInternalInstance[] {\n\tconst ancestors: ComponentInternalInstance[] = [instance]\n\tlet parent = getSameNodeParent(instance)\n\twhile (parent) {\n\t\tancestors.push(parent)\n\t\tparent = getSameNodeParent(parent)\n\t}\n\treturn ancestors\n}\n\n/**\n * Get a binding object for all data-v-scopeid attributes that are supposed to be on the root node.\n * It allows to have scoped styles from parents in edge cases not covered by Vue:\n * - Teleport on the root\n * - Fragments\n *\n * @todo Do we need to support slotScopeIds for `:slotted()`?\n *\n * @example\n * ```ts\n * <script setup>\n * import { useScopeIdAttrs } from './useScopeIdAttrs.ts'\n * const scopeIdAttrs = useScopeIdAttrs()\n * </script>\n * <template>\n * <teleport to=\"body\">\n * <div v-bind=\"scopeIdAttrs\" />\n * </teleport>\n * </template>\n * ```\n */\nexport function useScopeIdAttrs() {\n\tconst instance = getCurrentInstance()\n\n\tif (!instance) {\n\t\tthrow new Error('useScopeId must be called within a setup context')\n\t}\n\n\tconst sameNodeAncestors = getSameNodeAncestors(instance)\n\tconst scopeIds = sameNodeAncestors.map((instance) => instance.vnode.scopeId).filter(Boolean)\n\tconst scopeIdAttrs = Object.fromEntries(scopeIds.map((scopeId) => [scopeId, '']))\n\treturn scopeIdAttrs\n}\n","<!--\n - SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors\n - SPDX-License-Identifier: AGPL-3.0-or-later\n-->\n\n<script setup lang=\"ts\">\nimport type { UseSwipeDirection } from '@vueuse/core'\nimport type { FocusTargetValueOrFalse, FocusTrap, Options as FocusTrapOptions } from 'focus-trap'\nimport type { Slot } from 'vue'\n\nimport { mdiChevronLeft, mdiChevronRight, mdiClose, mdiPause, mdiPlay } from '@mdi/js'\nimport { useIntervalFn, useSwipe } from '@vueuse/core'\nimport { createFocusTrap } from 'focus-trap'\nimport { computed, nextTick, onMounted, onUnmounted, ref, toRef, useTemplateRef, warn, watch, watchEffect } from 'vue'\nimport NcActions from '../NcActions/NcActions.vue'\nimport NcButton from '../NcButton/NcButton.vue'\nimport NcIconSvgWrapper from '../NcIconSvgWrapper/NcIconSvgWrapper.vue'\nimport { useHotKey } from '../../composables/index.ts'\nimport { useScopeIdAttrs } from '../../composables/useScopeIdAttrs.ts'\nimport { t } from '../../l10n.ts'\nimport { createElementId } from '../../utils/createElementId.ts'\nimport { getTrapStack } from '../../utils/focusTrap.ts'\nimport { isRtl } from '../../utils/rtl.ts'\n\ndefineOptions({ inheritAttrs: false })\n\n/**\n * The show-state of the modal.\n */\nconst showModal = defineModel<boolean>('show', { default: true })\n\nconst props = withDefaults(defineProps<{\n\t/**\n\t * Name to be shown with the modal\n\t */\n\tname?: string\n\n\t/**\n\t * Declare if a previous slide is available\n\t */\n\thasPrevious?: boolean\n\n\t/**\n\t * Declare if a next slide is available\n\t */\n\thasNext?: boolean\n\n\t/**\n\t * Declare if hiding the modal should be animated\n\t */\n\toutTransition?: boolean\n\n\t/**\n\t * Declare if the slideshow functionality should be enabled\n\t */\n\tenableSlideshow?: boolean\n\n\t/**\n\t * Declare the slide interval\n\t */\n\tslideshowDelay?: number\n\n\t/**\n\t * Allow to pause an ongoing slideshow\n\t */\n\tslideshowPaused?: boolean\n\n\t/**\n\t * Disable swipe between slides\n\t */\n\tdisableSwipe?: boolean\n\n\t/**\n\t * Enable spread navigation\n\t */\n\tspreadNavigation?: boolean\n\n\t/**\n\t * Defines the modal size.\n\t * All sizes except 'small' change automatically to full-screen on mobile.\n\t */\n\tsize?: 'small' | 'normal' | 'large' | 'full'\n\n\t/**\n\t * Do not show the close button for the dialog.\n\t */\n\tnoClose?: boolean\n\n\t/**\n\t * Close the modal if the user clicked outside the modal\n\t * Only relevant if `noClose` is not set.\n\t */\n\tcloseOnClickOutside?: boolean\n\n\t/**\n\t * Makes the modal backdrop opaque if true\n\t * Will be overwritten if some buttons are shown outside\n\t */\n\tdark?: boolean\n\n\t/**\n\t * Set light backdrop. Makes the modal header appear light.\n\t */\n\tlightBackdrop?: boolean\n\n\t/**\n\t * Selector for the modal container, pass `null` to prevent automatic container mounting\n\t */\n\tcontainer?: string | null\n\n\t/**\n\t * Pass in `true` if you want the modal 'close' button to be displayed\n\t * outside the modal boundaries, in the top right corner of the window.\n\t *\n\t * @since 8.25.0\n\t */\n\tcloseButtonOutside?: boolean\n\n\t/**\n\t * Additional elements to add to the focus trap\n\t */\n\tadditionalTrapElements?: (string | HTMLElement)[]\n\n\t/**\n\t * Display x items inline\n\t *\n\t * @see NcActions component usage\n\t */\n\tinlineActions?: number\n\n\t/**\n\t * Id of the element that labels the dialog (the name)\n\t * Not needed if the `name` prop is set, but if no name is set you need to provide the ID of an element to label the dialog for accessibility.\n\t */\n\tlabelId?: string\n\n\t/**\n\t * Set element to return focus to after focus trap deactivation\n\t */\n\tsetReturnFocus?: FocusTargetValueOrFalse\n}>(), {\n\tadditionalTrapElements: () => [],\n\tcontainer: 'body',\n\tinlineActions: 0,\n\tlabelId: '',\n\tslideshowDelay: 5000,\n\tsize: 'normal',\n\tname: '',\n\tsetReturnFocus: undefined,\n})\n\nconst emit = defineEmits<{\n\t/**\n\t * Trigger showing the next slide.\n\t *\n\t * @param payload - The event that triggered showing the next slide\n\t */\n\tnext: [payload?: Event]\n\n\t/**\n\t * Trigger showing the previous slide.\n\t *\n\t * @param payload - The event that triggered showing the previous slide\n\t */\n\tprevious: [payload?: Event]\n\n\t/**\n\t * Emitted when the closing animation is finished\n\t *\n\t * @param payload - The event that triggered the close\n\t */\n\tclose: [payload?: Event]\n\n\t/**\n\t * @param payload - The new show-state\n\t */\n\t'update:show': [payload: boolean]\n}>()\n\ndefineSlots<{\n\t/**\n\t * Actions to show (one or more NcAction* components)\n\t */\n\tactions?: Slot\n\n\t/**\n\t * The modal content to show.\n\t */\n\tdefault?: Slot\n}>()\n\nconst scopeIdAttrs = useScopeIdAttrs()\n\nconst modalId = createElementId()\nconst maskElement = useTemplateRef('mask')\n\n// Set up the focus trap\nlet focusTrap: FocusTrap | undefined\nonMounted(() => useFocusTrap())\nonUnmounted(() => clearFocusTrap())\nwatch(() => props.additionalTrapElements, (elements) => {\n\tif (focusTrap) {\n\t\tfocusTrap.updateContainerElements([maskElement.value!, ...elements])\n\t}\n})\n\n// Set up the slideshow\nconst {\n\tisActive: isPlaying,\n\tpause: stopSlideshow,\n\tresume: startSlideshow,\n} = useIntervalFn(nextSlide, toRef(() => props.slideshowDelay), { immediate: false })\n\nconst animationKey = ref(0)\nconst runSlideshow = ref(false)\nwatchEffect(() => {\n\tif (runSlideshow.value && !props.slideshowPaused) {\n\t\tstartSlideshow()\n\t} else if (isPlaying.value) {\n\t\tstopSlideshow()\n\t}\n})\n\nconst cssSlideshowDelay = computed(() => `${props.slideshowDelay}ms`)\n\n// Setup swipe navigation\nconst { stop: stopSwipe } = useSwipe(maskElement, {\n\tonSwipeEnd: handleSwipe,\n})\nonUnmounted(stopSwipe)\n\n// Setup hotkeys (keyboard navigation)\nuseHotKey('Escape', () => {\n\tconst trapStack = getTrapStack()\n\t// Only close the most recent focus trap modal\n\tif (trapStack.at(-1) === focusTrap) {\n\t\tclose()\n\t}\n}, { allowInModal: true })\n\nuseHotKey(['ArrowLeft', 'ArrowRight'], (event) => {\n\t// Ignore arrow navigation, if there is a current focus outside the modal.\n\t// For example, when the focus is in Sidebar or NcActions' items,\n\t// arrow navigation should not be intercepted by modal slider\n\tif (document.activeElement && !maskElement.value!.contains(document.activeElement)) {\n\t\treturn\n\t}\n\n\tif ((event.key === 'ArrowLeft') !== isRtl) {\n\t\tpreviousSlide()\n\t} else {\n\t\tnextSlide()\n\t}\n}, { allowInModal: true })\n\n// for developers we should add a warning if used with invalid props combination\nonMounted(() => {\n\tif (!props.name && !props.labelId) {\n\t\twarn('[NcModal] You need either set the name or set a `labelId` for accessibility.')\n\t}\n})\n\n/**\n * Trigger showing the next slide\n *\n * @param event - The mouse click event if triggered by user\n */\nfunction nextSlide(event?: Event) {\n\tif (!props.hasNext) {\n\t\trunSlideshow.value = false\n\t\t// do not send the event if nothing is available\n\t\treturn\n\t}\n\n\tif (event && isPlaying.value) {\n\t\trestartSlideshow()\n\t}\n\temit('next', event)\n}\n\n/**\n * Trigger showing the previous slide\n *\n * @param event - The mouse click event if triggered by user\n */\nfunction previousSlide(event?: Event) {\n\tif (!props.hasPrevious) {\n\t\t// do not send the event if nothing is available\n\t\treturn\n\t}\n\n\tif (event && isPlaying.value) {\n\t\trestartSlideshow()\n\t}\n\temit('previous', event)\n}\n\n/**\n * handle the swipe event\n *\n * @param e - The touch event\n * @param direction - Swipe direction\n */\nfunction handleSwipe(e: TouchEvent, direction: UseSwipeDirection) {\n\tif (!props.disableSwipe) {\n\t\tif (direction !== 'left' && direction !== 'right') {\n\t\t\treturn\n\t\t}\n\n\t\tif ((direction === 'left') !== isRtl) {\n\t\t\tnextSlide(e)\n\t\t} else {\n\t\t\tpreviousSlide(e)\n\t\t}\n\t}\n}\n\n/**\n * Reset the slideshow interval and animation\n */\nfunction restartSlideshow() {\n\tstopSlideshow()\n\tstartSlideshow()\n\tanimationKey.value++\n}\n\n/**\n * Handle closing the modal.\n *\n * @param event - The event that triggered closing the modal\n */\nfunction close(event?: Event) {\n\t// do not fire event if forbidden\n\tif (props.noClose) {\n\t\treturn\n\t}\n\n\tshowModal.value = false\n\n\t// delay closing for animation\n\tsetTimeout(() => {\n\t\temit('close', event)\n\t}, 300)\n}\n\n/**\n * Handle click on modal wrapper\n * If `closeOnClickOutside` is set the modal will be closed\n *\n * @param event - The click event\n */\nfunction handleClickModalWrapper(event: MouseEvent) {\n\tif (props.closeOnClickOutside) {\n\t\tclose(event)\n\t}\n}\n\n/**\n * Add focus trap for accessibility.\n */\nasync function useFocusTrap() {\n\t// Don't do anything if the modal is hidden,\n\t// or we have a focus trap already\n\tif (!showModal.value || focusTrap) {\n\t\treturn\n\t}\n\n\t// wait until all children are mounted and available in the DOM before focusTrap can be added\n\tawait nextTick()\n\n\tconst options: FocusTrapOptions = {\n\t\tallowOutsideClick: true,\n\t\tfallbackFocus: maskElement.value!,\n\t\ttrapStack: getTrapStack(),\n\t\t// Esc can be used without stop in content or additionalTrapElements where it should not deactivate modal's focus trap.\n\t\t// Focus trap is deactivated on modal close anyway.\n\t\tescapeDeactivates: false,\n\t\tsetReturnFocus: props.setReturnFocus,\n\t}\n\n\t// Init focus trap\n\tfocusTrap = createFocusTrap([maskElement.value!, ...props.additionalTrapElements], options)\n\tfocusTrap.activate()\n}\n\n/**\n * Deactivate the active focus trap - if any.\n */\nfunction clearFocusTrap() {\n\tif (!focusTrap) {\n\t\treturn\n\t}\n\tfocusTrap?.deactivate()\n\tfocusTrap = undefined\n}\n</script>\n\n<template>\n\t<Teleport :disabled=\"container === null\" :to=\"container\">\n\t\t<transition\n\t\t\tname=\"fade\"\n\t\t\tappear\n\t\t\t@after-enter=\"useFocusTrap\"\n\t\t\t@before-leave=\"clearFocusTrap\">\n\t\t\t<div\n\t\t\t\tv-show=\"showModal\"\n\t\t\t\tv-bind=\"{ ...$attrs, ...scopeIdAttrs }\"\n\t\t\t\tref=\"mask\"\n\t\t\t\tclass=\"modal-mask\"\n\t\t\t\t:class=\"{\n\t\t\t\t\t'modal-mask--opaque': dark || closeButtonOutside || hasPrevious || hasNext,\n\t\t\t\t\t'modal-mask--light': lightBackdrop,\n\t\t\t\t}\"\n\t\t\t\trole=\"dialog\"\n\t\t\t\taria-modal=\"true\"\n\t\t\t\t:aria-labelledby=\"labelId || `modal-name-${modalId}`\"\n\t\t\t\t:aria-describedby=\"'modal-description-' + modalId\"\n\t\t\t\ttabindex=\"-1\">\n\t\t\t\t<!-- Header -->\n\t\t\t\t<transition name=\"fade-visibility\" appear>\n\t\t\t\t\t<div\n\t\t\t\t\t\tclass=\"modal-header\"\n\t\t\t\t\t\t:data-theme-light=\"lightBackdrop\"\n\t\t\t\t\t\t:data-theme-dark=\"!lightBackdrop\">\n\t\t\t\t\t\t<h2\n\t\t\t\t\t\t\tv-if=\"name.trim() !== ''\"\n\t\t\t\t\t\t\t:id=\"'modal-name-' + modalId\"\n\t\t\t\t\t\t\tclass=\"modal-header__name\">\n\t\t\t\t\t\t\t{{ name }}\n\t\t\t\t\t\t</h2>\n\t\t\t\t\t\t<div class=\"icons-menu\">\n\t\t\t\t\t\t\t<!-- Play-pause toggle -->\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\tv-if=\"hasNext && enableSlideshow\"\n\t\t\t\t\t\t\t\tclass=\"play-pause-icons\"\n\t\t\t\t\t\t\t\t:class=\"{ 'play-pause-icons--paused': slideshowPaused }\"\n\t\t\t\t\t\t\t\t:title=\"isPlaying ? t('Pause slideshow') : t('Start slideshow')\"\n\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t@click=\"runSlideshow = !runSlideshow\">\n\t\t\t\t\t\t\t\t<!-- Play/pause icons -->\n\t\t\t\t\t\t\t\t<NcIconSvgWrapper\n\t\t\t\t\t\t\t\t\tclass=\"play-pause-icons__icon\"\n\t\t\t\t\t\t\t\t\tinline\n\t\t\t\t\t\t\t\t\t:name=\"isPlaying ? t('Pause slideshow') : t('Start slideshow')\"\n\t\t\t\t\t\t\t\t\t:path=\"isPlaying ? mdiPause : mdiPlay\" />\n\n\t\t\t\t\t\t\t\t<!-- Progress circle, css animated -->\n\t\t\t\t\t\t\t\t<svg\n\t\t\t\t\t\t\t\t\tv-if=\"isPlaying\"\n\t\t\t\t\t\t\t\t\t:key=\"`${modalId}-animation-${animationKey}`\"\n\t\t\t\t\t\t\t\t\tclass=\"progress-ring\"\n\t\t\t\t\t\t\t\t\theight=\"50\"\n\t\t\t\t\t\t\t\t\twidth=\"50\">\n\t\t\t\t\t\t\t\t\t<circle\n\t\t\t\t\t\t\t\t\t\tclass=\"progress-ring__circle\"\n\t\t\t\t\t\t\t\t\t\tstroke=\"white\"\n\t\t\t\t\t\t\t\t\t\tstroke-width=\"2\"\n\t\t\t\t\t\t\t\t\t\tfill=\"transparent\"\n\t\t\t\t\t\t\t\t\t\tr=\"15\"\n\t\t\t\t\t\t\t\t\t\tcx=\"25\"\n\t\t\t\t\t\t\t\t\t\tcy=\"25\" />\n\t\t\t\t\t\t\t\t</svg>\n\t\t\t\t\t\t\t</button>\n\n\t\t\t\t\t\t\t<!-- Actions menu -->\n\t\t\t\t\t\t\t<NcActions class=\"header-actions\" :inline=\"inlineActions\">\n\t\t\t\t\t\t\t\t<slot name=\"actions\" />\n\t\t\t\t\t\t\t</NcActions>\n\n\t\t\t\t\t\t\t<!-- Close modal -->\n\t\t\t\t\t\t\t<NcButton\n\t\t\t\t\t\t\t\tv-if=\"!noClose && closeButtonOutside\"\n\t\t\t\t\t\t\t\t:aria-label=\"t('Close')\"\n\t\t\t\t\t\t\t\tclass=\"header-close\"\n\t\t\t\t\t\t\t\tvariant=\"tertiary\"\n\t\t\t\t\t\t\t\t@click=\"close\">\n\t\t\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t\t\t<NcIconSvgWrapper :path=\"mdiClose\" />\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t</NcButton>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</transition>\n\n\t\t\t\t<!-- Content wrapper -->\n\t\t\t\t<transition :name=\"`modal-${outTransition ? 'out' : 'in'}`\" appear>\n\t\t\t\t\t<div\n\t\t\t\t\t\tv-show=\"showModal\"\n\t\t\t\t\t\tclass=\"modal-wrapper\"\n\t\t\t\t\t\t:class=\"[\n\t\t\t\t\t\t\t`modal-wrapper--${size}`,\n\t\t\t\t\t\t\t{ 'modal-wrapper--spread-navigation': spreadNavigation },\n\t\t\t\t\t\t]\"\n\t\t\t\t\t\t@mousedown.self=\"handleClickModalWrapper\">\n\t\t\t\t\t\t<!-- Navigation button -->\n\t\t\t\t\t\t<transition name=\"fade-visibility\" appear>\n\t\t\t\t\t\t\t<NcButton\n\t\t\t\t\t\t\t\tv-show=\"hasPrevious\"\n\t\t\t\t\t\t\t\t:aria-label=\"t('Previous')\"\n\t\t\t\t\t\t\t\tclass=\"prev\"\n\t\t\t\t\t\t\t\tvariant=\"tertiary-no-background\"\n\t\t\t\t\t\t\t\t@click=\"previousSlide\">\n\t\t\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t\t\t<NcIconSvgWrapper\n\t\t\t\t\t\t\t\t\t\tdirectional\n\t\t\t\t\t\t\t\t\t\t:path=\"mdiChevronLeft\"\n\t\t\t\t\t\t\t\t\t\t:size=\"40\" />\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t</NcButton>\n\t\t\t\t\t\t</transition>\n\n\t\t\t\t\t\t<!-- Content -->\n\t\t\t\t\t\t<div :id=\"'modal-description-' + modalId\" class=\"modal-container\">\n\t\t\t\t\t\t\t<div class=\"modal-container__content\">\n\t\t\t\t\t\t\t\t<slot />\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t<!-- Close modal -->\n\t\t\t\t\t\t\t<NcButton\n\t\t\t\t\t\t\t\tv-if=\"!noClose && !closeButtonOutside\"\n\t\t\t\t\t\t\t\t:aria-label=\"t('Close')\"\n\t\t\t\t\t\t\t\tclass=\"modal-container__close\"\n\t\t\t\t\t\t\t\tvariant=\"tertiary\"\n\t\t\t\t\t\t\t\t@click=\"close\">\n\t\t\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t\t\t<NcIconSvgWrapper :path=\"mdiClose\" />\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t</NcButton>\n\t\t\t\t\t\t</div>\n\n\t\t\t\t\t\t<!-- Navigation button -->\n\t\t\t\t\t\t<transition name=\"fade-visibility\" appear>\n\t\t\t\t\t\t\t<NcButton\n\t\t\t\t\t\t\t\tv-show=\"hasNext\"\n\t\t\t\t\t\t\t\t:aria-label=\"t('Next')\"\n\t\t\t\t\t\t\t\tclass=\"next\"\n\t\t\t\t\t\t\t\tvariant=\"tertiary-no-background\"\n\t\t\t\t\t\t\t\t@click=\"nextSlide\">\n\t\t\t\t\t\t\t\t<template #icon>\n\t\t\t\t\t\t\t\t\t<NcIconSvgWrapper\n\t\t\t\t\t\t\t\t\t\tdirectional\n\t\t\t\t\t\t\t\t\t\t:path=\"mdiChevronRight\"\n\t\t\t\t\t\t\t\t\t\t:size=\"40\" />\n\t\t\t\t\t\t\t\t</template>\n\t\t\t\t\t\t\t</NcButton>\n\t\t\t\t\t\t</transition>\n\t\t\t\t\t</div>\n\t\t\t\t</transition>\n\t\t\t</div>\n\t\t</transition>\n\t</Teleport>\n</template>\n\n<style lang=\"scss\" scoped>\n\n.modal-mask {\n\tposition: fixed;\n\tz-index: 9998;\n\ttop: 0;\n\tinset-inline-start: 0;\n\tdisplay: block;\n\twidth: 100%;\n\theight: 100%;\n\t--backdrop-color: 0, 0, 0;\n\tbackground-color: rgba(var(--backdrop-color), .5);\n\n\t&,\n\t& * {\n\t\tbox-sizing: border-box;\n\t}\n\n\t&--opaque {\n\t\tbackground-color: rgba(var(--backdrop-color), .92);\n\t}\n\t&--light {\n\t\t--backdrop-color: 255, 255, 255;\n\t}\n}\n\n.modal-header {\n\tposition: absolute;\n\tz-index: 10001;\n\ttop: 0;\n\tinset-inline: 0 0;\n\t// prevent vue show to use display:none and resetting\n\t// the circle animation loop\n\tdisplay: flex !important;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 100%;\n\theight: var(--header-height);\n\toverflow: hidden;\n\ttransition: opacity 250ms, visibility 250ms;\n\n\t&__name {\n\t\toverflow-x: hidden;\n\t\twidth: 100%;\n\t\tpadding: 0 calc(var(--default-clickable-area) * 3) 0 12px; // maximum actions is 3\n\t\ttransition: padding ease 100ms;\n\t\twhite-space: nowrap;\n\t\ttext-overflow: ellipsis;\n\t\tfont-size: $icon-size;\n\t\tmargin-block: 0;\n\t}\n\n\t// On wider screens the name can be centered\n\t@media only screen and (min-width: $breakpoint-mobile) {\n\t\t&__name {\n\t\t\tpadding-inline-start: calc(var(--default-clickable-area) * 3); // maximum actions is 3\n\t\t\ttext-align: center;\n\t\t}\n\t}\n\n\t.icons-menu {\n\t\tposition: absolute;\n\t\tinset-inline-end: 0;\n\t\tdisplay: flex;\n\t\talign-items: center;\n\t\tjustify-content: flex-end;\n\n\t\t.header-close {\n\t\t\tdisplay: flex;\n\t\t\talign-items: center;\n\t\t\tjustify-content: center;\n\t\t\tmargin: calc((var(--header-height) - var(--default-clickable-area)) / 2);\n\t\t\tpadding: 0;\n\t\t}\n\n\t\t.play-pause-icons {\n\t\t\tposition: relative;\n\t\t\twidth: var(--header-height);\n\t\t\theight: var(--header-height);\n\t\t\tmargin: 0;\n\t\t\tpadding: 0;\n\t\t\tcursor: pointer;\n\t\t\tborder: none;\n\t\t\tbackground-color: transparent;\n\t\t\t&:hover,\n\t\t\t&:focus {\n\t\t\t\t.play-pause-icons__icon {\n\t\t\t\t\topacity: $opacity_full;\n\t\t\t\t\tborder-radius: calc(var(--default-clickable-area) / 2);\n\t\t\t\t\tbackground-color: $icon-focus-bg;\n\t\t\t\t}\n\t\t\t}\n\t\t\t&__icon {\n\t\t\t\twidth: var(--default-clickable-area);\n\t\t\t\theight: var(--default-clickable-area);\n\t\t\t\tmargin: calc((var(--header-height) - var(--default-clickable-area)) / 2);\n\t\t\t\tcursor: pointer;\n\t\t\t\topacity: $opacity_normal;\n\t\t\t}\n\t\t}\n\n\t\t&:deep() .action-item {\n\t\t\tmargin: calc((var(--header-height) - var(--default-clickable-area)) / 2);\n\n\t\t\t&--single {\n\t\t\t\twidth: var(--default-clickable-area);\n\t\t\t\theight: var(--default-clickable-area);\n\t\t\t\tcursor: pointer;\n\t\t\t\tbackground-position: center;\n\t\t\t\tbackground-size: 22px;\n\t\t\t}\n\t\t}\n\n\t\t// The modal ignores the color theme and adds a black backdrop\n\t\t// so we need to add custom color of the actions toggle\n\t\t.header-actions :deep(button:focus-visible) {\n\t\t\tbox-shadow: none !important;\n\t\t\toutline: 2px solid #fff !important;\n\t\t}\n\t}\n}\n\n.modal-wrapper {\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n\twidth: 100%;\n\theight: 100%;\n\n\t/* Navigation buttons */\n\t.prev,\n\t.next {\n\t\tz-index: 10000;\n\t\theight: 35vh;\n\t\tmin-height: 300px;\n\t\tposition: absolute;\n\t\ttransition: opacity 250ms;\n\t\t// hover the mask\n\t\tcolor: white;\n\n\t\t&:focus-visible {\n\t\t\t// Override NcButton focus styles\n\t\t\tbox-shadow: 0 0 0 2px var(--color-primary-element-text);\n\t\t\tbackground-color: var(--color-box-shadow);\n\t\t}\n\t}\n\n\t.prev {\n\t\tinset-inline-start: 2px;\n\t}\n\t.next {\n\t\tinset-inline-end: 2px;\n\t}\n\n\t/* Content */\n\t.modal-container {\n\t\tposition: relative;\n\t\tdisplay: flex;\n\t\tpadding: 0;\n\t\ttransition: transform 300ms ease;\n\t\tborder-radius: var(--border-radius-container);\n\t\tbackground-color: var(--color-main-background);\n\t\tcolor: var(--color-main-text);\n\t\tbox-shadow: 0 0 40px rgba(0, 0, 0, .2);\n\t\toverflow: auto;\n\n\t\t&__close {\n\t\t\t// Ensure the close button is always on top of the content\n\t\t\tz-index: 1;\n\t\t\tposition: absolute;\n\t\t\ttop: 4px;\n\t\t\tinset-inline-end: var(--default-grid-baseline);\n\t\t}\n\n\t\t&__content {\n\t\t\twidth: 100%;\n\t\t\tmin-height: 52px; // At least the close button shall fit in\n\t\t\toverflow: auto; // avoids unnecessary hacks if the content should be bigger than the modal\n\t\t}\n\t}\n\n\t// We allow 90% max-height, but we need to ensure the header does not overlap the modal\n\t// as the modal is centered, we need the space on top and bottom\n\t$max-modal-height: min(90%, calc(100% - 2 * var(--header-height)));\n\n\t// Sizing\n\t&--small {\n\t\t& > .modal-container {\n\t\t\twidth: 400px;\n\t\t\tmax-width: 90%;\n\t\t\tmax-height: $max-modal-height;\n\t\t}\n\t}\n\t&--normal {\n\t\t& > .modal-container {\n\t\t\tmax-width: 90%;\n\t\t\twidth: 600px;\n\t\t\tmax-height: $max-modal-height;\n\t\t}\n\t}\n\t&--large {\n\t\t& > .modal-container {\n\t\t\tmax-width: 90%;\n\t\t\twidth: 900px;\n\t\t\tmax-height: $max-modal-height;\n\t\t}\n\t}\n\t&--full {\n\t\t& > .modal-container {\n\t\t\twidth: 100%;\n\t\t\theight: calc(100% - var(--header-height));\n\t\t\tposition: absolute;\n\t\t\ttop: var(--header-height);\n\t\t\tborder-radius: 0;\n\t\t}\n\t}\n\n\t// Make modal full screen on mobile\n\t@media only screen and ((max-width: $breakpoint-small-mobile) or (max-height: 400px)) {\n\t\t.modal-container {\n\t\t\tmax-width: initial;\n\t\t\twidth: 100%;\n\t\t\tmax-height: initial;\n\t\t\theight: calc(100% - var(--header-height));\n\t\t\tposition: absolute;\n\t\t\ttop: var(--header-height);\n\t\t\tborder-radius: 0;\n\t\t}\n\t}\n}\n\n/* TRANSITIONS */\n.fade-enter-active,\n.fade-leave-active {\n\ttransition: opacity 250ms;\n}\n\n.fade-enter-from,\n.fade-leave-to {\n\topacity: 0;\n}\n\n.fade-visibility-enter-from,\n.fade-visibility-leave-to {\n\tvisibility: hidden;\n\topacity: 0;\n}\n\n.modal-in-enter-active,\n.modal-in-leave-active,\n.modal-out-enter-active,\n.modal-out-leave-active {\n\ttransition: opacity 250ms;\n}\n\n.modal-in-enter-from,\n.modal-in-leave-to,\n.modal-out-enter-from,\n.modal-out-leave-to {\n\topacity: 0;\n}\n\n.modal-in-enter .modal-container,\n.modal-in-leave-to .modal-container {\n\ttransform: scale(.9);\n}\n\n.modal-out-enter .modal-container,\n.modal-out-leave-to .modal-container {\n\ttransform: scale(1.1);\n}\n\n// animated circle\n$radius: 15;\n$pi: 3.14159265358979;\n\n.modal-mask .play-pause-icons {\n\t.progress-ring {\n\t\tposition: absolute;\n\t\ttop: 0;\n\t\tinset-inline-start: 0;\n\t\ttransform: rotate(-90deg);\n\t\t.progress-ring__circle {\n\t\t\ttransition: 100ms stroke-dashoffset;\n\t\t\ttransform-origin: 50% 50%; // axis compensation\n\t\t\tanimation: progressring linear v-bind('cssSlideshowDelay') infinite;\n\n\t\t\tstroke-linecap: round;\n\t\t\tstroke-dashoffset: $radius * 2 * $pi; // radius * 2 * PI\n\t\t\tstroke-dasharray: $radius * 2 * $pi; // radius * 2 * PI\n\t\t}\n\t}\n\t&--paused {\n\t\t.play-pause-icons__icon {\n\t\t\tanimation: breath 2s cubic-bezier(.4, 0, .2, 1) infinite;\n\t\t}\n\t\t.progress-ring__circle {\n\t\t\tanimation-play-state: paused !important;\n\t\t}\n\t}\n}\n\n// keyframes get scoped too and break the animation name, we need them unscoped\n@keyframes progressring {\n\tfrom {\n\t\tstroke-dashoffset: $radius * 2 * $pi; // radius * 2 * PI\n\t}\n\tto {\n\t\tstroke-dashoffset: 0;\n\t}\n}\n\n@keyframes breath {\n\t0% {\n\t\topacity: 1;\n\t}\n\t50% {\n\t\topacity: 0;\n\t}\n\t100% {\n\t\topacity: 1;\n\t}\n}\n</style>\n\n<docs>\nThe `NcModel` is the base component used for modals and dialogs.\nWhile `NcDialog` should be used for general dialogs like confirmations or forms,\n`NcModal` allows for custom content like showing image multimedia.\n\nFor showing the modal you can use either `v-model:show=\"showModal\"` or `v-if` on the `NcModal`,\ndepending on whether you require the Modal to stay within the DOM or not. Do not mix both, as this will break the out transition animation.\n\n```vue\n<template>\n\t<div>\n\t\t<NcButton @click=\"showModal\">Show Modal</NcButton>\n\t\t<NcModal\n\t\t\tv-model:show=\"modal\"\n\t\t\t@close=\"closeModal\"\n\t\t\tsize=\"small\"\n\t\t\tname=\"Name\"\n\t\t\tout-transition>\n\t\t\t<template #actions>\n\t\t\t\t<NcActionCaption name=\"Some action\" />\n\t\t\t</template>\n\t\t\t<div class=\"modal__content\">Hello world</div>\n\t\t</NcModal>\n\t</div>\n</template>\n<script>\nexport default {\n\tdata() {\n\t\treturn {\n\t\t\tmodal: false\n\t\t}\n\t},\n\tmethods: {\n\t\tshowModal() {\n\t\t\tthis.modal = true\n\t\t},\n\t\tcloseModal() {\n\t\t\tthis.modal = false\n\t\t}\n\t}\n}\n</script>\n<style scoped>\n.modal__content {\n\tmargin: 50px;\n\ttext-align: center;\n}\n</style>\n```\n\n### Modal with slideshow\n\n```vue\n<template>\n\t<div>\n\t\t<NcButton @click=\"isOpen = true\">Show Modal</NcButton>\n\t\t<NcModal\n\t\t\tv-if=\"isOpen\"\n\t\t\tclose-button-outside\n\t\t\tenable-slideshow\n\t\t\t:has-next=\"page < lastPage\"\n\t\t\t:has-previous=\"page > 0\"\n\t\t\tname=\"Modal with slideshow\"\n\t\t\t@next=\"page++\"\n\t\t\t@previous=\"page--\"\n\t\t\t@close=\"isOpen = false\">\n\t\t\t<div class=\"modal__content\" :style=\"{ background: currentPage.background }\">\n\t\t\t\t<p class=\"model__content-text\">{{ currentPage.text }}</p>\n\t\t\t</div>\n\t\t</NcModal>\n\t</div>\n</template>\n<script>\nconst PAGES = [\n\t{ text: 'First page', background: 'linear-gradient(#e66465, #9198e5)' },\n\t{ text: 'Second page', background: 'linear-gradient(0.25turn, #3f87a6, #ebf8e1, #f69d3c)' },\n\t{ text: 'Third page', background: 'lightblue' },\n\t{ text: 'Last page', background: 'lightgrey' },\n]\n\nexport default {\n\tdata() {\n\t\treturn {\n\t\t\tisOpen: false,\n\t\t\tpage: 0,\n\t\t\tlastPage: PAGES.length - 1,\n\t\t}\n\t},\n\tcomputed: {\n\t\tcurrentPage() {\n\t\t\treturn PAGES[this.page]\n\t\t},\n\t}\n}\n</script>\n<style scoped>\n.modal__content {\n\theight: 100%;\n\tmin-height: 30vh;\n\tdisplay: flex;\n\talign-items: center;\n\tjustify-content: center;\n}\n\n.model__content-text {\n\tfont-size: 16px;\n\tfont-weight: bold;\n}\n</style>\n```\n\n### Usage of popover in modal\n\n* Set container property to .modal-mask to inject popover context of the modal:\n\n```vue\n<template>\n\t<div>\n\t\t<NcButton @click=\"showModal\">Show Modal</NcButton>\n\t\t<NcModal\n\t\t\tv-model:show=\"modal\"\n\t\t\tclass=\"emoji-modal\"\n\t\t\tname=\"Modal with popover\"\n\t\t\tsize=\"small\"\n\t\t\t@close=\"closeModal\">\n\t\t\t<div class=\"emoji-modal__content\">\n\t\t\t\t<NcEmojiPicker container=\".emoji-modal\" @select=\"select\">\n\t\t\t\t\t<NcButton>Select emoji {{ emoji }}</NcButton>\n\t\t\t\t</NcEmojiPicker>\n\t\t\t</div>\n\t\t</NcModal>\n\t</div>\n</template>\n<script>\nexport default {\n\tdata() {\n\t\treturn {\n\t\t\temoji: '😛',\n\t\t\tmodal: false\n\t\t}\n\t},\n\tmethods: {\n\t\tshowModal() {\n\t\t\tthis.modal = true\n\t\t},\n\t\tcloseModal() {\n\t\t\tthis.modal = false\n\t\t},\n\t\tselect(emoji) {\n\t\t\tthis.emoji = emoji\n\t\t},\n\t},\n}\n</script>\n<style scoped>\n.emoji-modal__content {\n\tdisplay: flex;\n\tjustify-content: center;\n\tmargin: 20px 0px 100px;\n}\n</style>\n```\n</docs>\n"],"names":["instance","_useModel","_createBlock","_Teleport","container","_createVNode","_Transition","_withDirectives","_createElementVNode","_mergeProps","$attrs","_unref","dark","closeButtonOutside","hasPrevious","hasNext","lightBackdrop","labelId","name","_createElementBlock","enableSlideshow","_normalizeClass","slideshowPaused","inlineActions","_renderSlot","noClose","outTransition","size","spreadNavigation"],"mappings":"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"}