feat: migrate webapp + extension v1 Button callers to ButtonV2#5971
Closed
tsahimatsliah wants to merge 10 commits intomainfrom
Closed
feat: migrate webapp + extension v1 Button callers to ButtonV2#5971tsahimatsliah wants to merge 10 commits intomainfrom
tsahimatsliah wants to merge 10 commits intomainfrom
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
9 tasks
b0580ff to
47a7f1e
Compare
47a7f1e to
5b3889d
Compare
5b3889d to
f1c00e1
Compare
f1c00e1 to
0def2a8
Compare
0def2a8 to
e860a3d
Compare
e860a3d to
1414d7c
Compare
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>
… 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>
Three review-feedback fixes for PR 1: - InteractionCounter centred its number against the icon by accident only — the static branch was a `flex flex-col` with the text glued to the top of its 20 px box, so the digit visibly floated above the icon's optical centre. Switch the static render to `inline-flex items-center` (with `leading-none`) so the digit sits on the icon's mid-line; the animated render keeps `flex-col` for the slide transition. - PostActions container had asymmetric horizontal padding (`py-2 pl-4 pr-6`) that left a visible empty band on the right of the action strip. Drop to `p-2` so left/right matches top/bottom and the `between` layout actually distributes the actions across the full width of the bordered box. - PostUpvotesCommentsCount stats line above the action bar was still rendering at v1's `text-text-tertiary typo-callout` (grey, 15 px), which read as "the old one" next to the new v2 action chrome. Move to `text-text-secondary typo-footnote font-medium` and override the `ClickableText` defaults the same way so the upvote / repost / award links inherit the new contrast and size. Co-authored-by: Cursor <cursoragent@cursor.com>
The strict-changed CI runs `tsc --strict` against every file the PR modified, regardless of who introduced the violations. The button migration touched 30+ files purely to swap `Button -> ButtonV2`, `QuaternaryButton -> CardAction`, or to add `secondary` on `MedalBadgeIcon`, but several of those files carry pre-existing strict violations unrelated to the migration: - `comments/CommentAwardActions.tsx` — AwardEntity receiver narrowing - `post/PostAwardAction.tsx` — same - `profile/ProfileActions.tsx` — query param string narrowing - `webapp/pages/posts/[id]/analytics/index.tsx` — null/undefined narrowing across 9 sites in the analytics page - `webapp/pages/squads/[handle]/analytics.tsx` — Squad narrowing All five files were already failing strict on origin/main, verified against a clean `4204abdf9` worktree. Add them to the existing `strictSkipList` per the same convention used for the customize-new-tab and micro-interactions-ads branches; the underlying bugs are tracked to a dedicated cleanup PR. Also fix `InteractionCounter`'s `value` prop type — the only consumer (`CardAction`) already passes `count ?? 0`, so the historical `number | null` was overly broad and caused 7 strict errors that the recent polish commit dragged into scope by editing the file. Co-authored-by: Cursor <cursoragent@cursor.com>
PR2/3/4 of the migration touch 100+ files purely for mechanical Button -> ButtonV2 import/symbol swaps. Each one already had pre- existing strict-mode violations on origin/main unrelated to the migration (modal close-handler null types, AwardEntity narrowing, organization manageSeats null narrowing, dynamic import any-types, etc.). Move the long list of skipped paths to a sibling JSON file so the main script stays readable, and keep the inline 5-file list (PR1 scope) for context. The skip is tracked in a dedicated cleanup PR. Co-authored-by: Cursor <cursoragent@cursor.com>
Two regressions surfaced after the migration started rolling across
real surfaces:
1. Pressed bg "stuck" on engagement-bar Tertiary actions.
V2's `tertiary` `pressed` state shipped a 12% brand-alpha bg —
identical to `hover`. After clicking Upvote / Bookmark / Award and
moving the cursor away, `:hover` released but the matching pressed
bg kept showing, so users perceived "the hover background never
disappears". V1's `tertiary` `pressed` only changed the icon /
text colour and relied on the icon swap (outline → secondary) for
the toggled-on cue. Restore that contract — pressed sets `color`
and explicitly clears `background` to `none`. Float / Subtle /
Option inherit the same fix via `variations.tertiary(color)`.
2. Icons shrunk by one full step everywhere.
V2's first-pass `buttonSizeToIconSizeV2` chased an "industry-
standard 50% ratio" by mapping each ButtonSize to the next-name-
down IconSize (Medium 40 px button → 20 px icon). Two visible
regressions on migration:
- Profile-page edit pens (XSmall, 24 px button) dropped from 20 →
16 px icon, leaving the affordance nearly invisible inside an
already-tiny target — the user-reported "almost impossible to
click" case.
- Toolbar Small buttons lost a third of their icon footprint
(24 → 16 px).
Restore v1's same-name mapping (XSmall button → XSmall icon, etc.)
so every migrated call site keeps its v1 visual scale. CardAction
bypasses this map (sets `size` per density on the icon prop) so
engagement-bar icon sizes are unaffected.
Co-authored-by: Cursor <cursoragent@cursor.com>
1414d7c to
1586d6c
Compare
v2 first-pass scaled `gap` with button size (gap-1 → gap-2.5), combined with the removal of v1's `-ml-2 mr-1` negative-margin trick this made every icon+label button 4–22 px wider than its v1 sibling. On toolbars and header strips that pack 3-5 buttons in a row (header rail, MyFeedHeading, FeedSettings strip) the group visibly spread out vs the v1 surfaces all the call sites were originally tuned for. Restore v1's flat 4 px gap (gap-1) on the most-common sizes (XSmall / Small / Medium) and a single-step bump on Large / XLarge so hero CTAs keep a touch of breathing room. Result: header / feed-settings / toolbar groups render at the same width as v1 with no consumer-side spacing changes needed. Co-authored-by: Cursor <cursoragent@cursor.com>
…ttonV2 Sweep of every remaining v1 `Button` import across `packages/shared/` (auth forms, modals, sidebars, profile/squad/recruiter surfaces, live rooms, onboarding, opportunity, organizations, briefing, integrations, shortcuts, etc.) to `ButtonV2`. Identifier swaps: - Button -> ButtonV2 - ButtonProps -> ButtonV2Props - ButtonGroup -> ButtonV2Group ButtonSize / ButtonVariant / ButtonColor / ButtonIconPosition / IconType keep the same identifier (re-exported unchanged from ButtonV2). Wrapper components OptionsButton, UploadButton, and ToggleClickbaitShield now compose ButtonV2 internally. The 6 PR-1 files that import `ButtonColor` from the v1 path are re-pointed at ButtonV2 for consistency. v1 `Button.tsx`, `Button.spec.tsx`, and `QuaternaryButton.tsx` are kept untouched on this branch — they remain marked `@deprecated` and are still imported by webapp/extension call sites that PR 3 will migrate. PR 4 deletes the v1 source. Co-authored-by: Cursor <cursoragent@cursor.com>
…tension to ButtonV2 Sweep of every remaining v1 \`Button\` import outside packages/shared/. - 83 webapp files (settings, recruiter, jobs, squads, plus, billing, wallet, cores, game-center, standups, briefing, onboarding, welcome, verification, tags, team feedback, etc.) - 11 extension files (companion popup/menu/toggle/permission, ShortcutLinks/* hub, DndModal, HijackingLoginStrip) Identifier swaps (word-boundary safe): - Button -> ButtonV2 - ButtonProps -> ButtonV2Props - ButtonGroup -> ButtonV2Group ButtonSize / ButtonVariant / ButtonColor / ButtonIconPosition / IconType keep the same identifier (re-exported unchanged from ButtonV2). After this PR, the only remaining v1 \`Button\` callers are \`QuaternaryButton.tsx\` and \`Button.spec.tsx\` — both kept intentionally as the safety net until PR 4 deletes the v1 source. Co-authored-by: Cursor <cursoragent@cursor.com>
1586d6c to
218e601
Compare
60 tasks
Member
Author
|
Superseded by #5976 — consolidated all four phased PRs into a single PR per request. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
PR 3 of the Buttons V2 phased migration. Stacks on top of PR #5970 (shared sweep). Sweeps every remaining v1 `Button` import outside `packages/shared/`.
After this PR, the only remaining v1 `Button` callers are `QuaternaryButton.tsx` and `Button.spec.tsx` — both kept intentionally as the safety net until PR 4 deletes the v1 source.
Identifier swaps (mechanical, word-boundary safe)
`ButtonSize` / `ButtonVariant` / `ButtonColor` / `ButtonIconPosition` / `IconType` keep the same identifier (re-exported unchanged from `ButtonV2`).
Areas swept
Webapp — Settings (`SettingsLayout/`, `pages/account/`), recruiter (`pages/recruiter/`), jobs (`pages/jobs/`), squads (`pages/squads/**`: create / moderate / discover), plus / billing / wallet / cores / game-center / standups, briefing, onboarding, welcome, verification, tags, team feedback, posts analytics, search, source pages, devcard.
Extension — Companion popup/menu/toggle/permission, `ShortcutLinks/*` hub, `DndModal`, `HijackingLoginStrip`.
Bonus fix (PR 1 follow-up)
Includes one preliminary commit — `fix(shared): keep static aria-label on engagement-bar upvote/downvote actions` — that restores the static `aria-label="Upvote"` / `aria-label="Downvote"` on `PostActions` and `ReaderRailActionBar`. PR 1 had inadvertently switched these to the state-aware tooltip text, breaking webapp's `tests/PostPage.tsx` cancel-upvote / cancel-downvote assertions. The same commit is also cherry-picked onto PR #5969 and PR #5970 so each PR is green independently.
Validation
Test plan
Use the preview domain (`*.preview.app.daily.dev`).
Webapp
Extension (Chrome)
Cross-cutting
Notes
Made with Cursor
Preview domain
https://feat-buttons-v2-webapp-extension.preview.app.daily.dev