fix(cards): free the impressions slot and fit the feed action bar to the min card width - #6394
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
tsahimatsliah
left a comment
There was a problem hiding this comment.
Summary
Three independently sensible fixes, and the two logic ones are correct:
- Award vs impressions gate. Dropping
|| isLaptopis right, and it's fixed in bothActionButtons.tsxandActionButtons.v2.tsxso the two bars agree. isSameUser. Theundefined === undefineddiagnosis holds:if (!canAward && !isSameUser) return null, so an anonymous visitor on an authorless post fell through totrueand rendered the button. I traced the other quadrants — logged-in + authorless was alreadyfalse, and logged-out on an authored post is governed byuseCanAwardUser, which returnsfalsewhenever there's nosendingUser. So the fix is narrow and touches exactly the broken case, in both variants. (Small correction to the description: logged-out visitors were already not seeing it on authored posts; that half wasn't broken.)CardActionBargap removal is contained —layout="feedCard"has exactly one consumer,ActionButtons.v2.
The sizing change is where I'd push back, on one specific case.
Blocking
The control cohort — card_impressions off — is the one layout that wasn't measured, and it's plausibly the widest. With the flag off, the award action still renders, and PostAwardActionV1 hardcodes size={ButtonSize.Small} — it does not take buttonSize from variantConfig. So a control feed card now shows five XSmall buttons next to one Small one. Three consequences:
- Width. The measurements in the description ("tightest case 272px … 4px gap") are for the impressions-on row, which has five actions. Control has six, one of them at the old, larger size, and it can carry its own
numAwardscounter. Since buttons never shrink (flex-shrink: 0), the surplus becomes overflow rather than compression. The new Storybook page only setscard_impressions: truein all six rows, so this case isn't covered there either. - Alignment. "The two bars now have identical internal geometry" isn't true in control — the award button is a size taller and wider than its neighbours.
- Icon size. The un-awarded glyph takes the passed
iconSize(now 16px), but the awarded state is pinned toiconSizeToClassName[IconSize.XSmall](20px), so the same button changes size when a post gets awarded. Its counter also keepslabelClassName="!pl-[1px]"rather than the new sharedcounterLabelClassName.
The fix looks small — thread buttonSize/density into PostAwardActionV1 the way v2 already does with density="tight", and drop the hardcoded XSmall on the awarded image. Either way, please add a card_impressions: false row to the alignment story and re-check 272px, since that's the cohort the sizing change ships to unconditionally.
Non-blocking
1. The useViewSize mock in ActionButtons.spec.tsx is now vestigial and pins one viewport. It's forced to true (laptop), which is the right regression case for the old gate — but with the gate gone, the test no longer proves viewport-independence, and a reintroduced isLaptop check would still pass. describe.each over [false, true] for the viewport, or dropping the mock entirely, would make the assertion match what the fix actually claims.
2. PostAwardAction.spec.tsx doesn't cover logged-out on an authored post — the other half of the description's claim. It's currently protected by useCanAwardUser rather than by this change, so a case pinning it would document which mechanism owns it.
3. Seven Merge branch 'main' commits. Not worth a round trip on its own, but the history is hard to read against the four real commits.
4. CI was still running when I reviewed (install_deps green, everything else pending) — worth a glance before merge, particularly lint_shared given the useViewSize/classNames import churn.
Verification
- Read the PR review guide and code-style rules
- Traced all four auth/author quadrants through
isSameUser+useCanAwardUserin both variants - Checked every consumer of
layout="feedCard"before accepting the gap removal - Compared
PostAwardActionV1's sizing against the newvariantConfigvalues - Read both new specs and the alignment story's feature overrides
- Not measured on the preview — the 272px control-cohort case above is the specific thing I could not rule out from the diff
- CI incomplete at review time
Verdict
Comment — the control-cohort layout needs either a measurement or the size threaded through before merge; everything else is optional.
Reviewed by AI.
75f953c to
48d03e8
Compare
|
Review addressed in 48d03e8, and the branch is rebased onto Blocking — control cohort sizing. You were right that this was the unmeasured case. Blocking — story coverage. Two Measured across all four stat loads at the 272px min card width:
Non-blocking 1 — viewport mock. Non-blocking 2 — logged out on an authored post. Pinned in Non-blocking 3 — merge commits. Rebased away. Non-blocking 4 — CI. Green on the previous push; re-running now. One extraction while I was in there: the counter classes and the two feed-action size constants live in |
`isSameUser` compared `user?.id` to `post?.author?.id`, so an anonymous visitor on a post with no author compared `undefined` to `undefined` and got `true` — the button rendered on exactly the cards where an award is impossible, and stayed hidden on the ones that have an author. It now requires a real logged in id. While here, the action stops hardcoding its own geometry: it takes `buttonSize`/`iconSize` from the caller so it matches the rest of the feed bar, and the awarded image follows that icon size instead of a pinned `IconSize.XSmall`, which used to resize the button once a post was awarded. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The impressions counter sat 5px from the card edge at 320px and 6px past it at the 272px minimum, and the v2 bar pushed its trailing action up to 41px outside the card. Buttons never shrink here (global `flex-shrink: 0`), so six actions with counters have to fit on their intrinsic widths alone, and at the old size they needed up to 288px in a 262px row. - both bars move to 24px buttons with 16px icons, `py-1.5` keeping the row at its previous 36px height, and asymmetric `pl-1 pr-2.5` so the trailing number is not flush with the rounded corner; - v2 gets a `tight` CardAction density for that; `compact` is untouched, so comments, the reader bar, daily votes and hot takes are unaffected; - the `feedCard` CardActionBar layout drops its `gap`, which `justify-between` makes redundant when there is slack and costly when there is not; - awards give up their slot to the impressions stat on every viewport rather than only below laptop, so the two never render side by side. With `card_impressions` off the award action still renders, now at the same size as its neighbours. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
`ActionBarBeforeAfter` puts main's bar next to this branch's at 320px and the 272px minimum, with impressions on and off, for both engagement bar variants; main's side is plain markup so the comparison does not drift when the real component changes. `ActionBarAlignment` renders the after-state across four stat loads. The /dev/buttons vignettes move to the `tight` density so the internal review page documents what the feed ships. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
0f982f7 to
3be24bd
Compare
Two things go wrong on the default feed card once the impressions stat is on, plus one award-button bug that predates it.
1. Impressions and awards competed for the same slot. The gate was
showAwardAction && (!impressionsEnabled || isLaptop), so awards were only dropped below laptop and still rendered on desktop next to the impressions stat. Impressions replace that button, so awards are now hidden on every viewport for grid, list and signal cards in both engagement bar variants.2. The bar did not fit the card. The impressions counter sat 5px from the card edge at 320px and 6px past it at the 272px minimum; the v2 bar pushed its trailing action up to 41px outside the card. Buttons never shrink here (global
flex-shrink: 0), so six actions with counters have to fit on their intrinsic widths alone, and at the old size they needed up to 288px in a 262px row.Both bars now use 24px buttons with 16px icons,
py-1.5keeping the row at its previous 36px height, and asymmetricpl-1 pr-2.5so the trailing number is not flush with the rounded corner. Two supporting changes: atightCardAction density (compactis untouched, so comments, the reader bar, daily votes and hot takes are unaffected), and droppinggap-1from thefeedCardCardActionBar layout — withjustify-betweena gap is redundant when there is slack and pure added width when there is not.3. The award button rendered where an award is impossible.
isSameUsercompareduser?.idtopost?.author?.id, so an anonymous visitor on an authorless post comparedundefinedtoundefinedand gottrue. Logged out on an authored post was already correct —useCanAwardUserreturnsfalsewithout a sending user — and a spec now pins that so it is clear which mechanism owns it. The action also stops hardcodingButtonSize.Small, so it matches its neighbours, and its awarded image follows the icon size instead of a pinnedIconSize.XSmall.With
card_impressionsoff, the award action still renders — now at the same size as the rest of the bar.Measurements
Storybook
Components/Cards/ActionBarBeforeAfterputs main's bar next to this branch's; main's side is plain markup so the comparison does not drift when the real component changes.Components/Cards/ActionBarAlignmentrenders the after-state across 36·3·52.4K, 100·80·100K, 200·80·234.5K and 10K·999·1.2M at both widths, impressions on and off. Every row: 6 actions, uniform 24px, nothing escapes the card, worst gap 1px.Tests
ActionButtons.spec.tsx— both engagement bar variants x both sides of the laptop breakpoint x grid/list/signal: award absent and impressions present when the flag is on, award present when it is off.PostAwardAction.spec.tsx— both variants: visibility across all four auth/author quadrants, plus the button size and the awarded-image size.Rebased onto
mainafter thefeed_card_glass_actionsexperiment was removed in #6470; nothing here touches that code path.🤖 Generated with Claude Code
Preview domain
https://claude-award-button-visibility-c.preview.app.daily.dev