Skip to content

Components: complete Gridicon → @wordpress/icons migration (continues #48164)#48537

Open
CGastrell wants to merge 6 commits intotrunkfrom
chore/finish-gridicon-migration
Open

Components: complete Gridicon → @wordpress/icons migration (continues #48164)#48537
CGastrell wants to merge 6 commits intotrunkfrom
chore/finish-gridicon-migration

Conversation

@CGastrell
Copy link
Copy Markdown
Contributor

@CGastrell CGastrell commented May 5, 2026

Continues #48164 (by @simison) — see "Relationship to #48164" below.

Part of #48160 (UI Modernization).

Proposed changes

  • Remove the Gridicon component from @automattic/jetpack-components and replace every consumer with <Icon /> + named exports from @wordpress/icons. Original work by @simison in Replace RNA Gridicon with wp-ui Icon #48164 — those two commits are preserved unchanged in this branch.
  • Complete a Boost site that the original PR missed: plugins/boost/.../performance-history/graph-component/graph-component.tsx still imported and rendered <Gridicon icon="lock" /> and <Gridicon icon="checkmark" />. Without this, the Storybook build fails with does not provide an export named 'Gridicon'. Adds @wordpress/icons as a Boost dependency and swaps to <Icon icon={ lock } /> / <Icon icon={ check } />.
  • Fix a silent runtime regression in packages/search/.../record-meter/notice-box.jsx: it passed icon={ 'info-outline' } (a Gridicon name string) to <SimpleNotice>, which after the migration expects an icon object. Pass icon={ info } from @wordpress/icons instead.

Visual mapping

Side-by-side comparison of every Gridicon being removed against its @wordpress/icons replacement. Same fill colour, same 32×32 box, no surrounding chrome — what you see here is exactly the SVG that ships. In production the icons inherit color from their consuming component (status notices use blue/green/amber via .dops-notice CSS, etc.).

Icon-by-icon comparison: Gridicon vs @wordpress/icons

Icon name mapping (text reference)

Original Gridicon @wordpress/icons replacement Notes
cross close exact
chevron-left / chevron-right chevronLeft / chevronRight exact
computer / phone desktop / mobile exact
domains globe semantic shift
info / info-outline info filled vs outline
external external exact
search search exact
lock lock exact (Boost graph)
checkmark / check check exact
notice (status mapping) caution exact intent
help-outline help exact (Protect firewall subheading)

Related product discussion/links

Does this pull request change what data or activity we track or use?

No.

Testing instructions

  1. Visual check — confirm the icon-by-icon strip above looks acceptable. Every swap is either an exact match or an explicitly-noted intent shift.
  2. Code reviewgit log trunk..HEAD shows 4 commits: 2 by @simison (preserved unchanged), 2 follow-ups by @CGastrell (Boost completion + Search consumer fix).
  3. In-browser smoke — visit each URL in Section B and confirm pages render without console errors. Where state allows, hover/click to surface the migrated icon.
  4. Reachable surfaces in standard local Docker — see Section A for full-page no-regression captures.

Section A — full-page no-regression captures

These were captured against localhost Docker (Jetpack connected, no Search/Boost premium, no Protect threats, Offline Mode active). Most migrated icons aren't visible on these pages without their gating subscription/state, so the value is "page renders without regression" rather than "you can see the new icon." The visual mapping above is the authoritative icon-shape evidence.

Click to expand — 6 before/after page pairs

1. My Jetpack overview — /wp-admin/admin.php?page=my-jetpack

Before After
01-mj-overview-before 01-mj-overview-after

2. Boost dashboard — /wp-admin/admin.php?page=jetpack-boost

Before After
02-boost-dashboard-before 02-boost-dashboard-after

3. Protect / Scan tab — /wp-admin/admin.php?page=jetpack-protect#/scan

Before After
03-protect-scan-before 03-protect-scan-after

4. Protect / Firewall tab — /wp-admin/admin.php?page=jetpack-protect#/firewall

Before After
04-protect-firewall-before 04-protect-firewall-after

5. Jetpack legacy at-a-glance dashboard — /wp-admin/admin.php?page=jetpack#/dashboard

Before After
05-jetpack-legacy-dashboard-before 05-jetpack-legacy-dashboard-after

6. Jetpack legacy Security / SSO settings — /wp-admin/admin.php?page=jetpack#/security

Before After
06-jetpack-security-sso-before 06-jetpack-security-sso-after

Section B — surfaces NOT reachable in a standard local Docker site

These need a Jurassic Ninja site (or wpcom env) with the relevant subscription / plan / state. Reviewer help here is appreciated.

# Surface URL Trigger condition
#2 MJ Protect critical-threats info icon /wp-admin/admin.php?page=my-jetpack (Protect product card) Site needs critical Protect threats present (stub jetpack_protect_status option)
#4 Search dashboard record-count "i" /wp-admin/admin.php?page=jetpack-search Active Search subscription, records indexed
#5 Search dashboard near-record-limit notice (info-outlineinfo) same Search subscription + tierMaximumRecords approached
#6 Search dashboard donut-meter "i" same Search subscription + records
#7 Search settings mock-instant-search input (search, cross) same (preview area) Search subscription
#8 Search settings mock-legacy-search input (search) same (preview area) Search subscription
#9 Search dashboard nav cards chevron / external same Search subscription
#10 Search dashboard SimpleNotice statuses (info / check / caution / close) same Search subscription + each notice state
#11 Search dashboard NoticeAction external arrow same Search subscription + notice with external link
#12 Search first-run notice (icon prop now removed; falls through to default info) same Search subscription + first-run state
#13 Boost performance-history lock (free-tier upgrade prompt) /wp-admin/admin.php?page=jetpack-boost Public-URL site (not offline mode) + Boost free tier
#14 Boost performance-history check (just-upgraded popover) same Public-URL site + just-applied premium licence
#15 Protect firewall help "?" tooltip /wp-admin/admin.php?page=jetpack-protect#/firewall Site without Protect plan, with WAF rules state present
#16 Jetpack SSO survey close (crossclose) /wp-admin/admin.php?page=jetpack#/security Connected (non-offline) site + enable SSO + disable to surface survey
#17 wpcom-only celebrate-launch modal nav arrows wpcom launch flow wpcom env only — code-level diff verification

Section C — what was caught during this rescue (changes from the original #48164)

  1. Missed Boost site (graph-component.tsx, lock & checkmark icons) — without this fix, Storybook CI fails. Added @wordpress/icons to plugins/boost/package.json.
  2. String-vs-object icon prop (notice-box.jsx) — SimpleNotice now expects an icon object; one consumer was still passing 'info-outline'. Changed to pass the info import.

SimpleNotice.propTypes change (PropTypes.stringPropTypes.object) and removal of NoticeAction.icon are kept as in the original PR — verified that no in-tree consumer was relying on either.

Relationship to #48164

  • The first two commits on this branch are @simison's, unchanged. Authorship is preserved (git log shows them attributed to Mikael Korpela).
  • The two follow-up commits add the missed Boost site and the search consumer fix.
  • When this PR is approved, please close Replace RNA Gridicon with wp-ui Icon #48164 with a link back here.

simison and others added 4 commits May 5, 2026 15:07
…ges with @wordpress/icons

Replace all usages of the Gridicon component exported from @automattic/jetpack-components
with the Icon component and named icons from @wordpress/icons. Removes the Gridicon
component from js-packages/components entirely.
Add changelog entries for js-packages/components, packages/search, packages/my-jetpack,
packages/jetpack-mu-wpcom, plugins/jetpack, and plugins/protect.
The previous commit dropped the Gridicon export from
@automattic/jetpack-components but missed this consumer, breaking
Storybook with "does not provide an export named 'Gridicon'".

Add @wordpress/icons as a Boost dependency, swap lock and checkmark
to the equivalent named exports.
After the Gridicon → @wordpress/icons swap, SimpleNotice expects an
icon object (not a Gridicon name string). The notice-box consumer
still passed 'info-outline' which would render nothing. Switch to
the @wordpress/icons info export.
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 5, 2026

Are you an Automattician? Please test your changes on all WordPress.com environments to help mitigate accidental explosions.

  • To test on WoA, go to the Plugins menu on a WoA dev site. Click on the "Upload" button and follow the upgrade flow to be able to upload, install, and activate the Jetpack Beta plugin. Once the plugin is active, go to Jetpack > Jetpack Beta, select your plugin (Jetpack or WordPress.com Site Helper), and enable the chore/finish-gridicon-migration branch.
  • To test on Simple, run the following command on your sandbox:
bin/jetpack-downloader test jetpack chore/finish-gridicon-migration
bin/jetpack-downloader test jetpack-mu-wpcom-plugin chore/finish-gridicon-migration

Interested in more tips and information?

  • In your local development environment, use the jetpack rsync command to sync your changes to a WoA dev blog.
  • Read more about our development workflow here: PCYsg-eg0-p2
  • Figure out when your changes will be shipped to customers here: PCYsg-eg5-p2

@github-actions github-actions Bot added [JS Package] Components [Package] Jetpack mu wpcom WordPress.com Features [Package] My Jetpack [Package] Search Contains core Search functionality for Jetpack and Search plugins [Plugin] Boost A feature to speed up the site and improve performance. [Plugin] Jetpack Issues about the Jetpack plugin. https://wordpress.org/plugins/jetpack/ [Plugin] Protect A plugin with features to protect a site: brute force protection, security scanning, and a WAF. Admin Page React-powered dashboard under the Jetpack menu RNA labels May 5, 2026
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 5, 2026

Thank you for your PR!

When contributing to Jetpack, we have a few suggestions that can help us test and review your patch:

  • ✅ Include a description of your PR changes.
  • ✅ Add a "[Status]" label (In Progress, Needs Review, ...).
  • ✅ Add testing instructions.
  • ✅ Specify whether this PR includes any changes to data or privacy.
  • ✅ Add changelog entries to affected projects

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:

  1. Ensure all required checks appearing at the bottom of this PR are passing.
  2. Make sure to test your changes on all platforms that it applies to. You're responsible for the quality of the code you ship.
  3. You can use GitHub's Reviewers functionality to request a review.
  4. When it's reviewed and merged, you will be pinged in Slack to deploy the changes to WordPress.com simple once the build is done.

If you have questions about anything, reach out in #jetpack-developers for guidance!


Jetpack 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.


Boost 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.


Protect 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.

@github-actions github-actions Bot added the [Status] Needs Author Reply We need more details from you. This label will be auto-added until the PR meets all requirements. label May 5, 2026
Comment on lines +154 to +155
<Button href={ siteUrl } target="_blank" className="launched__modal-view-site">
<Gridicon icon="domains" size={ 18 } />
<Icon icon={ globe } size={ 18 } />
Copy link
Copy Markdown
Member

@simison simison May 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You might want Button with icon here instead. Do check if launched__modal-view-site had some icon-positional styles which can then also be removed.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 428c605. Kept the inner <span class="launched__modal-view-site-text"> so the existing typography rules (font-weight, font-size, line-height, white-space) still apply — those would be lost otherwise. Open question for follow-up: the parent .launched__modal-view-site still has display: flex; gap: $grid-unit-05 which is now redundant (Button does its own flex internally for the icon+text). Worth a separate pass to clean up the SCSS.

@CGastrell CGastrell added [Status] In Progress and removed [Status] Needs Author Reply We need more details from you. This label will be auto-added until the PR meets all requirements. labels May 5, 2026
Comment on lines 32 to 35
<a { ...attributes }>
<span>{ this.props.children }</span>
{ this.props.icon && <Gridicon icon={ this.props.icon } size={ 24 } /> }
{ this.props.external && <Gridicon icon="external" size={ 24 } /> }
{ this.props.external && <Icon icon={ externalIcon } size={ 24 } /> }
</a>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might make sense to replace with Link and openInNewTab as you get the icon for free. Otherwise lots of these external links just use ascii instead of icon.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good idea but I'd like to defer this one. It's a structural rewrite rather than a Gridicon swap:

  • Replaces the underlying <a> with <Link> from @wordpress/ui (search currently doesn't depend on @wordpress/ui — would add a dep).
  • Link brings its own CSS (variant/tone, focus ring, link-icon span) on top of the existing .dops-notice__action class — possible visual delta on every existing notice.
  • Behavioral surface (a11y label for the auto , focus styles) differs.

I'd rather ship the icon swap as-is for this PR (it's a like-for-like Gridicon → @wordpress/icons replacement) and open this Link migration as a separate follow-up so we can review/QA it on its own.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Follow up: #48550

Copy link
Copy Markdown
Member

@simison simison May 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thinking more, the whole Search dashboard notice component doesn't make sense to keep. :-D

The more top-level you replace these things, you don't need to spend time swapping icons and components within them. ;-)

Comment on lines 51 to 53
<Button onClick={ onClose } className="modal-survey-notice__popup-head-close">
<Gridicon icon="cross" size={ 16 } />
<Icon icon={ close } size={ 16 } />
</Button>
Copy link
Copy Markdown
Member

@simison simison May 5, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like <Button icon={ close } /> out of the box would work since it's wp-components Button.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 428c605. Switched to <Button icon={ close } iconSize={ 16 } label={ __( 'Close', 'jetpack' ) } /> and dropped the now-unused Icon import. Added label so the now-icon-only button keeps an accessible name (it had implicit one via the SVG title before).

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

01-sso-survey-modal-full 02-sso-survey-close-btn

@jp-launch-control
Copy link
Copy Markdown

jp-launch-control Bot commented May 5, 2026

Code Coverage Summary

Coverage changed in 1 file.

File Coverage Δ% Δ Uncovered
projects/packages/search/src/dashboard/components/notice/index.jsx 15/24 (62.50%) 9.38% -6 💚

Full summary · PHP report · JS report

CGastrell added 2 commits May 5, 2026 18:25
1. boost-score-bar tests queried for `.gridicons-phone` /
   `.gridicons-computer` CSS classes that no longer exist after the
   swap to wp-icons desktop / mobile. Replace with a presence check
   on the SVG inside `.jb-score-bar__label`.
2. The Boost rna-gridicon changelog used "Type: enhancement", but the
   Boost project's changelogger only accepts security / added /
   changed / deprecated / removed / fixed. Switch to patch + changed.
Two trivial cleanups suggested in #48537 review:

- sso.jsx: SSO survey close button — replace Button + child <Icon /> with
  <Button icon={close} iconSize={16} />. Adds an explicit `label` for
  the now-icon-only button so its accessible name stays present.

- celebrate-launch-modal.js: "View site" button — same pattern. Keep
  the inner <span class="launched__modal-view-site-text"> so the
  existing typography rules (font-weight / size / line-height /
  white-space) still apply.

Drop the now-unused Icon import from sso.jsx.

A third suggestion (search NoticeAction → @wordpress/ui Link) was
deferred — it's a structural rewrite (adds @wordpress/ui dep, changes
underlying CSS / a11y / focus), not a Gridicon swap. Tracking
separately.
CGastrell added a commit that referenced this pull request May 6, 2026
Replace the local SimpleNotice + NoticeAction wrappers with Notice.* from
@wordpress/ui across the search dashboard:

- record-meter/notice-box: tier notices use Notice.Root/Title/Description
  + Notice.Actions/ActionLink (openInNewTab); the legacy
  jp-search-notice-box__important class becomes intent="error".
- pages/sections/first-run-section: indexing notice uses Notice.Root/Title/
  Description.
- global-notices: snackbar notices use Notice.Root + Notice.Description +
  Notice.CloseIcon, with auto-dismiss preserved via a useEffect timer.
  Status strings remain in the redux store; mapped to wp-ui intents at render.

Drops vestigial fields the redux notice creators never set anyway
(isCompact, isPersistent, displayOnNextPage, notice.button/href).

Deletes the SimpleNotice/NoticeAction sources, their stylesheets, and
notice-box.scss; strips the dead .dops-notice* overrides from
global-notices/style.scss while keeping the snackbar positioning rules.

Removes one site of @automattic/jetpack-components Gridicon usage
(SimpleNotice's icon-wrapper) — helps the broader modernization sweep.

Follow-up to simison review feedback on #48537.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Admin Page React-powered dashboard under the Jetpack menu [JS Package] Components [Package] Jetpack mu wpcom WordPress.com Features [Package] My Jetpack [Package] Search Contains core Search functionality for Jetpack and Search plugins [Plugin] Boost A feature to speed up the site and improve performance. [Plugin] Jetpack Issues about the Jetpack plugin. https://wordpress.org/plugins/jetpack/ [Plugin] Protect A plugin with features to protect a site: brute force protection, security scanning, and a WAF. RNA [Status] In Progress [Tests] Includes Tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants