···
1
+
import React, { ReactNode, useState, useLayoutEffect, useRef } from 'react';
2
+
import { mount } from '@cypress/react';
4
+
import { makePriorityHook } from '../usePriority';
6
+
const usePriority = makePriorityHook();
8
+
const FocusOnPriority = (
9
+
{ id, children = null }:
10
+
{ id: string, children?: ReactNode }
12
+
const ref = useRef<HTMLDivElement>(null);
13
+
const hasPriority = usePriority(ref);
15
+
useLayoutEffect(() => {
16
+
if (hasPriority && ref.current) {
17
+
ref.current!.focus();
19
+
}, [hasPriority, ref]);
22
+
<div tabIndex={-1} ref={ref} id={id}>
28
+
it('allows sole element to take priority', () => {
30
+
<FocusOnPriority id="only" />
33
+
cy.focused().should('have.id', 'only');
36
+
it('tracks priority of sibling elements in order', () => {
39
+
<FocusOnPriority id="first" />
40
+
<FocusOnPriority id="second" />
44
+
cy.focused().should('have.id', 'second');
47
+
it('tracks priority of nested elements in order', () => {
49
+
<FocusOnPriority id="outer">
50
+
<FocusOnPriority id="inner" />
54
+
cy.focused().should('have.id', 'inner');
57
+
it('should switch priorities of sibling elements as needed', () => {
59
+
const [visible, setVisible] = useState(true);
63
+
<FocusOnPriority id="first" />
64
+
{visible && <FocusOnPriority id="second" />}
65
+
<button onClick={() => setVisible(false)}>switch</button>
72
+
cy.focused().should('have.id', 'second');
73
+
cy.get('button').first().click();
74
+
cy.focused().should('have.id', 'first');
77
+
it('should switch priorities of nested elements as needed', () => {
79
+
const [visible, setVisible] = useState(true);
83
+
<FocusOnPriority id="outer">
84
+
{visible && <FocusOnPriority id="inner" />}
86
+
<button onClick={() => setVisible(false)}>switch</button>
93
+
cy.focused().should('have.id', 'inner');
94
+
cy.get('button').first().click();
95
+
cy.focused().should('have.id', 'outer');
98
+
it('should preserve priorities when non-prioritised item is removed', () => {
100
+
const [visible, setVisible] = useState(true);
104
+
{visible && <FocusOnPriority id="first" />}
105
+
<FocusOnPriority id="second" />
106
+
<button onClick={() => setVisible(false)}>switch</button>
113
+
cy.focused().should('have.id', 'second');
114
+
cy.get('button').first().click();
115
+
cy.get('button').first().should('have.focus');
118
+
it('should update priorities when new prioritised item is added', () => {
119
+
const App = () => {
120
+
const [visible, setVisible] = useState(false);
124
+
<FocusOnPriority id="first" />
125
+
<FocusOnPriority id="second" />
126
+
{visible && <FocusOnPriority id="third" />}
127
+
<button onClick={() => setVisible(true)}>switch</button>
134
+
cy.focused().should('have.id', 'second');
135
+
cy.get('button').first().click();
136
+
cy.focused().should('have.id', 'third');