Skip to content

Commit fcf6cf5

Browse files
focus trap and fixes
1 parent a899582 commit fcf6cf5

File tree

2 files changed

+17
-4
lines changed

2 files changed

+17
-4
lines changed

src/UnderlineNav2/UnderlineNav.tsx

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import {UnderlineNavContext} from './UnderlineNavContext'
55
import {ActionMenu} from '../ActionMenu'
66
import {ActionList} from '../ActionList'
77
import {useResizeObserver, ResizeObserverEntry} from '../hooks/useResizeObserver'
8+
import {useFocusZone} from '../hooks/useFocusZone'
9+
import {FocusKeys} from '@primer/behaviors'
810

911
type Overflow = 'auto' | 'menu' | 'scroll'
1012
type ChildWidthArray = Array<{width: number}>
@@ -84,6 +86,16 @@ export const UnderlineNav = forwardRef(
8486
) => {
8587
const backupRef = useRef<HTMLElement>(null)
8688
const newRef = (forwardedRef ?? backupRef) as MutableRefObject<HTMLElement>
89+
90+
// This might change if we decide tab through the navigation items rather than navigationg with the arrow keys.
91+
// TBD. In the meantime keeping it as a menu with the focus trap.
92+
// ref: https://www.w3.org/WAI/ARIA/apg/example-index/menubar/menubar-navigation.html (Keyboard Support)
93+
useFocusZone({
94+
containerRef: backupRef,
95+
bindKeys: FocusKeys.ArrowHorizontal | FocusKeys.HomeAndEnd,
96+
focusOutBehavior: 'wrap'
97+
})
98+
8799
const styles = {
88100
display: 'flex',
89101
justifyContent: align === 'right' ? 'flex-end' : 'space-between',
@@ -144,7 +156,7 @@ export const UnderlineNav = forwardRef(
144156
<UnderlineNavContext.Provider
145157
value={{setChildrenWidth, selectedLink, setSelectedLink, afterSelect: afterSelectHandler, variant}}
146158
>
147-
<Box as={as} sx={merge(styles, sxProp)} aria-label={label} ref={newRef}>
159+
<Box tabIndex={0} as={as} sx={merge(styles, sxProp)} aria-label={label} ref={newRef}>
148160
<Box as="ul" sx={merge<BetterSystemStyleObject>(overflowStyles, ulStyles)}>
149161
{responsiveProps.items}
150162
</Box>

src/UnderlineNav2/UnderlineNavItem.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import {IconProps} from '@primer/octicons-react'
55
import {ForwardRefComponent as PolymorphicForwardRefComponent} from '../utils/polymorphic'
66
import {UnderlineNavContext} from './UnderlineNavContext'
77
import CounterLabel from '../CounterLabel'
8+
import {get} from '../constants'
89

910
// adopted from React.AnchorHTMLAttributes
1011
type LinkProps = {
@@ -109,15 +110,15 @@ export const UnderlineNavItem = forwardRef(
109110
'&:focus': {
110111
outline: 0,
111112
'& > div[data-component="wrapper"]': {
112-
boxShadow: `inset 0 0 0 2px #0969da`
113+
boxShadow: `inset 0 0 0 2px ${get('colors.accent.fg')}`
113114
},
114115
// where focus-visible is supported, remove the focus box-shadow
115116
'&:not(:focus-visible) > div[data-component="wrapper"]': {
116117
boxShadow: 'none'
117118
}
118119
},
119120
'&:focus-visible > div[data-component="wrapper"]': {
120-
boxShadow: `inset 0 0 0 2px #0969da`
121+
boxShadow: `inset 0 0 0 2px ${get('colors.accent.fg')}`
121122
},
122123
// renders a visibly hidden "copy" of the label in bold, reserving box space for when label becomes bold on selected
123124
'& span[data-content]::before': {
@@ -131,7 +132,7 @@ export const UnderlineNavItem = forwardRef(
131132
'&::after': {
132133
position: 'absolute',
133134
right: '50%',
134-
bottom: 'calc(50% - 23px)',
135+
bottom: 0,
135136
width: `calc(100% - 8px)`,
136137
height: 2,
137138
content: '""',

0 commit comments

Comments
 (0)