UNPKG

@oruga-ui/oruga-next

Version:

UI components for Vue.js and CSS framework agnostic

138 lines (137 loc) 4.46 kB
/*! Oruga v0.11.4 | MIT License | github.com/oruga-ui/oruga */ import { defineComponent, getCurrentInstance, onMounted, onUnmounted, createVNode, toValue, createApp } from "vue"; import { i as isClient, V as VueInstance } from "./config-BhtJomvl.mjs"; import { r as resolveElement } from "./unrefElement-D7RSwowH.mjs"; import { g as getTeleportDefault } from "./useConfig-BoLnLsCX.mjs"; class InstanceRegistry { entries; constructor() { this.entries = []; } /** Returns the number of registered active instances. */ count() { return this.entries.length; } /** Returns the first registered active instance. */ fist() { return this.entries.at(0); } /** Returns the last registered active instance. */ last() { return this.entries.at(-1); } /** Adds a new instance to the instance stack. */ add(entry) { this.entries.push(entry); } /** Removes an instance from the instance stack. */ remove(entry) { const index = this.entries.indexOf(entry); this.entries.splice(index, 1); } /** Call a function for every registered active instance. */ walk(callback) { this.entries = [...this.entries].filter((e) => { const ret = callback(e); return !(ret === true); }); } } const ProgrammaticComponent = defineComponent( (props, { expose, emit, slots }) => { const vm = getCurrentInstance(); if (!vm) throw new Error("ProgrammaticComponent initialisation failed."); let resolve; const promise = new Promise((p1) => resolve = p1); onMounted(() => props.registry?.add(vm)); onUnmounted(() => props.registry?.remove(vm)); function close(...args) { emit("close", ...args); resolve(args); setTimeout(() => { if (isClient) window.requestAnimationFrame(() => emit("destroy")); else emit("destroy"); }); } expose({ close, promise }); return () => createVNode( props.component, { ...props.props, onClose: close }, slots["default"] ); }, { name: "ProgrammaticApp", // manual runtime props declaration is currently still needed. props: ["component", "props", "registry"], // manual runtime emits declaration emits: ["close", "destroy"], // manual runtime slot declaration slots: ["default"] } ); const registry = new InstanceRegistry(); const ComponentProgrammatic = { /** Returns the number of registered active instances. */ count: registry.count, /** * Create a new programmatic component instance. * @param component component to render * @param options render options */ open(component, options) { options = { registry, ...options }; const targetQuery = toValue(options.target); const target = ( // either by a given query selector / element targetQuery && resolveElement(targetQuery) || // or by the default teleport target config resolveElement(getTeleportDefault()) ); if (!target) throw new Error("ComponentProgrammatic - no target is defined."); let container = document.createElement("div"); container.id = options.appId || "programmatic-app"; target.appendChild(container); function onDestroy() { if (app) { app.unmount(); app = void 0; } if (container && target) { target.removeChild(container); container = void 0; } } let app = createApp(ProgrammaticComponent, { registry: options.registry, // programmatic registry instance - can be overriden by given in options component, // the component which should be rendered props: { ...options.props, container: target }, // component props including the target as `container` onClose: options.onClose, // custom onClose handler onDestroy // node destory cleanup handler }); if (VueInstance) app._context = Object.assign(app._context, VueInstance._context); const instance = app.mount(container); return instance; }, /** close the last registred instance in the global programmatic instance registry */ close(...args) { registry.last()?.exposed?.close(...args); }, /** close all instances in the global programmatic instance registry */ closeAll(...args) { registry.walk((entry) => entry.exposed?.close(...args)); } }; export { ComponentProgrammatic as C, InstanceRegistry as I }; //# sourceMappingURL=useProgrammatic-BJ4NxHDC.mjs.map