Skip to content

feat(shared): Buttons V2 migration · PR 1 — engagement bars (CardAction)#5969

Open
tsahimatsliah wants to merge 3 commits intomainfrom
feat/buttons-v2-migration
Open

feat(shared): Buttons V2 migration · PR 1 — engagement bars (CardAction)#5969
tsahimatsliah wants to merge 3 commits intomainfrom
feat/buttons-v2-migration

Conversation

@tsahimatsliah
Copy link
Copy Markdown
Member

@tsahimatsliah tsahimatsliah commented May 3, 2026

Summary

PR 1 of 4 in the v2 button system migration tracked in #5940. Migrates every v1 QuaternaryButton engagement-row caller in the shared package to CardAction / CardActionBar, plus a 1-commit prerequisite that aligns MedalBadgeIcon with the project-wide icon convention so the v2 toggle pattern (iconPressed=, secondary={isActive}) reads correctly across surfaces.

Out of scope (later PRs):

  • PR 2: every remaining v1 Button caller in packages/shared/
  • PR 3: every v1 Button caller in packages/webapp/ + packages/extension/
  • PR 4: enable no-raw-button-class, delete v1 Button / QuaternaryButton / specs / CSS / tokens

Commits

  1. chore(shared): align MedalBadgeIcon with IconPrimary outlined convention — flips the MedalBadgeIcon primary/secondary slots and updates every explicit caller to preserve the existing rendered visual. Closes the v1→v2 known follow-up feat: about modal #4 from feat: v2 button system (ButtonV2, CardAction) + /dev/buttons review surface #5940.
  2. feat(shared): migrate every engagement bar to CardAction / CardActionBar — rewrites the engagement-bar surfaces below.

Files migrated

Surface File New layout
Post-detail strip packages/shared/src/components/post/PostActions.tsx CardActionBar layout="between" + comfortable density, ResizeObserver label collapse via new shared usePostActionsLabelVisibility hook
Mobile sticky bar packages/shared/src/components/post/MobilePostFloatingBar.tsx CardActionBar layout="between"
Award affordance packages/shared/src/components/post/PostAwardAction.tsx CardAction (icon swap + featured-award Image thumbnail)
Bookmark primitive packages/shared/src/components/buttons/BookmarkButton.tsx CardAction with state-aware aria-label (BookmarkRemove bookmark) and reminder dropdown
Feed grid / list / signal cards packages/shared/src/components/cards/common/ActionButtons.tsx CardActionBar layout="feedCard" + density compact (matches the production 272–340 px feed-card width clamp)
Reader desktop rail packages/shared/src/components/post/reader/ReaderRailActionBar.tsx CardActionBar layout="between"
Reader floating bar packages/shared/src/components/post/reader/ReaderFloatingActionBar.tsx CardActionBar layout="default" + density compact
Comment row packages/shared/src/components/comments/CommentActionButtons.tsx CardActionBar layout="compact" + density compact; menu trigger upgraded to ButtonV2
Profile hot-take row packages/shared/src/features/profile/components/hotTakes/HotTakeItem.tsx CardAction upvote, ButtonV2 edit/delete

Supporting changes:

  • packages/shared/src/components/buttons/CardActionBar.tsx — wrapped in forwardRef so consumers can attach a ref to the bar (used by PostActions for ResizeObserver).
  • packages/shared/src/components/buttons/CardAction.tsx — extends the underlying button/anchor HTMLAttributes so call sites can keep their existing id, data-*, aria-* props.
  • packages/shared/src/components/post/usePostActionsLabelVisibility.ts — new shared hook that mirrors the v1 ResizeObserver-driven label-collapse mechanic.

Verification

  • pnpm --filter @dailydotdev/shared lint
  • pnpm --filter webapp lint
  • pnpm --filter extension lint
  • pnpm --filter @dailydotdev/shared test ✅ — 1511/1511 pass (Feed, ActionButtons, ArticleGrid, ShareGrid, CollectionGrid, SocialTwitterGrid, CommentActionButtons all green)
  • pnpm --filter webapp build ✅ TypeScript / Next compile pass; SSG prerender for /gear fails with getaddrinfo ENOTFOUND api.local.fylla.dev — environmental, unrelated to this PR.
  • No new strict type errors in node ./scripts/typecheck-strict-changed.js (verified by stash + re-run on origin/main — the CommentAwardActions / PostAwardAction / ProfileActions / analytics page errors all pre-exist on main).

Manual test URLs (preview domain)

Test on *.preview.app.daily.dev once the preview is live:

  • /posts/{any-post-id} — post-detail action bar (Upvote / Downvote / Comment / Award / Bookmark / Copy). Resize the column to confirm responsive label collapse still works.
  • / (For You / popular feed), /upvoted, /discussed — feed-card engagement bar, in both grid (multi-column) and list density.
  • /bookmarks — bookmark feed.
  • /squads/{handle}/post/{post-id} — comment thread row actions (Upvote / Downvote / Reply / Share / Award / Options).
  • /{username}/posts, /{username}/upvoted, /{username}/replies — profile activity tabs (feed-card engagement bar).
  • /{username}/hottakes — hot-take row Upvote affordance + owner edit/delete buttons.
  • Mobile viewport (resize to <420 px) on any post → confirm MobilePostFloatingBar and label collapse.
  • Open the reader modal on any post (/posts/{id} web) → confirm desktop rail (ReaderRailActionBar) + floating bottom bar (ReaderFloatingActionBar).
  • /dev/buttonsPostActionsV2 vignette is now the contract production matches; visual diff against PostActionsV1Clone should still hold.

What I did NOT do here (reserved for later PRs)

  • Did not enable no-raw-button-class ESLint rule.
  • Did not delete v1 Button / QuaternaryButton / specs / CSS — they remain as the safety net while PRs 2 & 3 land.
  • Did not touch any non-engagement-bar v1 Button callers in shared / webapp / extension.

Made-with: Cursor

Made with Cursor

Preview domain

https://feat-buttons-v2-migration.preview.app.daily.dev

tsahimatsliah and others added 2 commits May 3, 2026 17:15
Flips MedalBadgeIcon to follow the project-wide convention every other
icon ships with (IconPrimary={Outlined}, IconSecondary={Filled}). Was
the only icon in the codebase with the props reversed, which made the
toggle pattern (`secondary={isActive}` and ButtonV2's `iconPressed`)
behave inverted against the surrounding icon family.

Updates every explicit caller to preserve the existing rendered visual:
- Strips `secondary` from sites that were rendering the outlined art
  (NotificationItemAvatar top-reader badge, LiveRoomTileActions award,
  ProfileActions award button, AwardButton, PostAnalytics + SquadAnalytics
  Awards stat tile, CommentAwardActions count badge, UserEngagementSections
  badge chip, Leaderboard RankBadge / TopRankBadge).
- Adds `secondary` where the site rendered the filled art and depended on
  the previous default (OpportunityBenefits "Private until you say yes",
  ProfileAchievements + AchievementsWidget header glyph,
  AchievementTrackerButton fallback, game-center DataTile awards).
- Inverts `secondary={!awarded}` to `secondary={!!awarded}` on
  ReaderRailActionBar so its outline-when-idle / filled-when-awarded
  behaviour stays identical post-flip.
- Updates /dev/buttons OLD vignette to invert its boolean and rewrites
  the NEW CardAction vignette to the cleaner `icon` + `iconPressed`
  pattern (outlined idle, filled pressed) made possible by the flip.

Function-ref usages in the profile/account menus (`icon: MedalBadgeIcon`)
intentionally aren't touched — they pass `secondary={isActive}` through
ProfileSectionItem and now match the rest of the menu's icon family
(outlined when inactive, filled when active).

Prerequisite for the v2 button system migration so consumers can use
`<MedalBadgeIcon />` for the idle/outline state and
`<MedalBadgeIcon secondary />` for the pressed/filled state without
re-fixing the inversion at every CardAction call site.

Made-with: Cursor
Replaces every v1 QuaternaryButton + v1 Button engagement-row caller
in the shared package with the v2 button system:

- packages/shared/src/components/buttons/BookmarkButton.tsx
  rewritten to compose CardAction. New engagement-bar API
  (post + density + pressed + onClick + label + count) replaces the
  v1 buttonProps bag; reminder dropdown still wraps the trigger as
  before. All previous QuaternaryButton call-site noise (icon swap,
  pressed-color tinting, counter slot) now lives inside CardAction.

- packages/shared/src/components/post/PostActions.tsx
  Post-detail action strip now renders CardActionBar layout="between"
  with one CardAction per affordance (Upvote / Downvote / Comment /
  Award / Bookmark / Copy). Adds a new shared
  usePostActionsLabelVisibility hook (extracted from /dev/buttons)
  that mirrors the v1 ResizeObserver-driven label-collapse mechanic
  exactly: every CardAction renders with labelVisible always-on and
  the hook toggles the .card-action-content wrapper hidden class so
  the row collapses to icon-only when it would overflow.

- packages/shared/src/components/post/MobilePostFloatingBar.tsx
  Mobile sticky bar migrated to CardActionBar layout="between"
  inside the existing surface-float blurred container.

- packages/shared/src/components/post/PostAwardAction.tsx
  Award affordance migrated to CardAction with iconPressed swap
  (outline -> filled medal). Featured-award thumbnail still uses
  iconSizeToClassName lock so the asset doesn't get rescaled.

- packages/shared/src/components/cards/common/ActionButtons.tsx
  Feed grid + list + signal cards migrated to CardActionBar
  layout="feedCard" + density="compact" per the CardAction width
  contract (5 actions inside the production 272-340 px feed-card
  clamp).

- packages/shared/src/components/post/reader/ReaderRailActionBar.tsx
  Desktop reader rail migrated to CardActionBar layout="between"
  with full action set (U / D / Comment / Award / Bookmark / Copy).

- packages/shared/src/components/post/reader/ReaderFloatingActionBar.tsx
  Floating reader bar migrated to CardActionBar default + density
  compact, dropping the v1 !h-8 !w-8 !rounded-10 size hacks.

- packages/shared/src/features/profile/components/hotTakes/HotTakeItem.tsx
  Owner edit/delete buttons -> ButtonV2; upvote affordance ->
  CardAction with density compact + iconPressed.

- packages/shared/src/components/comments/CommentActionButtons.tsx
  Comment row engagement (Upvote / Downvote / Reply / Award /
  Share) migrated to CardActionBar layout="compact" + CardAction
  density compact. Options menu trigger upgraded to ButtonV2.

Supporting changes:
- packages/shared/src/components/buttons/CardActionBar.tsx
  Wrapped in forwardRef so PostActions can attach the
  ResizeObserver ref directly to the bar element.
- packages/shared/src/components/buttons/CardAction.tsx
  Extends HTMLAttributes (id, role, aria-*, data-*, type, etc.)
  so call sites can keep the same hooks/IDs they had on v1.

CommentActionButtons.spec.tsx passes (16/16). Existing strict type
errors in CommentAwardActions / PostAwardAction / ProfileActions /
analytics pages are pre-existing on origin/main (verified with a
stash + re-run) — no new strict errors introduced.

Made-with: Cursor
Co-authored-by: Cursor <cursoragent@cursor.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented May 3, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
daily-webapp Ready Ready Preview May 3, 2026 3:04pm
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
storybook Ignored Ignored May 3, 2026 3:04pm

Request Review

… actions

PR 1 made the upvote/downvote `aria-label` on `PostActions` and
`ReaderRailActionBar` state-aware ("Remove upvote" / "More like this") to
mirror the v1 Tooltip *content*. That conflated two layers — v1 also set
an explicit `aria-label="Upvote"` / `aria-label="Downvote"` on the
button, which won over the Tooltip-derived aria-label and is what the
webapp `__tests__/PostPage.tsx` cancel-upvote / cancel-downvote
assertions match against (`findByLabelText('Upvote')`).

Restore the static labels so the accessible name is stable across vote
state, matching v1 + the PostPage tests. Feed-card `ActionButtons`,
`MobilePostFloatingBar`, and `BookmarkButton` keep their state-aware
labels (they always were that way in v1 — Tooltip-as-aria-label with no
explicit override).

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant