123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- // @ts-nocheck
- import { defineComponent, inject, nextTick, ref } from 'vue'
- import { mount } from '@vue/test-utils'
- import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'
- import { composeRefs } from '@element-plus/utils'
- import { EVENT_CODE } from '@element-plus/constants'
- import {
- ROVING_FOCUS_COLLECTION_INJECTION_KEY,
- ROVING_FOCUS_ITEM_COLLECTION_INJECTION_KEY,
- } from '../src/roving-focus-group'
- import {
- ROVING_FOCUS_GROUP_INJECTION_KEY,
- ROVING_FOCUS_GROUP_ITEM_INJECTION_KEY,
- } from '../src/tokens'
- import ElRovingFocusItem from '../src/roving-focus-item.vue'
- const AXIOM = 'rem is the best girl'
- const focusItemKls = 'item-kls'
- let counter = 0
- const FocusItem = defineComponent({
- setup() {
- const { rovingFocusGroupItemRef, ...itemInjection } = inject(
- ROVING_FOCUS_GROUP_ITEM_INJECTION_KEY,
- undefined
- )
- const collectionItemInjection = inject(
- ROVING_FOCUS_ITEM_COLLECTION_INJECTION_KEY,
- undefined
- )!
- const itemRef = composeRefs(
- rovingFocusGroupItemRef,
- collectionItemInjection.collectionItemRef
- )
- return {
- itemRef,
- ...itemInjection,
- id: ++counter,
- }
- },
- template: `<div
- :ref="itemRef"
- :tabindex="tabIndex"
- class="${focusItemKls}"
- @keydown="handleKeydown"
- @focus="handleFocus"
- @mousedown="handleMousedown"
- >
- ${AXIOM} {{ id }}
- </div>`,
- })
- describe('<ElRovingFocusItem />', () => {
- const currentTabbedId = ref('test_id')
- const loop = ref(false)
- const onItemFocus = vi.fn()
- const onItemShiftTab = vi.fn()
- const itemMap = new Map()
- const getItems = () => [...itemMap.values()]
- const defaultProvides = {
- [ROVING_FOCUS_GROUP_INJECTION_KEY as symbol]: {
- currentTabbedId,
- loop,
- onItemFocus,
- onItemShiftTab,
- },
- [ROVING_FOCUS_COLLECTION_INJECTION_KEY as symbol]: {
- getItems,
- itemMap,
- },
- }
- const createComponent = (props = {}) =>
- mount(
- {
- template: `<div>
- <el-roving-focus-item v-bind="$attrs">
- <focus-item />
- </el-roving-focus-item>
- <el-roving-focus-item v-bind="$attrs">
- <focus-item />
- </el-roving-focus-item>
- <el-roving-focus-item v-bind="$attrs">
- <focus-item />
- </el-roving-focus-item>
- </div>`,
- components: {
- ElRovingFocusItem,
- FocusItem,
- },
- },
- {
- props,
- global: {
- provide: defaultProvides,
- },
- attachTo: document.body,
- }
- )
- let wrapper: ReturnType<typeof createComponent>
- const findItems = () => wrapper.findAllComponents(ElRovingFocusItem)
- const findDOMItems = () => wrapper.findAll(`.${focusItemKls}`)
- beforeEach(async () => {
- wrapper = createComponent()
- await nextTick()
- })
- afterEach(() => {
- wrapper.unmount()
- })
- describe('rendering test', () => {
- it('should be able to render content', () => {
- expect(wrapper.html()).toContain(AXIOM)
- expect(findItems()).toHaveLength(3)
- })
- })
- describe('roving focus', () => {
- it('should be able to handle mousedown event', async () => {
- const DOMItems = findDOMItems()
- const items = findItems()
- const firstDOMItem = DOMItems.at(0)
- await firstDOMItem.trigger('mousedown')
- await nextTick()
- const firstItem = items.at(0)
- expect(firstItem.emitted()).toHaveProperty('mousedown')
- await wrapper.setProps({
- focusable: false,
- })
- await firstDOMItem.trigger('mousedown')
- // when the item is not focusable, the focus event should be prevented by default
- const emittedEvents = firstItem.emitted().mousedown
- expect(emittedEvents.at(0)[0].defaultPrevented).toBe(false)
- expect(emittedEvents.at(1)[0].defaultPrevented).toBe(true)
- })
- it('should be able to handle focus event', async () => {
- expect(onItemFocus).not.toHaveBeenCalled()
- const DOMItems = findDOMItems()
- const firstDOMItem = DOMItems.at(0)
- await firstDOMItem.trigger('focus')
- expect(onItemFocus).toHaveBeenCalled()
- expect(findItems().at(0).emitted()).toHaveProperty('focus')
- })
- it('should be able to handle keyboard navigation', async () => {
- const DOMItems = findDOMItems()
- const items = findItems()
- const firstDOMItem = DOMItems.at(0)
- expect(onItemShiftTab).not.toHaveBeenCalled()
- await firstDOMItem.trigger('keydown.shift', {
- key: EVENT_CODE.tab,
- })
- expect(items.at(0).emitted()).toHaveProperty('keydown')
- expect(onItemShiftTab).toHaveBeenCalled()
- // navigating clockwise
- expect(document.activeElement).toBe(document.body)
- await DOMItems.at(1).trigger('keydown', {
- key: EVENT_CODE.down,
- })
- await nextTick()
- expect(document.activeElement).toStrictEqual(DOMItems.at(2).element)
- // navigate anticlockwise
- await DOMItems.at(1).trigger('keydown', {
- key: EVENT_CODE.up,
- })
- await nextTick()
- expect(document.activeElement).toStrictEqual(DOMItems.at(0).element)
- // should be able to focus on the last element when press End
- await DOMItems.at(0).trigger('keydown', {
- key: EVENT_CODE.end,
- })
- await nextTick()
- expect(document.activeElement).toStrictEqual(DOMItems.at(2).element)
- await DOMItems.at(0).trigger('keydown', {
- key: EVENT_CODE.home,
- })
- await nextTick()
- expect(document.activeElement).toStrictEqual(DOMItems.at(0).element)
- })
- })
- })
|