pl-fe: Only use one type of dropdown menu
Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
@ -56,8 +56,6 @@
|
||||
"@mkljczk/lexical-remark": "^0.4.0",
|
||||
"@mkljczk/react-hotkeys": "^1.2.2",
|
||||
"@reach/combobox": "^0.18.0",
|
||||
"@reach/menu-button": "^0.18.0",
|
||||
"@reach/popover": "^0.18.0",
|
||||
"@reach/rect": "^0.18.0",
|
||||
"@reach/tabs": "^0.18.0",
|
||||
"@reduxjs/toolkit": "^2.0.1",
|
||||
|
||||
@ -27,15 +27,6 @@ export { default as Icon } from './icon/icon';
|
||||
export { default as IconButton } from './icon-button/icon-button';
|
||||
export { default as Input } from './input/input';
|
||||
export { default as Layout } from './layout/layout';
|
||||
export {
|
||||
Menu,
|
||||
MenuButton,
|
||||
MenuDivider,
|
||||
MenuItem,
|
||||
MenuItems,
|
||||
MenuLink,
|
||||
MenuList,
|
||||
} from './menu/menu';
|
||||
export { default as Modal } from './modal/modal';
|
||||
export { default as Popover } from './popover/popover';
|
||||
export { default as Portal } from './portal/portal';
|
||||
|
||||
@ -1,33 +0,0 @@
|
||||
[data-reach-menu-popover] {
|
||||
@apply origin-top-right rtl:origin-top-left absolute mt-2 rounded-md shadow-lg bg-white dark:bg-gray-900 dark:ring-2 dark:ring-gray-800 focus:outline-none z-[1003];
|
||||
}
|
||||
|
||||
[data-reach-menu-button] {
|
||||
@apply focus:ring-primary-500 focus:ring-2 focus:ring-offset-2;
|
||||
}
|
||||
|
||||
div:focus[data-reach-menu-list] {
|
||||
outline: none;
|
||||
}
|
||||
|
||||
[data-reach-menu-item][data-selected] {
|
||||
@apply bg-gray-100 dark:bg-gray-800;
|
||||
}
|
||||
|
||||
[data-reach-menu-list] {
|
||||
@apply py-1;
|
||||
}
|
||||
|
||||
[data-reach-menu-item],
|
||||
[data-reach-menu-link] {
|
||||
@apply block px-4 py-2.5 text-sm text-gray-700 dark:text-gray-500 cursor-pointer;
|
||||
}
|
||||
|
||||
[data-reach-menu-link] {
|
||||
@apply hover:bg-gray-100 dark:hover:bg-gray-800;
|
||||
}
|
||||
|
||||
[data-reach-menu-item][data-disabled],
|
||||
[data-reach-menu-link][data-disabled] {
|
||||
@apply opacity-25 cursor-default;
|
||||
}
|
||||
@ -1,42 +0,0 @@
|
||||
import {
|
||||
Menu,
|
||||
MenuButton,
|
||||
MenuItem,
|
||||
MenuItems,
|
||||
MenuPopover,
|
||||
MenuLink,
|
||||
MenuListProps,
|
||||
} from '@reach/menu-button';
|
||||
import { positionDefault, positionRight } from '@reach/popover';
|
||||
import clsx from 'clsx';
|
||||
import React from 'react';
|
||||
|
||||
import './menu.css';
|
||||
|
||||
interface IMenuList extends Omit<MenuListProps, 'position'> {
|
||||
/** Position of the dropdown menu. */
|
||||
position?: 'left' | 'right';
|
||||
className?: string;
|
||||
}
|
||||
|
||||
/** Renders children as a dropdown menu. */
|
||||
const MenuList: React.FC<IMenuList> = (props) => {
|
||||
const { position, className, ...filteredProps } = props;
|
||||
|
||||
return (
|
||||
<MenuPopover position={props.position === 'left' ? positionDefault : positionRight}>
|
||||
<MenuItems
|
||||
onKeyDown={(event) => event.nativeEvent.stopImmediatePropagation()}
|
||||
className={
|
||||
clsx(className, 'shadow-menu rounded-lg bg-white py-1 black:bg-black dark:bg-primary-900')
|
||||
}
|
||||
{...filteredProps}
|
||||
/>
|
||||
</MenuPopover>
|
||||
);
|
||||
};
|
||||
|
||||
/** Divides menu items. */
|
||||
const MenuDivider = () => <hr className='mx-2 my-1 border-t-2 border-gray-100 black:border-t dark:border-gray-800' />;
|
||||
|
||||
export { Menu, MenuButton, MenuDivider, MenuItems, MenuItem, MenuList, MenuLink };
|
||||
@ -3,7 +3,8 @@ import { defineMessages, useIntl } from 'react-intl';
|
||||
import { Link, useHistory, useParams } from 'react-router-dom';
|
||||
|
||||
import { blockAccount, unblockAccount } from 'pl-fe/actions/accounts';
|
||||
import { Avatar, HStack, Icon, IconButton, Menu, MenuButton, MenuItem, MenuList, Stack, Text } from 'pl-fe/components/ui';
|
||||
import DropdownMenu, { type Menu } from 'pl-fe/components/dropdown-menu';
|
||||
import { Avatar, HStack, IconButton, Stack, Text } from 'pl-fe/components/ui';
|
||||
import VerificationBadge from 'pl-fe/components/verification-badge';
|
||||
import { useChatContext } from 'pl-fe/contexts/chat-context';
|
||||
import { Entities } from 'pl-fe/entity-store/entities';
|
||||
@ -104,6 +105,20 @@ const ChatPageMain = () => {
|
||||
return null;
|
||||
}
|
||||
|
||||
const menuItems: Menu = [
|
||||
{
|
||||
icon: require('@tabler/icons/outline/ban.svg'),
|
||||
text: intl.formatMessage(isBlocking ? messages.unblockUser : messages.blockUser, { acct: chat.account.acct }),
|
||||
action: isBlocking ? handleUnblockUser : handleBlockUser,
|
||||
},
|
||||
];
|
||||
|
||||
if (features.chatsDelete) menuItems.push({
|
||||
icon: require('@tabler/icons/outline/logout.svg'),
|
||||
text: intl.formatMessage(messages.leaveChat),
|
||||
action: handleLeaveChat,
|
||||
});
|
||||
|
||||
return (
|
||||
<Stack className='h-full overflow-hidden'>
|
||||
<HStack alignItems='center' justifyContent='between' space={2} className='w-full p-4'>
|
||||
@ -132,52 +147,19 @@ const ChatPageMain = () => {
|
||||
</Stack>
|
||||
</HStack>
|
||||
|
||||
<Menu>
|
||||
<MenuButton
|
||||
as={IconButton}
|
||||
src={require('@tabler/icons/outline/info-circle.svg')}
|
||||
iconClassName='h-5 w-5 text-gray-600'
|
||||
children={null}
|
||||
/>
|
||||
|
||||
<MenuList className='w-80'>
|
||||
<Stack space={4} className='px-6 py-5'>
|
||||
<HStack alignItems='center' space={3}>
|
||||
<Avatar src={chat.account.avatar_static} alt={chat.account.avatar_description} size={50} />
|
||||
<Stack>
|
||||
<Text weight='semibold'>{chat.account.display_name}</Text>
|
||||
<Text size='sm' theme='primary'>@{chat.account.acct}</Text>
|
||||
</Stack>
|
||||
</HStack>
|
||||
|
||||
<Stack space={2}>
|
||||
<MenuItem
|
||||
as='button'
|
||||
onSelect={isBlocking ? handleUnblockUser : handleBlockUser}
|
||||
className='!px-0 hover:!bg-transparent'
|
||||
>
|
||||
<div className='flex w-full items-center space-x-2 text-sm font-bold text-primary-500 dark:text-accent-blue'>
|
||||
<Icon src={require('@tabler/icons/outline/ban.svg')} className='size-5' />
|
||||
<span>{intl.formatMessage(isBlocking ? messages.unblockUser : messages.blockUser, { acct: chat.account.acct })}</span>
|
||||
</div>
|
||||
</MenuItem>
|
||||
|
||||
{features.chatsDelete && (
|
||||
<MenuItem
|
||||
as='button'
|
||||
onSelect={handleLeaveChat}
|
||||
className='!px-0 hover:!bg-transparent'
|
||||
>
|
||||
<div className='flex w-full items-center space-x-2 text-sm font-bold text-danger-600 dark:text-danger-500'>
|
||||
<Icon src={require('@tabler/icons/outline/logout.svg')} className='size-5' />
|
||||
<span>{intl.formatMessage(messages.leaveChat)}</span>
|
||||
</div>
|
||||
</MenuItem>
|
||||
)}
|
||||
<DropdownMenu
|
||||
src={require('@tabler/icons/outline/info-circle.svg')}
|
||||
component={() => (
|
||||
<HStack className='px-4 py-2' alignItems='center' space={3}>
|
||||
<Avatar src={chat.account.avatar_static} alt={chat.account.avatar_description} size={50} />
|
||||
<Stack>
|
||||
<Text weight='semibold'>{chat.account.display_name}</Text>
|
||||
<Text size='sm' theme='primary'>@{chat.account.acct}</Text>
|
||||
</Stack>
|
||||
</Stack>
|
||||
</MenuList>
|
||||
</Menu>
|
||||
</HStack>
|
||||
)}
|
||||
items={menuItems}
|
||||
/>
|
||||
</HStack>
|
||||
|
||||
<div className='h-full overflow-hidden'>
|
||||
|
||||
@ -7,7 +7,6 @@ import { Link } from 'react-router-dom';
|
||||
import { fetchOwnAccounts, logOut, switchAccount } from 'pl-fe/actions/auth';
|
||||
import Account from 'pl-fe/components/account';
|
||||
import DropdownMenu from 'pl-fe/components/dropdown-menu';
|
||||
import { MenuDivider } from 'pl-fe/components/ui';
|
||||
import { useAppDispatch, useAppSelector, useFeatures } from 'pl-fe/hooks';
|
||||
import { makeGetAccount } from 'pl-fe/selectors';
|
||||
|
||||
@ -135,7 +134,7 @@ const MenuItem: React.FC<MenuItemProps> = ({ className, menuItem }) => {
|
||||
</div>
|
||||
);
|
||||
} else if (!menuItem.text) {
|
||||
return <MenuDivider />;
|
||||
return <hr className='mx-2 my-1 border-t-2 border-gray-100 black:border-t dark:border-gray-800' />;
|
||||
} else if (menuItem.action) {
|
||||
return (
|
||||
<button
|
||||
|
||||
@ -1972,27 +1972,6 @@
|
||||
dependencies:
|
||||
"@reach/utils" "0.18.0"
|
||||
|
||||
"@reach/dropdown@0.18.0":
|
||||
version "0.18.0"
|
||||
resolved "https://registry.yarnpkg.com/@reach/dropdown/-/dropdown-0.18.0.tgz#c2e2e99df682f2136558851b80dc05b4f9dd92a5"
|
||||
integrity sha512-LriXdVgxJoUhIQfS2r2DHYv3X6fHyplYxa9FmSwQIMXdESpE/P9Zsb1pVEObcNf3ZQBrl0L1bl/5rk7SpK7qfA==
|
||||
dependencies:
|
||||
"@reach/auto-id" "0.18.0"
|
||||
"@reach/descendants" "0.18.0"
|
||||
"@reach/polymorphic" "0.18.0"
|
||||
"@reach/popover" "0.18.0"
|
||||
"@reach/utils" "0.18.0"
|
||||
|
||||
"@reach/menu-button@^0.18.0":
|
||||
version "0.18.0"
|
||||
resolved "https://registry.yarnpkg.com/@reach/menu-button/-/menu-button-0.18.0.tgz#ae40dc86e47e7f925599ca720e3ba65263cc56f3"
|
||||
integrity sha512-v1lj5rYSpavOKI4ipXj8OfvQmvVNAYXCv+UcltRkjOcWEKWADUUKkGX55wiUhsCsTGCJ7lGYz5LqOZrn3LP6PQ==
|
||||
dependencies:
|
||||
"@reach/dropdown" "0.18.0"
|
||||
"@reach/polymorphic" "0.18.0"
|
||||
"@reach/popover" "0.18.0"
|
||||
"@reach/utils" "0.18.0"
|
||||
|
||||
"@reach/observe-rect@1.2.0":
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@reach/observe-rect/-/observe-rect-1.2.0.tgz#d7a6013b8aafcc64c778a0ccb83355a11204d3b2"
|
||||
@ -2003,7 +1982,7 @@
|
||||
resolved "https://registry.yarnpkg.com/@reach/polymorphic/-/polymorphic-0.18.0.tgz#2fe42007a774e06cdbc8e13e0d46f2dc30f2f1ed"
|
||||
integrity sha512-N9iAjdMbE//6rryZZxAPLRorzDcGBnluf7YQij6XDLiMtfCj1noa7KyLpEc/5XCIB/EwhX3zCluFAwloBKdblA==
|
||||
|
||||
"@reach/popover@0.18.0", "@reach/popover@^0.18.0":
|
||||
"@reach/popover@0.18.0":
|
||||
version "0.18.0"
|
||||
resolved "https://registry.yarnpkg.com/@reach/popover/-/popover-0.18.0.tgz#1eba3e9ed826ac69dfdf3b01a1dab15ca889b5fc"
|
||||
integrity sha512-mpnWWn4w74L2U7fcneVdA6Fz3yKWNdZIRMoK8s6H7F8U2dLM/qN7AjzjEBqi6LXKb3Uf1ge4KHSbMixW0BygJQ==
|
||||
|
||||
Reference in New Issue
Block a user