diff --git a/src/components/atoms/MapPin/MapPin.tsx b/src/components/atoms/MapPin/MapPin.tsx index 06c511d..5eb54eb 100644 --- a/src/components/atoms/MapPin/MapPin.tsx +++ b/src/components/atoms/MapPin/MapPin.tsx @@ -25,7 +25,7 @@ export interface MapPinProps { const PIN_PX = 'var(--fa-map-pin-padding-x)'; const PIN_RADIUS = 'var(--fa-map-pin-border-radius)'; const NUB_SIZE = 'var(--fa-map-pin-nub-size)'; -const MAX_WIDTH = 180; +const MAX_WIDTH = 210; // ─── Colour sets ──────────────────────────────────────────────────────────── @@ -141,22 +141,46 @@ export const MapPin = React.forwardRef( boxShadow: 'var(--fa-shadow-sm)', }} > - {/* Name */} + {/* Name row — verified icon (left) + name */} - {name} + {verified && ( + // Inline SVG of Material's Verified (outlined) icon. Kept as + // inline SVG because MapPin is mounted via createRoot outside + // the MUI ThemeProvider, so @mui/icons-material wouldn't pick + // up theme defaults. + + + + )} + + {name} + {/* Price line */} diff --git a/src/components/molecules/FilterPanel/FilterPanel.tsx b/src/components/molecules/FilterPanel/FilterPanel.tsx index 84a63d7..807638a 100644 --- a/src/components/molecules/FilterPanel/FilterPanel.tsx +++ b/src/components/molecules/FilterPanel/FilterPanel.tsx @@ -77,8 +77,14 @@ export const FilterPanel = React.forwardRef( title={label} footer={ - {onClear && activeCount > 0 ? ( - ) : ( diff --git a/src/components/pages/ProvidersStep/ProvidersStep.tsx b/src/components/pages/ProvidersStep/ProvidersStep.tsx index 11fa31a..160805e 100644 --- a/src/components/pages/ProvidersStep/ProvidersStep.tsx +++ b/src/components/pages/ProvidersStep/ProvidersStep.tsx @@ -337,44 +337,6 @@ export const ProvidersStep: React.FC = ({ * and the mobile-map floating FilterPanel. */ const filterDialogChildren = ( <> - {/* ── Location ── */} - - - Location - - { - const last = newValue[newValue.length - 1] ?? ''; - onSearchChange(typeof last === 'string' ? last : ''); - }} - options={[]} - renderInput={(params) => ( - - - - - {params.InputProps.startAdornment} - - ), - }} - /> - )} - size="small" - /> - - - - {/* ── Service tradition ── */} @@ -407,7 +369,7 @@ export const ProvidersStep: React.FC = ({ selected={filterValues.funeralTypes.includes(option.value)} onClick={() => handleFuneralTypeToggle(option.value)} variant="outlined" - size="small" + size="medium" /> ))} @@ -415,7 +377,8 @@ export const ProvidersStep: React.FC = ({ - {/* ── Provider features ── */} + {/* ── Provider features ── Switch aligned to the first text line so + wrapped labels read cleanly on narrow screens */} = ({ /> } label="Verified providers only" - sx={{ mx: 0 }} + sx={{ + mx: 0, + alignItems: 'flex-start', + '& .MuiFormControlLabel-label': { pt: 0.75 }, + }} /> = ({ /> } label="Online arrangements available" - sx={{ mx: 0 }} + sx={{ + mx: 0, + alignItems: 'flex-start', + '& .MuiFormControlLabel-label': { pt: 0.75 }, + }} /> @@ -510,7 +481,11 @@ export const ProvidersStep: React.FC = ({ if (showMobileMapLayout) { const active = mapActive ?? null; - const drawerOpen = !!(active && (active.provider || active.cluster)); + // Drawer is "open" only when there's an active selection AND the map + // isn't in the middle of its exit animation. Flipping to false on + // `exiting` kicks off the slide-down transform immediately, so the user + // sees the drawer leave as soon as they tap the close X. + const drawerOpen = !!(active && !active.exiting && (active.provider || active.cluster)); const drawerProvider = active?.provider ?? null; const drawerCluster = active?.cluster ?? null; @@ -624,6 +599,7 @@ export const ProvidersStep: React.FC = ({ '& .MuiOutlinedInput-root': { bgcolor: 'background.paper', boxShadow: 'var(--fa-shadow-sm)', + borderRadius: 'var(--fa-button-border-radius-default)', }, '& .MuiOutlinedInput-notchedOutline': { borderColor: 'var(--fa-color-neutral-300)', @@ -710,7 +686,8 @@ export const ProvidersStep: React.FC = ({ ))} - {/* View toggle — icon-only, aligned height with the buttons */} + {/* View toggle — text labels on mobile, aligned height with + the buttons */} = ({ boxShadow: 'var(--fa-shadow-sm)', '& .MuiToggleButton-root': { height: 32, - px: 1, + px: 1.25, py: 0, + textTransform: 'none', + fontSize: '0.8125rem', + fontWeight: 500, borderColor: 'var(--fa-color-neutral-300)', bgcolor: 'background.paper', '&:hover': { bgcolor: 'background.paper' }, @@ -737,10 +717,10 @@ export const ProvidersStep: React.FC = ({ }} > - + List - + Map @@ -771,9 +751,9 @@ export const ProvidersStep: React.FC = ({ borderTopRightRadius: 16, boxShadow: 'var(--fa-shadow-lg)', transform: drawerOpen ? 'translateY(0)' : 'translateY(100%)', - opacity: mapActive?.exiting ? 0 : 1, - transition: 'transform 220ms ease-out, opacity 180ms ease-out', + transition: 'transform 220ms ease-out', pointerEvents: drawerOpen ? 'auto' : 'none', + visibility: drawerOpen || mapActive?.exiting ? 'visible' : 'hidden', }} > {/* Drawer header — holds the close X (and the cluster count when @@ -845,16 +825,21 @@ export const ProvidersStep: React.FC = ({ px: 2, py: 1.25, gap: 1, + // Start-align so the verified icon sits on the + // name's baseline (matches desktop ClusterPopup) + alignItems: 'flex-start', borderBottom: '1px solid', borderColor: 'divider', '&:last-of-type': { borderBottom: 'none' }, '&:hover': { bgcolor: 'var(--fa-color-surface-subtle)' }, }} > - {/* Verified-icon slot (aligns all names) */} + {/* Verified-icon slot — height tuned to the name's + line-box so the tick aligns with the title top */} = ({ )} + {/* Price column — right-aligned "From $X" */} + {p.startingPrice != null && ( + + + From + + + ${p.startingPrice.toLocaleString('en-AU')} + + + )} ))} @@ -938,7 +943,7 @@ export const ProvidersStep: React.FC = ({ sx={sx} secondaryPanel={ - {/* Floating view toggle */} + {/* Floating view toggle — sized to match Filters/Sort buttons */} = ({ zIndex: 1, bgcolor: 'background.paper', boxShadow: 'var(--fa-shadow-md)', - borderRadius: 1, '& .MuiToggleButton-root': { + height: 'var(--fa-button-height-sm)', px: 1.5, - py: 0.5, - fontSize: '0.75rem', + py: 0, + fontSize: '0.8125rem', fontWeight: 500, - gap: 0.5, + gap: 0.75, border: '1px solid', borderColor: 'divider', textTransform: 'none',