{"version":3,"file":"masker.vue2.mjs","sources":["../../../components/masker/masker.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { Portal } from '@/components/portal'\nimport { ResizeObserver } from '@/components/resize-observer'\n\nimport { computed, nextTick, ref, watch } from 'vue'\n\nimport { emitEvent, useNameHelper, useProps, useZIndex } from '@vexip-ui/config'\nimport { getLast, isPromise, queryTabables } from '@vexip-ui/utils'\nimport { maskerProps } from './props'\n\ndefineOptions({ name: 'Masker' })\n\nconst nh = useNameHelper('masker')\nconst _props = defineProps(maskerProps)\nconst props = useProps('masker', _props, {\n  active: {\n    default: false,\n    static: true\n  },\n  closable: false,\n  inner: false,\n  maskTransition: () => nh.ns('fade'),\n  transitionName: () => nh.ns('fade'),\n  disabled: false,\n  onBeforeClose: {\n    default: null,\n    isFunc: true\n  },\n  transfer: false,\n  autoRemove: false,\n  permeable: false,\n  disableEsc: false\n})\n\nconst emit = defineEmits(['update:active'])\n\nconst slots = defineSlots<{\n  mask?: () => any,\n  default?: (params: { show: boolean }) => any\n}>()\n\nconst getIndex = useZIndex()\n\nconst currentActive = ref(props.active)\n// If initial active, we should set a valid index as initial value\nconst zIndex = ref(props.active ? getIndex() : 0)\nconst wrapperShow = ref(props.active)\n\nconst wrapper = ref<HTMLElement>()\nconst topTrap = ref<HTMLElement>()\nconst bottomTrap = ref<HTMLElement>()\n\nlet maskShow = false\nlet contentShow = false\nlet stable = false\nlet prevFocusedEl: HTMLElement | null = null\n\nconst transferTo = computed(() => {\n  return props.inner\n    ? ''\n    : typeof props.transfer === 'boolean'\n      ? props.transfer\n        ? 'body'\n        : ''\n      : props.transfer\n})\nconst className = computed(() => {\n  return [\n    nh.b(),\n    nh.bs('vars'),\n    {\n      [nh.bm('inherit')]: transferTo.value !== 'body' && props.inherit,\n      [nh.bm('inner')]: props.inner,\n      [nh.bm('disabled')]: props.disabled\n    }\n  ]\n})\n\nwatch(\n  () => props.active,\n  value => {\n    currentActive.value = value\n\n    if (value) {\n      wrapperShow.value = value\n    }\n  }\n)\nwatch(currentActive, value => {\n  if (!value) {\n    stable = false\n\n    if (prevFocusedEl) {\n      prevFocusedEl.focus()\n      prevFocusedEl = null\n    }\n  } else {\n    prevFocusedEl = document.activeElement as HTMLElement\n    zIndex.value = getIndex()\n  }\n\n  if ((!props.maskTransition || props.disabled) && !props.transitionName) {\n    value ? afterOpen() : afterClose()\n  }\n})\nwatch(\n  [() => props.permeable, wrapper],\n  () => {\n    if (wrapper.value) {\n      wrapper.value.removeEventListener('wheel', disableWheel)\n\n      if (!props.permeable) {\n        wrapper.value.addEventListener('wheel', disableWheel)\n      }\n    }\n  },\n  { immediate: true, flush: 'post' }\n)\n\ndefineExpose({\n  currentActive,\n  zIndex,\n  wrapperShow,\n  wrapper,\n  topTrap,\n  bottomTrap\n})\n\nfunction disableWheel(event: WheelEvent) {\n  event.preventDefault()\n  event.stopPropagation()\n}\n\nfunction toggleActive(active: boolean) {\n  if (currentActive.value === active) return\n\n  currentActive.value = active\n\n  emit('update:active', active)\n  emitEvent(props.onToggle, active)\n}\n\nasync function handleClose() {\n  if (!props.closable) return\n\n  let result: unknown = true\n\n  if (typeof props.onBeforeClose === 'function') {\n    result = props.onBeforeClose()\n\n    if (isPromise(result)) {\n      result = await result\n    }\n  }\n\n  if (result !== false) {\n    nextTick(() => {\n      toggleActive(false)\n      emitEvent(props.onClose)\n    })\n  }\n}\n\nfunction afterOpen() {\n  if (!currentActive.value) return\n\n  const activeEl = document && document.activeElement\n\n  if (!activeEl || !wrapper.value || !wrapper.value.contains(activeEl)) {\n    topTrap.value?.focus()\n  }\n\n  nextTick(() => {\n    stable = true\n    emitEvent(props.onShow)\n  })\n}\n\nfunction afterClose() {\n  if (currentActive.value) return\n\n  nextTick(() => {\n    wrapperShow.value = false\n    emitEvent(props.onHide)\n  })\n}\n\nfunction afterMaskOpen() {\n  if (!currentActive.value) return\n\n  maskShow = true\n  ;(!props.transitionName || !slots.default || contentShow) && afterOpen()\n}\n\nfunction afterMaskClose() {\n  if (currentActive.value) return\n\n  maskShow = false\n  ;(!props.transitionName || !slots.default || !contentShow) && afterClose()\n}\n\nfunction afterContentOpen() {\n  if (!currentActive.value) return\n\n  contentShow = true\n  ;(!props.maskTransition || props.disabled || maskShow) && afterOpen()\n}\n\nfunction afterContentClose() {\n  if (currentActive.value) return\n\n  contentShow = false\n  ;(!props.maskTransition || props.disabled || !maskShow) && afterClose()\n}\n\nfunction handleMaskClick(event: MouseEvent) {\n  emitEvent(props.onMaskClick, event)\n  handleClose()\n}\n\nfunction handleFocusIn(event: FocusEvent) {\n  const target = event.target as HTMLElement\n\n  if (!stable || !wrapper.value || !target || !topTrap.value || !bottomTrap.value) {\n    return\n  }\n\n  const tabables = queryTabables(wrapper.value)\n\n  if (!tabables.length) {\n    return\n  }\n\n  if (topTrap.value === target) {\n    getLast(tabables)!.focus()\n  } else if (bottomTrap.value === target) {\n    tabables[0].focus()\n  }\n}\n\nfunction handleResize(entry: ResizeObserverEntry) {\n  emitEvent(props.onResize, entry)\n}\n\nfunction handleEscape(event: KeyboardEvent) {\n  if (!props.disableEsc) {\n    event.preventDefault()\n    handleClose()\n  }\n}\n</script>\n\n<template>\n  <Portal v-if=\"!props.autoRemove || wrapperShow\" :to=\"transferTo\">\n    <div\n      v-bind=\"$attrs\"\n      ref=\"wrapper\"\n      :class=\"[className, $attrs.class]\"\n      tabindex=\"-1\"\n      :style=\"{\n        zIndex,\n        ...($attrs.style || {}),\n        pointerEvents: wrapperShow ? undefined : 'none',\n        visibility: wrapperShow ? undefined : 'hidden'\n      }\"\n      @focusin=\"handleFocusIn\"\n      @keydown.escape=\"handleEscape\"\n    >\n      <ResizeObserver @resize=\"handleResize\">\n        <Transition\n          v-if=\"!props.disabled\"\n          appear\n          :name=\"props.maskTransition\"\n          @after-enter=\"afterMaskOpen\"\n          @after-leave=\"afterMaskClose\"\n        >\n          <div v-show=\"currentActive\" :class=\"nh.be('mask')\" @click=\"handleMaskClick\">\n            <slot name=\"mask\">\n              <div :class=\"nh.be('mask-inner')\"></div>\n            </slot>\n          </div>\n        </Transition>\n        <div\n          v-else\n          :class=\"nh.be('placeholder')\"\n          role=\"none\"\n          aria-hidden\n        ></div>\n      </ResizeObserver>\n      <div\n        ref=\"topTrap\"\n        tabindex=\"0\"\n        role=\"none\"\n        style=\"width: 0; height: 0; overflow: hidden; outline: none\"\n      ></div>\n      <div :class=\"nh.be('content')\" @wheel.stop.prevent>\n        <Transition\n          v-if=\"props.transitionName\"\n          appear\n          :name=\"props.transitionName\"\n          @after-enter=\"afterContentOpen\"\n          @after-leave=\"afterContentClose\"\n        >\n          <slot :show=\"currentActive\"></slot>\n        </Transition>\n        <slot v-else :show=\"currentActive\"></slot>\n      </div>\n      <div\n        ref=\"bottomTrap\"\n        tabindex=\"0\"\n        role=\"none\"\n        style=\"width: 0; height: 0; overflow: hidden; outline: none\"\n      ></div>\n    </div>\n  </Portal>\n</template>\n"],"names":["nh","useNameHelper","props","useProps","__props","emit","__emit","slots","_useSlots","getIndex","useZIndex","currentActive","ref","zIndex","wrapperShow","wrapper","topTrap","bottomTrap","maskShow","contentShow","stable","prevFocusedEl","transferTo","computed","className","watch","value","afterOpen","afterClose","disableWheel","__expose","event","toggleActive","active","emitEvent","handleClose","result","isPromise","nextTick","activeEl","_a","afterMaskOpen","afterMaskClose","afterContentOpen","afterContentClose","handleMaskClick","handleFocusIn","target","tabables","queryTabables","getLast","handleResize","entry","handleEscape"],"mappings":"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"}