Batch 2: List-map layout rework — 420px fixed column, sticky headers
- WizardLayout ListMapLayout: 420px fixed left column (D-B), flex:1 right panel, back link rendered inside left panel instead of above the split (eliminates gap above map) - LAYOUT_MAP type updated to accept backLink prop for list-map variant - ProvidersStep: heading + search + filters wrapped in sticky Box that pins at top of scrollable left panel while card list scrolls - VenueStep: same sticky header treatment, heading moved inside form for consistent wrapper structure Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -146,50 +146,62 @@ export const ProvidersStep: React.FC<ProvidersStepProps> = ({
|
||||
)
|
||||
}
|
||||
>
|
||||
{/* Header */}
|
||||
<Typography variant="display3" component="h1" sx={{ mb: 0.5 }} tabIndex={-1}>
|
||||
Choose a funeral provider
|
||||
</Typography>
|
||||
<Typography variant="body2" color="text.secondary" sx={{ mb: 3 }}>
|
||||
{subheading}
|
||||
</Typography>
|
||||
|
||||
{/* Search bar */}
|
||||
<Box sx={{ mb: 2 }}>
|
||||
<SearchBar
|
||||
value={searchQuery}
|
||||
onChange={onSearchChange}
|
||||
onSearch={onSearch}
|
||||
placeholder="Search providers..."
|
||||
size="small"
|
||||
/>
|
||||
</Box>
|
||||
|
||||
{/* Filter chips */}
|
||||
{filters && filters.length > 0 && (
|
||||
<Box sx={{ display: 'flex', gap: 1, mb: 2, flexWrap: 'wrap' }}>
|
||||
{filters.map((filter, index) => (
|
||||
<Chip
|
||||
key={filter.label}
|
||||
label={filter.label}
|
||||
selected={filter.active}
|
||||
onClick={onFilterToggle ? () => onFilterToggle(index) : undefined}
|
||||
variant="outlined"
|
||||
size="small"
|
||||
/>
|
||||
))}
|
||||
</Box>
|
||||
)}
|
||||
|
||||
{/* Results count */}
|
||||
<Typography
|
||||
variant="caption"
|
||||
color="text.secondary"
|
||||
sx={{ mb: 2, display: 'block' }}
|
||||
aria-live="polite"
|
||||
{/* Sticky header — stays pinned while card list scrolls */}
|
||||
<Box
|
||||
sx={{
|
||||
position: 'sticky',
|
||||
top: 0,
|
||||
zIndex: 1,
|
||||
bgcolor: 'background.default',
|
||||
pb: 1,
|
||||
mx: -3,
|
||||
px: 3,
|
||||
}}
|
||||
>
|
||||
{providers.length} provider{providers.length !== 1 ? 's' : ''} found
|
||||
</Typography>
|
||||
<Typography variant="display3" component="h1" sx={{ mb: 0.5 }} tabIndex={-1}>
|
||||
Choose a funeral provider
|
||||
</Typography>
|
||||
<Typography variant="body2" color="text.secondary" sx={{ mb: 3 }}>
|
||||
{subheading}
|
||||
</Typography>
|
||||
|
||||
{/* Search bar */}
|
||||
<Box sx={{ mb: 2 }}>
|
||||
<SearchBar
|
||||
value={searchQuery}
|
||||
onChange={onSearchChange}
|
||||
onSearch={onSearch}
|
||||
placeholder="Search providers..."
|
||||
size="small"
|
||||
/>
|
||||
</Box>
|
||||
|
||||
{/* Filter chips */}
|
||||
{filters && filters.length > 0 && (
|
||||
<Box sx={{ display: 'flex', gap: 1, mb: 2, flexWrap: 'wrap' }}>
|
||||
{filters.map((filter, index) => (
|
||||
<Chip
|
||||
key={filter.label}
|
||||
label={filter.label}
|
||||
selected={filter.active}
|
||||
onClick={onFilterToggle ? () => onFilterToggle(index) : undefined}
|
||||
variant="outlined"
|
||||
size="small"
|
||||
/>
|
||||
))}
|
||||
</Box>
|
||||
)}
|
||||
|
||||
{/* Results count */}
|
||||
<Typography
|
||||
variant="caption"
|
||||
color="text.secondary"
|
||||
sx={{ mb: 0, display: 'block' }}
|
||||
aria-live="polite"
|
||||
>
|
||||
{providers.length} provider{providers.length !== 1 ? 's' : ''} found
|
||||
</Typography>
|
||||
</Box>
|
||||
|
||||
{/* Error message */}
|
||||
{error && (
|
||||
|
||||
Reference in New Issue
Block a user