CoffinsStep: rewrite to grid-sidebar ecommerce layout
- Switch from wide-form to grid-sidebar (viewport-locked, independent scroll) - Sidebar: heading, allowance info bubble (conditional), category menu with expandable subcategories, dual-knob price slider with editable inputs, sort by dropdown, clear all filters, save-and-exit link - Grid: coffin cards with thumbnail hover preview, equal-height cards, subtle bg for white-bg product photos, colour count, Most Popular badge - Card click navigates to CoffinDetailsStep (no Continue button) - 20 coffins per page max before pagination - WizardLayout grid-sidebar: wider sidebar (28%), overflowX hidden, vertical scroll at all breakpoints, viewport-lock on desktop only Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -230,31 +230,64 @@ const ListDetailLayout: React.FC<{
|
||||
</Container>
|
||||
);
|
||||
|
||||
/** Grid + Sidebar: ~25% filter sidebar (left) / ~75% card grid (right) */
|
||||
/** Grid + Sidebar: ~25% filter sidebar (left) / ~75% card grid (right).
|
||||
* Viewport-locked on desktop — both panels scroll independently.
|
||||
* On mobile, stacks vertically and scrolls as a single page. */
|
||||
const GridSidebarLayout: React.FC<{
|
||||
children: React.ReactNode;
|
||||
secondaryPanel?: React.ReactNode;
|
||||
}> = ({ children, secondaryPanel }) => (
|
||||
<Container maxWidth="lg" sx={{ flex: 1, py: 3 }}>
|
||||
<Box
|
||||
sx={{
|
||||
display: 'flex',
|
||||
flex: 1,
|
||||
overflow: { md: 'hidden' },
|
||||
flexDirection: { xs: 'column', md: 'row' },
|
||||
maxWidth: 1200,
|
||||
mx: 'auto',
|
||||
width: '100%',
|
||||
}}
|
||||
>
|
||||
{/* Left sidebar — scrollbar visible on hover */}
|
||||
<Box
|
||||
component="aside"
|
||||
sx={{
|
||||
display: 'flex',
|
||||
gap: { xs: 0, md: 3 },
|
||||
flexDirection: { xs: 'column', md: 'row' },
|
||||
width: { xs: '100%', md: '28%' },
|
||||
flexShrink: 0,
|
||||
overflowY: 'auto',
|
||||
overflowX: 'hidden',
|
||||
px: { xs: 2, md: 3 },
|
||||
py: 3,
|
||||
scrollbarWidth: 'thin',
|
||||
scrollbarColor: 'transparent transparent',
|
||||
'&:hover': {
|
||||
scrollbarColor: 'rgba(0,0,0,0.25) transparent',
|
||||
},
|
||||
'&::-webkit-scrollbar': { width: 6 },
|
||||
'&::-webkit-scrollbar-thumb': {
|
||||
background: 'transparent',
|
||||
borderRadius: 3,
|
||||
},
|
||||
'&:hover::-webkit-scrollbar-thumb': {
|
||||
background: 'rgba(0,0,0,0.25)',
|
||||
},
|
||||
}}
|
||||
>
|
||||
<Box
|
||||
component="aside"
|
||||
sx={{
|
||||
width: { xs: '100%', md: '25%' },
|
||||
flexShrink: 0,
|
||||
}}
|
||||
>
|
||||
{children}
|
||||
</Box>
|
||||
<Box sx={{ flex: 1 }}>{secondaryPanel}</Box>
|
||||
{children}
|
||||
</Box>
|
||||
</Container>
|
||||
{/* Right panel — always scrollable */}
|
||||
<Box
|
||||
sx={{
|
||||
flex: 1,
|
||||
overflowY: { md: 'auto' },
|
||||
px: { xs: 2, md: 3 },
|
||||
py: 3,
|
||||
scrollbarWidth: 'thin',
|
||||
}}
|
||||
>
|
||||
{secondaryPanel}
|
||||
</Box>
|
||||
</Box>
|
||||
);
|
||||
|
||||
/** Detail + Toggles: scrollable left (image/desc) / sticky right (info/CTA) */
|
||||
@@ -401,6 +434,10 @@ export const WizardLayout = React.forwardRef<HTMLDivElement, WizardLayoutProps>(
|
||||
height: '100vh',
|
||||
overflow: 'hidden',
|
||||
}),
|
||||
...(variant === 'grid-sidebar' && {
|
||||
height: { xs: 'auto', md: '100vh' },
|
||||
overflow: { xs: 'visible', md: 'hidden' },
|
||||
}),
|
||||
},
|
||||
...(Array.isArray(sx) ? sx : [sx]),
|
||||
]}
|
||||
|
||||
Reference in New Issue
Block a user