feat(web): font awesome icon animations

This commit is contained in:
Luke
2023-11-15 15:28:21 +01:00
parent a50f7a2052
commit 882e372895
24 changed files with 124 additions and 47 deletions

View File

@@ -1,11 +1,11 @@
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 '../../../../typings';
import { fetchNui } from '../../../../utils/fetchNui';
import { isIconUrl } from '../../../../utils/isIconUrl';
import { IconProp } from '@fortawesome/fontawesome-svg-core';
import MarkdownComponents from '../../../../config/MarkdownComponents';
import LibIcon from '../../../../components/LibIcon';
const openMenu = (id: string | undefined) => {
fetchNui<ContextMenuProps>('openContext', { id: id, back: false });
@@ -112,11 +112,12 @@ const ContextButton: React.FC<{
{typeof button.icon === 'string' && isIconUrl(button.icon) ? (
<img src={button.icon} className={classes.iconImage} alt="Missing img" />
) : (
<FontAwesomeIcon
<LibIcon
icon={button.icon as IconProp}
fixedWidth
size="lg"
style={{ color: button.iconColor }}
animation={button.iconAnimation}
/>
)}
</Stack>
@@ -137,7 +138,7 @@ const ContextButton: React.FC<{
</Stack>
{(button.menu || button.arrow) && button.arrow !== false && (
<Stack className={classes.buttonArrowContainer}>
<FontAwesomeIcon icon="chevron-right" fixedWidth />
<LibIcon icon="chevron-right" fixedWidth />
</Stack>
)}
</Group>

View File

@@ -1,6 +1,7 @@
import { Button, createStyles } from '@mantine/core';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { IconProp } from '@fortawesome/fontawesome-svg-core';
import LibIcon from '../../../../components/LibIcon';
interface Props {
icon: IconProp;
@@ -38,7 +39,7 @@ const HeaderButton: React.FC<Props> = ({ icon, canClose, iconSize, handleClick }
disabled={canClose === false}
onClick={handleClick}
>
<FontAwesomeIcon icon={icon} fontSize={iconSize} fixedWidth />
<LibIcon icon={icon} fontSize={iconSize} fixedWidth />
</Button>
);
};

View File

@@ -1,11 +1,11 @@
import { Box, Group, Stack, Text, Progress, Image } from '@mantine/core';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import React, { forwardRef } from 'react';
import CustomCheckbox from './CustomCheckbox';
import type { MenuItem } from '../../../typings';
import { createStyles } from '@mantine/core';
import { isIconUrl } from '../../../utils/isIconUrl';
import { IconProp } from '@fortawesome/fontawesome-svg-core';
import LibIcon from '../../../components/LibIcon';
interface Props {
item: MenuItem;
@@ -89,7 +89,12 @@ const ListItem = forwardRef<Array<HTMLDivElement | null>, Props>(({ item, index,
{typeof item.icon === 'string' && isIconUrl(item.icon) ? (
<img src={item.icon} alt="Missing image" className={classes.iconImage} />
) : (
<FontAwesomeIcon icon={item.icon as IconProp} className={classes.icon} fixedWidth />
<LibIcon
icon={item.icon as IconProp}
className={classes.icon}
fixedWidth
animation={item.iconAnimation}
/>
)}
</Box>
)}
@@ -105,11 +110,11 @@ const ListItem = forwardRef<Array<HTMLDivElement | null>, Props>(({ item, index,
</Text>
</Stack>
<Group spacing={1} position="center">
<FontAwesomeIcon icon="chevron-left" className={classes.chevronIcon} />
<LibIcon icon="chevron-left" className={classes.chevronIcon} />
<Text className={classes.scrollIndexValue}>
{scrollIndex + 1}/{item.values.length}
</Text>
<FontAwesomeIcon icon="chevron-right" className={classes.chevronIcon} />
<LibIcon icon="chevron-right" className={classes.chevronIcon} />
</Group>
</Group>
) : item.checked !== undefined ? (

View File

@@ -5,9 +5,9 @@ import ListItem from './ListItem';
import Header from './Header';
import FocusTrap from 'focus-trap-react';
import { fetchNui } from '../../../utils/fetchNui';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import React from 'react';
import type { MenuPosition, MenuSettings } from '../../../typings';
import LibIcon from '../../../components/LibIcon';
const useStyles = createStyles((theme, params: { position?: MenuPosition; itemCount: number; selected: number }) => ({
tooltip: {
@@ -28,7 +28,7 @@ const useStyles = createStyles((theme, params: { position?: MenuPosition; itemCo
left: params.position === 'bottom-left' ? 1 : undefined,
bottom: params.position === 'bottom-left' || params.position === 'bottom-right' ? 1 : undefined,
fontFamily: 'Roboto',
width: 384
width: 384,
},
buttonsWrapper: {
height: 'fit-content',
@@ -239,7 +239,7 @@ const ListMenu: React.FC = () => {
</Box>
{menu.items.length > 6 && selected !== menu.items.length - 1 && (
<Box className={classes.scrollArrow}>
<FontAwesomeIcon icon="chevron-down" className={classes.scrollArrowIcon} />
<LibIcon icon="chevron-down" className={classes.scrollArrowIcon} />
</Box>
)}
</Box>

View File

@@ -6,6 +6,7 @@ import { fetchNui } from '../../../utils/fetchNui';
import ScaleFade from '../../../transitions/ScaleFade';
import type { RadialMenuItem } from '../../../typings';
import { useLocales } from '../../../providers/LocaleProvider';
import LibIcon from '../../../components/LibIcon';
const useStyles = createStyles((theme) => ({
wrapper: {
@@ -81,18 +82,23 @@ const RadialMenu: React.FC = () => {
useEffect(() => {
if (menu.items.length <= PAGE_ITEMS) return setMenuItems(menu.items);
const items = menu.items.slice(PAGE_ITEMS * (menu.page - 1) - (menu.page - 1), PAGE_ITEMS * menu.page - menu.page + 1);
const items = menu.items.slice(
PAGE_ITEMS * (menu.page - 1) - (menu.page - 1),
PAGE_ITEMS * menu.page - menu.page + 1
);
if (PAGE_ITEMS * menu.page - menu.page + 1 < menu.items.length) {
items[items.length - 1] = { icon: 'ellipsis-h', label: locale.ui.more, isMore: true };
}
setMenuItems(items);
}, [menu.items, menu.page]);
useNuiEvent('openRadialMenu', async (data: { items: RadialMenuItem[]; sub?: boolean, option?: string } | false) => {
useNuiEvent('openRadialMenu', async (data: { items: RadialMenuItem[]; sub?: boolean; option?: string } | false) => {
if (!data) return setVisible(false);
let initialPage = 1;
if (data.option) {
data.items.findIndex((item, index) => item.menu == data.option && (initialPage = Math.floor(index / PAGE_ITEMS) + 1));
data.items.findIndex(
(item, index) => item.menu == data.option && (initialPage = Math.floor(index / PAGE_ITEMS) + 1)
);
}
setMenu({ ...data, page: initialPage });
setVisible(true);
@@ -134,7 +140,8 @@ const RadialMenu: React.FC = () => {
transform={`rotate(-${index * pieAngle} 175 175) translate(${sinAngle * gap}, ${cosAngle * gap})`}
className={classes.sector}
onClick={async () => {
const clickIndex = menu.page === 1 ? index : PAGE_ITEMS * (menu.page - 1) - (menu.page - 1) + index;
const clickIndex =
menu.page === 1 ? index : PAGE_ITEMS * (menu.page - 1) - (menu.page - 1) + index;
if (!item.isMore) fetchNui('radialClick', clickIndex);
else {
await changePage(true);
@@ -147,19 +154,21 @@ const RadialMenu: React.FC = () => {
}, ${175 + (175 - gap) * Math.sin(-degToRad(pieAngle))} z`}
/>
<g transform={`rotate(${index * pieAngle - 90} ${iconX} ${iconY})`} pointerEvents="none">
<FontAwesomeIcon
x={iconX - 12.5}
y={iconY - 17.5}
icon={item.icon}
width={25}
height={25}
fixedWidth
/>
<text x={iconX} y={iconY + (item.label.includes(" \n") ? 7 : 25)} fill="#fff" textAnchor="middle" pointerEvents="none">
{item.label.includes(" \n")
? item.label.split(" \n").map((value) => <tspan x={iconX} dy="1.2em">{value}</tspan>)
: item.label
}
<LibIcon x={iconX - 12.5} y={iconY - 17.5} icon={item.icon} width={25} height={25} fixedWidth />
<text
x={iconX}
y={iconY + (item.label.includes(' \n') ? 7 : 25)}
fill="#fff"
textAnchor="middle"
pointerEvents="none"
>
{item.label.includes(' \n')
? item.label.split(' \n').map((value) => (
<tspan x={iconX} dy="1.2em">
{value}
</tspan>
))
: item.label}
</text>
</g>
</g>
@@ -183,7 +192,7 @@ const RadialMenu: React.FC = () => {
</g>
</svg>
<div className={classes.centerIconContainer}>
<FontAwesomeIcon
<LibIcon
icon={!menu.sub && menu.page < 2 ? 'xmark' : 'arrow-rotate-left'}
fixedWidth
className={classes.centerIcon}