Skip to content

Commit

Permalink
fix(menuButton): fix RTL issues with MenuButton (#14565)
Browse files Browse the repository at this point in the history
* fix(menuButton): fix RTL issues with MenuButton

* fix(Menu): adjust caret rotation

* refactor(menu): remove rtl override

* fix(Menu): adjust story positioning, add CaretLeft for RTL mode

* refactor(Menu): useLayoutContext to check if parent has direction set
  • Loading branch information
tw15egan committed Sep 11, 2023
1 parent c866041 commit 8432fc6
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 10 deletions.
18 changes: 16 additions & 2 deletions packages/react/src/components/Menu/Menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { useMergedRefs } from '../../internal/useMergedRefs';
import { usePrefix } from '../../internal/usePrefix';

import { MenuContext, menuReducer } from './MenuContext';
import { useLayoutDirection } from '../LayoutDirection';

const spacing = 8; // distance to keep to window edges, in px

Expand Down Expand Up @@ -71,6 +72,9 @@ const Menu = React.forwardRef(function Menu(
(item) => !item.disabled && item.ref.current
);

// Set RTL based on document direction or `LayoutDirection`
const { direction } = useLayoutDirection();

function returnFocus() {
if (focusReturn.current) {
focusReturn.current.focus();
Expand All @@ -82,8 +86,18 @@ const Menu = React.forwardRef(function Menu(
focusReturn.current = document.activeElement;

const pos = calculatePosition();
menu.current.style.left = `${pos[0]}px`;
menu.current.style.top = `${pos[1]}px`;
if (
(document?.dir === 'rtl' || direction === 'rtl') &&
!rest?.id?.includes('MenuButton')
) {
menu.current.style.insetInlineStart = `initial`;
menu.current.style.insetInlineEnd = `${pos[0]}px`;
} else {
menu.current.style.insetInlineStart = `${pos[0]}px`;
menu.current.style.insetInlineEnd = `initial`;
}

menu.current.style.insetBlockStart = `${pos[1]}px`;
setPosition(pos);

menu.current.focus();
Expand Down
2 changes: 1 addition & 1 deletion packages/react/src/components/Menu/Menu.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ export const Playground = (args) => {
const target = document.getElementById('storybook-root');

return (
<Menu {...args} target={target}>
<Menu {...args} target={target} x={document?.dir === 'rtl' ? 250 : 0}>
<MenuItem label="Share with">
<MenuItemRadioGroup
label="Share with"
Expand Down
31 changes: 25 additions & 6 deletions packages/react/src/components/Menu/MenuItem.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@ import cx from 'classnames';
import PropTypes from 'prop-types';
import React, { useContext, useEffect, useRef, useState } from 'react';

import { CaretRight, Checkmark } from '@carbon/icons-react';
import { CaretRight, CaretLeft, Checkmark } from '@carbon/icons-react';
import { keys, match } from '../../internal/keyboard';
import { useControllableState } from '../../internal/useControllableState';
import { useMergedRefs } from '../../internal/useMergedRefs';
import { usePrefix } from '../../internal/usePrefix';

import { Menu } from './Menu';
import { MenuContext } from './MenuContext';
import { useLayoutDirection } from '../LayoutDirection';

const hoverIntentDelay = 150; // in ms

Expand All @@ -40,6 +41,7 @@ const MenuItem = React.forwardRef(function MenuItem(
const menuItem = useRef();
const ref = useMergedRefs([forwardRef, menuItem]);
const [boundaries, setBoundaries] = useState({ x: -1, y: -1 });
const [isRtl, setRtl] = useState(false);

const hasChildren = Boolean(children);
const [submenuOpen, setSubmenuOpen] = useState(false);
Expand All @@ -60,10 +62,17 @@ const MenuItem = React.forwardRef(function MenuItem(

function openSubmenu() {
const { x, y, width, height } = menuItem.current.getBoundingClientRect();
setBoundaries({
x: [x, x + width],
y: [y, y + height],
});
if (isRtl) {
setBoundaries({
x: [-x, x - width],
y: [y, y + height],
});
} else {
setBoundaries({
x: [x, x + width],
y: [y, y + height],
});
}

setSubmenuOpen(true);
}
Expand Down Expand Up @@ -126,6 +135,16 @@ const MenuItem = React.forwardRef(function MenuItem(
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

// Set RTL based on document direction or `LayoutDirection`
const { direction } = useLayoutDirection();
useEffect(() => {
if (document?.dir === 'rtl' || direction === 'rtl') {
setRtl(true);
} else {
setRtl(false);
}
}, [direction]);

return (
<li
role="menuitem"
Expand All @@ -150,7 +169,7 @@ const MenuItem = React.forwardRef(function MenuItem(
{hasChildren && (
<>
<div className={`${prefix}--menu-item__shortcut`}>
<CaretRight />
{isRtl ? <CaretLeft /> : <CaretRight />}
</div>
<Menu
label={label}
Expand Down
2 changes: 1 addition & 1 deletion packages/react/src/components/MenuButton/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ const MenuButton = React.forwardRef(function MenuButton(
}

function handleOpen() {
menuRef.current.style.width = `${width}px`;
menuRef.current.style.inlineSize = `${width}px`;
}

const triggerClasses = classNames(`${prefix}--menu-button__trigger`, {
Expand Down

0 comments on commit 8432fc6

Please sign in to comment.