@@ -210,18 +210,65 @@ export const Picklist: (<MultiSelect extends boolean | undefined>(
210210 [ getOptionValues ]
211211 ) ;
212212
213+ // Scroll focused element into view
214+ const scrollFocusedElementIntoView = useEventCallback (
215+ ( nextFocusedValue : PicklistValue | undefined ) => {
216+ if ( ! nextFocusedValue || ! dropdownElRef . current ) {
217+ return ;
218+ }
219+
220+ const dropdownContainer = dropdownElRef . current ;
221+ const targetElement = dropdownContainer . querySelector (
222+ `#option-${ nextFocusedValue } `
223+ ) ;
224+
225+ if ( ! ( targetElement instanceof HTMLElement ) ) {
226+ return ;
227+ }
228+
229+ // Calculate element position within container
230+ const elementTopPosition = targetElement . offsetTop ;
231+ const elementBottomPosition =
232+ elementTopPosition + targetElement . offsetHeight ;
233+
234+ // Calculate currently visible area
235+ const currentScrollPosition = dropdownContainer . scrollTop ;
236+ const visibleAreaHeight = dropdownContainer . clientHeight ;
237+ const visibleAreaTop = currentScrollPosition ;
238+ const visibleAreaBottom = currentScrollPosition + visibleAreaHeight ;
239+
240+ // Check if element is outside the visible area
241+ const isAbove = elementTopPosition < visibleAreaTop ;
242+ const isBelow = elementBottomPosition > visibleAreaBottom ;
243+
244+ // Scroll only if element is not currently visible
245+ if ( isAbove || isBelow ) {
246+ targetElement . scrollIntoView ( {
247+ block : 'center' ,
248+ } ) ;
249+ }
250+ }
251+ ) ;
252+
213253 // Set initial focus when dropdown opens
214254 useEffect ( ( ) => {
215255 if ( opened && ! focusedValue ) {
216256 // Focus on first selected value or first option
217257 const initialFocus =
218258 values . length > 0 ? values [ 0 ] : getOptionValues ( ) [ 0 ] ;
219259 setFocusedValue ( initialFocus ) ;
260+ scrollFocusedElementIntoView ( initialFocus ) ;
220261 } else if ( ! opened ) {
221262 // Reset focus when dropdown closes
222263 setFocusedValue ( undefined ) ;
223264 }
224- } , [ opened , values , getOptionValues , focusedValue ] ) ;
265+ } , [
266+ opened ,
267+ values ,
268+ getOptionValues ,
269+ focusedValue ,
270+ scrollFocusedElementIntoView ,
271+ ] ) ;
225272
226273 const elRef = useRef < HTMLDivElement | null > ( null ) ;
227274 const elementRef = useMergeRefs ( [ elRef , elementRef_ ] ) ;
@@ -307,6 +354,7 @@ export const Picklist: (<MultiSelect extends boolean | undefined>(
307354 // Navigate to next option
308355 const nextValue = getNextValue ( focusedValue ) ;
309356 setFocusedValue ( nextValue ) ;
357+ scrollFocusedElementIntoView ( nextValue ) ;
310358 }
311359 } else if ( e . keyCode === 38 ) {
312360 // up
@@ -318,6 +366,7 @@ export const Picklist: (<MultiSelect extends boolean | undefined>(
318366 // Navigate to previous option
319367 const prevValue = getPrevValue ( focusedValue ) ;
320368 setFocusedValue ( prevValue ) ;
369+ scrollFocusedElementIntoView ( prevValue ) ;
321370 }
322371 } else if ( e . keyCode === 27 ) {
323372 // ESC
0 commit comments