Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/react-core/src/components/Dropdown/Dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export interface DropdownPopperProps {
/** Vertical direction of the popper. If enableFlip is set to true, this will set the initial direction before the popper flips. */
direction?: 'up' | 'down';
/** Horizontal position of the popper */
position?: 'right' | 'left' | 'center';
position?: 'right' | 'left' | 'center' | 'start' | 'end';
/** Custom width of the popper. If the value is "trigger", it will set the width to the dropdown toggle's width */
width?: string | 'trigger';
/** Minimum width of the popper. If the value is "trigger", it will set the min width to the dropdown toggle's width */
Expand Down
2 changes: 1 addition & 1 deletion packages/react-core/src/components/Menu/MenuContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ export interface MenuPopperProps {
/** Vertical direction of the popper. If enableFlip is set to true, this will set the initial direction before the popper flips. */
direction?: 'up' | 'down';
/** Horizontal position of the popper */
position?: 'right' | 'left' | 'center';
position?: 'right' | 'left' | 'center' | 'start' | 'end';
/** Custom width of the popper. If the value is "trigger", it will set the width to the dropdown toggle's width */
width?: string | 'trigger';
/** Minimum width of the popper. If the value is "trigger", it will set the min width to the dropdown toggle's width */
Expand Down
2 changes: 1 addition & 1 deletion packages/react-core/src/components/Select/Select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export interface SelectPopperProps {
/** Vertical direction of the popper. If enableFlip is set to true, this will set the initial direction before the popper flips. */
direction?: 'up' | 'down';
/** Horizontal position of the popper */
position?: 'right' | 'left' | 'center';
position?: 'right' | 'left' | 'center' | 'start' | 'end';
/** Custom width of the popper. If the value is "trigger", it will set the width to the select toggle's width */
width?: string | 'trigger';
/** Minimum width of the popper. If the value is "trigger", it will set the min width to the select toggle's width */
Expand Down
49 changes: 43 additions & 6 deletions packages/react-core/src/helpers/Popper/Popper.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,21 @@ const getOppositePlacement = (placement: Placement): any =>
export const getOpacityTransition = (animationDuration: number) =>
`opacity ${animationDuration}ms cubic-bezier(.54, 1.5, .38, 1.11)`;

export const getLanguageDirection = (targetElement: HTMLElement) => {
const defaultDirection = 'ltr';
let direction = defaultDirection;

if (targetElement) {
direction = getComputedStyle(targetElement).getPropertyValue('direction');
}

if (['ltr', 'rtl'].includes(direction)) {
return direction as 'ltr' | 'rtl';
}

return defaultDirection;
};

export interface PopperProps {
/**
* Trigger reference element to which the popper is relatively placed to.
Expand All @@ -66,7 +81,7 @@ export interface PopperProps {
/** popper direction */
direction?: 'up' | 'down';
/** popper position */
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/** popper position */
/** popper position. "left" and "right" are deprecated, use "start" and "end" instead. */

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think left and right really are/should be deprecated in this case. I think there very well could be situations where left or right are what's actually desired rather than start and end.

position?: 'right' | 'left' | 'center';
position?: 'right' | 'left' | 'center' | 'start' | 'end';
/** Instead of direction and position can set the placement of the popper */
placement?: Placement;
/** Custom width of the popper. If the value is "trigger", it will set the width to the trigger element's width */
Expand Down Expand Up @@ -177,7 +192,7 @@ export const Popper: React.FunctionComponent<PopperProps> = ({
trigger,
popper,
direction = 'down',
position = 'left',
position = 'start',
placement,
width,
minWidth = 'trigger',
Expand Down Expand Up @@ -226,6 +241,28 @@ export const Popper: React.FunctionComponent<PopperProps> = ({
const refOrTrigger = refElement || triggerElement;
const showPopper = isVisible || internalIsVisible;

const triggerParent = ((triggerRef as React.RefObject<any>)?.current || triggerElement)?.parentElement;
const languageDirection = getLanguageDirection(triggerParent);

const internalPosition = React.useMemo<'left' | 'right' | 'center'>(() => {
const fixedPositions = { left: 'left', right: 'right', center: 'center' };

const positionMap = {
ltr: {
start: 'left',
end: 'right',
...fixedPositions
},
rtl: {
start: 'right',
end: 'left',
...fixedPositions
}
};

return positionMap[languageDirection][position] as 'left' | 'right' | 'center';
}, [position, languageDirection]);

const onDocumentClickCallback = React.useCallback(
(event: MouseEvent) => onDocumentClick(event, refOrTrigger, popperElement),
[showPopper, triggerElement, refElement, popperElement, onDocumentClick]
Expand Down Expand Up @@ -333,15 +370,15 @@ export const Popper: React.FunctionComponent<PopperProps> = ({
return placement;
}
let convertedPlacement = direction === 'up' ? 'top' : 'bottom';
if (position !== 'center') {
convertedPlacement = `${convertedPlacement}-${position === 'right' ? 'end' : 'start'}`;
if (internalPosition !== 'center') {
convertedPlacement = `${convertedPlacement}-${internalPosition === 'right' ? 'end' : 'start'}`;
}
return convertedPlacement as Placement;
};
const getPlacementMemo = React.useMemo(getPlacement, [direction, position, placement]);
const getPlacementMemo = React.useMemo(getPlacement, [direction, internalPosition, placement]);
const getOppositePlacementMemo = React.useMemo(
() => getOppositePlacement(getPlacement()),
[direction, position, placement]
[direction, internalPosition, placement]
);

const widthMods: Modifier<'widthMods', {}> = React.useMemo(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ const ActionsColumnBase: React.FunctionComponent<ActionsColumnProps> = ({
extraData,
actionsToggle,
popperProps = {
position: 'right',
position: 'end',
direction: 'down'
},
innerRef,
Expand Down