{"version":3,"file":"portal-vue.es.dev.mjs","sources":["../src/composables/wormhole.ts","../src/utils/index.ts","../src/components/portal.ts","../src/components/portal-target.ts","../src/wormhole.ts","../src/utils/mountPortalTarget.ts","../src/index.ts"],"sourcesContent":["import { type InjectionKey, inject, provide } from 'vue'\nimport type { Wormhole } from '../types'\n\nexport const wormholeSymbol = Symbol('wormhole') as InjectionKey<Wormhole>\n\nexport function useWormhole() {\n  const wh = inject(wormholeSymbol)\n\n  if (!wh) {\n    throw new Error(`\n    [portal-vue]: Necessary Injection not found. Make sur you installed the plugin properly.`)\n  }\n\n  return wh\n}\n\nexport function provideWormhole(wormhole: Wormhole) {\n  provide(wormholeSymbol, wormhole)\n}\n","import { watch } from 'vue'\n\nexport const inBrowser = typeof window !== 'undefined'\n\nexport const __DEV__ = __NODE_ENV__ === 'development'\n\nexport function warn(msg: string) {\n  console.log('[portal-vue]: ' + msg)\n}\n\nexport function assertStaticProps(\n  component: string,\n  props: Record<string, any>,\n  propNames: string[]\n) {\n  propNames.forEach(\n    (name) => {\n      watch(\n        () => props[name],\n        () => {\n          warn(\n            `Prop '${name}' of component ${component} is static, but was dynamically changed by the parent.\n          This change will not have any effect.`\n          )\n        }\n      )\n    },\n    { flush: 'post' }\n  )\n}\n\nexport function stableSort<T>(array: T[], compareFn: Function) {\n  return array\n    .map((v: T, idx: number) => {\n      return [idx, v] as [number, T]\n    })\n    .sort(function (a, b) {\n      return compareFn(a[1], b[1]) || a[0] - b[0]\n    })\n    .map((c) => c[1])\n}\n","import {\n  type Slots,\n  defineComponent,\n  onBeforeUnmount,\n  onMounted,\n  onUpdated,\n  watch,\n} from 'vue'\nimport { useWormhole } from '../composables/wormhole'\nimport type { Name, PortalProps } from '../types'\nimport { __DEV__, assertStaticProps, inBrowser } from '../utils'\n\nexport function usePortal(props: PortalProps, slots: Slots) {\n  const wormhole = useWormhole()\n\n  function sendUpdate() {\n    if (!inBrowser) return\n    const { to, name: from, order } = props\n    if (slots.default) {\n      wormhole.open({\n        to,\n        from: from!,\n        order,\n        content: slots.default,\n      })\n    } else {\n      clear()\n    }\n  }\n\n  function clear(target?: Name) {\n    wormhole.close({\n      to: target ?? props.to,\n      from: props.name,\n    })\n  }\n  onMounted(() => {\n    if (!props.disabled) {\n      sendUpdate()\n    }\n  })\n\n  onUpdated(() => {\n    if (props.disabled) {\n      clear()\n    } else {\n      sendUpdate()\n    }\n  })\n\n  onBeforeUnmount(() => {\n    clear()\n  })\n\n  watch(\n    () => props.to,\n    (newTo, oldTo) => {\n      if (props.disabled) return\n      if (oldTo && oldTo !== newTo) {\n        clear(oldTo)\n      }\n      sendUpdate()\n    }\n  )\n}\n\nexport default defineComponent({\n  compatConfig: { MODE: 3 },\n  name: 'portal',\n  props: {\n    disabled: { type: Boolean },\n    name: { type: [String, Symbol], default: () => Symbol() },\n    order: { type: Number },\n    slotProps: { type: Object, default: () => ({}) },\n    to: {\n      type: String,\n      default: () => String(Math.round(Math.random() * 10000000)),\n    },\n  },\n  setup(props, { slots }) {\n    __DEV__ && assertStaticProps('Portal', props, ['order', 'name'])\n    usePortal(props, slots)\n\n    return () => {\n      if (props.disabled && slots.default) {\n        return slots.default(props.slotProps)\n      } else {\n        return null\n      }\n    }\n  },\n})\n","import {\n  type FunctionalComponent,\n  type VNode,\n  computed,\n  defineComponent,\n  h,\n  watch,\n} from 'vue'\nimport { useWormhole } from '../composables/wormhole'\n\nconst PortalTargetContent: FunctionalComponent = (_, { slots }) => {\n  return slots.default?.()\n}\n\nexport default defineComponent({\n  compatConfig: { MODE: 3 },\n  name: 'portalTarget',\n  props: {\n    multiple: { type: Boolean, default: false },\n    name: { type: String, required: true },\n    slotProps: { type: Object, default: () => ({}) },\n  },\n  emits: ['change'],\n  setup(props, { emit, slots }) {\n    const wormhole = useWormhole()\n\n    const slotVnodes = computed<{ vnodes: VNode[]; vnodesFn: () => VNode[] }>(\n      () => {\n        const transports = wormhole.getContentForTarget(\n          props.name,\n          props.multiple\n        )\n        const wrapperSlot = slots.wrapper\n        const rawNodes = transports.map((t) => t.content(props.slotProps))\n        const vnodes = wrapperSlot\n          ? rawNodes.flatMap((nodes) =>\n              nodes.length ? wrapperSlot(nodes) : []\n            )\n          : rawNodes.flat(1)\n        return {\n          vnodes,\n          vnodesFn: () => vnodes, // just to make Vue happy. raw vnodes in a slot give a DEV warning\n        }\n      }\n    )\n\n    watch(\n      slotVnodes,\n      ({ vnodes }) => {\n        const hasContent = vnodes.length > 0\n        const content = wormhole.transports.get(props.name)\n        const sources = content ? [...content.keys()] : []\n        emit('change', { hasContent, sources })\n      },\n      { flush: 'post' }\n    )\n    return () => {\n      const hasContent = !!slotVnodes.value.vnodes.length\n      if (hasContent) {\n        return [\n          // this node is a necessary hack to force Vue to change the scoped-styles boundary\n          // TODO:  find less hacky solution\n          h('div', {\n            style: 'display: none',\n            key: '__portal-vue-hacky-scoped-slot-repair__',\n          }),\n          // we wrap the slot content in a functional component\n          // so that transitions in the slot can properly determine first render\n          // for `appear` behavior to work properly\n          h(PortalTargetContent, slotVnodes.value.vnodesFn),\n        ]\n      } else {\n        return slots.default?.()\n      }\n    }\n  },\n})\n","import { reactive, readonly } from 'vue'\nimport type {\n  Name,\n  Transport,\n  TransportCloser,\n  TransportInput,\n  TransportsHub,\n  Wormhole,\n} from './types'\nimport { inBrowser, stableSort } from './utils'\n\nexport function createWormhole(asReadonly = true): Wormhole {\n  const transports: TransportsHub = reactive(new Map())\n\n  function open(transport: TransportInput) {\n    if (!inBrowser) return\n\n    const { to, from, content, order = Infinity } = transport\n    if (!to || !from || !content) return\n\n    if (!transports.has(to)) {\n      transports.set(to, new Map())\n    }\n    const transportsForTarget = transports.get(to)!\n\n    const newTransport = {\n      to,\n      from,\n      content,\n      order,\n    } as Transport\n\n    transportsForTarget.set(from, newTransport)\n  }\n\n  function close(transport: TransportCloser) {\n    const { to, from } = transport\n    if (!to || !from) return\n    const transportsForTarget = transports.get(to)\n    if (!transportsForTarget) {\n      return\n    }\n    transportsForTarget.delete(from)\n    if (!transportsForTarget.size) {\n      transports.delete(to)\n    }\n  }\n\n  function getContentForTarget(target: Name, returnAll?: boolean) {\n    const transportsForTarget = transports.get(target)\n    if (!transportsForTarget) return []\n\n    const content = Array.from(transportsForTarget?.values() || [])\n\n    if (!returnAll) {\n      // return Transport that was added last\n      return [content.pop()] as Transport[]\n    }\n    // return all Transports, sorted by their order property\n    return stableSort(\n      content,\n      (a: Transport, b: Transport) => a.order - b.order\n    )\n  }\n\n  const wh: Wormhole = {\n    open,\n    close,\n    transports,\n    getContentForTarget,\n  }\n  return asReadonly ? (readonly(wh) as Wormhole) : wh\n}\n\nexport const wormhole = createWormhole()\n","import type { PortalTargetProps } from '../types'\nimport {\n  type ComponentInternalInstance,\n  createApp,\n  getCurrentInstance,\n  h,\n  onBeforeUnmount,\n  onMounted,\n} from 'vue'\nimport PortalTarget from '../components/portal-target'\n\nexport function mountPortalTarget(\n  targetProps: PortalTargetProps,\n  el: HTMLElement | string\n) {\n  const app = createApp({\n    // @ts-expect-error no idea why h() doesn't like this import\n    render: () => h(PortalTarget, targetProps),\n  })\n\n  if (!targetProps.multiple) {\n    // this is hacky as it relies on internals, but works.\n    // TODO: can we get rid of this by somehow properly replacing the target's .parent?\n    const provides =\n      (\n        getCurrentInstance() as ComponentInternalInstance & {\n          provides: Record<string, any>\n        }\n      ).provides ?? {}\n    app._context.provides = Object.create(provides)\n    //Object.assign(app._context.provides, Object.create(provides))\n  }\n  onMounted(() => {\n    app.mount(el)\n  })\n  onBeforeUnmount(() => {\n    app.unmount()\n  })\n}\n","import type { App } from 'vue'\nimport Portal from './components/portal'\nimport PortalTarget from './components/portal-target'\nimport {\n  provideWormhole,\n  useWormhole,\n  wormholeSymbol,\n} from './composables/wormhole'\nimport type { Wormhole as TWormhole } from './types'\nimport { createWormhole, wormhole as defaultWormhole } from './wormhole'\nexport { mountPortalTarget } from './utils/mountPortalTarget'\nexport interface PluginOptions {\n  portalName?: string | false\n  portalTargetName?: string | false\n  MountingPortalName?: string\n  wormhole?: TWormhole\n}\n\nexport default function install(app: App, options: PluginOptions = {}) {\n  options.portalName !== false &&\n    app.component(options.portalName || 'Portal', Portal)\n  options.portalTargetName !== false &&\n    app.component(options.portalTargetName || 'PortalTarget', PortalTarget)\n\n  const wormhole = options.wormhole ?? defaultWormhole\n  app.provide(wormholeSymbol, wormhole)\n}\n\nexport const Wormhole = defaultWormhole\n\nexport const version = __PORTAL_VUE_VERSION__\n\nexport {\n  install,\n  Portal,\n  PortalTarget,\n  useWormhole,\n  provideWormhole,\n  TWormhole,\n  createWormhole,\n}\n"],"names":["wormhole","defaultWormhole"],"mappings":";AAGa,MAAA,iBAAiB,OAAO,UAAU;AAExC,SAAS,cAAc;AACtB,QAAA,KAAK,OAAO,cAAc;AAEhC,MAAI,CAAC,IAAI;AACP,UAAM,IAAI,MAAM;AAAA,6FACyE;AAAA,EAC3F;AAEO,SAAA;AACT;AAEO,SAAS,gBAAgBA,WAAoB;AAClD,UAAQ,gBAAgBA,SAAQ;AAClC;AChBa,MAAA,YAAY,OAAO,WAAW;AAIpC,SAAS,KAAK,KAAa;AACxB,UAAA,IAAI,mBAAmB,GAAG;AACpC;AAEgB,SAAA,kBACd,WACA,OACA,WACA;AACU,YAAA;AAAA,IACR,CAAC,SAAS;AACR;AAAA,QACE,MAAM,MAAM;AAAA,QACZ,MAAM;AACJ;AAAA,YACE,SAAS,sBAAsB;AAAA;AAAA,UAAA;AAAA,QAGnC;AAAA,MAAA;AAAA,IAEJ;AAAA,IACA,EAAE,OAAO,OAAO;AAAA,EAAA;AAEpB;AAEgB,SAAA,WAAc,OAAY,WAAqB;AAC7D,SAAO,MACJ,IAAI,CAAC,GAAM,QAAgB;AACnB,WAAA,CAAC,KAAK,CAAC;AAAA,EACf,CAAA,EACA,KAAK,SAAU,GAAG,GAAG;AACb,WAAA,UAAU,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE;AAAA,EAAA,CAC1C,EACA,IAAI,CAAC,MAAM,EAAE,EAAE;AACpB;AC5BgB,SAAA,UAAU,OAAoB,OAAc;AAC1D,QAAMA,YAAW;AAEjB,WAAS,aAAa;AACpB,QAAI,CAAC;AAAW;AAChB,UAAM,EAAE,IAAI,MAAM,MAAM,UAAU;AAClC,QAAI,MAAM,SAAS;AACjB,MAAAA,UAAS,KAAK;AAAA,QACZ;AAAA,QACA;AAAA,QACA;AAAA,QACA,SAAS,MAAM;AAAA,MAAA,CAChB;AAAA,IAAA,OACI;AACC;IACR;AAAA,EACF;AAEA,WAAS,MAAM,QAAe;AAC5B,IAAAA,UAAS,MAAM;AAAA,MACb,IAAI,UAAU,MAAM;AAAA,MACpB,MAAM,MAAM;AAAA,IAAA,CACb;AAAA,EACH;AACA,YAAU,MAAM;AACV,QAAA,CAAC,MAAM,UAAU;AACR;IACb;AAAA,EAAA,CACD;AAED,YAAU,MAAM;AACd,QAAI,MAAM,UAAU;AACZ;IAAA,OACD;AACM;IACb;AAAA,EAAA,CACD;AAED,kBAAgB,MAAM;AACd;EAAA,CACP;AAED;AAAA,IACE,MAAM,MAAM;AAAA,IACZ,CAAC,OAAO,UAAU;AAChB,UAAI,MAAM;AAAU;AAChB,UAAA,SAAS,UAAU,OAAO;AAC5B,cAAM,KAAK;AAAA,MACb;AACW;IACb;AAAA,EAAA;AAEJ;AAEA,MAAA,SAAe,gBAAgB;AAAA,EAC7B,cAAc,EAAE,MAAM,EAAE;AAAA,EACxB,MAAM;AAAA,EACN,OAAO;AAAA,IACL,UAAU,EAAE,MAAM,QAAQ;AAAA,IAC1B,MAAM,EAAE,MAAM,CAAC,QAAQ,MAAM,GAAG,SAAS,MAAM,SAAS;AAAA,IACxD,OAAO,EAAE,MAAM,OAAO;AAAA,IACtB,WAAW,EAAE,MAAM,QAAQ,SAAS,OAAO,CAAI,GAAA;AAAA,IAC/C,IAAI;AAAA,MACF,MAAM;AAAA,MACN,SAAS,MAAM,OAAO,KAAK,MAAM,KAAK,OAAA,IAAW,GAAQ,CAAC;AAAA,IAC5D;AAAA,EACF;AAAA,EACA,MAAM,OAAO,EAAE,SAAS;AACX,sBAAkB,UAAU,OAAO,CAAC,SAAS,MAAM,CAAC;AAC/D,cAAU,OAAO,KAAK;AAEtB,WAAO,MAAM;AACP,UAAA,MAAM,YAAY,MAAM,SAAS;AAC5B,eAAA,MAAM,QAAQ,MAAM,SAAS;AAAA,MAAA,OAC/B;AACE,eAAA;AAAA,MACT;AAAA,IAAA;AAAA,EAEJ;AACF,CAAC;ACjFD,MAAM,sBAA2C,CAAC,GAAG,EAAE,YAAY;;AACjE,UAAO,WAAM,YAAN;AACT;AAEA,MAAA,eAAe,gBAAgB;AAAA,EAC7B,cAAc,EAAE,MAAM,EAAE;AAAA,EACxB,MAAM;AAAA,EACN,OAAO;AAAA,IACL,UAAU,EAAE,MAAM,SAAS,SAAS,MAAM;AAAA,IAC1C,MAAM,EAAE,MAAM,QAAQ,UAAU,KAAK;AAAA,IACrC,WAAW,EAAE,MAAM,QAAQ,SAAS,OAAO,CAAI,GAAA;AAAA,EACjD;AAAA,EACA,OAAO,CAAC,QAAQ;AAAA,EAChB,MAAM,OAAO,EAAE,MAAM,SAAS;AAC5B,UAAMA,YAAW;AAEjB,UAAM,aAAa;AAAA,MACjB,MAAM;AACJ,cAAM,aAAaA,UAAS;AAAA,UAC1B,MAAM;AAAA,UACN,MAAM;AAAA,QAAA;AAER,cAAM,cAAc,MAAM;AACpB,cAAA,WAAW,WAAW,IAAI,CAAC,MAAM,EAAE,QAAQ,MAAM,SAAS,CAAC;AAC3D,cAAA,SAAS,cACX,SAAS;AAAA,UAAQ,CAAC,UAChB,MAAM,SAAS,YAAY,KAAK,IAAI,CAAC;AAAA,QAAA,IAEvC,SAAS,KAAK,CAAC;AACZ,eAAA;AAAA,UACL;AAAA,UACA,UAAU,MAAM;AAAA,QAAA;AAAA,MAEpB;AAAA,IAAA;AAGF;AAAA,MACE;AAAA,MACA,CAAC,EAAE,OAAA,MAAa;AACR,cAAA,aAAa,OAAO,SAAS;AACnC,cAAM,UAAUA,UAAS,WAAW,IAAI,MAAM,IAAI;AAC5C,cAAA,UAAU,UAAU,CAAC,GAAG,QAAQ,KAAK,CAAC,IAAI;AAChD,aAAK,UAAU,EAAE,YAAY,QAAS,CAAA;AAAA,MACxC;AAAA,MACA,EAAE,OAAO,OAAO;AAAA,IAAA;AAElB,WAAO,MAAM;;AACX,YAAM,aAAa,CAAC,CAAC,WAAW,MAAM,OAAO;AAC7C,UAAI,YAAY;AACP,eAAA;AAAA,UAGL,EAAE,OAAO;AAAA,YACP,OAAO;AAAA,YACP,KAAK;AAAA,UAAA,CACN;AAAA,UAID,EAAE,qBAAqB,WAAW,MAAM,QAAQ;AAAA,QAAA;AAAA,MAClD,OACK;AACL,gBAAO,WAAM,YAAN;AAAA,MACT;AAAA,IAAA;AAAA,EAEJ;AACF,CAAC;ACjEe,SAAA,eAAe,aAAa,MAAgB;AAC1D,QAAM,aAA4B,SAAa,oBAAA,IAAK,CAAA;AAEpD,WAAS,KAAK,WAA2B;AACvC,QAAI,CAAC;AAAW;AAEhB,UAAM,EAAE,IAAI,MAAM,SAAS,QAAQ,SAAa,IAAA;AAChD,QAAI,CAAC,MAAM,CAAC,QAAQ,CAAC;AAAS;AAE9B,QAAI,CAAC,WAAW,IAAI,EAAE,GAAG;AACvB,iBAAW,IAAI,IAAQ,oBAAA,IAAK,CAAA;AAAA,IAC9B;AACM,UAAA,sBAAsB,WAAW,IAAI,EAAE;AAE7C,UAAM,eAAe;AAAA,MACnB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IAAA;AAGkB,wBAAA,IAAI,MAAM,YAAY;AAAA,EAC5C;AAEA,WAAS,MAAM,WAA4B;AACnC,UAAA,EAAE,IAAI,KAAS,IAAA;AACjB,QAAA,CAAC,MAAM,CAAC;AAAM;AACZ,UAAA,sBAAsB,WAAW,IAAI,EAAE;AAC7C,QAAI,CAAC,qBAAqB;AACxB;AAAA,IACF;AACA,wBAAoB,OAAO,IAAI;AAC3B,QAAA,CAAC,oBAAoB,MAAM;AAC7B,iBAAW,OAAO,EAAE;AAAA,IACtB;AAAA,EACF;AAES,WAAA,oBAAoB,QAAc,WAAqB;AACxD,UAAA,sBAAsB,WAAW,IAAI,MAAM;AACjD,QAAI,CAAC;AAAqB,aAAO;AAEjC,UAAM,UAAU,MAAM,MAAK,2DAAqB,aAAY,CAAA,CAAE;AAE9D,QAAI,CAAC,WAAW;AAEP,aAAA,CAAC,QAAQ,IAAA,CAAK;AAAA,IACvB;AAEO,WAAA;AAAA,MACL;AAAA,MACA,CAAC,GAAc,MAAiB,EAAE,QAAQ,EAAE;AAAA,IAAA;AAAA,EAEhD;AAEA,QAAM,KAAe;AAAA,IACnB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEK,SAAA,aAAc,SAAS,EAAE,IAAiB;AACnD;AAEO,MAAM,WAAW,eAAe;AC/DvB,SAAA,kBACd,aACA,IACA;AACA,QAAM,MAAM,UAAU;AAAA,IAEpB,QAAQ,MAAM,EAAE,cAAc,WAAW;AAAA,EAAA,CAC1C;AAEG,MAAA,CAAC,YAAY,UAAU;AAGzB,UAAM,WAEF,qBAGA,YAAY,CAAA;AAChB,QAAI,SAAS,WAAW,OAAO,OAAO,QAAQ;AAAA,EAEhD;AACA,YAAU,MAAM;AACd,QAAI,MAAM,EAAE;AAAA,EAAA,CACb;AACD,kBAAgB,MAAM;AACpB,QAAI,QAAQ;AAAA,EAAA,CACb;AACH;ACpBA,SAAwB,QAAQ,KAAU,UAAyB,IAAI;AACrE,UAAQ,eAAe,SACrB,IAAI,UAAU,QAAQ,cAAc,UAAU,MAAM;AACtD,UAAQ,qBAAqB,SAC3B,IAAI,UAAU,QAAQ,oBAAoB,gBAAgB,YAAY;AAElE,QAAAA,aAAW,QAAQ,YAAYC;AACjC,MAAA,QAAQ,gBAAgBD,UAAQ;AACtC;AAEO,MAAM,WAAWC;AAEjB,MAAM,UAAU;"}