@aurora-ds/components 1.8.1 → 1.8.2
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/dist/cjs/index.js +18 -6
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.js +18 -6
- package/dist/esm/index.js.map +1 -1
- package/dist/index.d.ts +9 -2
- package/package.json +1 -1
package/dist/cjs/index.js
CHANGED
|
@@ -3486,6 +3486,13 @@ width = '100%', minWidth = 0, maxWidth, flex, flexGrow, flexShrink, flexBasis, .
|
|
|
3486
3486
|
};
|
|
3487
3487
|
TextField.displayName = 'TextField';
|
|
3488
3488
|
|
|
3489
|
+
/**
|
|
3490
|
+
* Vertical padding (in px) applied to the top and bottom of the menu panel.
|
|
3491
|
+
* Matches `theme.spacing.xs` (0.25rem = 4px at 16px base font).
|
|
3492
|
+
* Exported so submenus can offset their position upward by this amount to align
|
|
3493
|
+
* their first item with the trigger item.
|
|
3494
|
+
*/
|
|
3495
|
+
const MENU_PANEL_PADDING_Y_PX = 6;
|
|
3489
3496
|
const MENU_PANEL_STYLES = theme.createStyles((theme) => ({
|
|
3490
3497
|
backdrop: {
|
|
3491
3498
|
position: 'fixed',
|
|
@@ -3559,7 +3566,7 @@ const MENU_MIN_WIDTH_PX = 224;
|
|
|
3559
3566
|
* Uses a two-pass strategy: first render with `menuHeight = 0`, then a rAF
|
|
3560
3567
|
* recompute with the actual rendered size to apply any overflow offset.
|
|
3561
3568
|
*/
|
|
3562
|
-
const useMenuPosition = ({ anchorEl, open, menuRef, minWidth, gap = 4, placement = 'bottom', }) => {
|
|
3569
|
+
const useMenuPosition = ({ anchorEl, open, menuRef, minWidth, gap = 4, verticalOffset = 0, placement = 'bottom', }) => {
|
|
3563
3570
|
const [style, setStyle] = React.useState({});
|
|
3564
3571
|
// Stays false until the rAF second pass has run with the real panel dimensions.
|
|
3565
3572
|
// Keeps the panel invisible during the initial style={} state and the first
|
|
@@ -3576,8 +3583,10 @@ const useMenuPosition = ({ anchorEl, open, menuRef, minWidth, gap = 4, placement
|
|
|
3576
3583
|
const viewportRight = window.innerWidth - VIEWPORT_MARGIN_PX;
|
|
3577
3584
|
const viewportBottom = window.innerHeight - VIEWPORT_MARGIN_PX;
|
|
3578
3585
|
if (placement === 'right' || placement === 'left') {
|
|
3579
|
-
// --- Vertical: align with the anchor top,
|
|
3580
|
-
|
|
3586
|
+
// --- Vertical: align with the anchor top, offset upward by verticalOffset
|
|
3587
|
+
// (e.g. the panel's paddingTop) so the first item lines up with the trigger,
|
|
3588
|
+
// then clamp inside the viewport. ---
|
|
3589
|
+
let top = anchor.top - verticalOffset;
|
|
3581
3590
|
if (menuHeight > 0 && top + menuHeight > viewportBottom) {
|
|
3582
3591
|
top = Math.max(VIEWPORT_MARGIN_PX, viewportBottom - menuHeight);
|
|
3583
3592
|
}
|
|
@@ -3637,7 +3646,7 @@ const useMenuPosition = ({ anchorEl, open, menuRef, minWidth, gap = 4, placement
|
|
|
3637
3646
|
const maxLeft = window.innerWidth - effectiveWidth - VIEWPORT_MARGIN_PX;
|
|
3638
3647
|
const left = Math.max(VIEWPORT_MARGIN_PX, Math.min(anchor.left, maxLeft));
|
|
3639
3648
|
setStyle({ top, left, minWidth: minWidth ?? fallbackMinWidth });
|
|
3640
|
-
}, [anchorEl, menuRef, minWidth, gap, placement]);
|
|
3649
|
+
}, [anchorEl, menuRef, minWidth, gap, verticalOffset, placement]);
|
|
3641
3650
|
// First pass: compute as soon as the menu opens (menuHeight = 0)
|
|
3642
3651
|
React.useLayoutEffect(() => {
|
|
3643
3652
|
if (open) {
|
|
@@ -3710,12 +3719,12 @@ const ITEM_SELECTOR = '[role^="menuitem"]:not([data-disabled]), [role="option"]:
|
|
|
3710
3719
|
* `aria-activedescendant`. Item order is read from the DOM (read-only) so the
|
|
3711
3720
|
* logic stays correct across groups and dynamic content.
|
|
3712
3721
|
*/
|
|
3713
|
-
const useMenuPanel = ({ open, onClose, anchorEl, minWidth, placement = 'bottom', onArrowLeft, }) => {
|
|
3722
|
+
const useMenuPanel = ({ open, onClose, anchorEl, minWidth, placement = 'bottom', verticalOffset = 0, onArrowLeft, }) => {
|
|
3714
3723
|
const panelRef = React.useRef(null);
|
|
3715
3724
|
const [focusedId, setFocusedId] = React.useState(undefined);
|
|
3716
3725
|
// True while a descendant submenu is open → pause this panel's keyboard nav.
|
|
3717
3726
|
const [childOpen, setChildOpen] = React.useState(false);
|
|
3718
|
-
const { style } = useMenuPosition({ anchorEl, open, menuRef: panelRef, minWidth, placement });
|
|
3727
|
+
const { style } = useMenuPosition({ anchorEl, open, menuRef: panelRef, minWidth, placement, verticalOffset });
|
|
3719
3728
|
/** Read this panel's focusable items in DOM order (excluding nested submenus). */
|
|
3720
3729
|
const getItems = React.useCallback(() => {
|
|
3721
3730
|
const panel = panelRef.current;
|
|
@@ -3929,6 +3938,9 @@ const MenuPanel = ({ open, onClose, anchorEl, minWidth, maxHeight = '20rem', pla
|
|
|
3929
3938
|
anchorEl,
|
|
3930
3939
|
minWidth,
|
|
3931
3940
|
placement,
|
|
3941
|
+
// Shift submenus upward by the panel's paddingTop so the first item aligns
|
|
3942
|
+
// visually with the trigger item in the parent menu.
|
|
3943
|
+
verticalOffset: isSubmenu ? MENU_PANEL_PADDING_Y_PX : 0,
|
|
3932
3944
|
onArrowLeft,
|
|
3933
3945
|
});
|
|
3934
3946
|
const contextValue = React.useMemo(() => ({ setChildOpen, closeMenu }), [setChildOpen, closeMenu]);
|