105 lines
3.4 KiB
JavaScript
105 lines
3.4 KiB
JavaScript
import { createVNode as _createVNode, mergeProps as _mergeProps } from "vue";
|
|
// Styles
|
|
import "./VDialog.css";
|
|
|
|
// Components
|
|
import { VDialogTransition } from "../transitions/index.js";
|
|
import { VDefaultsProvider } from "../VDefaultsProvider/index.js";
|
|
import { VOverlay } from "../VOverlay/index.js";
|
|
import { makeVOverlayProps } from "../VOverlay/VOverlay.js"; // Composables
|
|
import { forwardRefs } from "../../composables/forwardRefs.js";
|
|
import { useProxiedModel } from "../../composables/proxiedModel.js";
|
|
import { useScopeId } from "../../composables/scopeId.js"; // Utilities
|
|
import { mergeProps, nextTick, ref, watch } from 'vue';
|
|
import { genericComponent, omit, propsFactory, useRender } from "../../util/index.js"; // Types
|
|
export const makeVDialogProps = propsFactory({
|
|
fullscreen: Boolean,
|
|
scrollable: Boolean,
|
|
...omit(makeVOverlayProps({
|
|
captureFocus: true,
|
|
origin: 'center center',
|
|
scrollStrategy: 'block',
|
|
transition: {
|
|
component: VDialogTransition
|
|
},
|
|
zIndex: 2400,
|
|
retainFocus: true
|
|
}), ['disableInitialFocus'])
|
|
}, 'VDialog');
|
|
export const VDialog = genericComponent()({
|
|
name: 'VDialog',
|
|
props: makeVDialogProps(),
|
|
emits: {
|
|
'update:modelValue': value => true,
|
|
afterEnter: () => true,
|
|
afterLeave: () => true
|
|
},
|
|
setup(props, {
|
|
emit,
|
|
slots
|
|
}) {
|
|
const isActive = useProxiedModel(props, 'modelValue');
|
|
const {
|
|
scopeId
|
|
} = useScopeId();
|
|
const overlay = ref();
|
|
function onAfterEnter() {
|
|
emit('afterEnter');
|
|
if ((props.scrim || props.retainFocus) && overlay.value?.contentEl && !overlay.value.contentEl.contains(document.activeElement)) {
|
|
overlay.value.contentEl.focus({
|
|
preventScroll: true
|
|
});
|
|
}
|
|
}
|
|
function onAfterLeave() {
|
|
emit('afterLeave');
|
|
}
|
|
watch(isActive, async val => {
|
|
if (!val) {
|
|
await nextTick();
|
|
overlay.value.activatorEl?.focus({
|
|
preventScroll: true
|
|
});
|
|
}
|
|
});
|
|
useRender(() => {
|
|
const overlayProps = VOverlay.filterProps(props);
|
|
const activatorProps = mergeProps({
|
|
'aria-haspopup': 'dialog'
|
|
}, props.activatorProps);
|
|
const contentProps = mergeProps({
|
|
tabindex: -1
|
|
}, props.contentProps);
|
|
return _createVNode(VOverlay, _mergeProps({
|
|
"ref": overlay,
|
|
"class": ['v-dialog', {
|
|
'v-dialog--fullscreen': props.fullscreen,
|
|
'v-dialog--scrollable': props.scrollable
|
|
}, props.class],
|
|
"style": props.style
|
|
}, overlayProps, {
|
|
"modelValue": isActive.value,
|
|
"onUpdate:modelValue": $event => isActive.value = $event,
|
|
"aria-modal": "true",
|
|
"activatorProps": activatorProps,
|
|
"contentProps": contentProps,
|
|
"height": !props.fullscreen ? props.height : undefined,
|
|
"width": !props.fullscreen ? props.width : undefined,
|
|
"maxHeight": !props.fullscreen ? props.maxHeight : undefined,
|
|
"maxWidth": !props.fullscreen ? props.maxWidth : undefined,
|
|
"role": "dialog",
|
|
"onAfterEnter": onAfterEnter,
|
|
"onAfterLeave": onAfterLeave
|
|
}, scopeId), {
|
|
activator: slots.activator,
|
|
default: (...args) => _createVNode(VDefaultsProvider, {
|
|
"root": "VDialog"
|
|
}, {
|
|
default: () => [slots.default?.(...args)]
|
|
})
|
|
});
|
|
});
|
|
return forwardRefs({}, overlay);
|
|
}
|
|
});
|
|
//# sourceMappingURL=VDialog.js.map
|