element-plus
Version:
A Component Library for Vue 3
102 lines (99 loc) • 4.02 kB
JavaScript
import { defineComponent, ref, inject, computed, provide, readonly, toRef, unref, watch, renderSlot } from 'vue';
import { useEventListener } from '@vueuse/core';
import { rovingFocusGroupProps, ROVING_FOCUS_COLLECTION_INJECTION_KEY as COLLECTION_INJECTION_KEY } from './roving-focus-group2.mjs';
import { ROVING_FOCUS_GROUP_INJECTION_KEY } from './tokens.mjs';
import { focusFirst } from './utils.mjs';
import _export_sfc from '../../../_virtual/plugin-vue_export-helper.mjs';
import { composeEventHandlers } from '../../../utils/dom/event.mjs';
const CURRENT_TAB_ID_CHANGE_EVT = "currentTabIdChange";
const ENTRY_FOCUS_EVT = "rovingFocusGroup.entryFocus";
const EVT_OPTS = { bubbles: false, cancelable: true };
const _sfc_main = defineComponent({
name: "ElRovingFocusGroupImpl",
inheritAttrs: false,
props: rovingFocusGroupProps,
emits: [CURRENT_TAB_ID_CHANGE_EVT, "entryFocus"],
setup(props, { emit }) {
var _a;
const currentTabbedId = ref((_a = props.currentTabId || props.defaultCurrentTabId) != null ? _a : null);
const isBackingOut = ref(false);
const isClickFocus = ref(false);
const rovingFocusGroupRef = ref();
const { getItems } = inject(COLLECTION_INJECTION_KEY, void 0);
const rovingFocusGroupRootStyle = computed(() => {
return [
{
outline: "none"
},
props.style
];
});
const onItemFocus = (tabbedId) => {
emit(CURRENT_TAB_ID_CHANGE_EVT, tabbedId);
};
const onItemShiftTab = () => {
isBackingOut.value = true;
};
const onMousedown = composeEventHandlers((e) => {
var _a2;
(_a2 = props.onMousedown) == null ? void 0 : _a2.call(props, e);
}, () => {
isClickFocus.value = true;
});
const onFocus = composeEventHandlers((e) => {
var _a2;
(_a2 = props.onFocus) == null ? void 0 : _a2.call(props, e);
}, (e) => {
const isKeyboardFocus = !unref(isClickFocus);
const { target, currentTarget } = e;
if (target === currentTarget && isKeyboardFocus && !unref(isBackingOut)) {
const entryFocusEvt = new Event(ENTRY_FOCUS_EVT, EVT_OPTS);
currentTarget == null ? void 0 : currentTarget.dispatchEvent(entryFocusEvt);
if (!entryFocusEvt.defaultPrevented) {
const items = getItems().filter((item) => item.focusable);
const activeItem = items.find((item) => item.active);
const currentItem = items.find((item) => item.id === unref(currentTabbedId));
const candidates = [activeItem, currentItem, ...items].filter(Boolean);
const candidateNodes = candidates.map((item) => item.ref);
focusFirst(candidateNodes);
}
}
isClickFocus.value = false;
});
const onBlur = composeEventHandlers((e) => {
var _a2;
(_a2 = props.onBlur) == null ? void 0 : _a2.call(props, e);
}, () => {
isBackingOut.value = false;
});
const handleEntryFocus = (...args) => {
emit("entryFocus", ...args);
};
provide(ROVING_FOCUS_GROUP_INJECTION_KEY, {
currentTabbedId: readonly(currentTabbedId),
loop: toRef(props, "loop"),
tabIndex: computed(() => {
return unref(isBackingOut) ? -1 : 0;
}),
rovingFocusGroupRef,
rovingFocusGroupRootStyle,
orientation: toRef(props, "orientation"),
dir: toRef(props, "dir"),
onItemFocus,
onItemShiftTab,
onBlur,
onFocus,
onMousedown
});
watch(() => props.currentTabId, (val) => {
currentTabbedId.value = val != null ? val : null;
});
useEventListener(rovingFocusGroupRef, ENTRY_FOCUS_EVT, handleEntryFocus);
}
});
function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
return renderSlot(_ctx.$slots, "default");
}
var ElRovingFocusGroupImpl = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render], ["__file", "roving-focus-group-impl.vue"]]);
export { ElRovingFocusGroupImpl as default };
//# sourceMappingURL=roving-focus-group-impl.mjs.map