roving-focus-item.mjs 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. import { defineComponent, inject, ref, computed, unref, provide, nextTick, resolveComponent, openBlock, createBlock, withCtx, renderSlot } from 'vue';
  2. import { ElCollectionItem, ROVING_FOCUS_COLLECTION_INJECTION_KEY as COLLECTION_INJECTION_KEY } from './roving-focus-group.mjs';
  3. import { ROVING_FOCUS_GROUP_INJECTION_KEY, ROVING_FOCUS_GROUP_ITEM_INJECTION_KEY } from './tokens.mjs';
  4. import { getFocusIntent, reorderArray, focusFirst } from './utils.mjs';
  5. import _export_sfc from '../../../_virtual/plugin-vue_export-helper.mjs';
  6. import { useId } from '../../../hooks/use-id/index.mjs';
  7. import { composeEventHandlers } from '../../../utils/dom/event.mjs';
  8. import { EVENT_CODE } from '../../../constants/aria.mjs';
  9. const _sfc_main = defineComponent({
  10. components: {
  11. ElRovingFocusCollectionItem: ElCollectionItem
  12. },
  13. props: {
  14. focusable: {
  15. type: Boolean,
  16. default: true
  17. },
  18. active: {
  19. type: Boolean,
  20. default: false
  21. }
  22. },
  23. emits: ["mousedown", "focus", "keydown"],
  24. setup(props, { emit }) {
  25. const { currentTabbedId, loop, onItemFocus, onItemShiftTab } = inject(ROVING_FOCUS_GROUP_INJECTION_KEY, void 0);
  26. const { getItems } = inject(COLLECTION_INJECTION_KEY, void 0);
  27. const id = useId();
  28. const rovingFocusGroupItemRef = ref();
  29. const handleMousedown = composeEventHandlers((e) => {
  30. emit("mousedown", e);
  31. }, (e) => {
  32. if (!props.focusable) {
  33. e.preventDefault();
  34. } else {
  35. onItemFocus(unref(id));
  36. }
  37. });
  38. const handleFocus = composeEventHandlers((e) => {
  39. emit("focus", e);
  40. }, () => {
  41. onItemFocus(unref(id));
  42. });
  43. const handleKeydown = composeEventHandlers((e) => {
  44. emit("keydown", e);
  45. }, (e) => {
  46. const { code, shiftKey, target, currentTarget } = e;
  47. if (code === EVENT_CODE.tab && shiftKey) {
  48. onItemShiftTab();
  49. return;
  50. }
  51. if (target !== currentTarget)
  52. return;
  53. const focusIntent = getFocusIntent(e);
  54. if (focusIntent) {
  55. e.preventDefault();
  56. const items = getItems().filter((item) => item.focusable);
  57. let elements = items.map((item) => item.ref);
  58. switch (focusIntent) {
  59. case "last": {
  60. elements.reverse();
  61. break;
  62. }
  63. case "prev":
  64. case "next": {
  65. if (focusIntent === "prev") {
  66. elements.reverse();
  67. }
  68. const currentIdx = elements.indexOf(currentTarget);
  69. elements = loop.value ? reorderArray(elements, currentIdx + 1) : elements.slice(currentIdx + 1);
  70. break;
  71. }
  72. }
  73. nextTick(() => {
  74. focusFirst(elements);
  75. });
  76. }
  77. });
  78. const isCurrentTab = computed(() => currentTabbedId.value === unref(id));
  79. provide(ROVING_FOCUS_GROUP_ITEM_INJECTION_KEY, {
  80. rovingFocusGroupItemRef,
  81. tabIndex: computed(() => unref(isCurrentTab) ? 0 : -1),
  82. handleMousedown,
  83. handleFocus,
  84. handleKeydown
  85. });
  86. return {
  87. id,
  88. handleKeydown,
  89. handleFocus,
  90. handleMousedown
  91. };
  92. }
  93. });
  94. function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) {
  95. const _component_el_roving_focus_collection_item = resolveComponent("el-roving-focus-collection-item");
  96. return openBlock(), createBlock(_component_el_roving_focus_collection_item, {
  97. id: _ctx.id,
  98. focusable: _ctx.focusable,
  99. active: _ctx.active
  100. }, {
  101. default: withCtx(() => [
  102. renderSlot(_ctx.$slots, "default")
  103. ]),
  104. _: 3
  105. }, 8, ["id", "focusable", "active"]);
  106. }
  107. var ElRovingFocusItem = /* @__PURE__ */ _export_sfc(_sfc_main, [["render", _sfc_render], ["__file", "roving-focus-item.vue"]]);
  108. export { ElRovingFocusItem as default };
  109. //# sourceMappingURL=roving-focus-item.mjs.map