@@ -94,7 +94,7 @@ export const Item = React.forwardRef<HTMLLIElement, ItemProps>(
9494 onSelect = ( ) => null ,
9595 sx : sxProp = { } ,
9696 id,
97- _PrivateItemWrapper = ( { children } ) => < > { children } </ > ,
97+ _PrivateItemWrapper,
9898 ...props
9999 } ,
100100 forwardedRef
@@ -109,9 +109,9 @@ export const Item = React.forwardRef<HTMLLIElement, ItemProps>(
109109 fontSize : 1 ,
110110 paddingY : '6px' , // custom value off the scale
111111 lineHeight : TEXT_ROW_HEIGHT ,
112- marginX : listVariant === 'inset' ? 2 : 0 ,
113112 minHeight : 5 ,
114- borderRadius : 2 ,
113+ marginX : listVariant === 'inset' ? 2 : 0 ,
114+ borderRadius : listVariant === 'inset' ? 2 : 0 ,
115115 transition : 'background 33.333ms linear' ,
116116 color : getVariantStyles ( variant , disabled ) . color ,
117117 textDecoration : 'none' , // for as="a"
@@ -121,11 +121,17 @@ export const Item = React.forwardRef<HTMLLIElement, ItemProps>(
121121 backgroundColor : `actionListItem.${ variant } .hoverBg` ,
122122 color : getVariantStyles ( variant , disabled ) . hoverColor
123123 } ,
124- ':focus:not([aria-disabled ])' : {
124+ ':focus:not([data-focus-visible-added ])' : {
125125 backgroundColor : `actionListItem.${ variant } .selectedBg` ,
126126 color : getVariantStyles ( variant , disabled ) . hoverColor ,
127127 outline : 'none'
128128 } ,
129+ '&[data-focus-visible-added]' : {
130+ // we don't use :focus-visible because not all browsers (safari) have it yet
131+ outline : 'none' ,
132+ border : `2 solid` ,
133+ boxShadow : `0 0 0 2px ${ theme ?. colors . accent . emphasis } `
134+ } ,
129135 ':active:not([aria-disabled])' : {
130136 backgroundColor : `actionListItem.${ variant } .activeBg` ,
131137 color : getVariantStyles ( variant , disabled ) . hoverColor
@@ -147,14 +153,16 @@ export const Item = React.forwardRef<HTMLLIElement, ItemProps>(
147153 borderColor : 'var(--divider-color, transparent)'
148154 } ,
149155 // show between 2 items
150- ':not(:first-of-type):not([aria-selected=true]) ' : { '--divider-color' : theme ?. colors . actionListItem . inlineDivider } ,
156+ ':not(:first-of-type)' : { '--divider-color' : theme ?. colors . actionListItem . inlineDivider } ,
151157 // hide divider after dividers & group header, with higher importance!
152158 '[data-component="ActionList.Divider"] + &' : { '--divider-color' : 'transparent !important' } ,
153159 // hide border on current and previous item
154- '&:hover:not([aria-disabled]), &:focus:not([aria-disabled])' : { '--divider-color' : 'transparent' } ,
155- '&:hover:not([aria-disabled]) + &, &:focus:not([aria-disabled]) + &' : { '--divider-color' : 'transparent' } ,
156- // hide border around selected item
157- '&[aria-selected=true] + &' : { '--divider-color' : 'transparent' }
160+ '&:hover:not([aria-disabled]), &:focus:not([aria-disabled]), &[data-focus-visible-added]:not([aria-disabled])' : {
161+ '--divider-color' : 'transparent'
162+ } ,
163+ '&:hover:not([aria-disabled]) + &, &:focus:not([aria-disabled]) + &, &[data-focus-visible-added] + li' : {
164+ '--divider-color' : 'transparent'
165+ }
158166 }
159167
160168 const clickHandler = React . useCallback (
@@ -165,26 +173,40 @@ export const Item = React.forwardRef<HTMLLIElement, ItemProps>(
165173 [ onSelect , disabled ]
166174 )
167175
176+ const keyPressHandler = React . useCallback (
177+ event => {
178+ if ( disabled ) return
179+
180+ if ( ! event . defaultPrevented && [ ' ' , 'Enter' ] . includes ( event . key ) ) {
181+ onSelect ( event )
182+ }
183+ } ,
184+ [ onSelect , disabled ]
185+ )
186+
168187 // use props.id if provided, otherwise generate one.
169188 const labelId = useSSRSafeId ( id )
170189 const inlineDescriptionId = useSSRSafeId ( id && `${ id } --inline-description` )
171190 const blockDescriptionId = useSSRSafeId ( id && `${ id } --block-description` )
172191
192+ const ItemWrapper = _PrivateItemWrapper || React . Fragment
193+
173194 return (
174195 < Slots context = { { variant, disabled, inlineDescriptionId, blockDescriptionId} } >
175196 { slots => (
176197 < LiBox
177198 ref = { forwardedRef }
178199 sx = { merge ( styles , sxProp as SxProp ) }
179200 onClick = { clickHandler }
201+ onKeyPress = { keyPressHandler }
180202 aria-selected = { selected }
181203 aria-disabled = { disabled ? true : undefined }
182- tabIndex = { disabled ? undefined : - 1 }
204+ tabIndex = { disabled || _PrivateItemWrapper ? undefined : 0 }
183205 aria-labelledby = { `${ labelId } ${ slots . InlineDescription ? inlineDescriptionId : '' } ` }
184206 aria-describedby = { slots . BlockDescription ? blockDescriptionId : undefined }
185207 { ...props }
186208 >
187- < _PrivateItemWrapper >
209+ < ItemWrapper >
188210 < Selection selected = { selected } disabled = { disabled } />
189211 { slots . LeadingVisual }
190212 < Box
@@ -205,7 +227,7 @@ export const Item = React.forwardRef<HTMLLIElement, ItemProps>(
205227 </ ConditionalBox >
206228 { slots . BlockDescription }
207229 </ Box >
208- </ _PrivateItemWrapper >
230+ </ ItemWrapper >
209231 </ LiBox >
210232 ) }
211233 </ Slots >
0 commit comments