parent
e112d3d9ed
commit
8d5858bab4
@ -1446,6 +1446,7 @@
|
|||||||
"MenuArchivedChats" = "Archived Chats";
|
"MenuArchivedChats" = "Archived Chats";
|
||||||
"MenuContacts" = "Contacts";
|
"MenuContacts" = "Contacts";
|
||||||
"MenuSettings" = "Settings";
|
"MenuSettings" = "Settings";
|
||||||
|
"MenuMore" = "More";
|
||||||
"MenuNightMode" = "Night Mode";
|
"MenuNightMode" = "Night Mode";
|
||||||
"AriaMenuEnableNightMode" = "Enable night mode";
|
"AriaMenuEnableNightMode" = "Enable night mode";
|
||||||
"AriaMenuDisableNightMode" = "Disable night mode";
|
"AriaMenuDisableNightMode" = "Disable night mode";
|
||||||
|
|||||||
@ -57,7 +57,6 @@ const LeftSideMenuDropdown = ({
|
|||||||
return (
|
return (
|
||||||
<DropdownMenu
|
<DropdownMenu
|
||||||
trigger={trigger}
|
trigger={trigger}
|
||||||
footer={`${APP_NAME} ${versionString}`}
|
|
||||||
className={buildClassName(
|
className={buildClassName(
|
||||||
'main-menu',
|
'main-menu',
|
||||||
lang.isRtl && 'rtl',
|
lang.isRtl && 'rtl',
|
||||||
@ -77,6 +76,7 @@ const LeftSideMenuDropdown = ({
|
|||||||
onSelectSettings={handleSelectSettings}
|
onSelectSettings={handleSelectSettings}
|
||||||
onBotMenuOpened={markBotMenuOpen}
|
onBotMenuOpened={markBotMenuOpen}
|
||||||
onBotMenuClosed={unmarkBotMenuOpen}
|
onBotMenuClosed={unmarkBotMenuOpen}
|
||||||
|
footer={`${APP_NAME} ${versionString}`}
|
||||||
/>
|
/>
|
||||||
</DropdownMenu>
|
</DropdownMenu>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -37,6 +37,7 @@ import useLastCallback from '../../../hooks/useLastCallback';
|
|||||||
import AttachBotItem from '../../middle/composer/AttachBotItem';
|
import AttachBotItem from '../../middle/composer/AttachBotItem';
|
||||||
import MenuItem from '../../ui/MenuItem';
|
import MenuItem from '../../ui/MenuItem';
|
||||||
import MenuSeparator from '../../ui/MenuSeparator';
|
import MenuSeparator from '../../ui/MenuSeparator';
|
||||||
|
import NestedMenuItem from '../../ui/NestedMenuItem';
|
||||||
import Switcher from '../../ui/Switcher';
|
import Switcher from '../../ui/Switcher';
|
||||||
import Toggle from '../../ui/Toggle';
|
import Toggle from '../../ui/Toggle';
|
||||||
import AccountMenuItems from './AccountMenuItems';
|
import AccountMenuItems from './AccountMenuItems';
|
||||||
@ -47,6 +48,7 @@ type OwnProps = {
|
|||||||
onSelectArchived: NoneToVoidFunction;
|
onSelectArchived: NoneToVoidFunction;
|
||||||
onBotMenuOpened: NoneToVoidFunction;
|
onBotMenuOpened: NoneToVoidFunction;
|
||||||
onBotMenuClosed: NoneToVoidFunction;
|
onBotMenuClosed: NoneToVoidFunction;
|
||||||
|
footer?: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
type StateProps = {
|
type StateProps = {
|
||||||
@ -72,6 +74,7 @@ const LeftSideMenuItems = ({
|
|||||||
onSelectSettings,
|
onSelectSettings,
|
||||||
onBotMenuOpened,
|
onBotMenuOpened,
|
||||||
onBotMenuClosed,
|
onBotMenuClosed,
|
||||||
|
footer,
|
||||||
}: OwnProps & StateProps) => {
|
}: OwnProps & StateProps) => {
|
||||||
const {
|
const {
|
||||||
openChat,
|
openChat,
|
||||||
@ -196,63 +199,74 @@ const LeftSideMenuItems = ({
|
|||||||
>
|
>
|
||||||
{lang('MenuSettings')}
|
{lang('MenuSettings')}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
<MenuItem
|
<NestedMenuItem
|
||||||
icon="darkmode"
|
icon="more"
|
||||||
onClick={handleDarkModeToggle}
|
footer={footer}
|
||||||
|
submenu={(
|
||||||
|
<>
|
||||||
|
<MenuItem
|
||||||
|
icon="darkmode"
|
||||||
|
onClick={handleDarkModeToggle}
|
||||||
|
>
|
||||||
|
<span className="menu-item-name">{lang('MenuNightMode')}</span>
|
||||||
|
<Switcher
|
||||||
|
id="darkmode"
|
||||||
|
label={lang(theme === 'dark' ? 'AriaMenuDisableNightMode' : 'AriaMenuEnableNightMode')}
|
||||||
|
checked={theme === 'dark'}
|
||||||
|
noAnimation
|
||||||
|
/>
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem
|
||||||
|
icon="animations"
|
||||||
|
onClick={handleAnimationLevelChange}
|
||||||
|
>
|
||||||
|
<span className="menu-item-name capitalize">{lang('MenuAnimationsSwitch')}</span>
|
||||||
|
<Toggle value={animationLevelValue} />
|
||||||
|
</MenuItem>
|
||||||
|
<MenuSeparator />
|
||||||
|
<MenuItem
|
||||||
|
icon="help"
|
||||||
|
onClick={handleOpenTipsChat}
|
||||||
|
>
|
||||||
|
{lang('MenuTelegramFeatures')}
|
||||||
|
</MenuItem>
|
||||||
|
<MenuItem
|
||||||
|
icon="bug"
|
||||||
|
onClick={handleBugReportClick}
|
||||||
|
>
|
||||||
|
{lang('MenuReportBug')}
|
||||||
|
</MenuItem>
|
||||||
|
{IS_BETA && (
|
||||||
|
<MenuItem
|
||||||
|
icon="permissions"
|
||||||
|
onClick={handleChangelogClick}
|
||||||
|
>
|
||||||
|
{lang('MenuBetaChangelog')}
|
||||||
|
</MenuItem>
|
||||||
|
)}
|
||||||
|
{withOtherVersions && (
|
||||||
|
<MenuItem
|
||||||
|
icon="K"
|
||||||
|
isCharIcon
|
||||||
|
href={`${WEB_VERSION_BASE}k`}
|
||||||
|
onClick={handleSwitchToWebK}
|
||||||
|
>
|
||||||
|
{lang('MenuSwitchToK')}
|
||||||
|
</MenuItem>
|
||||||
|
)}
|
||||||
|
{canInstall && (
|
||||||
|
<MenuItem
|
||||||
|
icon="install"
|
||||||
|
onClick={getPromptInstall()}
|
||||||
|
>
|
||||||
|
{lang('MenuInstallApp')}
|
||||||
|
</MenuItem>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
>
|
>
|
||||||
<span className="menu-item-name">{lang('MenuNightMode')}</span>
|
{lang('MenuMore')}
|
||||||
<Switcher
|
</NestedMenuItem>
|
||||||
id="darkmode"
|
|
||||||
label={lang(theme === 'dark' ? 'AriaMenuDisableNightMode' : 'AriaMenuEnableNightMode')}
|
|
||||||
checked={theme === 'dark'}
|
|
||||||
noAnimation
|
|
||||||
/>
|
|
||||||
</MenuItem>
|
|
||||||
<MenuItem
|
|
||||||
icon="animations"
|
|
||||||
onClick={handleAnimationLevelChange}
|
|
||||||
>
|
|
||||||
<span className="menu-item-name capitalize">{lang('MenuAnimationsSwitch')}</span>
|
|
||||||
<Toggle value={animationLevelValue} />
|
|
||||||
</MenuItem>
|
|
||||||
<MenuItem
|
|
||||||
icon="help"
|
|
||||||
onClick={handleOpenTipsChat}
|
|
||||||
>
|
|
||||||
{lang('MenuTelegramFeatures')}
|
|
||||||
</MenuItem>
|
|
||||||
<MenuItem
|
|
||||||
icon="bug"
|
|
||||||
onClick={handleBugReportClick}
|
|
||||||
>
|
|
||||||
{lang('MenuReportBug')}
|
|
||||||
</MenuItem>
|
|
||||||
{IS_BETA && (
|
|
||||||
<MenuItem
|
|
||||||
icon="permissions"
|
|
||||||
onClick={handleChangelogClick}
|
|
||||||
>
|
|
||||||
{lang('MenuBetaChangelog')}
|
|
||||||
</MenuItem>
|
|
||||||
)}
|
|
||||||
{withOtherVersions && (
|
|
||||||
<MenuItem
|
|
||||||
icon="K"
|
|
||||||
isCharIcon
|
|
||||||
href={`${WEB_VERSION_BASE}k`}
|
|
||||||
onClick={handleSwitchToWebK}
|
|
||||||
>
|
|
||||||
{lang('MenuSwitchToK')}
|
|
||||||
</MenuItem>
|
|
||||||
)}
|
|
||||||
{canInstall && (
|
|
||||||
<MenuItem
|
|
||||||
icon="install"
|
|
||||||
onClick={getPromptInstall()}
|
|
||||||
>
|
|
||||||
{lang('MenuInstallApp')}
|
|
||||||
</MenuItem>
|
|
||||||
)}
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@ -87,9 +87,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.footer {
|
.footer {
|
||||||
padding: 0.5rem 0;
|
padding: 0.25rem 0.5rem;
|
||||||
|
|
||||||
font-size: 0.8125rem;
|
font-size: 0.75rem;
|
||||||
|
line-height: 1.25;
|
||||||
color: var(--color-text-secondary);
|
color: var(--color-text-secondary);
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
||||||
|
|||||||
@ -49,6 +49,7 @@ type OwnProps =
|
|||||||
onMouseEnterBackdrop?: (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => void;
|
onMouseEnterBackdrop?: (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => void;
|
||||||
onMouseLeave?: (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => void;
|
onMouseLeave?: (e: React.MouseEvent<HTMLDivElement, MouseEvent>) => void;
|
||||||
withPortal?: boolean;
|
withPortal?: boolean;
|
||||||
|
nested?: boolean;
|
||||||
children?: React.ReactNode;
|
children?: React.ReactNode;
|
||||||
}
|
}
|
||||||
& MenuPositionOptions;
|
& MenuPositionOptions;
|
||||||
@ -75,6 +76,7 @@ const Menu: FC<OwnProps> = ({
|
|||||||
onMouseLeave,
|
onMouseLeave,
|
||||||
withPortal,
|
withPortal,
|
||||||
onMouseEnterBackdrop,
|
onMouseEnterBackdrop,
|
||||||
|
nested,
|
||||||
...positionOptions
|
...positionOptions
|
||||||
}) => {
|
}) => {
|
||||||
const { isTouchScreen } = useAppLayout();
|
const { isTouchScreen } = useAppLayout();
|
||||||
@ -108,12 +110,16 @@ const Menu: FC<OwnProps> = ({
|
|||||||
|
|
||||||
const handleKeyDown = useKeyboardListNavigation(bubbleRef, isOpen, autoClose ? onClose : undefined, undefined, true);
|
const handleKeyDown = useKeyboardListNavigation(bubbleRef, isOpen, autoClose ? onClose : undefined, undefined, true);
|
||||||
|
|
||||||
|
const fullExcludedSelector = backdropExcludedSelector
|
||||||
|
? `${backdropExcludedSelector}, .submenu`
|
||||||
|
: '.submenu';
|
||||||
|
|
||||||
useVirtualBackdrop(
|
useVirtualBackdrop(
|
||||||
isOpen,
|
isOpen,
|
||||||
containerRef,
|
containerRef,
|
||||||
noCloseOnBackdrop ? undefined : onClose,
|
noCloseOnBackdrop ? undefined : onClose,
|
||||||
undefined,
|
undefined,
|
||||||
backdropExcludedSelector,
|
fullExcludedSelector,
|
||||||
);
|
);
|
||||||
|
|
||||||
const bubbleFullClassName = buildClassName(
|
const bubbleFullClassName = buildClassName(
|
||||||
@ -147,7 +153,7 @@ const Menu: FC<OwnProps> = ({
|
|||||||
onMouseEnter={onMouseEnter}
|
onMouseEnter={onMouseEnter}
|
||||||
onMouseLeave={isOpen ? onMouseLeave : undefined}
|
onMouseLeave={isOpen ? onMouseLeave : undefined}
|
||||||
>
|
>
|
||||||
{isOpen && (
|
{isOpen && !nested && (
|
||||||
// This only prevents click events triggering on underlying elements
|
// This only prevents click events triggering on underlying elements
|
||||||
<div
|
<div
|
||||||
className="backdrop"
|
className="backdrop"
|
||||||
|
|||||||
@ -113,6 +113,10 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.submenu-icon {
|
||||||
|
margin-inline: auto 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
&.compact {
|
&.compact {
|
||||||
will-change: transform;
|
will-change: transform;
|
||||||
|
|
||||||
|
|||||||
225
src/components/ui/NestedMenuItem.tsx
Normal file
225
src/components/ui/NestedMenuItem.tsx
Normal file
@ -0,0 +1,225 @@
|
|||||||
|
import {
|
||||||
|
useEffect, useRef, useState, useUnmountCleanup,
|
||||||
|
} from '@teact';
|
||||||
|
|
||||||
|
import type { IAnchorPosition } from '../../types';
|
||||||
|
import type { IconName } from '../../types/icons';
|
||||||
|
|
||||||
|
import { requestMeasure } from '../../lib/fasterdom/fasterdom';
|
||||||
|
import buildClassName from '../../util/buildClassName';
|
||||||
|
import { REM } from '../common/helpers/mediaDimensions';
|
||||||
|
|
||||||
|
import useFlag from '../../hooks/useFlag';
|
||||||
|
import useLang from '../../hooks/useLang';
|
||||||
|
import useLastCallback from '../../hooks/useLastCallback';
|
||||||
|
import useUniqueId from '../../hooks/useUniqueId';
|
||||||
|
import useWindowSize from '../../hooks/window/useWindowSize';
|
||||||
|
|
||||||
|
import Icon from '../common/icons/Icon';
|
||||||
|
import Menu from './Menu';
|
||||||
|
import MenuItem from './MenuItem';
|
||||||
|
|
||||||
|
const OPEN_TIMEOUT = 150;
|
||||||
|
const CLOSE_TIMEOUT = 150;
|
||||||
|
|
||||||
|
type OwnProps = {
|
||||||
|
icon?: IconName;
|
||||||
|
customIcon?: React.ReactNode;
|
||||||
|
submenuIcon?: IconName;
|
||||||
|
className?: string;
|
||||||
|
children: React.ReactNode;
|
||||||
|
submenu: React.ReactNode;
|
||||||
|
submenuClassName?: string;
|
||||||
|
disabled?: boolean;
|
||||||
|
destructive?: boolean;
|
||||||
|
ariaLabel?: string;
|
||||||
|
footer?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
const NestedMenuItem = ({
|
||||||
|
icon,
|
||||||
|
customIcon,
|
||||||
|
submenuIcon,
|
||||||
|
className,
|
||||||
|
children,
|
||||||
|
submenu,
|
||||||
|
submenuClassName,
|
||||||
|
disabled,
|
||||||
|
destructive,
|
||||||
|
ariaLabel,
|
||||||
|
footer,
|
||||||
|
}: OwnProps) => {
|
||||||
|
const lang = useLang();
|
||||||
|
|
||||||
|
const itemRef = useRef<HTMLDivElement>();
|
||||||
|
const closeTimeoutRef = useRef<number>();
|
||||||
|
const openTimeoutRef = useRef<number>();
|
||||||
|
const submenuId = useUniqueId();
|
||||||
|
const isClosingRef = useRef(false);
|
||||||
|
|
||||||
|
const [isSubmenuOpen, openSubmenu, closeSubmenu] = useFlag(false);
|
||||||
|
|
||||||
|
useUnmountCleanup(() => {
|
||||||
|
clearTimeout(closeTimeoutRef.current);
|
||||||
|
clearTimeout(openTimeoutRef.current);
|
||||||
|
});
|
||||||
|
|
||||||
|
const [submenuAnchor, setSubmenuAnchor] = useState<IAnchorPosition>();
|
||||||
|
const { isResizing } = useWindowSize();
|
||||||
|
|
||||||
|
const updateAnchor = useLastCallback(() => {
|
||||||
|
requestMeasure(() => {
|
||||||
|
if (!itemRef.current) return;
|
||||||
|
|
||||||
|
const rect = itemRef.current.getBoundingClientRect();
|
||||||
|
const overlap = REM;
|
||||||
|
|
||||||
|
setSubmenuAnchor({
|
||||||
|
x: lang.isRtl ? rect.left + overlap : rect.right - overlap,
|
||||||
|
y: rect.top,
|
||||||
|
width: rect.width - overlap * 2,
|
||||||
|
height: rect.height,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (isSubmenuOpen && !isResizing) {
|
||||||
|
updateAnchor();
|
||||||
|
}
|
||||||
|
}, [isSubmenuOpen, lang.isRtl, updateAnchor, isResizing]);
|
||||||
|
|
||||||
|
const cancelOpen = useLastCallback(() => {
|
||||||
|
clearTimeout(openTimeoutRef.current);
|
||||||
|
openTimeoutRef.current = undefined;
|
||||||
|
});
|
||||||
|
|
||||||
|
const cancelClose = useLastCallback(() => {
|
||||||
|
clearTimeout(closeTimeoutRef.current);
|
||||||
|
closeTimeoutRef.current = undefined;
|
||||||
|
});
|
||||||
|
|
||||||
|
const scheduleOpen = useLastCallback(() => {
|
||||||
|
cancelClose();
|
||||||
|
cancelOpen();
|
||||||
|
openTimeoutRef.current = window.setTimeout(() => {
|
||||||
|
openTimeoutRef.current = undefined;
|
||||||
|
// Don't open if the parent menu is closing
|
||||||
|
const parentBubble = itemRef.current?.closest('.bubble');
|
||||||
|
if (parentBubble?.classList.contains('closing')) return;
|
||||||
|
openSubmenu();
|
||||||
|
}, OPEN_TIMEOUT);
|
||||||
|
});
|
||||||
|
|
||||||
|
const scheduleClose = useLastCallback(() => {
|
||||||
|
cancelOpen();
|
||||||
|
cancelClose();
|
||||||
|
closeTimeoutRef.current = window.setTimeout(() => {
|
||||||
|
closeSubmenu();
|
||||||
|
closeTimeoutRef.current = undefined;
|
||||||
|
}, CLOSE_TIMEOUT);
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleMouseEnter = useLastCallback(() => {
|
||||||
|
if (disabled) return;
|
||||||
|
scheduleOpen();
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleSubmenuMouseEnter = useLastCallback(() => {
|
||||||
|
cancelOpen();
|
||||||
|
cancelClose();
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleSubmenuMouseLeave = useLastCallback(() => {
|
||||||
|
scheduleClose();
|
||||||
|
});
|
||||||
|
|
||||||
|
const closeParentMenu = useLastCallback(() => {
|
||||||
|
const parentMenu = itemRef.current?.closest('.Menu');
|
||||||
|
if (parentMenu) {
|
||||||
|
const backdrop = parentMenu.querySelector('.backdrop') as HTMLElement;
|
||||||
|
if (backdrop) {
|
||||||
|
const event = new MouseEvent('mousedown', {
|
||||||
|
bubbles: true,
|
||||||
|
cancelable: true,
|
||||||
|
view: window,
|
||||||
|
});
|
||||||
|
backdrop.dispatchEvent(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleSubmenuClose = useLastCallback(() => {
|
||||||
|
if (isClosingRef.current) return;
|
||||||
|
isClosingRef.current = true;
|
||||||
|
|
||||||
|
cancelOpen();
|
||||||
|
cancelClose();
|
||||||
|
closeSubmenu();
|
||||||
|
|
||||||
|
closeParentMenu();
|
||||||
|
|
||||||
|
// Reset after a short delay
|
||||||
|
setTimeout(() => {
|
||||||
|
isClosingRef.current = false;
|
||||||
|
}, 100);
|
||||||
|
});
|
||||||
|
|
||||||
|
const getTriggerElement = useLastCallback(() => itemRef.current);
|
||||||
|
const getRootElement = useLastCallback(() => document.body);
|
||||||
|
const getMenuElement = useLastCallback(
|
||||||
|
() => document.getElementById(submenuId)?.querySelector('.bubble') as HTMLElement | undefined,
|
||||||
|
);
|
||||||
|
const getLayout = useLastCallback(() => ({ withPortal: true }));
|
||||||
|
|
||||||
|
const handleClick = useLastCallback((e: React.SyntheticEvent<HTMLDivElement | HTMLAnchorElement>) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
if (disabled || isSubmenuOpen) return;
|
||||||
|
openSubmenu();
|
||||||
|
});
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
onMouseEnter={handleMouseEnter}
|
||||||
|
onMouseLeave={scheduleClose}
|
||||||
|
ref={itemRef}
|
||||||
|
>
|
||||||
|
<MenuItem
|
||||||
|
icon={icon}
|
||||||
|
customIcon={customIcon}
|
||||||
|
className={buildClassName(className, 'submenu')}
|
||||||
|
disabled={disabled}
|
||||||
|
destructive={destructive}
|
||||||
|
ariaLabel={ariaLabel}
|
||||||
|
onClick={handleClick}
|
||||||
|
>
|
||||||
|
{children}
|
||||||
|
<Icon name={submenuIcon || (lang.isRtl ? 'previous' : 'next')} className="submenu-icon" />
|
||||||
|
{submenuAnchor && (
|
||||||
|
<Menu
|
||||||
|
id={submenuId}
|
||||||
|
isOpen={isSubmenuOpen}
|
||||||
|
className={buildClassName('submenu', submenuClassName)}
|
||||||
|
anchor={submenuAnchor}
|
||||||
|
positionX={lang.isRtl ? 'left' : 'right'}
|
||||||
|
getTriggerElement={getTriggerElement}
|
||||||
|
getRootElement={getRootElement}
|
||||||
|
getMenuElement={getMenuElement}
|
||||||
|
getLayout={getLayout}
|
||||||
|
autoClose
|
||||||
|
nested
|
||||||
|
withPortal
|
||||||
|
footer={footer}
|
||||||
|
onClose={handleSubmenuClose}
|
||||||
|
onMouseEnter={handleSubmenuMouseEnter}
|
||||||
|
onMouseLeave={handleSubmenuMouseLeave}
|
||||||
|
>
|
||||||
|
{submenu}
|
||||||
|
</Menu>
|
||||||
|
)}
|
||||||
|
</MenuItem>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default NestedMenuItem;
|
||||||
@ -132,6 +132,8 @@ function processDynamically(
|
|||||||
let { x, y } = anchor;
|
let { x, y } = anchor;
|
||||||
const anchorX = x;
|
const anchorX = x;
|
||||||
const anchorY = y;
|
const anchorY = y;
|
||||||
|
const anchorWidth = anchor.width || 0;
|
||||||
|
const anchorHeight = anchor.height || 0;
|
||||||
|
|
||||||
const menuEl = getMenuElement();
|
const menuEl = getMenuElement();
|
||||||
const rootEl = getRootElement();
|
const rootEl = getRootElement();
|
||||||
@ -161,9 +163,9 @@ function processDynamically(
|
|||||||
if (isDense || (x + menuRect.width + extraPaddingX < rootRect.width + rootRect.left)) {
|
if (isDense || (x + menuRect.width + extraPaddingX < rootRect.width + rootRect.left)) {
|
||||||
x += 3;
|
x += 3;
|
||||||
positionX = 'left';
|
positionX = 'left';
|
||||||
} else if (x - menuRect.width - rootRect.left > 0) {
|
} else if (x - anchorWidth - menuRect.width - rootRect.left > 0) {
|
||||||
positionX = 'right';
|
positionX = 'right';
|
||||||
x -= 3;
|
x = x - anchorWidth - 3;
|
||||||
} else {
|
} else {
|
||||||
positionX = 'left';
|
positionX = 'left';
|
||||||
x = 16;
|
x = 16;
|
||||||
@ -178,6 +180,7 @@ function processDynamically(
|
|||||||
y = yWithTopShift;
|
y = yWithTopShift;
|
||||||
} else {
|
} else {
|
||||||
positionY = 'bottom';
|
positionY = 'bottom';
|
||||||
|
y = y + anchorHeight;
|
||||||
|
|
||||||
if (y - menuRect.height < rootRect.top + extraTopPadding) {
|
if (y - menuRect.height < rootRect.top + extraTopPadding) {
|
||||||
y = rootRect.top + rootRect.height;
|
y = rootRect.top + rootRect.height;
|
||||||
|
|||||||
@ -163,6 +163,8 @@ export interface AccountSettings {
|
|||||||
export type IAnchorPosition = {
|
export type IAnchorPosition = {
|
||||||
x: number;
|
x: number;
|
||||||
y: number;
|
y: number;
|
||||||
|
width?: number;
|
||||||
|
height?: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface ShippingOption {
|
export interface ShippingOption {
|
||||||
|
|||||||
1
src/types/language.d.ts
vendored
1
src/types/language.d.ts
vendored
@ -1235,6 +1235,7 @@ export interface LangPair {
|
|||||||
'MenuArchivedChats': undefined;
|
'MenuArchivedChats': undefined;
|
||||||
'MenuContacts': undefined;
|
'MenuContacts': undefined;
|
||||||
'MenuSettings': undefined;
|
'MenuSettings': undefined;
|
||||||
|
'MenuMore': undefined;
|
||||||
'MenuNightMode': undefined;
|
'MenuNightMode': undefined;
|
||||||
'AriaMenuEnableNightMode': undefined;
|
'AriaMenuEnableNightMode': undefined;
|
||||||
'AriaMenuDisableNightMode': undefined;
|
'AriaMenuDisableNightMode': undefined;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user