Skip to content

Commit

Permalink
regression: emojiPicker position (#29408)
Browse files Browse the repository at this point in the history
  • Loading branch information
juliajforesti authored Jun 5, 2023
1 parent df4701f commit 1ca6d70
Show file tree
Hide file tree
Showing 3 changed files with 105 additions and 3 deletions.
7 changes: 4 additions & 3 deletions apps/meteor/client/views/composer/EmojiPicker/EmojiPicker.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { TextInput, Icon, Button, Divider, Dropdown } from '@rocket.chat/fuselage';
import { TextInput, Icon, Button, Divider } from '@rocket.chat/fuselage';
import { useLocalStorage, useMediaQuery, useOutsideClick } from '@rocket.chat/fuselage-hooks';
import {
EmojiPickerCategoryHeader,
Expand Down Expand Up @@ -28,6 +28,7 @@ import { usePreviewEmoji } from '../../../contexts/EmojiPickerContext';
import { useIsVisible } from '../../room/hooks/useIsVisible';
import CategoriesResult from './CategoriesResult';
import EmojiPickerCategoryItem from './EmojiPickerCategoryItem';
import EmojiPickerDropdown from './EmojiPickerDropDown';
import SearchingResult from './SearchingResult';
import ToneSelector from './ToneSelector';
import ToneSelectorWrapper from './ToneSelector/ToneSelectorWrapper';
Expand Down Expand Up @@ -231,7 +232,7 @@ const EmojiPicker = ({ reference, onClose, onPickEmoji }: EmojiPickerProps) => {
};

return (
<Dropdown reference={ref as RefObject<HTMLElement>} ref={emojiContainerRef}>
<EmojiPickerDropdown reference={ref as RefObject<HTMLElement>} ref={emojiContainerRef}>
<EmojiPickerContainer role='dialog' aria-label={t('Emoji_picker')} onKeyDown={handleKeyDown}>
<EmojiPickerHeader>
<TextInput
Expand Down Expand Up @@ -285,7 +286,7 @@ const EmojiPicker = ({ reference, onClose, onPickEmoji }: EmojiPickerProps) => {
</EmojiPickerPreviewArea>
<EmojiPickerFooter>{t('Powered_by_JoyPixels')}</EmojiPickerFooter>
</EmojiPickerContainer>
</Dropdown>
</EmojiPickerDropdown>
);
};

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { Box, Tile } from '@rocket.chat/fuselage';
import { useMergedRefs, usePosition } from '@rocket.chat/fuselage-hooks';
import type { ReactNode, Ref, RefObject } from 'react';
import React, { useMemo, useRef, forwardRef } from 'react';

const getDropdownContainer = (descendant: HTMLElement | null) => {
for (let element = descendant ?? document.body; element !== document.body; element = element.parentElement ?? document.body) {
if (
getComputedStyle(element).transform !== 'none' ||
getComputedStyle(element).position === 'fixed' ||
getComputedStyle(element).willChange === 'transform'
) {
return element;
}
}

return document.body;
};

const useDropdownPosition = (reference: RefObject<HTMLElement>, target: RefObject<HTMLElement>) => {
const innerContainer = getDropdownContainer(reference.current);
const boundingRect = innerContainer.getBoundingClientRect();

const viewHeight = document.body.getBoundingClientRect().height;
const refTop = reference.current?.getBoundingClientRect().top ?? 0;
const targetHeight = target.current?.getBoundingClientRect().height || 0;

const placement = useMemo(() => {
if (boundingRect.top === 0) {
return 'top-start';
}
if (refTop >= viewHeight / 2) {
return 'top-end';
}
return 'bottom-end';
}, [targetHeight, refTop]);

const maxHeight = useMemo(() => (placement === 'bottom-end' ? '482px' : `${refTop - 12}px`), [placement, refTop]);

const { style } = usePosition(reference, target, {
placement,
container: innerContainer,
});

return useMemo(() => {
return { ...style, maxHeight };
}, [style]);
};

type EmojiPickerDesktopDropdownProps = {
children: ReactNode;
reference: RefObject<HTMLElement>;
};

const EmojiPickerDesktopDropdown = forwardRef(function ToolboxDropdownDesktop(
{ reference, children }: EmojiPickerDesktopDropdownProps,
ref: Ref<HTMLElement>,
) {
const targetRef = useRef<HTMLElement>(null);
const mergedRef = useMergedRefs(ref, targetRef);

const style = useDropdownPosition(reference, targetRef);

return (
<Tile is='ul' style={style} ref={mergedRef} elevation='2' pi='0' pb='0' display='flex' flexDirection='column' overflow='auto'>
<Box flexShrink={1} pb='x12'>
{children}
</Box>
</Tile>
);
});

export default EmojiPickerDesktopDropdown;
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { Dropdown as DropdownMobile } from '@rocket.chat/fuselage';
import { useLayout } from '@rocket.chat/ui-contexts';
import type { ReactNode } from 'react';
import React, { forwardRef } from 'react';

import EmojiPickerDesktopDropdown from './EmojiPickerDesktopDropdown';

type EmojiPickerDropdownProps<R> = {
children: ReactNode;
reference: React.RefObject<R>;
};

const EmojiPickerDropdown = forwardRef(function EmojiPickerDropdown<TReferenceElement extends HTMLElement>(
{ children, reference }: EmojiPickerDropdownProps<TReferenceElement>,
ref: React.ForwardedRef<HTMLElement>,
) {
const { isMobile } = useLayout();

const Dropdown = isMobile ? DropdownMobile : EmojiPickerDesktopDropdown;

return (
<Dropdown ref={ref} reference={reference}>
{children}
</Dropdown>
);
});

export default EmojiPickerDropdown;

0 comments on commit 1ca6d70

Please sign in to comment.