UNPKG

@oruga-ui/oruga-next

Version:

UI components for Vue.js and CSS framework agnostic

279 lines (278 loc) 10.8 kB
/*! Oruga v0.11.0 | MIT License | github.com/oruga-ui/oruga */ import { defineComponent, mergeModels, useTemplateRef, useModel, computed, watch, onMounted, ref, createBlock, openBlock, Teleport, withDirectives, createElementBlock, mergeProps, unref, createCommentVNode, createVNode, normalizeClass, Transition, withCtx, createElementVNode, renderSlot, resolveDynamicComponent, toHandlers, vShow } from "vue"; import { i as isClient, g as getDefault, b as registerComponent, a as registerComponentProgrammatic } from "./config-Dl7tu_Ly.mjs"; import { d as defineClasses } from "./defineClasses-CWB9NuS-.mjs"; import { u as useEventListener } from "./useEventListener-nW3U5kAY.mjs"; import { u as useMatchMedia } from "./useMatchMedia-Go6cZv_b.mjs"; import { u as useClickOutside } from "./useClickOutside-Cq7Otb3W.mjs"; import { u as usePreventScrolling } from "./usePreventScrolling-CRyyOkPi.mjs"; import { u as useTeleportDefault } from "./useConfig-43UsDYp_.mjs"; import { u as useTrapFocus } from "./useTrapFocus-lpk0D-Ty.mjs"; import { I as InstanceRegistry, C as ComponentProgrammatic } from "./useProgrammatic-B50-6K60.mjs"; const _sfc_main = /* @__PURE__ */ defineComponent({ ...{ isOruga: true, name: "OSidebar", configField: "sidebar", inheritAttrs: false }, __name: "Sidebar", props: /* @__PURE__ */ mergeModels({ override: { type: Boolean, default: void 0 }, active: { type: Boolean, default: false }, overlay: { type: Boolean, default: () => getDefault("sidebar.overlay", false) }, inline: { type: Boolean, default: false }, position: { default: () => getDefault("sidebar.position", "left") }, fullheight: { type: Boolean, default: () => getDefault("sidebar.fullheight", false) }, fullwidth: { type: Boolean, default: () => getDefault("sidebar.fullwidth", false) }, reduce: { type: Boolean, default: () => getDefault("sidebar.reduce", false) }, mobile: { default: () => getDefault("sidebar.mobile") }, expandOnHover: { type: Boolean, default: () => getDefault("sidebar.expandOnHover", false) }, animation: { default: () => getDefault("sidebar.animation") }, cancelable: { type: [Array, Boolean], default: () => getDefault("sidebar.cancelable", ["escape", "outside"]) }, clipScroll: { type: Boolean, default: () => getDefault("sidebar.clipScroll", false) }, trapFocus: { type: Boolean, default: () => getDefault("sidebar.trapFocus", true) }, mobileBreakpoint: { default: () => getDefault("sidebar.mobileBreakpoint") }, teleport: { type: [Boolean, String, Object], default: () => getDefault("sidebar.teleport", false) }, container: {}, component: { default: void 0 }, props: { default: void 0 }, events: { default: void 0 }, rootClass: {}, mobileClass: {}, activeClass: {}, teleportClass: {}, inlineClass: {}, overlayClass: {}, contentClass: {}, hiddenClass: {}, visibleClass: {}, positionClass: {}, fullheightClass: {}, fullwidthClass: {}, reduceClass: {}, expandOnHoverClass: {}, scrollClipClass: {}, scrollKeepClass: {} }, { "active": { type: Boolean, ...{ default: false } }, "activeModifiers": {} }), emits: /* @__PURE__ */ mergeModels(["update:active", "close"], ["update:active"]), setup(__props, { expose: __expose, emit: __emit }) { const props = __props; const emits = __emit; const { vTrapFocus } = useTrapFocus(); const rootRef = useTemplateRef("rootElement"); const contentRef = useTemplateRef("contentElement"); const isActive = useModel(__props, "active"); const { isMobile } = useMatchMedia(props.mobileBreakpoint); const _teleport = computed( () => typeof props.teleport === "boolean" ? { to: useTeleportDefault(), disabled: !props.teleport } : { to: props.teleport, disabled: false } ); const transitionName = computed(() => { if (props.animation) return props.animation; const vertical = props.position === "top" || props.position === "bottom"; const right = props.position === "right"; const open = right ? !isActive.value : isActive.value; return open ? vertical ? "slide-down" : "slide-next" : vertical ? "slide-up" : "slide-prev"; }); const hideOnMobile = computed( () => props.mobile === "hidden" && isMobile.value ); const toggleScroll = usePreventScrolling(props.clipScroll); watch( isActive, (value) => { if (props.overlay) toggleScroll(value); }, { flush: "post" } ); onMounted(() => { if (isActive.value && props.overlay) toggleScroll(true); }); if (isClient) { useEventListener(rootRef, "keyup", onKeyPress, { trigger: isActive }); if (!props.overlay) useClickOutside(contentRef, clickedOutside, { trigger: isActive }); } function onKeyPress(event) { if (!isActive.value) return; if (event.key === "Escape" || event.key === "Esc") cancel("escape"); } function clickedOutside(event) { if (props.inline || !isActive.value || isAnimating.value) return; if (props.overlay || contentRef.value && !event.composedPath().includes(contentRef.value)) event.preventDefault(); cancel("outside"); } 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 = ref(!props.active); function afterEnter() { isAnimating.value = false; } function beforeLeave() { isAnimating.value = true; } const rootClasses = defineClasses( ["rootClass", "o-sidebar"], ["mobileClass", "o-sidebar--mobile", null, isMobile], ["activeClass", "o-sidebar--active", null, isActive], [ "teleportClass", "o-sidebar--teleport", null, computed(() => !!props.teleport) ], ["inlineClass", "o-sidebar--inline", null, computed(() => props.inline)] ); const overlayClasses = defineClasses(["overlayClass", "o-sidebar__overlay"]); const contentClasses = defineClasses( ["contentClass", "o-sidebar__content"], [ "positionClass", "o-sidebar__content--", computed(() => props.position), computed(() => !!props.position) ], [ "fullheightClass", "o-sidebar__content--fullheight", null, computed(() => props.fullheight) ], [ "fullwidthClass", "o-sidebar__content--fullwidth", null, computed( () => props.fullwidth || isMobile.value && props.mobile === "expanded" ) ], [ "reduceClass", "o-sidebar__content--reduced", null, computed( () => props.reduce || isMobile.value && props.mobile === "reduced" ) ], [ "expandOnHoverClass", "o-sidebar__content--hover-expand", null, computed( () => props.expandOnHover && (!isMobile.value || props.mobile !== "expanded") ) ], ["visibleClass", "o-sidebar__content--visible", null, isActive], [ "hiddenClass", "o-sidebar__content--hidden", null, computed(() => !isActive.value) ] ); __expose({ close }); return (_ctx, _cache) => { return openBlock(), createBlock(Teleport, { to: _teleport.value.to, disabled: _teleport.value.disabled }, [ withDirectives((openBlock(), createElementBlock("div", mergeProps({ ref: "rootElement" }, _ctx.$attrs, { "data-oruga": "sidebar", class: unref(rootClasses) }), [ _ctx.overlay && isActive.value ? (openBlock(), createElementBlock("div", { key: 0, class: normalizeClass(unref(overlayClasses)), tabindex: -1, onClick: clickedOutside }, null, 2)) : createCommentVNode("", true), createVNode(Transition, { name: transitionName.value, onAfterEnter: afterEnter, onBeforeLeave: beforeLeave }, { default: withCtx(() => [ withDirectives(createElementVNode("div", { ref: "contentElement", class: normalizeClass(unref(contentClasses)) }, [ renderSlot(_ctx.$slots, "default", { close }, () => [ _ctx.component ? (openBlock(), createBlock(resolveDynamicComponent(_ctx.component), mergeProps({ key: 0 }, _ctx.$props.props, toHandlers(_ctx.$props.events || {}), { onClose: close }), null, 16)) : createCommentVNode("", true) ]) ], 2), [ [vShow, isActive.value] ]) ]), _: 3 }, 8, ["name"]) ], 16)), [ [vShow, !hideOnMobile.value], [unref(vTrapFocus), _ctx.trapFocus && isActive.value && !_ctx.inline] ]) ], 8, ["to", "disabled"]); }; } }); const registry = new InstanceRegistry(); const SidebarProgrammatic = { /** Returns the number of registered active instances. */ count: registry.count, /** * Create a new programmatic sidebar component instance. * @param options sidebar component props object * @param target specify a target the component get rendered into - default is `document.body` * @returns ProgrammaticExpose */ open(options, target) { const componentProps = { active: true, // set the active default state to true ...options }; return 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 sidebar 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 sidebar instance registry. */ closeAll(...args) { registry.walk((entry) => { var _a; return (_a = entry.exposed) == null ? void 0 : _a.close(...args); }); } }; const index = { install(app) { registerComponent(app, _sfc_main); registerComponentProgrammatic(app, "sidebar", SidebarProgrammatic); } }; export { _sfc_main as OSidebar, SidebarProgrammatic, index as default }; //# sourceMappingURL=sidebar.mjs.map