@aurora-ds/components 1.7.18 → 1.7.19
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 +48 -16
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.js +48 -16
- package/dist/esm/index.js.map +1 -1
- package/dist/index.d.ts +25 -10
- package/package.json +1 -1
package/dist/cjs/index.js
CHANGED
|
@@ -3544,12 +3544,12 @@ const MENU_MIN_WIDTH_PX = 224;
|
|
|
3544
3544
|
* Computes and continuously updates the `position: fixed` style for a menu panel.
|
|
3545
3545
|
*
|
|
3546
3546
|
* Positioning strategy:
|
|
3547
|
-
* - `placement="bottom"` (default):
|
|
3548
|
-
*
|
|
3549
|
-
*
|
|
3550
|
-
* - `placement="
|
|
3551
|
-
*
|
|
3552
|
-
*
|
|
3547
|
+
* - `placement="bottom"` (default): opens below the anchor; overflows are shifted up.
|
|
3548
|
+
* - `placement="top"`: opens above the anchor; flips to bottom when no room.
|
|
3549
|
+
* - `placement="right"`: opens to the right of the anchor; flips to the left when no room.
|
|
3550
|
+
* - `placement="left"`: opens to the left of the anchor; flips to the right when no room.
|
|
3551
|
+
*
|
|
3552
|
+
* In all cases the vertical position is clamped inside the viewport.
|
|
3553
3553
|
*
|
|
3554
3554
|
* Scroll handling: the page scroll is locked while the menu is open (see
|
|
3555
3555
|
* `MenuPanel`), so the anchor cannot move out from under the menu. As a safety
|
|
@@ -3571,24 +3571,56 @@ const useMenuPosition = ({ anchorEl, open, menuRef, minWidth, gap = 4, placement
|
|
|
3571
3571
|
const menuWidth = menuEl?.offsetWidth ?? 0;
|
|
3572
3572
|
const viewportRight = window.innerWidth - VIEWPORT_MARGIN_PX;
|
|
3573
3573
|
const viewportBottom = window.innerHeight - VIEWPORT_MARGIN_PX;
|
|
3574
|
-
if (placement === 'right') {
|
|
3574
|
+
if (placement === 'right' || placement === 'left') {
|
|
3575
3575
|
// --- Vertical: align with the anchor top, clamp inside the viewport ---
|
|
3576
3576
|
let top = anchor.top;
|
|
3577
3577
|
if (menuHeight > 0 && top + menuHeight > viewportBottom) {
|
|
3578
3578
|
top = Math.max(VIEWPORT_MARGIN_PX, viewportBottom - menuHeight);
|
|
3579
3579
|
}
|
|
3580
|
-
// --- Horizontal: open to the
|
|
3581
|
-
let left
|
|
3582
|
-
if (
|
|
3583
|
-
|
|
3584
|
-
left
|
|
3585
|
-
|
|
3586
|
-
|
|
3580
|
+
// --- Horizontal: open to the preferred side, flip to the opposite when no room ---
|
|
3581
|
+
let left;
|
|
3582
|
+
if (placement === 'right') {
|
|
3583
|
+
left = anchor.right + gap;
|
|
3584
|
+
if (menuWidth > 0 && left + menuWidth > viewportRight) {
|
|
3585
|
+
const flippedLeft = anchor.left - gap - menuWidth;
|
|
3586
|
+
left = flippedLeft >= VIEWPORT_MARGIN_PX
|
|
3587
|
+
? flippedLeft
|
|
3588
|
+
: Math.max(VIEWPORT_MARGIN_PX, viewportRight - menuWidth);
|
|
3589
|
+
}
|
|
3590
|
+
}
|
|
3591
|
+
else {
|
|
3592
|
+
// placement === 'left'
|
|
3593
|
+
left = anchor.left - gap - menuWidth;
|
|
3594
|
+
if (menuWidth > 0 && left < VIEWPORT_MARGIN_PX) {
|
|
3595
|
+
const flippedLeft = anchor.right + gap;
|
|
3596
|
+
left = flippedLeft + menuWidth <= viewportRight
|
|
3597
|
+
? flippedLeft
|
|
3598
|
+
: Math.max(VIEWPORT_MARGIN_PX, viewportRight - menuWidth);
|
|
3599
|
+
}
|
|
3587
3600
|
}
|
|
3588
3601
|
setStyle({ top, left, minWidth: minWidth ?? MENU_MIN_WIDTH_PX });
|
|
3589
3602
|
return;
|
|
3590
3603
|
}
|
|
3591
|
-
|
|
3604
|
+
if (placement === 'top') {
|
|
3605
|
+
// --- Vertical: open above, flip to bottom when no room ---
|
|
3606
|
+
let top = anchor.top - gap - menuHeight;
|
|
3607
|
+
if (menuHeight > 0 && top < VIEWPORT_MARGIN_PX) {
|
|
3608
|
+
const flippedTop = anchor.bottom + gap;
|
|
3609
|
+
top = flippedTop + menuHeight <= viewportBottom
|
|
3610
|
+
? flippedTop
|
|
3611
|
+
: Math.max(VIEWPORT_MARGIN_PX, viewportBottom - menuHeight);
|
|
3612
|
+
}
|
|
3613
|
+
// --- Horizontal ---
|
|
3614
|
+
const fallbackMinWidth = Math.max(anchor.width, MENU_MIN_WIDTH_PX);
|
|
3615
|
+
const resolvedMinWidth = typeof minWidth === 'number' ? minWidth : fallbackMinWidth;
|
|
3616
|
+
const effectiveWidth = Math.max(menuWidth, resolvedMinWidth);
|
|
3617
|
+
const maxLeft = window.innerWidth - effectiveWidth - VIEWPORT_MARGIN_PX;
|
|
3618
|
+
const left = Math.max(VIEWPORT_MARGIN_PX, Math.min(anchor.left, maxLeft));
|
|
3619
|
+
setStyle({ top, left, minWidth: minWidth ?? fallbackMinWidth });
|
|
3620
|
+
return;
|
|
3621
|
+
}
|
|
3622
|
+
// --- placement === 'bottom' ---
|
|
3623
|
+
// --- Vertical ---
|
|
3592
3624
|
const preferredTop = anchor.bottom + gap;
|
|
3593
3625
|
let top = preferredTop;
|
|
3594
3626
|
if (menuHeight > 0 && preferredTop + menuHeight > viewportBottom) {
|
|
@@ -4112,7 +4144,7 @@ const MenuItem = ({ ref, label, icon, iconColor, role = 'menuitem', checked, sel
|
|
|
4112
4144
|
const isOption = role === 'option';
|
|
4113
4145
|
const isHighlighted = isCheckable ? Boolean(checked) : Boolean(selected);
|
|
4114
4146
|
const { liRef, mergedRef, submenuOpen, handleClick, scheduleOpen, scheduleClose, clearTimers, closeSubmenu, } = useMenuItem({ ref, role, hasSubmenu, disabled, onClick, closeOnClick });
|
|
4115
|
-
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.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 ? scheduleOpen : undefined, onMouseLeave: hasSubmenu ? scheduleClose : undefined, ...rest, children: [isCheckable && (jsxRuntime.jsxs("span", { className: MENU_ITEM_STYLES.indicator, "aria-hidden": true, children: [checked && role === 'menuitemcheckbox' && (jsxRuntime.jsx(Icon, { icon: CheckIcon, size: 'sm', strokeColor: 'primaryMain' })), checked && role === 'menuitemradio' && (jsxRuntime.jsx("span", { className: MENU_ITEM_STYLES.radioDot }))] })), icon !== undefined && (jsxRuntime.jsx(Icon, { icon: icon, size: 'sm', strokeColor: iconColor ?? (isHighlighted ? 'primaryMain' : 'textSecondary') })), jsxRuntime.jsx(Text, { variant: 'span', fontSize: 'sm', className: MENU_ITEM_STYLES.label, children: label }), hasSubmenu && (jsxRuntime.jsx("span", { className: MENU_ITEM_STYLES.submenuChevron, "aria-hidden": true, children: jsxRuntime.jsx(Icon, { icon: ChevronRightIcon, size: 'sm', strokeColor: 'textTertiary' }) }))] }), hasSubmenu && (jsxRuntime.jsx(MenuPanel, { open: submenuOpen, onClose: () => closeSubmenu(true), onArrowLeft: () => closeSubmenu(true), anchorEl: liRef.current, placement: submenuPlacement, isSubmenu: true, "aria-label": label, onMouseEnter: clearTimers, onMouseLeave: scheduleClose, children: submenu }))] }));
|
|
4147
|
+
return (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.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 ? scheduleOpen : undefined, onMouseLeave: hasSubmenu ? scheduleClose : undefined, ...rest, children: [isCheckable && (jsxRuntime.jsxs("span", { className: MENU_ITEM_STYLES.indicator, "aria-hidden": true, children: [checked && role === 'menuitemcheckbox' && (jsxRuntime.jsx(Icon, { icon: CheckIcon, size: size === 'default' ? 'sm' : 'md', strokeColor: 'primaryMain' })), checked && role === 'menuitemradio' && (jsxRuntime.jsx("span", { className: MENU_ITEM_STYLES.radioDot }))] })), icon !== undefined && (jsxRuntime.jsx(Icon, { icon: icon, size: 'sm', strokeColor: iconColor ?? (isHighlighted ? 'primaryMain' : 'textSecondary') })), jsxRuntime.jsx(Text, { variant: 'span', fontSize: 'sm', className: MENU_ITEM_STYLES.label, children: label }), hasSubmenu && (jsxRuntime.jsx("span", { className: MENU_ITEM_STYLES.submenuChevron, "aria-hidden": true, children: jsxRuntime.jsx(Icon, { icon: ChevronRightIcon, size: 'sm', strokeColor: 'textTertiary' }) }))] }), hasSubmenu && (jsxRuntime.jsx(MenuPanel, { open: submenuOpen, onClose: () => closeSubmenu(true), onArrowLeft: () => closeSubmenu(true), anchorEl: liRef.current, placement: submenuPlacement, isSubmenu: true, "aria-label": label, onMouseEnter: clearTimers, onMouseLeave: scheduleClose, children: submenu }))] }));
|
|
4116
4148
|
};
|
|
4117
4149
|
MenuItem.displayName = 'MenuItem';
|
|
4118
4150
|
|