refactor(web/menu): improve menu focus handling

This commit is contained in:
Luke
2022-07-27 10:50:37 +02:00
committed by Luke
parent 303d81c196
commit 933acd2852

View File

@@ -20,6 +20,12 @@ debugData<MenuSettings>([
{ label: "Option 1", value: "option1" }, { label: "Option 1", value: "option1" },
{ label: "Option 2", value: "option2" }, { label: "Option 2", value: "option2" },
{ label: "Vehicle class", value: ["Nice", "Super nice", "Extra nice"] }, { label: "Vehicle class", value: ["Nice", "Super nice", "Extra nice"] },
{ label: "Option 1", value: "option1" },
{ label: "Option 2", value: "option2" },
{ label: "Vehicle class", value: ["Nice", "Super nice", "Extra nice"] },
{ label: "Option 1", value: "option1" },
{ label: "Option 2", value: "option2" },
{ label: "Vehicle class", value: ["Nice", "Super nice", "Extra nice"] },
], ],
}, },
}, },
@@ -33,18 +39,21 @@ const ListMenu: React.FC = () => {
}); });
const [selected, setSelected] = useState(0); const [selected, setSelected] = useState(0);
const [visible, setVisible] = useState(false); const [visible, setVisible] = useState(false);
const listRefs = useRef<Array<HTMLDivElement | null>>([]);
const moveMenu = (e: KeyboardEvent) => { const moveMenu = (e: KeyboardEvent) => {
switch (e.code) { switch (e.code) {
case "ArrowDown": case "ArrowDown":
setSelected((selected) => { setSelected((selected) => {
if (selected >= menu.items.length - 1) return selected; if (selected >= menu.items.length - 1) return selected;
listRefs.current[selected + 1]?.focus();
return selected + 1; return selected + 1;
}); });
break; break;
case "ArrowUp": case "ArrowUp":
setSelected((selected) => { setSelected((selected) => {
if (selected <= 0) return selected; if (selected <= 0) return selected;
listRefs.current[selected - 1]?.focus();
return selected - 1; return selected - 1;
}); });
break; break;
@@ -67,7 +76,9 @@ const ListMenu: React.FC = () => {
<> <>
<Box <Box
width="sm" width="sm"
height="md" height="fit-content"
maxHeight={480}
overflow="hidden"
borderRadius="md" borderRadius="md"
bg="#141517" bg="#141517"
position="absolute" position="absolute"
@@ -80,24 +91,28 @@ const ListMenu: React.FC = () => {
left={menu.position === "bottom-left" ? 1 : undefined} left={menu.position === "bottom-left" ? 1 : undefined}
bottom={menu.position === "bottom-left" || menu.position === "bottom-right" ? 1 : undefined} bottom={menu.position === "bottom-left" || menu.position === "bottom-right" ? 1 : undefined}
> >
<Box p={2} textAlign="center" borderTopLeftRadius="md" borderTopRightRadius="md"> <Box p={3} textAlign="center" borderTopLeftRadius="md" borderTopRightRadius="md" bg="#25262B">
<Text fontSize={24} textTransform="uppercase" fontWeight={500}> <Text fontSize={24} textTransform="uppercase" fontWeight={300} fontFamily="Poppins">
{menu.title} {menu.title}
</Text> </Text>
</Box> </Box>
<Stack direction="column" p={2}> <Stack direction="column" p={2} overflowY="scroll">
{menu.items.map((item, index) => ( {menu.items.map((item, index) => (
<Box <Box
bg={index !== selected ? "#25262B" : "#373A40"} bg="#25262B"
borderRadius="md" borderRadius="md"
tabIndex={index} tabIndex={index}
p={5} pointerEvents="none"
p={2}
height="60px"
key={`item-${index}`} key={`item-${index}`}
_focus={{ bg: "#373A40", outline: "none" }}
ref={(element) => (listRefs.current = [...listRefs.current, element])}
> >
{Array.isArray(item.value) ? ( {Array.isArray(item.value) ? (
<Flex justifyContent="center" alignItems="center"> <Flex justifyContent="center" alignItems="center">
<Stack spacing={1}> <Stack spacing={1}>
<Text color="#909296" textTransform="uppercase" fontSize={12}> <Text color="#909296" textTransform="uppercase" fontSize={12} verticalAlign="middle">
{item.label} {item.label}
</Text> </Text>
<Text>Nice cool</Text> <Text>Nice cool</Text>