UNPKG

@oruga-ui/oruga-next

Version:

UI components for Vue.js and CSS framework agnostic

250 lines (249 loc) 10.8 kB
"use strict"; /*! Oruga v0.11.0 | MIT License | github.com/oruga-ui/oruga */ Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } }); const vue = require("vue"); const Icon_vue_vue_type_script_setup_true_lang = require("./Icon.vue_vue_type_script_setup_true_lang-ZtEqoTvT.cjs"); const config = require("./config-eYBvpFOZ.cjs"); const helpers = require("./helpers.cjs"); const defineClasses = require("./defineClasses-Cqhbv-UT.cjs"); const useMatchMedia = require("./useMatchMedia-EgWTgaUx.cjs"); const useClickOutside = require("./useClickOutside-CoQ2BNWF.cjs"); const usePreventScrolling = require("./usePreventScrolling-Ct3PCoON.cjs"); const useConfig = require("./useConfig-Zt3uf2uW.cjs"); const useTrapFocus = require("./useTrapFocus-DXSX2lWD.cjs"); const useProgrammatic = require("./useProgrammatic-D_ewnsB3.cjs"); const _hoisted_1 = ["role", "aria-label", "aria-modal"]; const _hoisted_2 = { key: 0 }; const _sfc_main = /* @__PURE__ */ vue.defineComponent({ ...{ isOruga: true, name: "OModal", configField: "modal", inheritAttrs: false }, __name: "Modal", props: /* @__PURE__ */ vue.mergeModels({ override: { type: Boolean, default: void 0 }, active: { type: Boolean, default: false }, fullScreen: { type: Boolean, default: false }, content: { default: void 0 }, width: { default: () => config.getDefault("modal.width", 960) }, animation: { default: () => config.getDefault("modal.animation", "zoom-out") }, overlay: { type: Boolean, default: () => config.getDefault("modal.overlay", true) }, cancelable: { type: [Array, Boolean], default: () => config.getDefault("modal.cancelable", ["escape", "x", "outside"]) }, clipScroll: { type: Boolean, default: () => config.getDefault("modal.clipScroll", false) }, trapFocus: { type: Boolean, default: () => config.getDefault("modal.trapFocus", true) }, alert: { type: Boolean, default: () => config.getDefault("modal.alert", false) }, ariaLabel: { default: () => config.getDefault("modal.ariaLabel") }, autoFocus: { type: Boolean, default: () => config.getDefault("modal.autoFocus", true) }, closeIcon: { default: () => config.getDefault("modal.closeIcon", "close") }, closeIconSize: { default: () => config.getDefault("modal.closeIconSize", "medium") }, ariaCloseLabel: { default: () => config.getDefault("modal.ariaCloseLabel", "Close") }, mobileBreakpoint: { default: () => config.getDefault("modal.mobileBreakpoint") }, teleport: { type: [Boolean, String, Object], default: () => config.getDefault("modal.teleport", false) }, container: {}, component: { default: void 0 }, props: { default: void 0 }, events: { default: void 0 }, rootClass: {}, mobileClass: {}, activeClass: {}, overlayClass: {}, contentClass: {}, fullScreenClass: {}, closeClass: {}, scrollClipClass: {}, scrollKeepClass: {} }, { "active": { type: Boolean, ...{ default: false } }, "activeModifiers": {} }), emits: /* @__PURE__ */ vue.mergeModels(["update:active", "close"], ["update:active"]), setup(__props, { expose: __expose, emit: __emit }) { const props = __props; const emits = __emit; const { vTrapFocus } = useTrapFocus.useTrapFocus(); const rootRef = vue.useTemplateRef("rootElement"); const contentRef = vue.useTemplateRef("contentElement"); const isActive = vue.useModel(__props, "active"); const { isMobile } = useMatchMedia.useMatchMedia(props.mobileBreakpoint); const _teleport = vue.computed( () => typeof props.teleport === "boolean" ? { to: useConfig.useTeleportDefault(), disabled: !props.teleport } : { to: props.teleport, disabled: false } ); const showX = vue.computed( () => Array.isArray(props.cancelable) ? props.cancelable.indexOf("x") >= 0 : props.cancelable ); const customStyle = vue.computed( () => !props.fullScreen ? { maxWidth: helpers.toCssDimension(props.width) } : null ); const toggleScroll = usePreventScrolling.usePreventScrolling(props.clipScroll); vue.watch(isActive, (value) => { if (props.overlay) toggleScroll(value); if (value && props.autoFocus) vue.nextTick(() => { if (rootRef.value) rootRef.value.focus(); }); }); vue.onMounted(() => { if (isActive.value && props.overlay) toggleScroll(isActive.value); }); if (config.isClient) { if (!props.overlay) useClickOutside.useClickOutside(contentRef, onClickedOutside, { trigger: isActive }); } function onClickedOutside(event) { if (!isActive.value || isAnimating.value) return; if (props.overlay || contentRef.value && !event.composedPath().includes(contentRef.value)) event.preventDefault(); cancel("outside"); } function onEscapePress() { if (!isActive.value) return; cancel("escape"); } function cancel(method) { if (typeof props.cancelable === "boolean" && !props.cancelable || !props.cancelable || Array.isArray(props.cancelable) && !props.cancelable.includes(method)) return; close(method); } function close(...args) { isActive.value = false; emits("close", ...args); } const isAnimating = vue.ref(!props.active); function afterEnter() { isAnimating.value = false; } function beforeLeave() { isAnimating.value = true; } const rootClasses = defineClasses.defineClasses( ["rootClass", "o-modal"], ["mobileClass", "o-modal--mobile", null, isMobile], ["activeClass", "o-modal--active", null, isActive] ); const overlayClasses = defineClasses.defineClasses(["overlayClass", "o-modal__overlay"]); const contentClasses = defineClasses.defineClasses( ["contentClass", "o-modal__content"], [ "fullScreenClass", "o-modal__content--full-screen", null, vue.computed(() => props.fullScreen) ] ); const closeClasses = defineClasses.defineClasses(["closeClass", "o-modal__close"]); __expose({ close }); return (_ctx, _cache) => { return vue.openBlock(), vue.createBlock(vue.Teleport, { to: _teleport.value.to, disabled: _teleport.value.disabled }, [ vue.createVNode(vue.Transition, { name: _ctx.animation, onAfterEnter: afterEnter, onBeforeLeave: beforeLeave }, { default: vue.withCtx(() => [ vue.withDirectives((vue.openBlock(), vue.createElementBlock("div", vue.mergeProps({ ref: "rootElement" }, _ctx.$attrs, { "data-oruga": "modal", class: vue.unref(rootClasses), tabindex: -1, role: _ctx.alert ? "alertdialog" : "dialog", "aria-label": _ctx.ariaLabel, "aria-modal": isActive.value, onKeyup: vue.withKeys(onEscapePress, ["escape"]) }), [ _ctx.overlay ? (vue.openBlock(), vue.createElementBlock("div", { key: 0, class: vue.normalizeClass(vue.unref(overlayClasses)), tabindex: "-1", onClick: onClickedOutside }, null, 2)) : vue.createCommentVNode("", true), vue.createElementVNode("div", { ref: "contentElement", class: vue.normalizeClass(vue.unref(contentClasses)), style: vue.normalizeStyle(customStyle.value) }, [ _ctx.component ? (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(_ctx.component), vue.mergeProps({ key: 0 }, _ctx.$props.props, vue.toHandlers(_ctx.$props.events || {}), { onClose: close }), null, 16)) : vue.renderSlot(_ctx.$slots, "default", { key: 1, close }, () => [ _ctx.content ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_2, vue.toDisplayString(_ctx.content), 1)) : vue.createCommentVNode("", true) ]), showX.value ? vue.withDirectives((vue.openBlock(), vue.createBlock(Icon_vue_vue_type_script_setup_true_lang._sfc_main, { key: 2, class: vue.normalizeClass(vue.unref(closeClasses)), icon: _ctx.closeIcon, size: _ctx.closeIconSize, clickable: "", "aria-label": _ctx.ariaCloseLabel, onClick: _cache[0] || (_cache[0] = ($event) => cancel("x")) }, null, 8, ["class", "icon", "size", "aria-label"])), [ [vue.vShow, !isAnimating.value] ]) : vue.createCommentVNode("", true) ], 6) ], 16, _hoisted_1)), [ [vue.vShow, isActive.value], [vue.unref(vTrapFocus), _ctx.trapFocus && isActive.value] ]) ]), _: 3 }, 8, ["name"]) ], 8, ["to", "disabled"]); }; } }); const registry = new useProgrammatic.InstanceRegistry(); const ModalProgrammatic = { /** Returns the number of registered active instances. */ count: registry.count, /** * Create a new programmatic modal component instance. * @param options modal content string or modal component props object * @param target specify a target the component get rendered into - default is `document.body` * @returns ProgrammaticExpose */ open(options, target) { const _options = typeof options === "string" ? { content: options } : options; const componentProps = { active: true, // set the active default state to true ..._options }; return useProgrammatic.ComponentProgrammatic.open(_sfc_main, { registry, // custom programmatic instance registry target, // target the component get rendered into props: componentProps, // component specific props onClose: _options.onClose // on close event handler }); }, /** Close the last registred instance in the modal programmatic instance registry. */ close(...args) { var _a, _b; (_b = (_a = registry.last()) == null ? void 0 : _a.exposed) == null ? void 0 : _b.close(...args); }, /** Close all instances in the programmatic modal instance registry. */ closeAll(...args) { registry.walk((entry) => { var _a; return (_a = entry.exposed) == null ? void 0 : _a.close(...args); }); } }; const index = { install(app) { config.registerComponent(app, _sfc_main); config.registerComponentProgrammatic(app, "modal", ModalProgrammatic); } }; exports.ModalProgrammatic = ModalProgrammatic; exports.OModal = _sfc_main; exports.default = index; //# sourceMappingURL=modal.cjs.map