@@ -43,6 +43,8 @@ type BasePopoverProps = {
43
43
mode ?: TriggerMode ;
44
44
} ;
45
45
46
+ // By separating controlled and uncontrolled props, we achieve more accurate
47
+ // type inference.
46
48
type UncontrolledPopoverProps = BasePopoverProps & {
47
49
open ?: undefined ;
48
50
onOpenChange ?: undefined ;
@@ -57,16 +59,15 @@ export type PopoverProps = UncontrolledPopoverProps | ControlledPopoverProps;
57
59
58
60
export const Popover : FC < PopoverProps > = ( props ) => {
59
61
const hookId = useId ( ) ;
60
- const [ open , setOpen ] = useState ( false ) ;
62
+ const [ uncontrolledOpen , setUncontrolledOpen ] = useState ( false ) ;
61
63
const triggerRef : TriggerRef = useRef ( null ) ;
62
- const isControlled = props . open !== undefined ;
63
64
64
65
const value : PopoverContextValue = {
65
66
triggerRef,
66
67
id : `${ hookId } -popover` ,
67
68
mode : props . mode ?? "click" ,
68
- open : isControlled ? props . open : open ,
69
- setOpen : isControlled ? props . onOpenChange : setOpen ,
69
+ open : props . open ?? uncontrolledOpen ,
70
+ setOpen : props . onOpenChange ?? setUncontrolledOpen ,
70
71
} ;
71
72
72
73
return (
@@ -113,7 +114,8 @@ export const PopoverTrigger = (
113
114
...elementProps ,
114
115
...( popover . mode === "click" ? clickProps : hoverProps ) ,
115
116
"aria-haspopup" : true ,
116
- "aria-owns" : popover . open ? popover . id : undefined ,
117
+ "aria-owns" : popover . id ,
118
+ "aria-expanded" : popover . open ,
117
119
ref : popover . triggerRef ,
118
120
} ) ;
119
121
} ;
0 commit comments