mirror of
https://github.com/CommunityOx/ox_lib.git
synced 2026-08-17 06:56:03 +01:00
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:
@@ -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);
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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' },
|
||||||
|
|||||||
@@ -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)}
|
||||||
|
|||||||
@@ -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;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user