From 4de8a916aff2c37f76b52a4c18f52c4d348ebb80 Mon Sep 17 00:00:00 2001 From: Richie Date: Thu, 23 Apr 2026 11:40:14 +1000 Subject: [PATCH] CompareBar: raise above HelpBar, fix centering, responsive sizing on xs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Raise bottom offset from theme.spacing(3) (24px) → theme.spacing(9) (72px) so the pill clears the sticky HelpBar with ~16px breathing. - Centering: swap `left:50%; transform: translateX(-50%)` for `left:0; right:0; mx:auto; width:fit-content`. Slide (the wrapper) animates via transform, which was clobbering our centering transform and leaving the bar's left edge at the viewport centre instead of its centre (measured 171px off-centre pre-fix). Auto-margin centering doesn't fight Slide's animation. - Mobile sizing: responsive step-down on xs — - Badge: large (32px) → medium (26px) - Typography: body1 (16px) → body2 (14px) - Button: medium (40px) → small (32px) - Container: gap 2→1.5, px 3→2, py 1.5→1 md+ keeps the larger sizes from the earlier bump. Rejected alternatives: slide/peek collapsed-state (adds interaction cost and hides state behind a tap — bad for FA's grief-sensitive audience); full-width bottom bar (loses the "floating reminder" pill character). Co-Authored-By: Claude Opus 4.7 (1M context) --- .../molecules/CompareBar/CompareBar.tsx | 42 +++++++++++++------ 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/src/components/molecules/CompareBar/CompareBar.tsx b/src/components/molecules/CompareBar/CompareBar.tsx index 2f55695..1bcd6dc 100644 --- a/src/components/molecules/CompareBar/CompareBar.tsx +++ b/src/components/molecules/CompareBar/CompareBar.tsx @@ -1,7 +1,8 @@ import React from 'react'; import Paper from '@mui/material/Paper'; import Slide from '@mui/material/Slide'; -import type { SxProps, Theme } from '@mui/material/styles'; +import useMediaQuery from '@mui/material/useMediaQuery'; +import { useTheme, type SxProps, type Theme } from '@mui/material/styles'; import { Typography } from '../../atoms/Typography'; import { Button } from '../../atoms/Button'; import { Badge } from '../../atoms/Badge'; @@ -42,6 +43,8 @@ export interface CompareBarProps { */ export const CompareBar = React.forwardRef( ({ packages, onCompare, error, sx }, ref) => { + const theme = useTheme(); + const isMobile = useMediaQuery(theme.breakpoints.down('md')); const count = packages.length; const visible = count > 0; const canCompare = count >= 2; @@ -59,29 +62,42 @@ export const CompareBar = React.forwardRef( sx={[ (theme: Theme) => ({ position: 'fixed', - bottom: theme.spacing(3), - left: '50%', - transform: 'translateX(-50%)', + // Clear the sticky HelpBar (~56px + 16px breathing) so the + // pill doesn't overlap it. + bottom: theme.spacing(9), + // Centre via auto-margin rather than `left:50%; translateX(-50%)` + // — Slide (the wrapper) animates via transform, which would + // otherwise clobber the centering transform. + left: 0, + right: 0, + mx: 'auto', + width: 'fit-content', zIndex: theme.zIndex.snackbar, borderRadius: '9999px', display: 'flex', alignItems: 'center', - gap: 2, - px: 3, - py: 1.5, + gap: { xs: 1.5, md: 2 }, + px: { xs: 2, md: 3 }, + py: { xs: 1, md: 1.5 }, maxWidth: { xs: 'calc(100vw - 32px)', md: 460 }, }), ...(Array.isArray(sx) ? sx : [sx]), ]} > - {/* Fraction badge — 1/3, 2/3, 3/3 */} - + {/* Fraction badge — 1/3, 2/3, 3/3. Responsive: medium on xs, + large on md+ to match the rest of the bar's size step. */} + {count}/3 - {/* Status text */} + {/* Status text — body2 on mobile (smaller footprint), body1 on md+ */} ( {error || statusText} - {/* Compare CTA — icon dropped; label alone at medium size is enough */} + {/* Compare CTA — small (32px) on mobile, medium (40px) on md+ */}