feat(web): support icon urls in radial menu (#487)

* feat(package): support icon urls in radial menu

* fix: update lua & ts types + clamp size parameters
This commit is contained in:
ktx-mega
2024-02-18 12:11:40 +01:00
committed by GitHub
parent bd6183aa04
commit 78891fb4b9
5 changed files with 27 additions and 5 deletions

View File

@@ -3,9 +3,11 @@ import type { IconName, IconPrefix } from '@fortawesome/fontawesome-common-types
type RadialItem = { type RadialItem = {
id: string; id: string;
label: string; label: string;
icon: IconName | [IconPrefix, IconName]; icon: IconName | [IconPrefix, IconName] | string;
onSelect?: (currentMenu: string | null, itemIndex: number) => void | string; onSelect?: (currentMenu: string | null, itemIndex: number) => void | string;
menu?: string; menu?: string;
iconWidth?: number;
iconHeight?: number;
}; };
export const addRadialItem = (items: RadialItem | RadialItem[]) => exports.ox_lib.addRadialItem(items); export const addRadialItem = (items: RadialItem | RadialItem[]) => exports.ox_lib.addRadialItem(items);

View File

@@ -5,6 +5,8 @@
---@field onSelect? fun(currentMenu: string | nil, itemIndex: number) | string ---@field onSelect? fun(currentMenu: string | nil, itemIndex: number) | string
---@field [string] any ---@field [string] any
---@field keepOpen? boolean ---@field keepOpen? boolean
---@field iconWidth? number
---@field iconHeight? number
---@class RadialMenuItem: RadialItem ---@class RadialMenuItem: RadialItem
---@field id string ---@field id string

View File

@@ -1,13 +1,14 @@
import { debugData } from '../../../utils/debugData'; import { debugData } from '../../../utils/debugData';
import type { MenuItem } from '../../../typings'; import type { RadialMenuItem } from '../../../typings';
export const debugRadial = () => { export const debugRadial = () => {
debugData<{ items: MenuItem[]; sub?: boolean }>([ debugData<{ items: RadialMenuItem[]; sub?: boolean }>([
{ {
action: 'openRadialMenu', action: 'openRadialMenu',
data: { data: {
items: [ items: [
{ icon: 'palette', label: 'Paint' }, { icon: 'palette', label: 'Paint' },
{ iconWidth: 35, iconHeight: 35, icon: 'https://icon-library.com/images/white-icon-png/white-icon-png-18.jpg', label: 'External icon'},
{ icon: 'warehouse', label: 'Garage' }, { icon: 'warehouse', label: 'Garage' },
{ icon: 'palette', label: 'Quite long \ntext' }, { icon: 'palette', label: 'Quite long \ntext' },
{ icon: 'palette', label: 'Paint' }, { icon: 'palette', label: 'Paint' },

View File

@@ -1,7 +1,9 @@
import { Box, createStyles } from '@mantine/core'; import { Box, createStyles } from '@mantine/core';
import { useEffect, useState } from 'react'; import { useEffect, useState } from 'react';
import { IconProp } from '@fortawesome/fontawesome-svg-core';
import { useNuiEvent } from '../../../hooks/useNuiEvent'; import { useNuiEvent } from '../../../hooks/useNuiEvent';
import { fetchNui } from '../../../utils/fetchNui'; import { fetchNui } from '../../../utils/fetchNui';
import { isIconUrl } from '../../../utils/isIconUrl';
import ScaleFade from '../../../transitions/ScaleFade'; import ScaleFade from '../../../transitions/ScaleFade';
import type { RadialMenuItem } from '../../../typings'; import type { RadialMenuItem } from '../../../typings';
import { useLocales } from '../../../providers/LocaleProvider'; import { useLocales } from '../../../providers/LocaleProvider';
@@ -132,6 +134,9 @@ const RadialMenu: React.FC = () => {
const cosAngle = Math.cos(angle); const cosAngle = Math.cos(angle);
const iconX = 175 + sinAngle * radius; const iconX = 175 + sinAngle * radius;
const iconY = 175 + cosAngle * radius; const iconY = 175 + cosAngle * radius;
const iconWidth = Math.min(Math.max(item.iconWidth || 50, 0), 100);
const iconHeight = Math.min(Math.max(item.iconHeight || 50, 0), 100);
return ( return (
<> <>
@@ -153,7 +158,17 @@ const RadialMenu: React.FC = () => {
}, ${175 + (175 - gap) * Math.sin(-degToRad(pieAngle))} z`} }, ${175 + (175 - gap) * Math.sin(-degToRad(pieAngle))} z`}
/> />
<g transform={`rotate(${index * pieAngle - 90} ${iconX} ${iconY})`} pointerEvents="none"> <g transform={`rotate(${index * pieAngle - 90} ${iconX} ${iconY})`} pointerEvents="none">
<LibIcon x={iconX - 12.5} y={iconY - 17.5} icon={item.icon} width={25} height={25} fixedWidth /> {typeof item.icon === 'string' && isIconUrl(item.icon) ? (
<image
href={item.icon}
width={iconWidth}
height={iconHeight}
x={iconX - iconWidth / 2}
y={iconY - iconHeight / 2 - iconHeight / 4}
/>
) : (
<LibIcon x={iconX - 12.5} y={iconY - 17.5} icon={item.icon as IconProp} width={25} height={25} fixedWidth/>
)}
<text <text
x={iconX} x={iconX}
y={iconY + (item.label.includes(' \n') ? 7 : 25)} y={iconY + (item.label.includes(' \n') ? 7 : 25)}

View File

@@ -1,8 +1,10 @@
import { IconProp } from '@fortawesome/fontawesome-svg-core'; import { IconProp } from '@fortawesome/fontawesome-svg-core';
export interface RadialMenuItem { export interface RadialMenuItem {
icon: IconProp; icon: string | IconProp;
label: string; label: string;
isMore?: boolean; isMore?: boolean;
menu?: string; menu?: string;
iconWidth?: number;
iconHeight?: number;
} }