diff --git a/src/components/PickItemRow.tsx b/src/components/PickItemRow.tsx index 2080f1e..cc10b92 100644 --- a/src/components/PickItemRow.tsx +++ b/src/components/PickItemRow.tsx @@ -10,9 +10,10 @@ import { IconButton, Stack, Typography, + useMediaQuery, } from '@mui/material'; import { alpha, useTheme } from '@mui/material/styles'; -import useMediaQuery from '@mui/material/useMediaQuery'; +import type React from 'react'; import { useState } from 'react'; import { PickItem } from '../models/PickItem'; import { DEFAULT_BULK_NAME, DEFAULT_UNIT_TYPE, Product } from '../models/Product'; @@ -36,10 +37,10 @@ export const PickItemRow = ({ onStatusChange, onDelete, }: PickItemRowProps) => { + const theme = useTheme(); const [isConfirmOpen, setIsConfirmOpen] = useState(false); const [isControlsOpen, setIsControlsOpen] = useState(false); - const theme = useTheme(); - const isDesktop = useMediaQuery(theme.breakpoints.up('sm')); + const isNarrowScreen = useMediaQuery(theme.breakpoints.down('sm')); const packagingLabel = item.is_carton ? product?.bulk_name ?? DEFAULT_BULK_NAME : product?.unit_type ?? DEFAULT_UNIT_TYPE; @@ -53,7 +54,24 @@ export const PickItemRow = ({ setIsConfirmOpen(false); }; - const openControls = () => setIsControlsOpen(true); + const handleRowClick = () => { + if (isNarrowScreen) { + setIsControlsOpen(true); + } + }; + + const handleRowKeyDown = (event: React.KeyboardEvent) => { + if (!isNarrowScreen) return; + + if (event.key === 'Enter' || event.key === ' ') { + event.preventDefault(); + setIsControlsOpen(true); + } + }; + + const stopPropagation = (event: React.SyntheticEvent) => { + event.stopPropagation(); + }; return ( { - if (event.key === 'Enter' || event.key === ' ') { - event.preventDefault(); - openControls(); - } - }, - } - : undefined)} + onClick={handleRowClick} + role={isNarrowScreen ? 'button' : undefined} + tabIndex={isNarrowScreen ? 0 : undefined} + onKeyDown={handleRowKeyDown} > {product?.name ?? 'Unknown product'} - - {`Qty: ${item.quantity} ${packagingLabel}`} - + {isNarrowScreen && ( + + Tap to adjust quantity and packaging + + )} {isDesktop ? ( @@ -133,7 +144,57 @@ export const PickItemRow = ({ )} - {!isDesktop && ( + {!isNarrowScreen && ( + + { + stopPropagation(event); + onToggleCarton(); + }} + sx={{ + boxShadow: item.is_carton + ? (theme) => `0 0 0 8px ${alpha(theme.palette.primary.main, 0.15)}` + : 'none', + }} + > + + + { + stopPropagation(event); + onDecrementQuantity(); + }} + > + + + { + stopPropagation(event); + onIncrementQuantity(); + }} + > + + + { + stopPropagation(event); + setIsConfirmOpen(true); + }} + aria-label="Delete item" + > + + + + )} + + {isNarrowScreen && ( setIsControlsOpen(false)} @@ -141,39 +202,72 @@ export const PickItemRow = ({ maxWidth="xs" aria-labelledby="item-controls-title" > - + {product?.name ?? 'Unknown product'} - setIsControlsOpen(false)}> + { + stopPropagation(event); + setIsControlsOpen(false); + }} + > - {`Quantity: ${item.quantity} ${packagingLabel}`} + Quantity: {item.quantity} {packagingLabel} { + stopPropagation(event); + onToggleCarton(); + }} sx={{ boxShadow: item.is_carton - ? (dialogTheme) => `0 0 0 8px ${alpha(dialogTheme.palette.primary.main, 0.15)}` + ? (theme) => `0 0 0 8px ${alpha(theme.palette.primary.main, 0.15)}` : 'none', }} > - + { + stopPropagation(event); + onDecrementQuantity(); + }} + > - + { + stopPropagation(event); + onIncrementQuantity(); + }} + > - setIsConfirmOpen(true)} aria-label="Delete item"> + { + stopPropagation(event); + setIsConfirmOpen(true); + }} + aria-label="Delete item" + > @@ -198,7 +292,12 @@ export const PickItemRow = ({ -