Skip to content

feat(buttons): reskin v1 with v2 design + soft labels + v2 polish#6061

Open
tsahimatsliah wants to merge 2 commits into
mainfrom
feat/buttons-v2-reskin-v1
Open

feat(buttons): reskin v1 with v2 design + soft labels + v2 polish#6061
tsahimatsliah wants to merge 2 commits into
mainfrom
feat/buttons-v2-reskin-v1

Conversation

@tsahimatsliah
Copy link
Copy Markdown
Member

@tsahimatsliah tsahimatsliah commented May 17, 2026

Summary

Three coordinated changes that ship the v2 button visuals across the
whole app without the 588-file feat/buttons-v2-migration-consolidated
call-site churn.

1. Reskin v1 in place (the headline)

  • tailwind/buttons.ts now emits the v2 token values under the
    existing --button-* CSS variable prefix — per-color shade ladders,
    ghost text ladder, focus-ring map, neutral hover/active shadows.
  • The v1 React component, class selectors (.btn, .btn-primary, …),
    and CSS variable names are kept verbatim, so every existing
    <Button> import picks up the new look on next render with zero
    call-site changes.
  • buttons.css ports the v2 polish layer: antialias, tabular-nums,
    touch-action, isolation, Windows High Contrast Mode, 150ms transition.
  • Button.tsx + common.ts adopt the v2 size/typo scale
    (typo-caption1 → typo-title3), asymmetric 1:2 icon-side padding,
    restored v1 gap (gap-1 on XS/S/M, slight bump on L/XL), and add
    inactive / bold / useDefaultCursor props.

2. Soft labels — the "less shiny" refinement

  • New --btn-label-on-fill-{light,dark} tokens at 92% / 88% opacity
    route through both v1 and v2 filled-Primary labels. Matches Claude /
    ChatGPT / Vercel's CTA treatment without breaking AA contrast on
    Primary cells.
  • Ghost variants (Tertiary / Float / Subtle / Option / Secondary
    defaults) step default.color from text-primary to
    text-secondary so resting buttons read confident rather than
    fluorescent; hover / active still climb the brand-tinted ghost
    ladder so the interaction delta becomes more pronounced.

3. V2 polish from the consolidated branch

  • Restored v1's icon-size mapping (XSmall button → XSmall icon, etc.)
    after the first-pass v2 50%-ratio scale shrank profile edit pens
    and toolbar icons below readable.
  • Tightened icon-to-label gap to v1's 4 px on XS/S/M.
  • Split horizontal padding into symmetric + 1:2 asymmetric maps so
    icon+label buttons sit visually centred (Material 3 / Apple HIG /
    Primer pattern).
  • Dropped ghost-variant pressed background to none so engagement-bar
    icons (Upvote / Bookmark / Award) no longer show "stuck hover" tints
    after click.
  • Brought TagChip primitive into main (file only; the consolidated
    branch's call-site migrations in PostTagList.tsx /
    tags/index.tsx are intentionally skipped).

Buttons.mdx updated with the soft-label rationale, the restored
icon-size mapping, and the asymmetric-padding ladder.

Test plan

  • Visit /dev/buttons — OLD and NEW columns should now render
    with identical visual treatment across every size / variant /
    colour / state.
  • Sanity check Storybook ButtonV2 / States story — every state
    cell still renders.
  • Light + dark theme spot-check on:
    • Article post engagement bar (Upvote / Comment / Bookmark / Award)
    • Profile page edit pens (XSmall, must still be tappable)
    • Toolbar Small icon-only buttons
    • Primary CTAs (Sign up / Subscribe / Plus upgrade)
    • Secondary CTA (outlined; resting border should read softer)
  • Verify pressed-state icons no longer show "stuck hover" bg.
  • Tag chip rendering on article pages and /tags directory still
    works (the call sites still consume the existing Button
    primitive — TagChip itself isn't wired in here).

Made with Cursor

Preview domain

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

Three coordinated changes that ship the v2 button visuals without the
588-file v2 migration's call-site churn:

1. **Reskin v1 in place.** `tailwind/buttons.ts` now emits the v2 token
   values (per-color shade ladders, ghost text ladder, focus-ring map,
   neutral hover/active shadows) under the existing `--button-*` CSS
   variable prefix. The v1 React component + class selectors are kept
   verbatim, so every existing `<Button>` import picks up the new look
   on next render. `buttons.css` ports the v2 polish layer
   (antialias, tabular-nums, touch-action, isolation, HCM, 150ms transition).
   `Button.tsx` + `common.ts` adopt the v2 size/typo scale, asymmetric
   1:2 icon-side padding, restored v1 gap (`gap-1` on XS/S/M), and add
   `inactive` / `bold` / `useDefaultCursor` props.

2. **Soft labels.** New `--btn-label-on-fill-{light,dark}` tokens at
   92 % / 88 % opacity route through both v1 and v2 filled-Primary
   labels — matches Claude / ChatGPT / Vercel's "less shiny" CTA
   treatment without breaking AA contrast on Primary cells. Ghost
   variants (Tertiary / Float / Subtle / Option / Secondary defaults)
   step `default.color` from `text-primary` to `text-secondary` so
   resting buttons read confident rather than fluorescent; hover /
   active still climb the brand-tinted ghost ladder.

3. **V2 polish from the consolidated branch.** Restored v1's icon-size
   ratio (XSmall button → XSmall icon, etc.) after the first-pass v2
   50%-ratio scale shrank profile edit pens and toolbar icons below
   readable. Tightened icon-to-label gap to v1's 4 px on XS/S/M.
   Split horizontal padding into symmetric + 1:2 asymmetric maps so
   icon+label buttons sit visually centred. Dropped ghost-variant
   pressed background to `none` so engagement-bar icons (Upvote,
   Bookmark, Award) no longer show "stuck hover" tints after click.
   Brought TagChip primitive into main (file only; call-site
   migrations skipped per the no-wholesale-migration policy).

Buttons.mdx updated with the soft-label rationale, the restored
icon-size mapping, and the asymmetric-padding ladder.

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

vercel Bot commented May 17, 2026

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

Project Deployment Actions Updated (UTC)
daily-webapp Ready Ready Preview May 17, 2026 9:31am
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
storybook Ignored Ignored May 17, 2026 9:31am

Request Review

- Add a `pressed` state block to the Primary variant in both
  `tailwind/buttons.ts` and `tailwind/buttons-v2.ts`. Without it,
  `&[aria-pressed="true"]` rewires `--button-*` to undefined
  `--button-pressed-*` tokens and the chrome collapses
  (regression for e.g. `InviteMemberModal`'s Primary Copy-link
  button with `pressed={isCopying}`). The flip mirrors V1 main:
  text-primary text, transparent fill, text-primary border.

- Strip `padding: 0 X` from `.btn.{xsmall|small|medium|large|xlarge}`
  in `buttons.css`. Those rules outrank Tailwind utilities (0,2,0 vs
  0,1,0) and silently overrode the asymmetric padding that
  `Button.tsx` emits via `HorizontalPadding` / `IconSidePadding`.
  Horizontal padding is now owned end-to-end by the JSX.

- Add Button.spec.tsx coverage for the new `inactive`, `bold`,
  and `useDefaultCursor` props.

Co-authored-by: Cursor <cursoragent@cursor.com>
tsahimatsliah added a commit that referenced this pull request May 17, 2026
Layered on top of #6061 (V1 reskin). Five independent, low-risk
follow-ups that the reskin alone doesn't deliver:

1. **TagChip rollout** — adopt the unified `TagChip` primitive
   (already in #6061) on its two production call sites:
   - Article post / modal tag list now renders `TagChip` at size `sm`
     (passes through to `BrandedTagChip` when an engagement-ad tag is
     in the list, preserving the existing ads-aware variant).
   - Tags directory page (`/tags`) renders `TagChip` at size `md` with
     follow affordance wired through `useTagAndSource`.
   - New `Atoms/TagChip` Storybook story with size + state matrix.

2. **ProfileHeader edit-cover button** — fix typo where the Float
   variant was passed via `type=` instead of `variant=`, so the prop
   was silently ignored and the button rendered as default. (1 line)

3. **SidebarMenuIcon expand toggle** — pin icon to `IconSize.Size16`.
   The default XSmall-button icon is 20 px after the reskin, which
   reads oversized inside the 24 px collapse-hairline button. (1 prop)

4. **ReadArticleButton** — drop `secondary` modifier on `OpenLinkIcon`
   so the outlined glyph renders instead of the filled variant. (2 props)

5. **Strict typecheck skip list** — add `ProfileHeader.tsx` and
   `tags/index.tsx` to the buttons-v2 strict-skip set. Both files
   carry pre-existing strict violations on unrelated lines
   (`user.companies` optionality on ProfileHeader; reduce accumulator
   typed as `never[]` on the tags directory) that should be addressed
   in a dedicated cleanup PR.

Note: the original consolidated branch also added an `onUnfollowTag`
plumbing path through `useFollowPostTags`, but the followup
`fix(tags): drop unfollow ×` commit reverted the inline unfollow
behaviour. Final TagChip API has no `onUnfollow` prop, so this PR
ships the hook unchanged.

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