@aurora-ds/components 1.7.19 → 1.7.21
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 +26 -9
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.js +26 -9
- package/dist/esm/index.js.map +1 -1
- package/dist/index.d.ts +8 -0
- package/package.json +1 -1
package/dist/esm/index.js
CHANGED
|
@@ -3541,6 +3541,10 @@ const MENU_MIN_WIDTH_PX = 224;
|
|
|
3541
3541
|
*/
|
|
3542
3542
|
const useMenuPosition = ({ anchorEl, open, menuRef, minWidth, gap = 4, placement = 'bottom', }) => {
|
|
3543
3543
|
const [style, setStyle] = useState({});
|
|
3544
|
+
// Stays false until the rAF second pass has run with the real panel dimensions.
|
|
3545
|
+
// Keeps the panel invisible during the initial style={} state and the first
|
|
3546
|
+
// pass (menuHeight = 0) to prevent the position-jump flickering.
|
|
3547
|
+
const [isPositioned, setIsPositioned] = useState(false);
|
|
3544
3548
|
const computePosition = useCallback(() => {
|
|
3545
3549
|
if (!anchorEl) {
|
|
3546
3550
|
return;
|
|
@@ -3621,14 +3625,19 @@ const useMenuPosition = ({ anchorEl, open, menuRef, minWidth, gap = 4, placement
|
|
|
3621
3625
|
}
|
|
3622
3626
|
else {
|
|
3623
3627
|
setStyle({});
|
|
3628
|
+
setIsPositioned(false);
|
|
3624
3629
|
}
|
|
3625
3630
|
}, [open, computePosition]);
|
|
3626
|
-
// Second pass: recompute after the panel renders to get actual height/width
|
|
3631
|
+
// Second pass: recompute after the panel renders to get actual height/width,
|
|
3632
|
+
// then mark as positioned so the panel becomes visible.
|
|
3627
3633
|
useEffect(() => {
|
|
3628
3634
|
if (!open) {
|
|
3629
3635
|
return;
|
|
3630
3636
|
}
|
|
3631
|
-
const id = requestAnimationFrame(
|
|
3637
|
+
const id = requestAnimationFrame(() => {
|
|
3638
|
+
computePosition();
|
|
3639
|
+
setIsPositioned(true);
|
|
3640
|
+
});
|
|
3632
3641
|
return () => cancelAnimationFrame(id);
|
|
3633
3642
|
}, [open, computePosition]);
|
|
3634
3643
|
// Keep the menu glued to its anchor on scroll (nested containers) and resize.
|
|
@@ -3643,7 +3652,7 @@ const useMenuPosition = ({ anchorEl, open, menuRef, minWidth, gap = 4, placement
|
|
|
3643
3652
|
window.removeEventListener('resize', computePosition);
|
|
3644
3653
|
};
|
|
3645
3654
|
}, [open, computePosition]);
|
|
3646
|
-
return { style };
|
|
3655
|
+
return { style: { ...style, visibility: isPositioned ? 'visible' : 'hidden' } };
|
|
3647
3656
|
};
|
|
3648
3657
|
|
|
3649
3658
|
/** Custom DOM event fired on a submenu trigger item to request it opens. */
|
|
@@ -3967,7 +3976,7 @@ const HOVER_CLOSE_DELAY_MS = 160;
|
|
|
3967
3976
|
* focus restoration, parent-keyboard pausing and the configurable close-on-click
|
|
3968
3977
|
* behaviour.
|
|
3969
3978
|
*/
|
|
3970
|
-
const useMenuItem = ({ ref, role, hasSubmenu, disabled, onClick, closeOnClick, }) => {
|
|
3979
|
+
const useMenuItem = ({ ref, role, hasSubmenu, disabled, onClick, closeOnClick, submenuTrigger = 'hover', }) => {
|
|
3971
3980
|
const { setChildOpen, closeMenu } = useContext(MenuContext);
|
|
3972
3981
|
const liRef = useRef(null);
|
|
3973
3982
|
const mergedRef = useMergedRefs(ref, liRef);
|
|
@@ -4027,14 +4036,20 @@ const useMenuItem = ({ ref, role, hasSubmenu, disabled, onClick, closeOnClick, }
|
|
|
4027
4036
|
return;
|
|
4028
4037
|
}
|
|
4029
4038
|
if (hasSubmenu) {
|
|
4030
|
-
|
|
4039
|
+
if (submenuTrigger === 'click') {
|
|
4040
|
+
// Toggle: click again closes the submenu.
|
|
4041
|
+
setSubmenuOpen((prev) => !prev);
|
|
4042
|
+
}
|
|
4043
|
+
else {
|
|
4044
|
+
openSubmenu();
|
|
4045
|
+
}
|
|
4031
4046
|
return;
|
|
4032
4047
|
}
|
|
4033
4048
|
onClick?.(event);
|
|
4034
4049
|
if (shouldCloseOnClick) {
|
|
4035
4050
|
closeMenu?.();
|
|
4036
4051
|
}
|
|
4037
|
-
}, [disabled, hasSubmenu, openSubmenu, onClick, shouldCloseOnClick, closeMenu]);
|
|
4052
|
+
}, [disabled, hasSubmenu, submenuTrigger, openSubmenu, onClick, shouldCloseOnClick, closeMenu]);
|
|
4038
4053
|
return {
|
|
4039
4054
|
liRef,
|
|
4040
4055
|
mergedRef,
|
|
@@ -4044,6 +4059,7 @@ const useMenuItem = ({ ref, role, hasSubmenu, disabled, onClick, closeOnClick, }
|
|
|
4044
4059
|
scheduleClose,
|
|
4045
4060
|
clearTimers,
|
|
4046
4061
|
closeSubmenu,
|
|
4062
|
+
submenuTrigger,
|
|
4047
4063
|
};
|
|
4048
4064
|
};
|
|
4049
4065
|
|
|
@@ -4118,13 +4134,14 @@ const MENU_ITEM_STYLES = createStyles((theme) => {
|
|
|
4118
4134
|
};
|
|
4119
4135
|
}, { id: 'menu-item' });
|
|
4120
4136
|
|
|
4121
|
-
const MenuItem = ({ ref, label, icon, iconColor, role = 'menuitem', checked, selected, focused, disabled, size = 'default', closeOnClick, submenu, submenuPlacement = 'right', onClick, ...rest }) => {
|
|
4137
|
+
const MenuItem = ({ ref, label, icon, iconColor, role = 'menuitem', checked, selected, focused, disabled, size = 'default', closeOnClick, submenu, submenuTrigger = 'click', submenuPlacement = 'right', onClick, ...rest }) => {
|
|
4122
4138
|
const hasSubmenu = submenu !== undefined;
|
|
4123
4139
|
const isCheckable = role === 'menuitemcheckbox' || role === 'menuitemradio';
|
|
4124
4140
|
const isOption = role === 'option';
|
|
4125
4141
|
const isHighlighted = isCheckable ? Boolean(checked) : Boolean(selected);
|
|
4126
|
-
const { liRef, mergedRef, submenuOpen, handleClick, scheduleOpen, scheduleClose, clearTimers, closeSubmenu, } = useMenuItem({ ref, role, hasSubmenu, disabled, onClick, closeOnClick });
|
|
4127
|
-
|
|
4142
|
+
const { liRef, mergedRef, submenuOpen, handleClick, scheduleOpen, scheduleClose, clearTimers, closeSubmenu, } = useMenuItem({ ref, role, hasSubmenu, disabled, onClick, closeOnClick, submenuTrigger });
|
|
4143
|
+
const isHoverTrigger = submenuTrigger === 'hover';
|
|
4144
|
+
return (jsxs(Fragment$1, { children: [jsxs("li", { ref: mergedRef, role: role, "aria-checked": isCheckable ? Boolean(checked) : undefined, "aria-selected": isOption ? Boolean(selected) : undefined, "aria-disabled": disabled, "aria-haspopup": hasSubmenu ? 'menu' : undefined, "aria-expanded": hasSubmenu ? submenuOpen : undefined, "data-selected": isHighlighted || undefined, "data-focused": focused || undefined, "data-disabled": disabled || undefined, className: MENU_ITEM_STYLES.root({ size }), onClick: handleClick, onMouseEnter: hasSubmenu && !disabled && isHoverTrigger ? scheduleOpen : undefined, onMouseLeave: hasSubmenu && isHoverTrigger ? scheduleClose : undefined, ...rest, children: [isCheckable && (jsxs("span", { className: MENU_ITEM_STYLES.indicator, "aria-hidden": true, children: [checked && role === 'menuitemcheckbox' && (jsx(Icon, { icon: CheckIcon, size: size === 'default' ? 'sm' : 'md', strokeColor: 'primaryMain' })), checked && role === 'menuitemradio' && (jsx("span", { className: MENU_ITEM_STYLES.radioDot }))] })), icon !== undefined && (jsx(Icon, { icon: icon, size: 'sm', strokeColor: iconColor ?? (isHighlighted ? 'primaryMain' : 'textSecondary') })), jsx(Text, { variant: 'span', fontSize: 'sm', className: MENU_ITEM_STYLES.label, children: label }), hasSubmenu && (jsx("span", { className: MENU_ITEM_STYLES.submenuChevron, "aria-hidden": true, children: jsx(Icon, { icon: ChevronRightIcon, size: 'sm', strokeColor: 'textTertiary' }) }))] }), hasSubmenu && (jsx(MenuPanel, { open: submenuOpen, onClose: () => closeSubmenu(true), onArrowLeft: () => closeSubmenu(true), anchorEl: liRef.current, placement: submenuPlacement, isSubmenu: true, "aria-label": label, onMouseEnter: isHoverTrigger ? clearTimers : undefined, onMouseLeave: isHoverTrigger ? scheduleClose : undefined, children: submenu }))] }));
|
|
4128
4145
|
};
|
|
4129
4146
|
MenuItem.displayName = 'MenuItem';
|
|
4130
4147
|
|