mirror of
https://github.com/CommunityOx/ox_lib.git
synced 2026-08-19 07:56:02 +01:00
refactor(web/menu)!: pass scrollIndex or checked in the same value
If the button is a scroll button then `isScroll` is passed into args, if a button is a checkbox then `isCheck` is passed into args. Requires `args` to always be of type `table`
This commit is contained in:
@@ -10,7 +10,7 @@ interface MenuOptions {
|
|||||||
values?: Array<string | { label: string; description: string }>;
|
values?: Array<string | { label: string; description: string }>;
|
||||||
description?: string;
|
description?: string;
|
||||||
defaultIndex?: number;
|
defaultIndex?: number;
|
||||||
args?: any;
|
args?: Record<any, any>;
|
||||||
close?: boolean;
|
close?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ local keepInput = IsNuiFocusKeepingInput()
|
|||||||
---@field values? Array<string | { label: string, description: string }>
|
---@field values? Array<string | { label: string, description: string }>
|
||||||
---@field description? string
|
---@field description? string
|
||||||
---@field defaultIndex? number
|
---@field defaultIndex? number
|
||||||
---@field args? any
|
---@field args? {[any]: any}
|
||||||
---@field close? boolean
|
---@field close? boolean
|
||||||
|
|
||||||
---@class MenuProps
|
---@class MenuProps
|
||||||
@@ -148,7 +148,7 @@ RegisterNUICallback('changeIndex', function(data, cb)
|
|||||||
data[2] += 1 -- scrollIndex
|
data[2] += 1 -- scrollIndex
|
||||||
end
|
end
|
||||||
|
|
||||||
openMenu.onSideScroll(data[1], data[2], openMenu.options[data[1]].args, data[3])
|
openMenu.onSideScroll(data[1], data[2], openMenu.options[data[1]].args)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
RegisterNUICallback('changeSelected', function(data, cb)
|
RegisterNUICallback('changeSelected', function(data, cb)
|
||||||
@@ -157,11 +157,23 @@ RegisterNUICallback('changeSelected', function(data, cb)
|
|||||||
|
|
||||||
data[1] += 1 -- selected
|
data[1] += 1 -- selected
|
||||||
|
|
||||||
if data[2] then
|
|
||||||
|
local args = openMenu.options[data[1]].args
|
||||||
|
|
||||||
|
if args and type(args) ~= 'table' then
|
||||||
|
return error("Menu args must be passed as a table")
|
||||||
|
end
|
||||||
|
|
||||||
|
if not args then args = {} end
|
||||||
|
print(data[2], data[3])
|
||||||
|
if data[2] then args[data[3]] = true end
|
||||||
|
print(args.isScroll, args.isCheck)
|
||||||
|
|
||||||
|
if data[2] and not args.isCheck then
|
||||||
data[2] += 1 -- scrollIndex
|
data[2] += 1 -- scrollIndex
|
||||||
end
|
end
|
||||||
|
|
||||||
openMenu.onSelected(data[1], data[2], openMenu.options[data[1]].args, data[3])
|
openMenu.onSelected(data[1], data[2], args)
|
||||||
end)
|
end)
|
||||||
|
|
||||||
RegisterNUICallback('changeChecked', function(data, cb)
|
RegisterNUICallback('changeChecked', function(data, cb)
|
||||||
@@ -170,11 +182,7 @@ RegisterNUICallback('changeChecked', function(data, cb)
|
|||||||
|
|
||||||
data[1] += 1 -- selected
|
data[1] += 1 -- selected
|
||||||
|
|
||||||
if data[2] then
|
openMenu.onCheck(data[1], data[2], openMenu.options[data[1]].args)
|
||||||
data[2] += 1 -- scrollIndex
|
|
||||||
end
|
|
||||||
|
|
||||||
openMenu.onCheck(data[1], data[2], openMenu.options[data[1]].args, data[3])
|
|
||||||
end)
|
end)
|
||||||
|
|
||||||
RegisterNUICallback('closeMenu', function(data, cb)
|
RegisterNUICallback('closeMenu', function(data, cb)
|
||||||
|
|||||||
@@ -61,43 +61,28 @@ const ListMenu: React.FC = () => {
|
|||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case 'ArrowRight':
|
case 'ArrowRight':
|
||||||
if (Array.isArray(menu.items[selected].values)) {
|
if (Array.isArray(menu.items[selected].values))
|
||||||
setIndexStates({
|
setIndexStates({
|
||||||
...indexStates,
|
...indexStates,
|
||||||
[selected]:
|
[selected]:
|
||||||
indexStates[selected] + 1 <= menu.items[selected].values?.length! - 1
|
indexStates[selected] + 1 <= menu.items[selected].values?.length! - 1 ? indexStates[selected] + 1 : 0,
|
||||||
? indexStates[selected] + 1
|
|
||||||
: 0
|
|
||||||
});
|
});
|
||||||
} else if (menu.items[selected].checked !== undefined) {
|
|
||||||
setCheckedStates({
|
|
||||||
...checkedStates,
|
|
||||||
[selected]: !checkedStates[selected]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 'ArrowLeft':
|
case 'ArrowLeft':
|
||||||
if (Array.isArray(menu.items[selected].values)) {
|
if (Array.isArray(menu.items[selected].values))
|
||||||
setIndexStates({
|
setIndexStates({
|
||||||
...indexStates,
|
...indexStates,
|
||||||
[selected]:
|
[selected]:
|
||||||
indexStates[selected] - 1 >= 0
|
indexStates[selected] - 1 >= 0 ? indexStates[selected] - 1 : menu.items[selected].values?.length! - 1,
|
||||||
? indexStates[selected] - 1
|
|
||||||
: menu.items[selected].values?.length! - 1
|
|
||||||
});
|
});
|
||||||
} else if (menu.items[selected].checked !== undefined) {
|
|
||||||
setCheckedStates({
|
|
||||||
...checkedStates,
|
|
||||||
[selected]: !checkedStates[selected]
|
|
||||||
});
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 'Enter':
|
case 'Enter':
|
||||||
if (!menu.items[selected]) return;
|
if (!menu.items[selected]) return;
|
||||||
if (menu.items[selected].checked !== undefined) {
|
if (menu.items[selected].checked !== undefined && !menu.items[selected].values) {
|
||||||
setCheckedStates({
|
return setCheckedStates({
|
||||||
...checkedStates,
|
...checkedStates,
|
||||||
[selected]: !checkedStates[selected]
|
[selected]: !checkedStates[selected],
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
fetchNui('confirmSelected', [selected, indexStates[selected]]).catch();
|
fetchNui('confirmSelected', [selected, indexStates[selected]]).catch();
|
||||||
@@ -113,10 +98,10 @@ const ListMenu: React.FC = () => {
|
|||||||
}
|
}
|
||||||
if (menu.items[selected]?.checked === undefined) return;
|
if (menu.items[selected]?.checked === undefined) return;
|
||||||
const timer = setTimeout(() => {
|
const timer = setTimeout(() => {
|
||||||
fetchNui('changeChecked', [selected, indexStates[selected], checkedStates[selected]]).catch();
|
fetchNui('changeChecked', [selected, checkedStates[selected]]).catch();
|
||||||
}, 100);
|
}, 100);
|
||||||
return () => clearTimeout(timer);
|
return () => clearTimeout(timer);
|
||||||
}, [checkedStates])
|
}, [checkedStates]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (firstRenderRef.current) {
|
if (firstRenderRef.current) {
|
||||||
@@ -125,7 +110,7 @@ const ListMenu: React.FC = () => {
|
|||||||
}
|
}
|
||||||
if (!menu.items[selected]?.values) return;
|
if (!menu.items[selected]?.values) return;
|
||||||
const timer = setTimeout(() => {
|
const timer = setTimeout(() => {
|
||||||
fetchNui('changeIndex', [selected, indexStates[selected], checkedStates[selected]]).catch();
|
fetchNui('changeIndex', [selected, indexStates[selected]]).catch();
|
||||||
}, 100);
|
}, 100);
|
||||||
return () => clearTimeout(timer);
|
return () => clearTimeout(timer);
|
||||||
}, [indexStates]);
|
}, [indexStates]);
|
||||||
@@ -139,7 +124,15 @@ const ListMenu: React.FC = () => {
|
|||||||
listRefs.current[selected]?.focus({ preventScroll: true });
|
listRefs.current[selected]?.focus({ preventScroll: true });
|
||||||
// debounces the callback to avoid spam
|
// debounces the callback to avoid spam
|
||||||
const timer = setTimeout(() => {
|
const timer = setTimeout(() => {
|
||||||
fetchNui('changeSelected', [selected, indexStates[selected], checkedStates[selected]]).catch();
|
fetchNui('changeSelected', [
|
||||||
|
selected,
|
||||||
|
menu.items[selected].values
|
||||||
|
? indexStates[selected]
|
||||||
|
: menu.items[selected].checked
|
||||||
|
? checkedStates[selected]
|
||||||
|
: null,
|
||||||
|
menu.items[selected].values ? 'isScroll' : menu.items[selected].checked ? 'isCheck' : null,
|
||||||
|
]).catch();
|
||||||
}, 100);
|
}, 100);
|
||||||
return () => clearTimeout(timer);
|
return () => clearTimeout(timer);
|
||||||
}, [selected, menu]);
|
}, [selected, menu]);
|
||||||
@@ -224,7 +217,13 @@ const ListMenu: React.FC = () => {
|
|||||||
{menu.items.map((item, index) => (
|
{menu.items.map((item, index) => (
|
||||||
<React.Fragment key={`menu-item-${index}`}>
|
<React.Fragment key={`menu-item-${index}`}>
|
||||||
{item.label && (
|
{item.label && (
|
||||||
<ListItem index={index} item={item} scrollIndex={indexStates[index]} checked={checkedStates[index]} ref={listRefs} />
|
<ListItem
|
||||||
|
index={index}
|
||||||
|
item={item}
|
||||||
|
scrollIndex={indexStates[index]}
|
||||||
|
checked={checkedStates[index]}
|
||||||
|
ref={listRefs}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
))}
|
))}
|
||||||
|
|||||||
Reference in New Issue
Block a user