Move List/Map toggle to floating overlay on map panel

- View toggle: floating in top-left of map panel with shadow + paper bg
- Control bar: just Filters + Sort (consistent heights, no overflow)
- Results count: bumped mt from 1 to 2 for more breathing room
- Both ProvidersStep and VenueStep updated

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-31 17:21:06 +11:00
parent e67c6342e9
commit 7b8cb65a63
2 changed files with 124 additions and 104 deletions

View File

@@ -305,23 +305,69 @@ export const ProvidersStep: React.FC<ProvidersStepProps> = ({
onBack={onBack} onBack={onBack}
sx={sx} sx={sx}
secondaryPanel={ secondaryPanel={
mapPanel || ( <Box sx={{ position: 'relative', flex: 1, display: 'flex' }}>
<Box {/* Floating view toggle */}
<ToggleButtonGroup
value={viewMode}
exclusive
onChange={(_, val) => val && onViewModeChange?.(val as ListViewMode)}
size="small"
aria-label="View mode"
sx={{ sx={{
bgcolor: 'var(--fa-color-surface-cool)', position: 'absolute',
flex: 1, top: 12,
display: 'flex', left: 12,
alignItems: 'center', zIndex: 1,
justifyContent: 'center', bgcolor: 'background.paper',
borderLeft: '1px solid', boxShadow: 'var(--fa-shadow-md)',
borderColor: 'divider', borderRadius: 1,
'& .MuiToggleButton-root': {
px: 1.5,
py: 0.5,
fontSize: '0.75rem',
fontWeight: 500,
gap: 0.5,
border: '1px solid',
borderColor: 'divider',
textTransform: 'none',
'&.Mui-selected': {
bgcolor: 'var(--fa-color-brand-100)',
color: 'primary.main',
borderColor: 'primary.main',
'&:hover': { bgcolor: 'var(--fa-color-brand-200)' },
},
},
}} }}
> >
<Typography variant="body1" color="text.secondary"> <ToggleButton value="list" aria-label="List view">
Map coming soon <ViewListOutlinedIcon sx={{ fontSize: 16 }} />
</Typography> List
</Box> </ToggleButton>
) <ToggleButton value="map" aria-label="Map view">
<MapOutlinedIcon sx={{ fontSize: 16 }} />
Map
</ToggleButton>
</ToggleButtonGroup>
{/* Map content */}
{mapPanel || (
<Box
sx={{
flex: 1,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
bgcolor: 'var(--fa-color-surface-cool)',
borderLeft: '1px solid',
borderColor: 'divider',
}}
>
<Typography variant="body1" color="text.secondary">
Map coming soon
</Typography>
</Box>
)}
</Box>
} }
> >
{/* Heading — scrolls with listings */} {/* Heading — scrolls with listings */}
@@ -371,7 +417,7 @@ export const ProvidersStep: React.FC<ProvidersStepProps> = ({
sx={{ mb: 1.5 }} sx={{ mb: 1.5 }}
/> />
{/* Control bar — view toggle, filters, sort on one line */} {/* Control bar — filters + sort */}
<Box <Box
sx={{ sx={{
display: 'flex', display: 'flex',
@@ -379,42 +425,6 @@ export const ProvidersStep: React.FC<ProvidersStepProps> = ({
gap: 1, gap: 1,
}} }}
> >
{/* View toggle */}
<ToggleButtonGroup
value={viewMode}
exclusive
onChange={(_, val) => val && onViewModeChange?.(val as ListViewMode)}
size="small"
aria-label="View mode"
sx={{
'& .MuiToggleButton-root': {
px: 1.5,
py: 0.5,
fontSize: '0.75rem',
fontWeight: 500,
gap: 0.5,
border: '1px solid',
borderColor: 'divider',
textTransform: 'none',
'&.Mui-selected': {
bgcolor: 'var(--fa-color-brand-100)',
color: 'primary.main',
borderColor: 'primary.main',
'&:hover': { bgcolor: 'var(--fa-color-brand-200)' },
},
},
}}
>
<ToggleButton value="list" aria-label="List view">
<ViewListOutlinedIcon sx={{ fontSize: 16 }} />
List
</ToggleButton>
<ToggleButton value="map" aria-label="Map view">
<MapOutlinedIcon sx={{ fontSize: 16 }} />
Map
</ToggleButton>
</ToggleButtonGroup>
{/* Filters */} {/* Filters */}
<FilterPanel activeCount={activeCount} onClear={handleClear}> <FilterPanel activeCount={activeCount} onClear={handleClear}>
{/* ── Location ── */} {/* ── Location ── */}
@@ -631,7 +641,7 @@ export const ProvidersStep: React.FC<ProvidersStepProps> = ({
<Typography <Typography
variant="caption" variant="caption"
color="text.secondary" color="text.secondary"
sx={{ mt: 1, display: 'block' }} sx={{ mt: 2, display: 'block' }}
aria-live="polite" aria-live="polite"
> >
{providers.length} provider{providers.length !== 1 ? 's' : ''} found {providers.length} provider{providers.length !== 1 ? 's' : ''} found

View File

@@ -249,23 +249,69 @@ export const VenueStep: React.FC<VenueStepProps> = ({
onBack={onBack} onBack={onBack}
sx={sx} sx={sx}
secondaryPanel={ secondaryPanel={
mapPanel || ( <Box sx={{ position: 'relative', flex: 1, display: 'flex' }}>
<Box {/* Floating view toggle */}
<ToggleButtonGroup
value={viewMode}
exclusive
onChange={(_, val) => val && onViewModeChange?.(val as ListViewMode)}
size="small"
aria-label="View mode"
sx={{ sx={{
bgcolor: 'var(--fa-color-surface-cool)', position: 'absolute',
flex: 1, top: 12,
display: 'flex', left: 12,
alignItems: 'center', zIndex: 1,
justifyContent: 'center', bgcolor: 'background.paper',
borderLeft: '1px solid', boxShadow: 'var(--fa-shadow-md)',
borderColor: 'divider', borderRadius: 1,
'& .MuiToggleButton-root': {
px: 1.5,
py: 0.5,
fontSize: '0.75rem',
fontWeight: 500,
gap: 0.5,
border: '1px solid',
borderColor: 'divider',
textTransform: 'none',
'&.Mui-selected': {
bgcolor: 'var(--fa-color-brand-100)',
color: 'primary.main',
borderColor: 'primary.main',
'&:hover': { bgcolor: 'var(--fa-color-brand-200)' },
},
},
}} }}
> >
<Typography variant="body1" color="text.secondary"> <ToggleButton value="list" aria-label="List view">
Map coming soon <ViewListOutlinedIcon sx={{ fontSize: 16 }} />
</Typography> List
</Box> </ToggleButton>
) <ToggleButton value="map" aria-label="Map view">
<MapOutlinedIcon sx={{ fontSize: 16 }} />
Map
</ToggleButton>
</ToggleButtonGroup>
{/* Map content */}
{mapPanel || (
<Box
sx={{
flex: 1,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
bgcolor: 'var(--fa-color-surface-cool)',
borderLeft: '1px solid',
borderColor: 'divider',
}}
>
<Typography variant="body1" color="text.secondary">
Map coming soon
</Typography>
</Box>
)}
</Box>
} }
> >
{/* Heading — scrolls with listings */} {/* Heading — scrolls with listings */}
@@ -315,7 +361,7 @@ export const VenueStep: React.FC<VenueStepProps> = ({
sx={{ mb: 1.5 }} sx={{ mb: 1.5 }}
/> />
{/* Control bar — view toggle, filters, sort on one line */} {/* Control bar — filters + sort */}
<Box <Box
sx={{ sx={{
display: 'flex', display: 'flex',
@@ -323,42 +369,6 @@ export const VenueStep: React.FC<VenueStepProps> = ({
gap: 1, gap: 1,
}} }}
> >
{/* View toggle */}
<ToggleButtonGroup
value={viewMode}
exclusive
onChange={(_, val) => val && onViewModeChange?.(val as ListViewMode)}
size="small"
aria-label="View mode"
sx={{
'& .MuiToggleButton-root': {
px: 1.5,
py: 0.5,
fontSize: '0.75rem',
fontWeight: 500,
gap: 0.5,
border: '1px solid',
borderColor: 'divider',
textTransform: 'none',
'&.Mui-selected': {
bgcolor: 'var(--fa-color-brand-100)',
color: 'primary.main',
borderColor: 'primary.main',
'&:hover': { bgcolor: 'var(--fa-color-brand-200)' },
},
},
}}
>
<ToggleButton value="list" aria-label="List view">
<ViewListOutlinedIcon sx={{ fontSize: 16 }} />
List
</ToggleButton>
<ToggleButton value="map" aria-label="Map view">
<MapOutlinedIcon sx={{ fontSize: 16 }} />
Map
</ToggleButton>
</ToggleButtonGroup>
{/* Filters */} {/* Filters */}
<FilterPanel activeCount={activeCount} onClear={handleClear}> <FilterPanel activeCount={activeCount} onClear={handleClear}>
{/* ── Location ── */} {/* ── Location ── */}
@@ -514,7 +524,7 @@ export const VenueStep: React.FC<VenueStepProps> = ({
<Typography <Typography
variant="caption" variant="caption"
color="text.secondary" color="text.secondary"
sx={{ mt: 1, display: 'block' }} sx={{ mt: 2, display: 'block' }}
aria-live="polite" aria-live="polite"
> >
{venues.length} venue{venues.length !== 1 ? 's' : ''} {venues.length} venue{venues.length !== 1 ? 's' : ''}