@seed-design/react-menu 0.0.0-alpha-20260511052324 → 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/{Menu-12s-KCTCu-et.cjs → Menu-12s-BZEIsPP0.cjs} +1 -1
- package/lib/{Menu-12s-DcQqm37B.js → Menu-12s-Cfv1stLD.js} +1 -1
- package/lib/index.cjs +1 -1
- package/lib/index.js +2 -2
- package/lib/{useMenu-12s-WINwYlwH.js → useMenu-12s-BrOJabEO.js} +60 -5
- package/lib/{useMenu-12s-DN0SpRKs.cjs → useMenu-12s-Cv5FQJ3x.cjs} +59 -4
- package/package.json +5 -5
- package/src/useMenu.ts +59 -4
|
@@ -7,7 +7,7 @@ var reactDismissibleLayer = require('@seed-design/react-dismissible-layer');
|
|
|
7
7
|
var domUtils = require('@seed-design/dom-utils');
|
|
8
8
|
var reactPrimitive = require('@seed-design/react-primitive');
|
|
9
9
|
var React = require('react');
|
|
10
|
-
var useMenu12s = require('./useMenu-12s-
|
|
10
|
+
var useMenu12s = require('./useMenu-12s-Cv5FQJ3x.cjs');
|
|
11
11
|
|
|
12
12
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
13
13
|
|
|
@@ -7,7 +7,7 @@ import { DismissibleLayer } from '@seed-design/react-dismissible-layer';
|
|
|
7
7
|
import { mergeProps } from '@seed-design/dom-utils';
|
|
8
8
|
import { Primitive } from '@seed-design/react-primitive';
|
|
9
9
|
import React, { createContext, useContext, forwardRef } from 'react';
|
|
10
|
-
import { u as useMenu } from './useMenu-12s-
|
|
10
|
+
import { u as useMenu } from './useMenu-12s-BrOJabEO.js';
|
|
11
11
|
|
|
12
12
|
const MenuContext = /*#__PURE__*/ createContext(null);
|
|
13
13
|
const MenuProvider = MenuContext.Provider;
|
package/lib/index.cjs
CHANGED
package/lib/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { M as MenuAnchor, a as MenuContent, b as MenuGroup, c as MenuGroupLabel, d as MenuItem, e as MenuPositioner, f as MenuRoot, g as MenuTrigger } from './Menu-12s-
|
|
2
|
-
export { u as useMenuContext, h as useMenuItemContext } from './Menu-12s-
|
|
1
|
+
import { M as MenuAnchor, a as MenuContent, b as MenuGroup, c as MenuGroupLabel, d as MenuItem, e as MenuPositioner, f as MenuRoot, g as MenuTrigger } from './Menu-12s-Cfv1stLD.js';
|
|
2
|
+
export { u as useMenuContext, h as useMenuItemContext } from './Menu-12s-Cfv1stLD.js';
|
|
3
3
|
|
|
4
4
|
var Menu_namespace = {
|
|
5
5
|
__proto__: null,
|
|
@@ -2,9 +2,23 @@
|
|
|
2
2
|
import { useFloating, offset, size, flip, shift, useTransitionStatus, autoUpdate, useClick, useRole, useListNavigation, useTypeahead, useInteractions } from '@floating-ui/react';
|
|
3
3
|
import { useControllableState } from '@seed-design/react-use-controllable-state';
|
|
4
4
|
import { elementProps, dataAttr, buttonProps } from '@seed-design/dom-utils';
|
|
5
|
-
import { useCallback, useEffect, useMemo,
|
|
5
|
+
import { useState, useCallback, useEffect, useMemo, useRef, useId } from 'react';
|
|
6
6
|
|
|
7
7
|
const MIN_HEIGHT = 200;
|
|
8
|
+
// flip/size/shift derive collisions from numeric padding, so the safe-area insets
|
|
9
|
+
// have to reach floating-ui as numbers — a CSS env() value alone can't. The first
|
|
10
|
+
// cut stayed in CSS, insetting the menu's max-height per placement; on iOS WebKit
|
|
11
|
+
// that coupled height to placement, so flip kept re-measuring, oscillated
|
|
12
|
+
// top<->bottom, and the synchronous reposition re-renders pinned the main thread.
|
|
13
|
+
// Folding the insets into the collision boundary instead keeps placement stable.
|
|
14
|
+
//
|
|
15
|
+
// So, like Snackbar's `useSafeOffset`, the positioner re-declares the insets from
|
|
16
|
+
// env() here and the hook reads them back as px (see the effect after useFloating),
|
|
17
|
+
// which also keeps this layer self-contained from the global SEED safe-area tokens.
|
|
18
|
+
const SAFE_AREA_STYLE = {
|
|
19
|
+
"--seed-safe-area-top": "env(safe-area-inset-top)",
|
|
20
|
+
"--seed-safe-area-bottom": "env(safe-area-inset-bottom)"
|
|
21
|
+
};
|
|
8
22
|
function getTransformOrigin(placement) {
|
|
9
23
|
const [side, align] = placement.split("-");
|
|
10
24
|
const y = {
|
|
@@ -47,6 +61,20 @@ function useMenuState(props) {
|
|
|
47
61
|
function useMenu(props) {
|
|
48
62
|
const { open, setOpenState, activeIndex, setActiveIndex, elementsRef, labelsRef, triggerRef, groupIndexCounter, menuId } = useMenuState(props);
|
|
49
63
|
const { disabled = false, placement = "bottom", gutter = 8, overflowPadding = 8, strategy = "absolute", matchReferenceWidth = false } = props;
|
|
64
|
+
const [safeArea, setSafeArea] = useState({
|
|
65
|
+
top: 0,
|
|
66
|
+
bottom: 0
|
|
67
|
+
});
|
|
68
|
+
// Inset the viewport collision boundary so flip/size/shift keep the menu clear of
|
|
69
|
+
// the notch and home indicator, not just the viewport edge. The safe area is already
|
|
70
|
+
// a visual buffer, so where it exists the menu sits right at its boundary; only where
|
|
71
|
+
// there is none does it fall back to overflowPadding off the bare viewport edge.
|
|
72
|
+
const collisionPadding = {
|
|
73
|
+
top: safeArea.top || overflowPadding,
|
|
74
|
+
right: overflowPadding,
|
|
75
|
+
bottom: safeArea.bottom || overflowPadding,
|
|
76
|
+
left: overflowPadding
|
|
77
|
+
};
|
|
50
78
|
const setOpen = useCallback((nextOpen, details)=>{
|
|
51
79
|
if (disabled && nextOpen) return;
|
|
52
80
|
setOpenState(nextOpen, details);
|
|
@@ -75,7 +103,7 @@ function useMenu(props) {
|
|
|
75
103
|
middleware: [
|
|
76
104
|
offset(gutter),
|
|
77
105
|
size({
|
|
78
|
-
padding:
|
|
106
|
+
padding: collisionPadding,
|
|
79
107
|
apply ({ availableHeight, rects, elements }) {
|
|
80
108
|
elements.floating.style.setProperty("--seed-menu-available-height", `${Math.max(MIN_HEIGHT, availableHeight)}px`);
|
|
81
109
|
if (matchReferenceWidth) {
|
|
@@ -84,11 +112,11 @@ function useMenu(props) {
|
|
|
84
112
|
}
|
|
85
113
|
}),
|
|
86
114
|
flip({
|
|
87
|
-
padding:
|
|
115
|
+
padding: collisionPadding,
|
|
88
116
|
fallbackStrategy: "initialPlacement"
|
|
89
117
|
}),
|
|
90
118
|
shift({
|
|
91
|
-
padding:
|
|
119
|
+
padding: collisionPadding
|
|
92
120
|
})
|
|
93
121
|
]
|
|
94
122
|
});
|
|
@@ -106,6 +134,30 @@ function useMenu(props) {
|
|
|
106
134
|
floatingRefs.floating,
|
|
107
135
|
context
|
|
108
136
|
]);
|
|
137
|
+
// Read the env()-resolved insets off the positioner, which carries the env()
|
|
138
|
+
// declarations via SAFE_AREA_STYLE. Key on the reactive `elements.floating`, not
|
|
139
|
+
// `refs.floating`: the ref object's identity never changes, so an effect depending
|
|
140
|
+
// on it runs only once at mount — before FloatingPortal has committed the positioner
|
|
141
|
+
// child — reads a null ref, bails, and never re-fires, leaving `safeArea` stuck at
|
|
142
|
+
// {0,0}. `elements.floating` updates when the positioner mounts (it stays mounted
|
|
143
|
+
// even while closed), so the insets are read before the first open and the menu
|
|
144
|
+
// clears the safe area on its first frame. Re-read on resize for orientation changes.
|
|
145
|
+
const floatingElement = context.elements.floating;
|
|
146
|
+
useEffect(()=>{
|
|
147
|
+
if (!floatingElement) return;
|
|
148
|
+
const read = ()=>{
|
|
149
|
+
const styles = getComputedStyle(floatingElement);
|
|
150
|
+
setSafeArea({
|
|
151
|
+
top: Number.parseInt(styles.getPropertyValue("--seed-safe-area-top"), 10) || 0,
|
|
152
|
+
bottom: Number.parseInt(styles.getPropertyValue("--seed-safe-area-bottom"), 10) || 0
|
|
153
|
+
});
|
|
154
|
+
};
|
|
155
|
+
read();
|
|
156
|
+
window.addEventListener("resize", read);
|
|
157
|
+
return ()=>window.removeEventListener("resize", read);
|
|
158
|
+
}, [
|
|
159
|
+
floatingElement
|
|
160
|
+
]);
|
|
109
161
|
const click = useClick(context, {
|
|
110
162
|
enabled: !disabled
|
|
111
163
|
});
|
|
@@ -173,7 +225,10 @@ function useMenu(props) {
|
|
|
173
225
|
}),
|
|
174
226
|
positionerProps: elementProps({
|
|
175
227
|
...stateProps,
|
|
176
|
-
style:
|
|
228
|
+
style: {
|
|
229
|
+
...SAFE_AREA_STYLE,
|
|
230
|
+
...floatingStyles
|
|
231
|
+
}
|
|
177
232
|
}),
|
|
178
233
|
contentProps: elementProps({
|
|
179
234
|
...stateProps,
|
|
@@ -5,6 +5,20 @@ var domUtils = require('@seed-design/dom-utils');
|
|
|
5
5
|
var React = require('react');
|
|
6
6
|
|
|
7
7
|
const MIN_HEIGHT = 200;
|
|
8
|
+
// flip/size/shift derive collisions from numeric padding, so the safe-area insets
|
|
9
|
+
// have to reach floating-ui as numbers — a CSS env() value alone can't. The first
|
|
10
|
+
// cut stayed in CSS, insetting the menu's max-height per placement; on iOS WebKit
|
|
11
|
+
// that coupled height to placement, so flip kept re-measuring, oscillated
|
|
12
|
+
// top<->bottom, and the synchronous reposition re-renders pinned the main thread.
|
|
13
|
+
// Folding the insets into the collision boundary instead keeps placement stable.
|
|
14
|
+
//
|
|
15
|
+
// So, like Snackbar's `useSafeOffset`, the positioner re-declares the insets from
|
|
16
|
+
// env() here and the hook reads them back as px (see the effect after useFloating),
|
|
17
|
+
// which also keeps this layer self-contained from the global SEED safe-area tokens.
|
|
18
|
+
const SAFE_AREA_STYLE = {
|
|
19
|
+
"--seed-safe-area-top": "env(safe-area-inset-top)",
|
|
20
|
+
"--seed-safe-area-bottom": "env(safe-area-inset-bottom)"
|
|
21
|
+
};
|
|
8
22
|
function getTransformOrigin(placement) {
|
|
9
23
|
const [side, align] = placement.split("-");
|
|
10
24
|
const y = {
|
|
@@ -47,6 +61,20 @@ function useMenuState(props) {
|
|
|
47
61
|
function useMenu(props) {
|
|
48
62
|
const { open, setOpenState, activeIndex, setActiveIndex, elementsRef, labelsRef, triggerRef, groupIndexCounter, menuId } = useMenuState(props);
|
|
49
63
|
const { disabled = false, placement = "bottom", gutter = 8, overflowPadding = 8, strategy = "absolute", matchReferenceWidth = false } = props;
|
|
64
|
+
const [safeArea, setSafeArea] = React.useState({
|
|
65
|
+
top: 0,
|
|
66
|
+
bottom: 0
|
|
67
|
+
});
|
|
68
|
+
// Inset the viewport collision boundary so flip/size/shift keep the menu clear of
|
|
69
|
+
// the notch and home indicator, not just the viewport edge. The safe area is already
|
|
70
|
+
// a visual buffer, so where it exists the menu sits right at its boundary; only where
|
|
71
|
+
// there is none does it fall back to overflowPadding off the bare viewport edge.
|
|
72
|
+
const collisionPadding = {
|
|
73
|
+
top: safeArea.top || overflowPadding,
|
|
74
|
+
right: overflowPadding,
|
|
75
|
+
bottom: safeArea.bottom || overflowPadding,
|
|
76
|
+
left: overflowPadding
|
|
77
|
+
};
|
|
50
78
|
const setOpen = React.useCallback((nextOpen, details)=>{
|
|
51
79
|
if (disabled && nextOpen) return;
|
|
52
80
|
setOpenState(nextOpen, details);
|
|
@@ -75,7 +103,7 @@ function useMenu(props) {
|
|
|
75
103
|
middleware: [
|
|
76
104
|
react.offset(gutter),
|
|
77
105
|
react.size({
|
|
78
|
-
padding:
|
|
106
|
+
padding: collisionPadding,
|
|
79
107
|
apply ({ availableHeight, rects, elements }) {
|
|
80
108
|
elements.floating.style.setProperty("--seed-menu-available-height", `${Math.max(MIN_HEIGHT, availableHeight)}px`);
|
|
81
109
|
if (matchReferenceWidth) {
|
|
@@ -84,11 +112,11 @@ function useMenu(props) {
|
|
|
84
112
|
}
|
|
85
113
|
}),
|
|
86
114
|
react.flip({
|
|
87
|
-
padding:
|
|
115
|
+
padding: collisionPadding,
|
|
88
116
|
fallbackStrategy: "initialPlacement"
|
|
89
117
|
}),
|
|
90
118
|
react.shift({
|
|
91
|
-
padding:
|
|
119
|
+
padding: collisionPadding
|
|
92
120
|
})
|
|
93
121
|
]
|
|
94
122
|
});
|
|
@@ -106,6 +134,30 @@ function useMenu(props) {
|
|
|
106
134
|
floatingRefs.floating,
|
|
107
135
|
context
|
|
108
136
|
]);
|
|
137
|
+
// Read the env()-resolved insets off the positioner, which carries the env()
|
|
138
|
+
// declarations via SAFE_AREA_STYLE. Key on the reactive `elements.floating`, not
|
|
139
|
+
// `refs.floating`: the ref object's identity never changes, so an effect depending
|
|
140
|
+
// on it runs only once at mount — before FloatingPortal has committed the positioner
|
|
141
|
+
// child — reads a null ref, bails, and never re-fires, leaving `safeArea` stuck at
|
|
142
|
+
// {0,0}. `elements.floating` updates when the positioner mounts (it stays mounted
|
|
143
|
+
// even while closed), so the insets are read before the first open and the menu
|
|
144
|
+
// clears the safe area on its first frame. Re-read on resize for orientation changes.
|
|
145
|
+
const floatingElement = context.elements.floating;
|
|
146
|
+
React.useEffect(()=>{
|
|
147
|
+
if (!floatingElement) return;
|
|
148
|
+
const read = ()=>{
|
|
149
|
+
const styles = getComputedStyle(floatingElement);
|
|
150
|
+
setSafeArea({
|
|
151
|
+
top: Number.parseInt(styles.getPropertyValue("--seed-safe-area-top"), 10) || 0,
|
|
152
|
+
bottom: Number.parseInt(styles.getPropertyValue("--seed-safe-area-bottom"), 10) || 0
|
|
153
|
+
});
|
|
154
|
+
};
|
|
155
|
+
read();
|
|
156
|
+
window.addEventListener("resize", read);
|
|
157
|
+
return ()=>window.removeEventListener("resize", read);
|
|
158
|
+
}, [
|
|
159
|
+
floatingElement
|
|
160
|
+
]);
|
|
109
161
|
const click = react.useClick(context, {
|
|
110
162
|
enabled: !disabled
|
|
111
163
|
});
|
|
@@ -173,7 +225,10 @@ function useMenu(props) {
|
|
|
173
225
|
}),
|
|
174
226
|
positionerProps: domUtils.elementProps({
|
|
175
227
|
...stateProps,
|
|
176
|
-
style:
|
|
228
|
+
style: {
|
|
229
|
+
...SAFE_AREA_STYLE,
|
|
230
|
+
...floatingStyles
|
|
231
|
+
}
|
|
177
232
|
}),
|
|
178
233
|
contentProps: domUtils.elementProps({
|
|
179
234
|
...stateProps,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@seed-design/react-menu",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "1.0.0",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/daangn/seed-design.git",
|
|
@@ -31,10 +31,10 @@
|
|
|
31
31
|
"@floating-ui/react": "^0.27.0",
|
|
32
32
|
"@radix-ui/react-compose-refs": "^1.1.2",
|
|
33
33
|
"@radix-ui/react-focus-scope": "^1.1.8",
|
|
34
|
-
"@seed-design/dom-utils": "
|
|
35
|
-
"@seed-design/react-dismissible-layer": "
|
|
36
|
-
"@seed-design/react-primitive": "
|
|
37
|
-
"@seed-design/react-use-controllable-state": "
|
|
34
|
+
"@seed-design/dom-utils": "^2.0.0",
|
|
35
|
+
"@seed-design/react-dismissible-layer": "^1.0.0",
|
|
36
|
+
"@seed-design/react-primitive": "^2.0.0",
|
|
37
|
+
"@seed-design/react-use-controllable-state": "^2.0.0"
|
|
38
38
|
},
|
|
39
39
|
"devDependencies": {
|
|
40
40
|
"@types/react": "^19.1.6",
|
package/src/useMenu.ts
CHANGED
|
@@ -21,6 +21,21 @@ import { useCallback, useEffect, useId, useMemo, useRef, useState } from "react"
|
|
|
21
21
|
|
|
22
22
|
const MIN_HEIGHT = 200;
|
|
23
23
|
|
|
24
|
+
// flip/size/shift derive collisions from numeric padding, so the safe-area insets
|
|
25
|
+
// have to reach floating-ui as numbers — a CSS env() value alone can't. The first
|
|
26
|
+
// cut stayed in CSS, insetting the menu's max-height per placement; on iOS WebKit
|
|
27
|
+
// that coupled height to placement, so flip kept re-measuring, oscillated
|
|
28
|
+
// top<->bottom, and the synchronous reposition re-renders pinned the main thread.
|
|
29
|
+
// Folding the insets into the collision boundary instead keeps placement stable.
|
|
30
|
+
//
|
|
31
|
+
// So, like Snackbar's `useSafeOffset`, the positioner re-declares the insets from
|
|
32
|
+
// env() here and the hook reads them back as px (see the effect after useFloating),
|
|
33
|
+
// which also keeps this layer self-contained from the global SEED safe-area tokens.
|
|
34
|
+
const SAFE_AREA_STYLE = {
|
|
35
|
+
"--seed-safe-area-top": "env(safe-area-inset-top)",
|
|
36
|
+
"--seed-safe-area-bottom": "env(safe-area-inset-bottom)",
|
|
37
|
+
} as React.CSSProperties;
|
|
38
|
+
|
|
24
39
|
function getTransformOrigin(placement: string) {
|
|
25
40
|
const [side, align] = placement.split("-");
|
|
26
41
|
const y = { top: "bottom", bottom: "top", left: "center", right: "center" }[side] ?? "top";
|
|
@@ -167,6 +182,19 @@ export function useMenu(props: UseMenuProps) {
|
|
|
167
182
|
matchReferenceWidth = false,
|
|
168
183
|
} = props;
|
|
169
184
|
|
|
185
|
+
const [safeArea, setSafeArea] = useState({ top: 0, bottom: 0 });
|
|
186
|
+
|
|
187
|
+
// Inset the viewport collision boundary so flip/size/shift keep the menu clear of
|
|
188
|
+
// the notch and home indicator, not just the viewport edge. The safe area is already
|
|
189
|
+
// a visual buffer, so where it exists the menu sits right at its boundary; only where
|
|
190
|
+
// there is none does it fall back to overflowPadding off the bare viewport edge.
|
|
191
|
+
const collisionPadding = {
|
|
192
|
+
top: safeArea.top || overflowPadding,
|
|
193
|
+
right: overflowPadding,
|
|
194
|
+
bottom: safeArea.bottom || overflowPadding,
|
|
195
|
+
left: overflowPadding,
|
|
196
|
+
};
|
|
197
|
+
|
|
170
198
|
const setOpen = useCallback(
|
|
171
199
|
(nextOpen: boolean, details?: MenuChangeDetails) => {
|
|
172
200
|
if (disabled && nextOpen) return;
|
|
@@ -201,7 +229,7 @@ export function useMenu(props: UseMenuProps) {
|
|
|
201
229
|
middleware: [
|
|
202
230
|
offset(gutter),
|
|
203
231
|
size({
|
|
204
|
-
padding:
|
|
232
|
+
padding: collisionPadding,
|
|
205
233
|
apply({ availableHeight, rects, elements }) {
|
|
206
234
|
elements.floating.style.setProperty(
|
|
207
235
|
"--seed-menu-available-height",
|
|
@@ -215,8 +243,8 @@ export function useMenu(props: UseMenuProps) {
|
|
|
215
243
|
}
|
|
216
244
|
},
|
|
217
245
|
}),
|
|
218
|
-
flip({ padding:
|
|
219
|
-
shift({ padding:
|
|
246
|
+
flip({ padding: collisionPadding, fallbackStrategy: "initialPlacement" }),
|
|
247
|
+
shift({ padding: collisionPadding }),
|
|
220
248
|
],
|
|
221
249
|
});
|
|
222
250
|
|
|
@@ -237,6 +265,33 @@ export function useMenu(props: UseMenuProps) {
|
|
|
237
265
|
);
|
|
238
266
|
}, [mounted, floatingRefs.reference, floatingRefs.floating, context]);
|
|
239
267
|
|
|
268
|
+
// Read the env()-resolved insets off the positioner, which carries the env()
|
|
269
|
+
// declarations via SAFE_AREA_STYLE. Key on the reactive `elements.floating`, not
|
|
270
|
+
// `refs.floating`: the ref object's identity never changes, so an effect depending
|
|
271
|
+
// on it runs only once at mount — before FloatingPortal has committed the positioner
|
|
272
|
+
// child — reads a null ref, bails, and never re-fires, leaving `safeArea` stuck at
|
|
273
|
+
// {0,0}. `elements.floating` updates when the positioner mounts (it stays mounted
|
|
274
|
+
// even while closed), so the insets are read before the first open and the menu
|
|
275
|
+
// clears the safe area on its first frame. Re-read on resize for orientation changes.
|
|
276
|
+
const floatingElement = context.elements.floating;
|
|
277
|
+
|
|
278
|
+
useEffect(() => {
|
|
279
|
+
if (!floatingElement) return;
|
|
280
|
+
|
|
281
|
+
const read = () => {
|
|
282
|
+
const styles = getComputedStyle(floatingElement);
|
|
283
|
+
setSafeArea({
|
|
284
|
+
top: Number.parseInt(styles.getPropertyValue("--seed-safe-area-top"), 10) || 0,
|
|
285
|
+
bottom: Number.parseInt(styles.getPropertyValue("--seed-safe-area-bottom"), 10) || 0,
|
|
286
|
+
});
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
read();
|
|
290
|
+
window.addEventListener("resize", read);
|
|
291
|
+
|
|
292
|
+
return () => window.removeEventListener("resize", read);
|
|
293
|
+
}, [floatingElement]);
|
|
294
|
+
|
|
240
295
|
const click = useClick(context, {
|
|
241
296
|
enabled: !disabled,
|
|
242
297
|
});
|
|
@@ -309,7 +364,7 @@ export function useMenu(props: UseMenuProps) {
|
|
|
309
364
|
|
|
310
365
|
positionerProps: elementProps({
|
|
311
366
|
...stateProps,
|
|
312
|
-
style: floatingStyles,
|
|
367
|
+
style: { ...SAFE_AREA_STYLE, ...floatingStyles },
|
|
313
368
|
}),
|
|
314
369
|
|
|
315
370
|
contentProps: elementProps({
|