@@ -944,26 +944,6 @@ function OptionsFn<TTag extends ElementType = typeof DEFAULT_OPTIONS_TAG>(
944
944
allowed : useEvent ( ( ) => [ data . buttonRef . current , data . optionsRef . current ] ) ,
945
945
} )
946
946
947
- let initialOption = useRef < number | null > ( null )
948
-
949
- useEffect ( ( ) => {
950
- if ( ! anchor ?. to ?. includes ( 'selection' ) ) return
951
-
952
- if ( ! visible ) {
953
- initialOption . current = null
954
- return
955
- }
956
-
957
- let elements = Array . from ( data . listRef . current . values ( ) )
958
- // TODO: Do not rely on DOM elements here
959
- initialOption . current = elements . findIndex ( ( el ) => el ?. dataset . selected === '' )
960
- // Default to first option if nothing is selected
961
- if ( initialOption . current === - 1 ) {
962
- initialOption . current = elements . findIndex ( ( el ) => el ?. dataset . disabled === undefined )
963
- actions . goToOption ( Focus . First )
964
- }
965
- } , [ visible , data . listRef ] )
966
-
967
947
// We keep track whether the button moved or not, we only check this when the menu state becomes
968
948
// closed. If the button moved, then we want to cancel pending transitions to prevent that the
969
949
// attached `MenuItems` is still transitioning while the button moved away.
@@ -980,17 +960,38 @@ function OptionsFn<TTag extends ElementType = typeof DEFAULT_OPTIONS_TAG>(
980
960
// its transitions, or rely on the `visible` state to hide the panel whenever necessary.
981
961
let panelEnabled = didButtonMove ? false : visible
982
962
963
+ // We should freeze when the listbox is visible but "closed". This means that
964
+ // a transition is currently happening and the component is still visible (for
965
+ // the transition) but closed from a functionality perspective.
966
+ let shouldFreeze = visible && data . listboxState === ListboxStates . Closed
967
+
968
+ // Frozen state, the selected value will only update visually when the user re-opens the <Listbox />
969
+ let frozenValue = useFrozenData ( shouldFreeze , data . value )
970
+
971
+ let isSelected = useEvent ( ( compareValue : unknown ) => data . compare ( frozenValue , compareValue ) )
972
+
973
+ let selectedOptionIndex = useMemo ( ( ) => {
974
+ if ( anchor == null ) return null
975
+ if ( ! anchor ?. to ?. includes ( 'selection' ) ) return null
976
+
977
+ // Only compute the selected option index when using `selection` in the
978
+ // `anchor` prop.
979
+ let idx = data . options . findIndex ( ( option ) => isSelected ( option . dataRef . current . value ) )
980
+ // Ensure that if no data is selected, we default to the first item.
981
+ if ( idx === - 1 ) idx = 0
982
+ return idx
983
+ } , [ anchor , data . options ] )
984
+
983
985
let anchorOptions = ( ( ) => {
984
- if ( anchor == null ) return undefined
985
- if ( data . listRef . current . size <= 0 ) return { ...anchor , inner : undefined }
986
+ if ( selectedOptionIndex === null ) return { ...anchor , inner : undefined }
986
987
987
988
let elements = Array . from ( data . listRef . current . values ( ) )
988
989
989
990
return {
990
991
...anchor ,
991
992
inner : {
992
993
listRef : { current : elements } ,
993
- index : initialOption . current ! ,
994
+ index : selectedOptionIndex ,
994
995
} ,
995
996
}
996
997
} ) ( )
@@ -1115,16 +1116,6 @@ function OptionsFn<TTag extends ElementType = typeof DEFAULT_OPTIONS_TAG>(
1115
1116
...transitionDataAttributes ( transitionData ) ,
1116
1117
} )
1117
1118
1118
- // We should freeze when the listbox is visible but "closed". This means that
1119
- // a transition is currently happening and the component is still visible (for
1120
- // the transition) but closed from a functionality perspective.
1121
- let shouldFreeze = visible && data . listboxState === ListboxStates . Closed
1122
-
1123
- // Frozen state, the selected value will only update visually when the user re-opens the <Listbox />
1124
- let frozenValue = useFrozenData ( shouldFreeze , data . value )
1125
-
1126
- let isSelected = useEvent ( ( compareValue : unknown ) => data . compare ( frozenValue , compareValue ) )
1127
-
1128
1119
return (
1129
1120
< Portal enabled = { portal ? props . static || visible : false } >
1130
1121
< ListboxDataContext . Provider
0 commit comments