From e7d86af637609b19c0e4f87fda35fb3c9616e145 Mon Sep 17 00:00:00 2001 From: Luke Date: Sat, 17 Dec 2022 14:27:55 +0100 Subject: [PATCH] refactor(web/context): context menu mantine rewrite --- web/src/features/menu/context/ContextMenu.tsx | 72 +++------ web/src/features/menu/context/Item.tsx | 142 ------------------ .../menu/context/components/ContextButton.tsx | 110 ++++++++++++++ .../menu/context/components/HeaderButton.tsx | 44 ++++++ 4 files changed, 173 insertions(+), 195 deletions(-) delete mode 100644 web/src/features/menu/context/Item.tsx create mode 100644 web/src/features/menu/context/components/ContextButton.tsx create mode 100644 web/src/features/menu/context/components/HeaderButton.tsx diff --git a/web/src/features/menu/context/ContextMenu.tsx b/web/src/features/menu/context/ContextMenu.tsx index aee714f..635093f 100644 --- a/web/src/features/menu/context/ContextMenu.tsx +++ b/web/src/features/menu/context/ContextMenu.tsx @@ -1,11 +1,11 @@ import { useNuiEvent } from '../../../hooks/useNuiEvent'; -import { Box, Text, Flex, ScaleFade } from '@chakra-ui/react'; +import { Box, Stack, Text, Flex, Transition } from '@mantine/core'; import { useEffect, useState } from 'react'; import { ContextMenuProps } from '../../../interfaces/context'; -import Item from './Item'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import ContextButton from './components/ContextButton'; import { fetchNui } from '../../../utils/fetchNui'; import ReactMarkdown from 'react-markdown'; +import HeaderButton from './components/HeaderButton'; const openMenu = (id: string | undefined) => { fetchNui('openContext', { id: id, back: true }); @@ -49,64 +49,30 @@ const ContextMenu: React.FC = () => { }); return ( - - - - + + {(styles) => ( + + {contextMenu.menu && ( - openMenu(contextMenu.menu)} - > - - + openMenu(contextMenu.menu)} /> )} - - + + {contextMenu.title} - closeContext()} - > - - + - - {Object.entries(contextMenu.options).map((option, index) => ( - - ))} + + + {Object.entries(contextMenu.options).map((option, index) => ( + + ))} + - - + )} + ); }; diff --git a/web/src/features/menu/context/Item.tsx b/web/src/features/menu/context/Item.tsx deleted file mode 100644 index c24ba15..0000000 --- a/web/src/features/menu/context/Item.tsx +++ /dev/null @@ -1,142 +0,0 @@ -import { - Portal, - Popover, - PopoverTrigger, - PopoverBody, - PopoverContent, - Box, - Text, - Flex, - Spacer, - Image, - HStack, - Progress, -} from '@chakra-ui/react'; -import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; -import ReactMarkdown from 'react-markdown'; -import { Option, ContextMenuProps } from '../../../interfaces/context'; -import { fetchNui } from '../../../utils/fetchNui'; - -const openMenu = (id: string | undefined) => { - fetchNui('openContext', { id: id, back: false }); -}; - -const clickContext = (id: string) => { - fetchNui('clickContext', id); -}; - -const Item: React.FC<{ - option: [string, Option]; -}> = ({ option }) => { - const button = option[1]; - const buttonKey = option[0]; - - return ( - <> - - - - - !button.disabled ? (button.menu ? openMenu(button.menu) : clickContext(buttonKey)) : null - } - > - {button?.icon && ( - - )} - - - - {button.title ? button.title : buttonKey} - - - {button.description && ( - - {button.description} - - )} - {button?.progress && ( - - )} - - {(button.menu || button.arrow) && button.arrow !== false && ( - <> - - - - - - )} - - - {!button.disabled && (button.metadata || button.image) && ( - - - <> - {button.image && } - {Array.isArray(button.metadata) ? ( - button.metadata.map((metadata: string | { label: string; value: any }, index: number) => ( - - {typeof metadata === 'string' ? `${metadata}` : `${metadata.label}: ${metadata.value}`} - - )) - ) : ( - <> - {typeof button.metadata === 'object' && - Object.entries(button.metadata).map((metadata: { [key: string]: any }, index) => ( - - {metadata[0]}: {metadata[1]} - - ))} - - )} - - - - )} - - - - - - ); -}; - -export default Item; diff --git a/web/src/features/menu/context/components/ContextButton.tsx b/web/src/features/menu/context/components/ContextButton.tsx new file mode 100644 index 0000000..b0cafbe --- /dev/null +++ b/web/src/features/menu/context/components/ContextButton.tsx @@ -0,0 +1,110 @@ +import { Button, Box, Group, Stack, Text, Progress, HoverCard, Image, createStyles } from '@mantine/core'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import ReactMarkdown from 'react-markdown'; +import { Option, ContextMenuProps } from '../../../../interfaces/context'; +import { fetchNui } from '../../../../utils/fetchNui'; + +const openMenu = (id: string | undefined) => { + fetchNui('openContext', { id: id, back: false }); +}; + +const clickContext = (id: string) => { + fetchNui('clickContext', id); +}; + +const useStyles = createStyles((theme, params: { disabled?: boolean }) => ({ + inner: { + justifyContent: 'flex-start', + }, + label: { + width: '100%', + color: params.disabled ? theme.colors.dark[3] : theme.colors.dark[0], + whiteSpace: 'pre-wrap', + }, + dropdown: { + padding: 10, + color: theme.colors.dark[0], + fontSize: 14, + maxWidth: 256, + width: 'fit-content', + }, +})); + +const ContextButton: React.FC<{ + option: [string, Option]; +}> = ({ option }) => { + const button = option[1]; + const buttonKey = option[0]; + const { classes } = useStyles({ disabled: button.disabled }); + + return ( + <> + + + + + + {button.image && } + {Array.isArray(button.metadata) ? ( + button.metadata.map((metadata: string | { label: string; value: any }, index: number) => ( + + {typeof metadata === 'string' ? `${metadata}` : `${metadata.label}: ${metadata.value}`} + + )) + ) : ( + <> + {typeof button.metadata === 'object' && + Object.entries(button.metadata).map((metadata: { [key: string]: any }, index) => ( + + {metadata[0]}: {metadata[1]} + + ))} + + )} + + + + ); +}; + +export default ContextButton; diff --git a/web/src/features/menu/context/components/HeaderButton.tsx b/web/src/features/menu/context/components/HeaderButton.tsx new file mode 100644 index 0000000..e10e759 --- /dev/null +++ b/web/src/features/menu/context/components/HeaderButton.tsx @@ -0,0 +1,44 @@ +import { Button, createStyles } from '@mantine/core'; +import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; +import { IconProp } from '@fortawesome/fontawesome-svg-core'; + +interface Props { + icon: IconProp; + canClose?: boolean; + iconSize: number; + handleClick: () => void; +} + +const useStyles = createStyles((theme, params: { canClose?: boolean }) => ({ + button: { + borderRadius: 4, + flex: '1 15%', + alignSelf: 'stretch', + height: 'auto', + textAlign: 'center', + justifyContent: 'center', + padding: 2, + }, + + label: { + color: params.canClose ? theme.colors.dark[0] : theme.colors.dark[2], + }, +})); + +const HeaderButton: React.FC = ({ icon, canClose, iconSize, handleClick }) => { + const { classes } = useStyles({ canClose }); + + return ( + + ); +}; + +export default HeaderButton;