PackageDetail: add inCart state for the Compare button

When a package is already in the comparison basket, the Compare button
swaps to a "In comparison" selected-state: soft brand-50 fill +
brand-300 border + brand-700 text + leading check icon. Technically
disabled (aria-disabled + no onClick) but sx-overrides the default
greyed Mui-disabled look so it reads as "selected/added," not
"unavailable."

Pattern: e-commerce "Added to cart" state. Removal happens via the
floating CompareBar (already owns basket mutation), not this button —
keeps the responsibility split clean.

API:
- PackageDetail: new `inCart?: boolean` prop.
- PackagesStep: forwarded as `isSelectedPackageInCart?: boolean`.
- Demo route (Packages.tsx): computes `basket.has(key)` for the
  current selection and passes it through.

Storybook: new PackageDetail story `InCart` alongside the existing
`Default` and `CompareLoading` states.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-23 10:58:56 +10:00
parent 75832ced24
commit 13bd245872
4 changed files with 70 additions and 13 deletions

View File

@@ -23,11 +23,15 @@ export function PackagesRoute() {
// Compare CTA on the PackageDetail panel just adds the selection to the
// basket. The floating CompareBar (mounted in App.tsx) handles navigation
// once the user has 2+ packages selected.
// and removal once the user has 2+ packages selected.
const handleCompare = () => {
if (selectedId) basket.add(makeBasketKey(provider.id, selectedId));
};
// When the selected package is already in the basket, PackageDetail swaps
// the Compare button into its "In comparison" selected state.
const isSelectedInCart = selectedId ? basket.has(makeBasketKey(provider.id, selectedId)) : false;
// Tier-3 / tier-2 providers show "nearby verified" cards instead of
// "more from this provider".
const secondaryList =
@@ -51,6 +55,7 @@ export function PackagesRoute() {
)
}
onCompare={handleCompare}
isSelectedPackageInCart={isSelectedInCart}
onNearbyPackageClick={(key) => {
const [otherProviderId] = key.split(':');
if (otherProviderId) navigate(`/providers/${otherProviderId}/packages`);