@@ -257,10 +257,27 @@ const OptionList: React.ForwardRefRenderFunction<RefOptionListProps, {}> = (_, r
257257 } ,
258258 } ) ) ;
259259
260- // Skip group headers to match native <select> announcements with <optgroup>
261- const optionPositions = React . useMemo ( ( ) => {
260+ // `optionPositions`: skip group headers to match native <select> announcements with <optgroup>
261+ // `itemGroups`: owning group header of each option, so lookups stay O(1) while rendering
262+ const [ optionPositions , itemGroups ] = React . useMemo ( ( ) => {
262263 let count = 0 ;
263- return memoFlattenOptions . map ( ( item ) => ( item . group ? count : ( count += 1 ) ) ) ;
264+ let group : FlattenOptionData < BaseOptionType > | null = null ;
265+
266+ const positions : number [ ] = [ ] ;
267+ const groups : ( FlattenOptionData < BaseOptionType > | null ) [ ] = [ ] ;
268+
269+ memoFlattenOptions . forEach ( ( item ) => {
270+ if ( item . group ) {
271+ group = item ;
272+ positions . push ( count ) ;
273+ groups . push ( null ) ;
274+ } else {
275+ positions . push ( ( count += 1 ) ) ;
276+ groups . push ( item . groupOption ? group : null ) ;
277+ }
278+ } ) ;
279+
280+ return [ positions , groups ] as const ;
264281 } , [ memoFlattenOptions ] ) ;
265282
266283 // ========================== Render ==========================
@@ -315,18 +332,6 @@ const OptionList: React.ForwardRefRenderFunction<RefOptionListProps, {}> = (_, r
315332 ) ;
316333 } ;
317334
318- const getGroupItem = ( index : number ) => {
319- for ( let i = index ; i >= 0 ; i -= 1 ) {
320- const current = memoFlattenOptions [ i ] ;
321- if ( current ?. group ) {
322- return current ;
323- }
324- }
325- // Unreachable: a grouped option always has a preceding group header
326- /* istanbul ignore next */
327- return null ;
328- } ;
329-
330335 // Nest options inside `role="group"` wrappers
331336 const renderHiddenItems = ( ) => {
332337 const segments : {
@@ -340,7 +345,7 @@ const OptionList: React.ForwardRefRenderFunction<RefOptionListProps, {}> = (_, r
340345 return ;
341346 }
342347
343- const groupItem = item . groupOption ? getGroupItem ( index ) : null ;
348+ const groupItem = itemGroups [ index ] ;
344349 const lastSegment = segments [ segments . length - 1 ] ;
345350
346351 if ( lastSegment && lastSegment . group === groupItem ) {
@@ -360,7 +365,7 @@ const OptionList: React.ForwardRefRenderFunction<RefOptionListProps, {}> = (_, r
360365 < div
361366 key = { group . key }
362367 role = "group"
363- aria-label = { isTitleType ( groupLabel ) ? String ( groupLabel ) : null }
368+ aria-label = { group . data . title ?? ( isTitleType ( groupLabel ) ? String ( groupLabel ) : null ) }
364369 >
365370 { indexes . map ( renderItem ) }
366371 </ div >
0 commit comments