🕵️ SicherheitslückenHak5: Hackers Just Poisoned the Rust Supply Chain | Threat Wire(01.09.2026 um 14:00 Uhr)
🕵️ SicherheitslückenHak5: Hackers Found a Way Into Humanoid Robots | Threat Wire(04.09.2026 um 15:04 Uhr)
🔧 AI Nachrichten Bits und so #1021 (Passwort für Laufwerk)(31.08.2026 um 22:15 Uhr)
🔧 AI Nachrichten Bits und so #1022 (Wie Weißbier)(06.09.2026 um 20:39 Uhr)
🍏 iOS / Mac OSHue-App 6.0 ist da: das sind die Neuerungen(07.09.2026 um 17:21 Uhr)
🕵️ SicherheitslückenHak5: Hackers Just Poisoned the Rust Supply Chain | Threat Wire(01.09.2026 um 14:00 Uhr)
🕵️ SicherheitslückenHak5: Hackers Found a Way Into Humanoid Robots | Threat Wire(04.09.2026 um 15:04 Uhr)
🔧 AI Nachrichten Bits und so #1021 (Passwort für Laufwerk)(31.08.2026 um 22:15 Uhr)
🔧 AI Nachrichten Bits und so #1022 (Wie Weißbier)(06.09.2026 um 20:39 Uhr)
🍏 iOS / Mac OSHue-App 6.0 ist da: das sind die Neuerungen(07.09.2026 um 17:21 Uhr)

🔧 Programmierung 🕛 kürzlich 9 Min Lesezeit
0

Focus Issues and Refinement Support

↗ Quelle (dev.to)
🗣️ Stimme:
📑 Inhaltsübersicht

Prologue



A while ago, I decided to develop a fully accessible main navigation component in React and write a series of articles documenting the steps it took to create a non-trivial accessible component.



My last development with releases tied to one or more articles; each builds on the previous one until a fully implemented navigation component is complete.



Each release and its associated tag contain fully runnable code for the article. The code discussed in this article is available in the release. and may be downloaded at along with previous requirements.









Content Links




  • Introduction

  • Acceptance Criteria

  • Entering



  • Closings




    • Setting Up For Success











Introduction



The implementation of keyboard handling left one obvious keyboard issue to fix: an apparent keyboard trap that occurs when focus shifts into the component via a Shift+Tab key combination.



In addition to the keyboard trap, other issues arise that, while not errors, can be refined to meet user expectations. Closing sublists when a parent is closed, or closing open lists when navigating through the top row, will give the component a finished aspect.



This release, while fixing one nagging issue, once again focuses on the internal, foundational aspects necessary to support those requirements and sets up the next release for success, enhancing the component to close cleanly, beginning with additions to the NavigationProvider.






Acceptance Criteria



Focus and Closing Foundation Release




  • AC 1 - When Shift+Tab is used to enter the component and the last child on the top row is a button, focus should land on that button



A navigation component is not modal; it does not block interaction with other elements on a page, and exiting can be done using the Tab and Shift+Tab keys on the first and last component elements.



As a reminder, the entire component is always in the document object model, meaning that when Shift+Tab is executed to shift focus into the component, there's a good chance the focus will initially land on a link in an unexpanded sublist. In that case, the focus should shift to its parent on the last row.



For the last component element, if it is contained in an unexpanded sublist, focus should shift to its parent on the last row.






Entering



AC 1 fixes the last remaining keyboard-related issue, which occurs when Shift+Tab moves focus from outside the component to the last focusable element in the navigation component. If the top-row parent is a button and the sublist containing the last focusable element is closed, focus should shift to the top-row parent.







Any disappearance of the focus outline is regarded as an error by a screen-perceiving, keyboard-operating user.



The solution is to shift the focus to the top-row parent when focus is placed on the last element of the component within a closed sublist. This requires another event listener, onFocus.






Navigation Item






CODE
const handleFocus = () => {
const linkEl = linkRef.current;
const focusableEl = handleLinkFocus(linkEl);
if (!!focusableEl && focusableEl !== linkEl) {
shiftFocus(focusableEl);
}
};

...
const linkProps = {
...,
onFocus: handleFocus,
onKeyDown: handleKeyDown,
ref: linkRef,
...rest,
};






GitHub (release 0.8.0) -



The last element of a component is always a link, so a check is implemented to determine whether the link holding focus is the last component element; if so, the handler for the last child is called, which will either return itself or its topmost ancestor on the top row.






_isLastElementInComponent





CODE
const _isLastElementInComponent = (focusedEl) => {
return focusedEl === _getLastElementbyComponent();
};






GitHub (release 0.8.0) -



Determining the last element of the component involves finding the last focusable element associated with a particular parent, which, in this case, would be the last element in the top row. The _getLastElementByParent function triggers a recursive call, which can be resource-intensive. Since the entire nested list resides in the DOM, the last element will not change, so it makes sense to store it in state on the first call.



If the link is the last element within the component, a specific handler for that condition is called.






_handleLastChildFocus






CODE
const _handleLastChildFocus = (focusedEl) => {
const { isSubListOpen } = _getNavigationObjectByListElement(focusedEl);
if (!isSubListOpen) {
return _getLastElementInTopRow(focusedEl);
} else {
return focusedEl;
}
};






GitHub (release 0.8.0) -



If the last element on the top row is a button, the recursive function is called to request the last component element associated with the last element in the top row; if the link matches, the last element on the top row is returned, and the issue is fixed.



Retrieving the last element in the top row first requires fetching the last element in that row.






_getLastElementInIndexedList






CODE
const _getLastElementInIndexedList = useCallback(
(index) => {
const { storedList } = getNavigationArray()[index];
return storedList[storedList.length - 1];
},
[getNavigationArray],
);






GitHub (release 0.8.0) -



Unlike updates to state, updates to a ref held within the context provider don't trigger a re-render when the map object changes.






getNavigationArray






CODE
const getNavigationArray =  useCallback(() => {
return state.navigationArray.map((obj) => ({
...obj,
dispatchSubListClose: _dispatchSubListCloseByParent.current.get(
obj.storedParentEl,
),
}));
}, [state.navigationArray]);






GitHub (release 0.8.0) -



RegisterButtonAsParent is also modified, setting the map directly and tying the close function to the parent element.



All that's left to do is to add the close function in the correct useEffect.






SubNavigation






CODE
useEffect(() => {
if (buttonRef.current !== null) {
registerItemInCurrentList(buttonRef.current as FocusableElementType);
registerButtonAsParent(
isSubListOpen,
buttonRef.current,
closeSubNavigation,
);
}
}, [buttonRef, closeSubNavigation, isSubListOpen, registerButtonAsParent, registerItemInCurrentList]);






GitHub (release 0.8.0) - SubNavigation.tsx - Line 83



With registration complete, work on actually closing the sublists can begin and will be detailed in the next article.






Summary



With keyboard navigation (finally) completed, attention now turns to refinements; fixing the last entry issue by sending focus to the last button in the top row when the last element in the component receives focus in an unopened list and preparing architecture to support each button closing itself and any open sublists maintained by its children.

Vollständiger Original-Bericht
Ausführliche Details, Code-Beispiele & Hersteller-Stellungnahme auf dev.to.
↗ Original-Artikel auf dev.to lesen
Wie bewertest du diesen Beitrag?
1 Klick Feedback
Teilen mit Netzwerk & Team:

Community-Analysen & Experten-Meinungen 0

Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
Community Pulse: Relevanz-Einschätzung
1 Klick Experten-Votum
🔴 Akute Relevanz 0%
🟡 In Evaluierung 0%
🟢 Keine Auswirkung 0%
Spannende Innovation 0%
Verwandte Story-Cluster & Quellen (Vektor-KI)
Port 8095 Engine
1 Quelle
Hackers Just Poisoned the Rust Supply Chain | Threat Wire
1 Quelle
Hackers Found a Way Into Humanoid Robots | Threat Wire
1 Quelle
Bits und so #1021 (Passwort für Laufwerk)
Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Focus Issues and Refinement Support

Thematisch verwandte Begriffe: Focus, Issues, Refinement, Support · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...