Publicize: migrate all Button consumers to @wordpress/ui#48150
Publicize: migrate all Button consumers to @wordpress/ui#48150
Conversation
|
Are you an Automattician? Please test your changes on all WordPress.com environments to help mitigate accidental explosions.
Interested in more tips and information?
|
|
Thank you for your PR! When contributing to Jetpack, we have a few suggestions that can help us test and review your patch:
This comment will be updated as you work on your PR and make changes. If you think that some of those checks are not needed for your PR, please explain why you think so. Thanks for cooperation 🤖 Follow this PR Review Process:
If you have questions about anything, reach out in #jetpack-developers for guidance! Social plugin: No scheduled milestone found for this plugin. If you have any questions about the release process, please ask in the #jetpack-releases channel on Slack. |
Code Coverage SummaryCoverage changed in 7 files. Only the first 5 are listed here.
|
7c6de1c to
0520baf
Compare
0520baf to
fb7209c
Compare
Migrates the Button in connect-form, connection-info, service-item, and media-picker from @automattic/jetpack-components to @wordpress/ui, mapping the variants (primary→solid, secondary→outline, tertiary→minimal). In media-picker, the shared .preview class used border:0 to strip chrome from the image-wrapper button. That worked for the old secondary Button (which draws its border via box-shadow) but wipes the outline of the new @wordpress/ui Button. Gives the picker Button its own .picker-button class so the two buttons no longer share conflicting styles. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…s/ui Swap the Button-as-link usage for a proper Link component. The Reconnect control and the "fix" link inside BrokenConnectionsNotice are now anchors with preventDefault click handlers; Reconnect uses aria-disabled instead of the now-absent disabled prop. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…m styles Disconnect now renders a wp/ui Button (variant "outline" by default, "minimal" inside the manage-connections service row) or a wp/ui Link when called with variant="link" from the unsupported-service branch. Drops the old isDestructive + buttonClassName props; wp/ui Button has no destructive tone, and the ConfirmDialog already protects against accidental disconnects. Also removes the orphan .fields-item wrapper and .connect-button rule in the connect form. The wrapper was forcing flex-basis: 50% on the submit button, which at wp/ui defaults caused "Connect more" to wrap across two lines. The .connect-button SCSS targeted :global(.components-button), which wp/ui Button never emits. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Drops useBreakpointMatch in favor of a CSS media query: scoping
justify-self: flex-start to >=600px lets the grid default stretch
kick in on mobile, replicating the old fullWidth={isSmall} behavior.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ress/ui Mirrors the SIG toggle change: drop useBreakpointMatch + fullWidth, move justify-self: flex-start into the >=600px media query so the button still fills its grid cell below 600px. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Swap @automattic/jetpack-components Button for wp/ui Button with the SocialServiceIcon rendered as a child. wp/ui's Icon/IconButton extracts icon.props onto a bare SVG, so SocialServiceIcon (a wrapper component) gets its props stripped — Button-with-child renders it correctly. Replicate IconButton's square shape via CSS custom properties (--wp-ui-button-aspect-ratio, --wp-ui-button-padding-inline, --wp-ui-button-min-width). Also override --wp-ui-button-border-color to transparent so the per-network background isn't framed by wp/ui's default brand-blue border. Add an explicit hover rule for the darker-gray hover state, scoped to .icon-button; unlayered CSS beats wp/ui's in-layer hover rule regardless of specificity. Drop the dead buttonVariant prop (no caller passed it, and the type would be awkward post-migration with CopyToClipboard still on the old Button). Drop dead SCSS selectors targeting :global(.components-button), which wp/ui Button doesn't emit. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replaces fullWidth with a width:100% .cta-button class on both CTAs, drops useBreakpointMatch and the dead isLarge && styles.button className (the .button class had already been removed from the SCSS). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The @wordpress/ui Button (Base UI-backed) represents disabled state via aria-disabled="true" + data-disabled="" rather than the native disabled attribute, because focusableWhenDisabled defaults to true so screen-reader users don't lose focus on a disabled control. jest-dom's toBeDisabled() only matches the native attribute, so update the assertion to check aria-disabled directly. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The @wordpress/ui Button (Base UI-backed) renders a <button> element and
silently ignores href/target/rel. That drops link semantics (role=link),
broke the Jetpack Social e2e connection test's getByRole('link', { name:
'Write a post' }) assertion, and left target/rel non-functional for share
buttons.
Use Base UI's render prop ({ <a /> }) + nativeButton={ false } on the four
remaining href-bearing Buttons so they render as anchors while keeping the
button's visual chrome. The Button stylesheet already has &[href]{...}
rules anticipating this use.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Base UI's useButton hook hard-codes role=button into the props it merges
onto the rendered element whenever nativeButton is false, even when the
render prop is <a/>. Result: the previous fix produced an <a href>
element but the accessibility tree still reported it as role=button, so
the social plugin e2e's getByRole('link', { name: 'Write a post' }) kept
failing.
Pass role="link" explicitly on the four anchor-rendered Buttons (header
"Write a post", pricing "Get Social", social-notes "Create a note", and
per-network share buttons). In useButton's merge call
(use-button/useButton.js:169), otherExternalProps come after Base UI's
{ role: 'button' }, so our override wins.
Verified locally by running plugins/social tests/e2e connection.test.ts
against a docker + tunnel env — 3/3 passing.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The render={<a/>} + role=link approach rendered @wordpress/ui Buttons as
anchors, but collided with WP admin's unlayered `a { color }` rule — the
button's layered color lost the cascade, bleaching label text against the
solid variant. Adding a CSS override would work, but it compounds
workarounds against a library primitive whose semantics (Button = button)
are actually correct.
Instead: let the Button stay a <button>, navigate via an explicit onClick
handler, and update the e2e test to assert role=button. Trade-off: loses
middle-click / right-click "open in new tab"; acceptable here because
these three CTAs ("Write a post", "Get Social", "Create a note") are
flow-driven, not navigation-surface links.
Share buttons already had onClick handlers (preventDefault + window.open),
so they just drop the render props. Per-file handlers use useCallback for
stable identity.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Part of #48160
Proposed changes
Migrates every
Buttonconsumer in the Publicize package from@automattic/jetpack-componentsto@wordpress/ui, split across commits one per logical surface. Covers:outlineandminimalcontexts)@wordpress/uiLink)Prop mapping applied:
@automattic/jetpack-components@wordpress/uivariant="primary"variant="solid"variant="secondary"variant="outline"variant="tertiary"variant="minimal"variant="link"Linkcomponent (orvariant="unstyled"for anchor-shaped cases)isLoadingloadingsize="normal"size="default"href={...}(for navigation-on-click)onClickhandler that setswindow.location.href(@wordpress/uiButton renders a<button>, which doesn't honorhref); share buttons' existing click handlers already workedisDestructiveoutline/minimalnow)fullWidthwidth: 100%) where layout required itTwo test-side fixes were needed because
@wordpress/uiButton (Base UI-backed) usesaria-disabled="true"(withfocusableWhenDisabled: truedefault) instead of the nativedisabledattribute, and Link renders<a>(rolelink) rather than<button>:disconnect.test.js:toBeDisabled()→toHaveAttribute('aria-disabled', 'true')reconnect.test.js:getByRole('button')→getByRole('link'); samearia-disabledswapOther information
@wordpress/uiis already a direct dependency of the Publicize package, so nopackage.jsonchanges were needed.Does this pull request change what data or activity we track or use?
No.
Testing instructions
Sequenced to touch every changed button in the fewest sessions. Each step leaves the site in the state the next step needs.
Before you start
Deploy the branch to a Jurassic Ninja (or equivalent) site with Jetpack Social (or Jetpack with Publicize enabled). Confirm you're signed in to WordPress.com.
1. Pricing page (tests Get Social + Start for free buttons)
On a fresh install the pricing page shows automatically. If it doesn't:
Then open the Social admin (
/wp-admin/admin.php?page=jetpack-social):<button>with anonClickhandler, not an anchor).2. Admin dashboard — no connections yet (tests Connect accounts, Write a post, Change defaults, Choose image in media picker, Create a note)
<button>s withonClick, not anchors).3. Connections modal (tests service/connection chevrons, Connect / Connect more, Connect an account footer, Disconnect in two variants)
Click "Connect accounts" (from the header) or "Connect an account" (from the connection management widget) to open the Connections modal.
aria-disabledstate while deleting (button text becomes "Disconnecting…"). Then reconnect for the next step.variant="minimal"viaservice-connection-info).4. Broken-connection state (tests Manage connections link in notice + Reconnect unstyled link)
No UI path marks a connection broken, but the social store exposes a client-only
updateConnectionaction that lets us fake it. On the Social admin page, open DevTools Console and run:The page updates immediately — no reload needed:
link;variant="default"of@wordpress/uiLink).variant="unstyled").To restore real state, just reload the page — connections rehydrate from the server.
5. Per-network share buttons (tests share-buttons)
onClickhandler callswindow.openwith popup sizing).6. Quick a11y pass (~30 seconds)
aria-disabled="true").Screenshots