Files
ox_lib/web/src/features/menu/list/ListItem.tsx

127 lines
3.7 KiB
TypeScript

import { Box, Group, Stack, Text, Progress } 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';
interface Props {
item: MenuItem;
index: number;
scrollIndex: number;
checked: boolean;
}
const useStyles = createStyles((theme, params: { iconColor?: string }) => ({
buttonContainer: {
backgroundColor: theme.colors.dark[6],
borderRadius: theme.radius.md,
padding: 2,
height: 60,
scrollMargin: 8,
'&:focus': {
backgroundColor: theme.colors.dark[4],
outline: 'none',
},
},
buttonWrapper: {
paddingLeft: 5,
paddingRight: 12,
height: '100%',
},
iconContainer: {
display: 'flex',
alignItems: 'center',
},
icon: {
fontSize: 24,
color: params.iconColor || theme.colors.dark[2],
},
label: {
color: theme.colors.dark[2],
textTransform: 'uppercase',
fontSize: 12,
verticalAlign: 'middle',
},
chevronIcon: {
fontSize: 14,
color: theme.colors.dark[2],
},
scrollIndexValue: {
color: theme.colors.dark[2],
textTransform: 'uppercase',
fontSize: 14,
},
progressStack: {
width: '100%',
marginRight: 5,
},
progressLabel: {
verticalAlign: 'middle',
marginBottom: 3,
},
}));
const ListItem = forwardRef<Array<HTMLDivElement | null>, Props>(({ item, index, scrollIndex, checked }, ref) => {
const { classes } = useStyles({ iconColor: item.iconColor });
return (
<Box
tabIndex={index}
className={classes.buttonContainer}
key={`item-${index}`}
ref={(element: HTMLDivElement) => {
if (ref)
// @ts-ignore i cba
return (ref.current = [...ref.current, element]);
}}
>
<Group spacing={15} noWrap className={classes.buttonWrapper}>
{item.icon && (
<Box className={classes.iconContainer}>
<FontAwesomeIcon icon={item.icon} className={classes.icon} fixedWidth />
</Box>
)}
{Array.isArray(item.values) ? (
<Group position="apart" w="100%">
<Stack spacing={0} justify="space-between">
<Text className={classes.label}>{item.label}</Text>
<Text>
{typeof item.values[scrollIndex] === 'object'
? // @ts-ignore for some reason even checking the type TS still thinks it's a string
item.values[scrollIndex].label
: item.values[scrollIndex]}
</Text>
</Stack>
<Group spacing={1} position="center">
<FontAwesomeIcon icon="chevron-left" className={classes.chevronIcon} />
<Text className={classes.scrollIndexValue}>
{scrollIndex + 1}/{item.values.length}
</Text>
<FontAwesomeIcon icon="chevron-right" className={classes.chevronIcon} />
</Group>
</Group>
) : item.checked !== undefined ? (
<Group position="apart" w="100%">
<Text>{item.label}</Text>
<CustomCheckbox checked={checked}></CustomCheckbox>
</Group>
) : item.progress !== undefined ? (
<Stack className={classes.progressStack} spacing={0}>
<Text className={classes.progressLabel}>{item.label}</Text>
<Progress
value={item.progress}
color={item.colorScheme || 'dark.0'}
styles={(theme) => ({ root: { backgroundColor: theme.colors.dark[3] } })}
/>
</Stack>
) : (
<Text>{item.label}</Text>
)}
</Group>
</Box>
);
});
export default React.memo(ListItem);