@@ -18,7 +18,7 @@ import {
1818 useOverlay ,
1919 useOverlayPosition ,
2020} from 'react-aria' ;
21- import { Section as BaseSection } from 'react-stately' ;
21+ import { Section as BaseSection , useListState } from 'react-stately' ;
2222
2323import { useEvent } from '../../../_internal' ;
2424import { CloseIcon , DirectionIcon , LoadingIcon } from '../../../icons' ;
@@ -896,7 +896,7 @@ function ComboBoxOverlay({
896896 const placementDirection = placement ?. split ( ' ' ) [ 0 ] || direction ;
897897
898898 const overlayContent = (
899- < DisplayTransition exposeUnmounted isShown = { isOpen } >
899+ < DisplayTransition isShown = { isOpen } >
900900 { ( { phase, isShown, ref : transitionRef } ) => (
901901 < ComboBoxOverlayElement
902902 { ...mergeProps (
@@ -1199,6 +1199,14 @@ export const ComboBox = forwardRef(function ComboBox<T extends object>(
11991199 ? filteredChildren
12001200 : frozenFilteredChildrenRef . current ?? filteredChildren ;
12011201
1202+ // Create local collection state for reading item data (labels, etc.)
1203+ // This allows us to read item labels even before the popover opens
1204+ const localCollectionState = useListState ( {
1205+ children : displayedFilteredChildren ,
1206+ items : sortedItems ,
1207+ selectionMode : 'none' , // Don't manage selection in this state
1208+ } ) ;
1209+
12021210 const { isFocused, focusProps } = useFocus ( { isDisabled } ) ;
12031211
12041212 // Composite blur handler - fires when focus leaves the entire component
@@ -1268,11 +1276,14 @@ export const ComboBox = forwardRef(function ComboBox<T extends object>(
12681276 const listStateRef = useRef < any > ( null ) ;
12691277 const focusInitAttemptsRef = useRef ( 0 ) ;
12701278
1271- // Helper to get label from collection item
1272- const getItemLabel = useCallback ( ( key : Key ) : string => {
1273- const item = listStateRef . current ?. collection ?. getItem ( key ) ;
1274- return item ?. textValue || String ( key ) ;
1275- } , [ ] ) ;
1279+ // Helper to get label from local collection
1280+ const getItemLabel = useCallback (
1281+ ( key : Key ) : string => {
1282+ const item = localCollectionState ?. collection ?. getItem ( key ) ;
1283+ return item ?. textValue || String ( key ) ;
1284+ } ,
1285+ [ localCollectionState ?. collection ] ,
1286+ ) ;
12761287
12771288 // Selection change handler
12781289 const handleSelectionChange = useEvent ( ( selection : Key | Key [ ] | null ) => {
@@ -1360,9 +1371,6 @@ export const ComboBox = forwardRef(function ComboBox<T extends object>(
13601371
13611372 // Priority 2: fall back to defaultSelectedKey's label
13621373 if ( defaultSelectedKey ) {
1363- // Wait for collection to be ready
1364- if ( ! listStateRef . current ?. collection ) return ;
1365-
13661374 const label = getItemLabel ( defaultSelectedKey ) ;
13671375
13681376 setInternalInputValue ( label ) ;
@@ -1382,9 +1390,6 @@ export const ComboBox = forwardRef(function ComboBox<T extends object>(
13821390 // Only run when selectedKey is controlled but inputValue is uncontrolled
13831391 if ( ! isControlledKey || isControlledInput ) return ;
13841392
1385- // Wait for collection to be ready
1386- if ( ! listStateRef . current ?. collection ) return ;
1387-
13881393 // Get the expected label for the current selection
13891394 const expectedLabel =
13901395 effectiveSelectedKey != null ? getItemLabel ( effectiveSelectedKey ) : '' ;
0 commit comments