import type { Column } from '../..' import { Grid, GridCellBase, useSubNavigation } from '../..' import { getNormalizedIndex, getNextSubFocusIndex } from './utils' import { render } from '../../utils/test-utils' import userEvent from '@testing-library/user-event' import React from 'react' import { theme } from '@planview/pv-utilities' import { Tag } from '@planview/pv-uikit' type RowData = { id: string; tags: number; label: string } const rows: RowData[] = [ { id: '1', label: 'Row 1', tags: 4, }, { id: '2', label: 'Row 2', tags: 2, }, { id: '3', label: 'Row 3', tags: 0, }, ] const columns: Column[] = [ { id: 'tags', label: 'Column 1', cell: { Renderer({ value, tabIndex }) { const { currentSubFocusIndex, setCurrentSubFocusIndex } = useSubNavigation({ indexes: value, inlineFocusStylingEnabled: true, }) return ( {value ? Array.from(Array(value), (e, i) => (
setCurrentSubFocusIndex(i)} >
)) : 'No tags!'}
) }, }, }, { id: 'label', label: 'Name', }, ] describe('grid-sub-navigation-context', () => { describe('utils', () => { describe('getNormalizedIndex', () => { it('return 0 from first', () => { expect(getNormalizedIndex('first', 3)).toBe(0) }) it('return last', () => { expect(getNormalizedIndex('last', 5)).toBe(4) }) it('return number', () => { expect(getNormalizedIndex(3, 5)).toBe(3) }) }) describe('getNextSubFocusIndex', () => { it('should move right from first', () => { expect(getNextSubFocusIndex('right', 'first', 4)).toBe(1) }) it('should not move right from last', () => { expect(getNextSubFocusIndex('right', 'last', 4)).toBe(3) }) it('should move left from last', () => { expect(getNextSubFocusIndex('left', 'last', 4)).toBe(2) }) it('should return -1 when moving left if no sub-navigation available', () => { expect(getNextSubFocusIndex('left', 'last', 0)).toBe(-1) }) it('should return -1 when moving right if no sub-navigation available', () => { expect(getNextSubFocusIndex('right', 'last', 0)).toBe(-1) }) }) }) describe('navigation', () => { it('should navigate within cell if multiple stops and move out after last stop', async () => { const { getByText } = render( ) await userEvent.keyboard('{Tab}{ArrowDown}') expect(getByText('Tag 1 has focus')).toBeInTheDocument() await userEvent.keyboard('{ArrowRight}{ArrowRight}') expect(getByText('Tag 3 has focus')).toBeInTheDocument() await userEvent.keyboard('{ArrowLeft}') expect(getByText('Tag 2 has focus')).toBeInTheDocument() await userEvent.keyboard('{ArrowRight}{ArrowRight}') expect(getByText('Tag 4 has focus')).toBeInTheDocument() await userEvent.keyboard('{ArrowRight}') expect(getByText('Row 1')).toHaveFocus() }) it('should navigate to last sub-index in cell when entering from cell to the right', async () => { const { getByText } = render( ) await userEvent.keyboard('{Tab}{ArrowRight}{ArrowDown}') expect(getByText('Row 1')).toHaveFocus() await userEvent.keyboard('{ArrowLeft}') expect(getByText('Tag 4 has focus')).toBeInTheDocument() }) it('should navigate correctly between cells with differing amount of sub-indexes', async () => { const { getByText } = render( ) //Navigate to last tag in first row (row contains 4 tags) await userEvent.keyboard('{Tab}{ArrowRight}{ArrowDown}{ArrowLeft}') expect(getByText('Tag 4 has focus')).toBeInTheDocument() //Navigate down to second row (row contains 2 tags) await userEvent.keyboard('{ArrowDown}') expect(getByText('Tag 2 has focus')).toBeInTheDocument() //Navigate up again to first row await userEvent.keyboard('{ArrowUp}') expect(getByText('Tag 4 has focus')).toBeInTheDocument() }) it('should navigate after setting sub-focus on click', async () => { const { getByText } = render( ) await userEvent.click(getByText('Tag 3')) expect(getByText('Tag 3 has focus')).toBeInTheDocument() await userEvent.keyboard('{ArrowLeft}') expect(getByText('Tag 2 has focus')).toBeInTheDocument() }) it('should use tabIndex from Renderer if no indexes in cell', async () => { const { getByText } = render( ) await userEvent.keyboard('{Tab}{ArrowDown}{ArrowDown}{ArrowDown}') expect(getByText('No tags!')).toHaveFocus() }) }) })