1
1
'use client' ;
2
2
import * as React from 'react' ;
3
3
import PropTypes from 'prop-types' ;
4
- import {
5
- FloatingNode ,
6
- useFloatingNodeId ,
7
- useFloatingParentNodeId ,
8
- useFloatingTree ,
9
- } from '@floating-ui/react' ;
4
+ import { FloatingNode , useFloatingNodeId , useFloatingParentNodeId } from '@floating-ui/react' ;
10
5
import { MenuPositionerContext } from './MenuPositionerContext' ;
11
6
import { useMenuRootContext } from '../root/MenuRootContext' ;
12
7
import type { Align , Side } from '../../utils/useAnchorPositioning' ;
13
8
import { useComponentRenderer } from '../../utils/useComponentRenderer' ;
14
9
import { useForkRef } from '../../utils/useForkRef' ;
15
10
import { useMenuPositioner } from './useMenuPositioner' ;
16
- import { HTMLElementType } from '../../utils/proptypes' ;
17
11
import { BaseUIComponentProps } from '../../utils/types' ;
18
12
import { popupStateMapping } from '../../utils/popupStateMapping' ;
19
13
import { CompositeList } from '../../composite/list/CompositeList' ;
20
14
import { InternalBackdrop } from '../../utils/InternalBackdrop' ;
15
+ import { HTMLElementType , refType } from '../../utils/proptypes' ;
21
16
22
17
/**
23
18
* Positions the menu popup against the trigger.
@@ -43,6 +38,7 @@ const MenuPositioner = React.forwardRef(function MenuPositioner(
43
38
collisionPadding = 5 ,
44
39
arrowPadding = 5 ,
45
40
sticky = false ,
41
+ trackAnchor = true ,
46
42
...otherProps
47
43
} = props ;
48
44
@@ -54,12 +50,9 @@ const MenuPositioner = React.forwardRef(function MenuPositioner(
54
50
itemLabels,
55
51
mounted,
56
52
nested,
57
- setOpen,
58
53
modal,
59
54
} = useMenuRootContext ( ) ;
60
55
61
- const { events : menuEvents } = useFloatingTree ( ) ! ;
62
-
63
56
const nodeId = useFloatingNodeId ( ) ;
64
57
const parentNodeId = useFloatingParentNodeId ( ) ;
65
58
@@ -88,8 +81,8 @@ const MenuPositioner = React.forwardRef(function MenuPositioner(
88
81
sticky,
89
82
nodeId,
90
83
parentNodeId,
91
- menuEvents ,
92
- setOpen ,
84
+ keepMounted ,
85
+ trackAnchor ,
93
86
} ) ;
94
87
95
88
const state : MenuPositioner . State = React . useMemo (
@@ -110,15 +103,15 @@ const MenuPositioner = React.forwardRef(function MenuPositioner(
110
103
arrowRef : positioner . arrowRef ,
111
104
arrowUncentered : positioner . arrowUncentered ,
112
105
arrowStyles : positioner . arrowStyles ,
113
- floatingContext : positioner . floatingContext ,
106
+ floatingContext : positioner . context ,
114
107
} ) ,
115
108
[
116
109
positioner . side ,
117
110
positioner . align ,
118
111
positioner . arrowRef ,
119
112
positioner . arrowUncentered ,
120
113
positioner . arrowStyles ,
121
- positioner . floatingContext ,
114
+ positioner . context ,
122
115
] ,
123
116
) ;
124
117
@@ -175,6 +168,7 @@ MenuPositioner.propTypes /* remove-proptypes */ = {
175
168
// └─────────────────────────────────────────────────────────────────────┘
176
169
/**
177
170
* How to align the popup relative to the specified side.
171
+ * @default 'center'
178
172
*/
179
173
align : PropTypes . oneOf ( [ 'center' , 'end' , 'start' ] ) ,
180
174
/**
@@ -188,6 +182,7 @@ MenuPositioner.propTypes /* remove-proptypes */ = {
188
182
*/
189
183
anchor : PropTypes /* @typescript -to-proptypes-ignore */ . oneOfType ( [
190
184
HTMLElementType ,
185
+ refType ,
191
186
PropTypes . object ,
192
187
PropTypes . func ,
193
188
] ) ,
@@ -236,7 +231,7 @@ MenuPositioner.propTypes /* remove-proptypes */ = {
236
231
} ) ,
237
232
] ) ,
238
233
/**
239
- * Whether to keep the HTML element in the DOM while the menu is hidden.
234
+ * Whether to keep the popup mounted in the DOM while it's hidden.
240
235
* @default false
241
236
*/
242
237
keepMounted : PropTypes . bool ,
@@ -255,6 +250,7 @@ MenuPositioner.propTypes /* remove-proptypes */ = {
255
250
/**
256
251
* Which side of the anchor element to align the popup against.
257
252
* May automatically change to avoid collisions.
253
+ * @default 'bottom'
258
254
*/
259
255
side : PropTypes . oneOf ( [ 'bottom' , 'inline-end' , 'inline-start' , 'left' , 'right' , 'top' ] ) ,
260
256
/**
@@ -263,11 +259,16 @@ MenuPositioner.propTypes /* remove-proptypes */ = {
263
259
*/
264
260
sideOffset : PropTypes . number ,
265
261
/**
266
- * Whether to maintain the menu in the viewport after
267
- * the anchor element is scrolled out of view.
262
+ * Whether to maintain the popup in the viewport after
263
+ * the anchor element was scrolled out of view.
268
264
* @default false
269
265
*/
270
266
sticky : PropTypes . bool ,
267
+ /**
268
+ * Whether the popup tracks any layout shift of its positioning anchor.
269
+ * @default true
270
+ */
271
+ trackAnchor : PropTypes . bool ,
271
272
} as any ;
272
273
273
274
export { MenuPositioner } ;
0 commit comments