You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1 line
5.1 KiB
1 line
5.1 KiB
2 months ago
|
{"version":3,"file":"index.js","sources":["../../../../../packages/hooks/use-focus-controller/index.ts"],"sourcesContent":["import { getCurrentInstance, onMounted, ref, shallowRef, watch } from 'vue'\nimport { useEventListener } from '@vueuse/core'\nimport { isElement, isFunction } from '@element-plus/utils'\nimport type { ShallowRef } from 'vue'\n\ninterface UseFocusControllerOptions {\n /**\n * return true to cancel focus\n * @param event FocusEvent\n */\n beforeFocus?: (event: FocusEvent) => boolean | undefined\n afterFocus?: () => void\n /**\n * return true to cancel blur\n * @param event FocusEvent\n */\n beforeBlur?: (event: FocusEvent) => boolean | undefined\n afterBlur?: () => void\n}\n\nexport function useFocusController<T extends { focus: () => void }>(\n target: ShallowRef<T | undefined>,\n {\n beforeFocus,\n afterFocus,\n beforeBlur,\n afterBlur,\n }: UseFocusControllerOptions = {}\n) {\n const instance = getCurrentInstance()!\n const { emit } = instance\n const wrapperRef = shallowRef<HTMLElement>()\n const isFocused = ref(false)\n\n const handleFocus = (event: FocusEvent) => {\n const cancelFocus = isFunction(beforeFocus) ? beforeFocus(event) : false\n if (cancelFocus || isFocused.value) return\n isFocused.value = true\n emit('focus', event)\n afterFocus?.()\n }\n\n const handleBlur = (event: FocusEvent) => {\n const cancelBlur = isFunction(beforeBlur) ? beforeBlur(event) : false\n if (\n cancelBlur ||\n (event.relatedTarget &&\n wrapperRef.value?.contains(event.relatedTarget as Node))\n )\n return\n\n isFocused.value = false\n emit('blur', event)\n afterBlur?.()\n }\n\n const handleClick = () => {\n if (\n wrapperRef.value?.contains(document.activeElement) &&\n wrapperRef.value !== document.activeElement\n )\n return\n\n target.value?.focus()\n }\n\n watch(wrapperRef, (el) => {\n if (el) {\n el.setAttribute('tabindex', '-1')\n }\n })\n\n useEventListener(wrapperRef, 'focus', handleFocus, true)\n useEventListener(wrapperRef, 'blur', handleBlur, true)\n useEventListener(wrapperRef, 'click', handleClick, true)\n\n // only for test\n if (process.env.NODE_ENV === 'test') {\n onMounted(() => {\n const targetEl = isElement(target.value)\n ? target.value\n : document.querySelector('input,textarea')\n\n if (targetEl) {\n useEventListener(targetEl, 'focus', handleFocus, true)\n useEventListener(targetEl, 'blur', handleBlur, true)\n }\n })\n }\n\n return {\n isFocused,\n /** Avoid using wrapperRef and handleFocus/handleBlur together */\n wrapperRef,\n handleFocus,\n handleBlur,\n }\n}\n"],"names":["getCurrentInstance","shallowRef","ref","isFunction","watch","useEventListener","onMounted","isElement"],"mappings":";;;;;;;;;;AAGO,SAAS,kBAAkB,CAAC,MAAM,EAAE;AAC3C,EAAE,WAAW;AACb,EAAE,UAAU;AACZ,EAAE,UAAU;AACZ,EAAE,SAAS;AACX,CAAC,GAAG,EAAE,EAAE;AACR,EAAE,MAAM,QAAQ,GAAGA,sBAAkB,EAAE,CAAC;AACxC,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,QAAQ,CAAC;AAC5B,EAAE,MAAM,UAAU,GAAGC,cAAU,EAAE,CAAC;AAClC,EAAE,MAAM,SAAS,GAAGC,OAAG,CAAC,KAAK,CAAC,CAAC;AAC/B,EAAE,MAAM,WAAW,GAAG,CAAC,KAAK,KAAK;AACjC,IAAI,MAAM,WAAW,GAAGC,iBAAU,CAAC,WAAW,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC;AAC7E,IAAI,IAAI,WAAW,IAAI,SAAS,CAAC,KAAK;AACtC,MAAM,OAAO;AACb,IAAI,SAAS,CAAC,KAAK,GAAG,IAAI,CAAC;AAC3B,IAAI,IAAI,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;AACzB,IAAI,UAAU,IAAI,IAAI,GAAG,KAAK,CAAC,GAAG,UAAU,EAAE,CAAC;AAC/C,GAAG,CAAC;AACJ,EAAE,MAAM,UAAU,GAAG,CAAC,KAAK,KAAK;AAChC,IAAI,IAAI,EAAE,CAAC;AACX,IAAI,MAAM,UAAU,GAAGA,iBAAU,CAAC,UAAU,CAAC,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,KAAK,CAAC;AAC1E,IAAI,IAAI,UAAU,IAAI,KAAK,CAAC,aAAa,KAAK,CAAC,EAAE,GAAG,UAAU,CAAC,KAAK,KAAK,IAAI,GAAG,KAAK,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;AAC1H,MAAM,OAAO;AACb,IAAI,SAAS,CAAC,KAAK,GAAG,KAAK,CAAC;AAC5B,IAAI,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;AACxB,IAAI,SAAS,IAAI,IAAI,GAAG,KAAK,CAAC,GAAG,SAAS,EAAE,CAAC;AAC7C,GAAG,CAAC;AACJ,EAAE,MAAM,WAAW,GAAG,MAAM;AAC5B,IAAI,IAAI,EAAE,EAAE,EAAE,CAAC;AACf,IAAI,IAAI,
|