From 18a567ea09e43fb54d72b318b561e1c3dfea092d Mon Sep 17 00:00:00 2001 From: Christian Gastrell Date: Tue, 12 May 2026 01:53:12 -0300 Subject: [PATCH 1/3] Componentry: migrate Status to @wordpress/ui Text in plugin consumers Part of #48160. Replace the internal Jetpack Status component (from @automattic/jetpack-components) with inline JSX using Text from @wordpress/ui plus a small colour-coded indicator span in the six consumer sites in plugins/protect and plugins/jetpack: - protect: AdminSectionHero storybook, firewall hero, scan hero, scan history hero -- single Status sites, inline style blocks keep the same var(--jp-green-50|gray-50) colour vars, 0.666em indicator, font-weight 600, and line-height 1.666 as the wrapper SCSS. - jetpack: security/waf "Standalone mode" label -- inline style, preserves the waf__standalone__mode className. - jetpack: pro-status renders four different status states; co-locate a style.module.scss mirroring the wrapper's status colour map (is-active|inactive|error|action|initializing) so the four call sites stay terse. Also drop the dead text prop on the legacy rewind status site (the original wrapper only ever read "label") and fall back to the now-explicit default label per status. Annotate the Status source in js-packages/components with an @deprecated JSDoc block (mirroring the Chip -> Badge pattern from #48162) so external consumers see the guidance without breaking on upgrade. Implementation, styles, stories, and barrel export are otherwise unchanged. --- .../changelog/change-migrate-status-wp-ui | 4 ++ .../components/components/status/index.tsx | 11 ++++ .../jetpack/_inc/client/pro-status/index.jsx | 43 ++++++++++++-- .../_inc/client/pro-status/style.module.scss | 56 +++++++++++++++++++ .../jetpack/_inc/client/security/waf.jsx | 31 ++++++++-- .../changelog/change-migrate-status-wp-ui | 4 ++ .../changelog/change-migrate-status-wp-ui | 4 ++ .../stories/index.stories.jsx | 29 +++++++++- .../firewall/firewall-admin-section-hero.tsx | 29 +++++++++- .../history/history-admin-section-hero.tsx | 27 ++++++++- .../routes/scan/scan-admin-section-hero.tsx | 27 ++++++++- 11 files changed, 245 insertions(+), 20 deletions(-) create mode 100644 projects/js-packages/components/changelog/change-migrate-status-wp-ui create mode 100644 projects/plugins/jetpack/_inc/client/pro-status/style.module.scss create mode 100644 projects/plugins/jetpack/changelog/change-migrate-status-wp-ui create mode 100644 projects/plugins/protect/changelog/change-migrate-status-wp-ui diff --git a/projects/js-packages/components/changelog/change-migrate-status-wp-ui b/projects/js-packages/components/changelog/change-migrate-status-wp-ui new file mode 100644 index 000000000000..bec61ec14e93 --- /dev/null +++ b/projects/js-packages/components/changelog/change-migrate-status-wp-ui @@ -0,0 +1,4 @@ +Significance: patch +Type: changed + +Components: deprecate Status; inline @wordpress/ui Text in consumers. diff --git a/projects/js-packages/components/components/status/index.tsx b/projects/js-packages/components/components/status/index.tsx index b370cc4312c7..c3c0b3639ea2 100644 --- a/projects/js-packages/components/components/status/index.tsx +++ b/projects/js-packages/components/components/status/index.tsx @@ -10,6 +10,17 @@ export interface StatusProps { className?: string; } +/** + * Status component. + * + * @deprecated Inline the equivalent JSX using `Text` from `@wordpress/ui` and a small color-coded indicator span. The wrapper renders a flex container at `body-extra-small` size with `font-weight: 600` and a `0.666em` round indicator coloured by status (`var(--jp-green-50)` for `active`, `--jp-red-50` for `error`, `--jp-gray-50` for `inactive`, `--jp-yellow-30` for `action`, `--jp-blue-40` for `initializing`). + * + * @param {StatusProps} props - The component properties. + * @param {string} props.className - Optional className forwarded to the outer element. + * @param {string} props.label - Status label. Defaults to a status-derived string. + * @param {string} props.status - Status key: `active | error | inactive | action | initializing`. + * @return {JSX.Element} The `Status` component. + */ const Status = ( { className, label, status = 'inactive' }: StatusProps ): JSX.Element => { const defaultLabels: Record< string, string > = { active: __( 'Active', 'jetpack-components' ), diff --git a/projects/plugins/jetpack/_inc/client/pro-status/index.jsx b/projects/plugins/jetpack/_inc/client/pro-status/index.jsx index ad1e9bb2ba1c..3dba0f998eaa 100644 --- a/projects/plugins/jetpack/_inc/client/pro-status/index.jsx +++ b/projects/plugins/jetpack/_inc/client/pro-status/index.jsx @@ -1,5 +1,7 @@ -import { Status, getRedirectUrl } from '@automattic/jetpack-components'; +import { getRedirectUrl } from '@automattic/jetpack-components'; import { __, _n, _x } from '@wordpress/i18n'; +import { Text } from '@wordpress/ui'; +import clsx from 'clsx'; import PropTypes from 'prop-types'; import { Component } from 'react'; import { connect } from 'react-redux'; @@ -22,6 +24,30 @@ import { getRewindStatus } from 'state/rewind'; import { getScanStatus } from 'state/scan'; import { getSitePlan, siteHasFeature, isFetchingSiteData } from 'state/site'; import { isFetchingPluginsData, isPluginActive, isPluginInstalled } from 'state/site/plugins'; +import styles from './style.module.scss'; + +/** + * Render a small status indicator with a coloured dot and label. + * + * @param {object} props - Component props. + * @param {string} props.status - Status key. + * @param {React.ReactNode} props.label - Label content. + * @return {import('react').ReactElement} The status indicator. + */ +const StatusIndicator = ( { status, label } ) => ( + + + { label } + +); + +const DEFAULT_LABELS = { + active: __( 'Active', 'jetpack' ), + error: __( 'Error', 'jetpack' ), + action: __( 'Action needed', 'jetpack' ), + inactive: __( 'Inactive', 'jetpack' ), + initializing: __( 'Setting up', 'jetpack' ), +}; /** * Track click on Pro status badge. @@ -110,10 +136,15 @@ class ProStatus extends Component { return; case 'rewind_connected': { const rewindMessage = this.getRewindMessage(); - return ; + return ( + + ); } case 'active': - return ; + return ; } const label = ( @@ -131,7 +162,7 @@ class ProStatus extends Component { ); - return ; + return ; }; /** @@ -209,7 +240,7 @@ class ProStatus extends Component { } else if ( scanStatus && scanStatus.state !== 'unavailable' ) { if ( Array.isArray( scanStatus.threats ) && scanStatus.threats.length > 0 ) { return ( - @@ -219,7 +250,7 @@ class ProStatus extends Component { return ''; } if ( scanStatus.credentials.length === 0 ) { - return ; + return ; } return this.getProActions( 'secure', 'scan' ); } diff --git a/projects/plugins/jetpack/_inc/client/pro-status/style.module.scss b/projects/plugins/jetpack/_inc/client/pro-status/style.module.scss new file mode 100644 index 000000000000..290a7713c820 --- /dev/null +++ b/projects/plugins/jetpack/_inc/client/pro-status/style.module.scss @@ -0,0 +1,56 @@ +.status { + align-items: center; + display: inline-flex; + font-weight: 600; + line-height: 1.666; + white-space: nowrap; + + &.is-active { + color: var(--jp-green-50); + + .indicator { + background-color: var(--jp-green-50); + } + } + + &.is-inactive { + color: var(--jp-gray-50); + + .indicator { + background-color: var(--jp-gray-50); + } + } + + &.is-error { + color: var(--jp-red-50); + + .indicator { + background-color: var(--jp-red-50); + } + } + + &.is-action { + color: var(--jp-yellow-30); + + .indicator { + background-color: var(--jp-yellow-30); + } + } + + &.is-initializing { + color: var(--jp-blue-40); + + .indicator { + background-color: var(--jp-blue-40); + } + } +} + +.indicator { + background-color: var(--jp-gray-50); + border-radius: 50%; + flex-shrink: 0; + height: 0.666em; + margin-right: 4px; + width: 0.666em; +} diff --git a/projects/plugins/jetpack/_inc/client/security/waf.jsx b/projects/plugins/jetpack/_inc/client/security/waf.jsx index 3315ec00148a..9ae53410373f 100644 --- a/projects/plugins/jetpack/_inc/client/security/waf.jsx +++ b/projects/plugins/jetpack/_inc/client/security/waf.jsx @@ -1,8 +1,8 @@ -import { getRedirectUrl, Status } from '@automattic/jetpack-components'; +import { getRedirectUrl } from '@automattic/jetpack-components'; import { ToggleControl } from '@wordpress/components'; import { createInterpolateElement } from '@wordpress/element'; import { __, _x, sprintf } from '@wordpress/i18n'; -import { Link } from '@wordpress/ui'; +import { Link, Text } from '@wordpress/ui'; import { Component } from 'react'; import { connect } from 'react-redux'; import Button from 'components/button'; @@ -206,11 +206,30 @@ export const Waf = class extends Component {
{ _x( 'Firewall', 'Settings header', 'jetpack' ) } { this.props.settings?.standaloneMode && ( - + style={ { + alignItems: 'center', + color: 'var(--jp-green-50)', + display: 'inline-flex', + fontWeight: 600, + lineHeight: 1.666, + whiteSpace: 'nowrap', + } } + > + + { __( 'Standalone mode', 'jetpack' ) } + ) }
); diff --git a/projects/plugins/jetpack/changelog/change-migrate-status-wp-ui b/projects/plugins/jetpack/changelog/change-migrate-status-wp-ui new file mode 100644 index 000000000000..0db43b2fd7e1 --- /dev/null +++ b/projects/plugins/jetpack/changelog/change-migrate-status-wp-ui @@ -0,0 +1,4 @@ +Significance: patch +Type: compat + +Jetpack: migrate Status indicator to @wordpress/ui Text. diff --git a/projects/plugins/protect/changelog/change-migrate-status-wp-ui b/projects/plugins/protect/changelog/change-migrate-status-wp-ui new file mode 100644 index 000000000000..a9cf6c8f48dc --- /dev/null +++ b/projects/plugins/protect/changelog/change-migrate-status-wp-ui @@ -0,0 +1,4 @@ +Significance: patch +Type: changed + +Protect: migrate Status indicator to @wordpress/ui Text. diff --git a/projects/plugins/protect/src/js/components/admin-section-hero/stories/index.stories.jsx b/projects/plugins/protect/src/js/components/admin-section-hero/stories/index.stories.jsx index 7d5b4f8066c9..42b3186cea5a 100644 --- a/projects/plugins/protect/src/js/components/admin-section-hero/stories/index.stories.jsx +++ b/projects/plugins/protect/src/js/components/admin-section-hero/stories/index.stories.jsx @@ -1,7 +1,10 @@ -import { Status, Text } from '@automattic/jetpack-components'; +import { Text } from '@automattic/jetpack-components'; +import { Text as UIText } from '@wordpress/ui'; import AdminSectionHero from '..'; import InProgressAnimation from '../../in-progress-animation'; +const activeColor = 'var(--jp-green-50)'; + export default { title: 'Plugins/Protect/AdminSectionHero', component: AdminSectionHero, @@ -11,7 +14,29 @@ export const Default = args => ; Default.args = { main: ( <> - + + + { 'Active' } + { 'No threats found' } { 'Most recent results' } diff --git a/projects/plugins/protect/src/js/routes/firewall/firewall-admin-section-hero.tsx b/projects/plugins/protect/src/js/routes/firewall/firewall-admin-section-hero.tsx index a8efa2587de9..64166f102dfa 100644 --- a/projects/plugins/protect/src/js/routes/firewall/firewall-admin-section-hero.tsx +++ b/projects/plugins/protect/src/js/routes/firewall/firewall-admin-section-hero.tsx @@ -1,5 +1,6 @@ -import { Status, Text } from '@automattic/jetpack-components'; +import { Text } from '@automattic/jetpack-components'; import { __, _x } from '@wordpress/i18n'; +import { Text as UIText } from '@wordpress/ui'; import { useMemo } from 'react'; import AdminSectionHero from '../../components/admin-section-hero'; import useWafData from '../../hooks/use-waf-data'; @@ -83,11 +84,35 @@ const FirewallAdminSectionHero = () => { return ; }, [ status ] ); + const statusColor = 'on' === status ? 'var(--jp-green-50)' : 'var(--jp-gray-50)'; + return ( - + + + { statusLabel } + { heading } { subheading } diff --git a/projects/plugins/protect/src/js/routes/scan/history/history-admin-section-hero.tsx b/projects/plugins/protect/src/js/routes/scan/history/history-admin-section-hero.tsx index ef7176423c4b..8e9db3386d01 100644 --- a/projects/plugins/protect/src/js/routes/scan/history/history-admin-section-hero.tsx +++ b/projects/plugins/protect/src/js/routes/scan/history/history-admin-section-hero.tsx @@ -1,6 +1,7 @@ -import { Status, Text } from '@automattic/jetpack-components'; +import { Text } from '@automattic/jetpack-components'; import { dateI18n } from '@wordpress/date'; import { __, sprintf } from '@wordpress/i18n'; +import { Text as UIText } from '@wordpress/ui'; import { useMemo } from 'react'; import { useParams } from 'react-router'; import AdminSectionHero from '../../../components/admin-section-hero'; @@ -49,7 +50,29 @@ const HistoryAdminSectionHero: FC = () => { - + + + { __( 'Active', 'jetpack-protect' ) } + { numAllThreats > 0 ? sprintf( diff --git a/projects/plugins/protect/src/js/routes/scan/scan-admin-section-hero.tsx b/projects/plugins/protect/src/js/routes/scan/scan-admin-section-hero.tsx index 41a06db94b7c..30a598f15386 100644 --- a/projects/plugins/protect/src/js/routes/scan/scan-admin-section-hero.tsx +++ b/projects/plugins/protect/src/js/routes/scan/scan-admin-section-hero.tsx @@ -1,6 +1,7 @@ -import { Text, Status, useBreakpointMatch } from '@automattic/jetpack-components'; +import { Text, useBreakpointMatch } from '@automattic/jetpack-components'; import { dateI18n } from '@wordpress/date'; import { __, _n, _x, sprintf } from '@wordpress/i18n'; +import { Text as UIText } from '@wordpress/ui'; import { useState } from 'react'; import AdminSectionHero from '../../components/admin-section-hero'; import ErrorAdminSectionHero from '../../components/error-admin-section-hero'; @@ -51,7 +52,29 @@ const ScanAdminSectionHero: FC = () => { - + + + { __( 'Active', 'jetpack-protect' ) } + { numThreats > 0 ? sprintf( From e3c3bfe609c2779a93cf175decb0e694ba4a8897 Mon Sep 17 00:00:00 2001 From: Christian Gastrell Date: Tue, 12 May 2026 13:49:20 -0300 Subject: [PATCH 2/3] Componentry: address review - design tokens + CSS classes (no inline styles) - Replace all --jp-* color vars with --wpds-color-fg-content-* design tokens (success/error/warning/info/neutral-weak) in pro-status and protect heroes. - waf.jsx: drop the inline style blocks; move styling under the existing .waf__standalone__mode class in _inc/client/security/style.scss. - Protect heroes: extract a small AdminSectionHero.StatusIndicator helper co-located with the existing admin-section-hero module so the four consumers (storybook, firewall, scan, scan history) share one CSS source instead of duplicating inline style blocks. - Update the @deprecated JSDoc on the Status component to point at the new WPDS tokens so future consumers do not reintroduce --jp-*. Addresses review comments r3228168471, r3228177952, r3228180635 on PR #48711. --- .../components/components/status/index.tsx | 2 +- .../_inc/client/pro-status/style.module.scss | 22 ++++++------- .../jetpack/_inc/client/security/style.scss | 15 +++++++++ .../jetpack/_inc/client/security/waf.jsx | 24 ++------------ .../components/admin-section-hero/index.tsx | 17 ++++++++++ .../stories/index.stories.jsx | 27 +-------------- .../admin-section-hero/styles.module.scss | 33 +++++++++++++++++++ .../firewall/firewall-admin-section-hero.tsx | 27 ++------------- .../history/history-admin-section-hero.tsx | 28 +++------------- .../routes/scan/scan-admin-section-hero.tsx | 28 +++------------- 10 files changed, 90 insertions(+), 133 deletions(-) diff --git a/projects/js-packages/components/components/status/index.tsx b/projects/js-packages/components/components/status/index.tsx index c3c0b3639ea2..0921b18ea4a2 100644 --- a/projects/js-packages/components/components/status/index.tsx +++ b/projects/js-packages/components/components/status/index.tsx @@ -13,7 +13,7 @@ export interface StatusProps { /** * Status component. * - * @deprecated Inline the equivalent JSX using `Text` from `@wordpress/ui` and a small color-coded indicator span. The wrapper renders a flex container at `body-extra-small` size with `font-weight: 600` and a `0.666em` round indicator coloured by status (`var(--jp-green-50)` for `active`, `--jp-red-50` for `error`, `--jp-gray-50` for `inactive`, `--jp-yellow-30` for `action`, `--jp-blue-40` for `initializing`). + * @deprecated Inline the equivalent JSX using `Text` from `@wordpress/ui` and a small color-coded indicator span. The wrapper renders a flex container at `body-sm` size with `font-weight: 600` and a `0.666em` round indicator coloured by status using WPDS design tokens (`var(--wpds-color-fg-content-success)` for `active`, `--wpds-color-fg-content-error` for `error`, `--wpds-color-fg-content-neutral-weak` for `inactive`, `--wpds-color-fg-content-warning` for `action`, `--wpds-color-fg-content-info` for `initializing`). * * @param {StatusProps} props - The component properties. * @param {string} props.className - Optional className forwarded to the outer element. diff --git a/projects/plugins/jetpack/_inc/client/pro-status/style.module.scss b/projects/plugins/jetpack/_inc/client/pro-status/style.module.scss index 290a7713c820..04a1bfa2290c 100644 --- a/projects/plugins/jetpack/_inc/client/pro-status/style.module.scss +++ b/projects/plugins/jetpack/_inc/client/pro-status/style.module.scss @@ -6,48 +6,48 @@ white-space: nowrap; &.is-active { - color: var(--jp-green-50); + color: var(--wpds-color-fg-content-success); .indicator { - background-color: var(--jp-green-50); + background-color: var(--wpds-color-fg-content-success); } } &.is-inactive { - color: var(--jp-gray-50); + color: var(--wpds-color-fg-content-neutral-weak); .indicator { - background-color: var(--jp-gray-50); + background-color: var(--wpds-color-fg-content-neutral-weak); } } &.is-error { - color: var(--jp-red-50); + color: var(--wpds-color-fg-content-error); .indicator { - background-color: var(--jp-red-50); + background-color: var(--wpds-color-fg-content-error); } } &.is-action { - color: var(--jp-yellow-30); + color: var(--wpds-color-fg-content-warning); .indicator { - background-color: var(--jp-yellow-30); + background-color: var(--wpds-color-fg-content-warning); } } &.is-initializing { - color: var(--jp-blue-40); + color: var(--wpds-color-fg-content-info); .indicator { - background-color: var(--jp-blue-40); + background-color: var(--wpds-color-fg-content-info); } } } .indicator { - background-color: var(--jp-gray-50); + background-color: var(--wpds-color-fg-content-neutral-weak); border-radius: 50%; flex-shrink: 0; height: 0.666em; diff --git a/projects/plugins/jetpack/_inc/client/security/style.scss b/projects/plugins/jetpack/_inc/client/security/style.scss index 38e89cc74342..647d7019e014 100644 --- a/projects/plugins/jetpack/_inc/client/security/style.scss +++ b/projects/plugins/jetpack/_inc/client/security/style.scss @@ -9,7 +9,22 @@ display: flex; .waf__standalone__mode { + align-items: center; + color: var(--wpds-color-fg-content-success); + display: inline-flex; + font-weight: 600; + line-height: 1.666; margin-left: auto; + white-space: nowrap; + + .waf__standalone__mode__indicator { + background-color: var(--wpds-color-fg-content-success); + border-radius: 50%; + flex-shrink: 0; + height: 0.666em; + margin-right: 4px; + width: 0.666em; + } } } diff --git a/projects/plugins/jetpack/_inc/client/security/waf.jsx b/projects/plugins/jetpack/_inc/client/security/waf.jsx index 9ae53410373f..2c73cbb4907d 100644 --- a/projects/plugins/jetpack/_inc/client/security/waf.jsx +++ b/projects/plugins/jetpack/_inc/client/security/waf.jsx @@ -206,28 +206,8 @@ export const Waf = class extends Component {
{ _x( 'Firewall', 'Settings header', 'jetpack' ) } { this.props.settings?.standaloneMode && ( - - + + { __( 'Standalone mode', 'jetpack' ) } ) } diff --git a/projects/plugins/protect/src/js/components/admin-section-hero/index.tsx b/projects/plugins/protect/src/js/components/admin-section-hero/index.tsx index 1d176867c602..8d2b77f56d9b 100644 --- a/projects/plugins/protect/src/js/components/admin-section-hero/index.tsx +++ b/projects/plugins/protect/src/js/components/admin-section-hero/index.tsx @@ -3,6 +3,8 @@ import { H3, getIconBySlug, } from '@automattic/jetpack-components'; +import { Text as UIText } from '@wordpress/ui'; +import clsx from 'clsx'; import SeventyFiveLayout from '../seventy-five-layout'; import AdminSectionHeroNotices from './admin-section-hero-notices'; import styles from './styles.module.scss'; @@ -15,9 +17,15 @@ interface AdminSectionHeroProps { spacing?: number; } +interface StatusIndicatorProps { + status: 'active' | 'inactive'; + label: ReactNode; +} + interface AdminSectionHeroComponent extends FC< AdminSectionHeroProps > { Heading: FC< { children: ReactNode; showIcon?: boolean } >; Subheading: FC< { children: ReactNode } >; + StatusIndicator: FC< StatusIndicatorProps >; } const AdminSectionHero: AdminSectionHeroComponent = ( { @@ -64,4 +72,13 @@ AdminSectionHero.Subheading = ( { children }: { children: ReactNode } ) => { return
{ children }
; }; +AdminSectionHero.StatusIndicator = ( { status, label }: StatusIndicatorProps ) => { + return ( + + + { label } + + ); +}; + export default AdminSectionHero; diff --git a/projects/plugins/protect/src/js/components/admin-section-hero/stories/index.stories.jsx b/projects/plugins/protect/src/js/components/admin-section-hero/stories/index.stories.jsx index 42b3186cea5a..524ebb509add 100644 --- a/projects/plugins/protect/src/js/components/admin-section-hero/stories/index.stories.jsx +++ b/projects/plugins/protect/src/js/components/admin-section-hero/stories/index.stories.jsx @@ -1,10 +1,7 @@ import { Text } from '@automattic/jetpack-components'; -import { Text as UIText } from '@wordpress/ui'; import AdminSectionHero from '..'; import InProgressAnimation from '../../in-progress-animation'; -const activeColor = 'var(--jp-green-50)'; - export default { title: 'Plugins/Protect/AdminSectionHero', component: AdminSectionHero, @@ -14,29 +11,7 @@ export const Default = args => ; Default.args = { main: ( <> - - - { 'Active' } - + { 'No threats found' } { 'Most recent results' } diff --git a/projects/plugins/protect/src/js/components/admin-section-hero/styles.module.scss b/projects/plugins/protect/src/js/components/admin-section-hero/styles.module.scss index 566f57bad886..2e3370f3f646 100644 --- a/projects/plugins/protect/src/js/components/admin-section-hero/styles.module.scss +++ b/projects/plugins/protect/src/js/components/admin-section-hero/styles.module.scss @@ -24,3 +24,36 @@ .connection-error-col { margin-top: calc(var(--spacing-base) * 3 + 1px); // 25px } + +.status { + align-items: center; + display: inline-flex; + font-weight: 600; + line-height: 1.666; + white-space: nowrap; + + &.is-active { + color: var(--wpds-color-fg-content-success); + + .indicator { + background-color: var(--wpds-color-fg-content-success); + } + } + + &.is-inactive { + color: var(--wpds-color-fg-content-neutral-weak); + + .indicator { + background-color: var(--wpds-color-fg-content-neutral-weak); + } + } +} + +.indicator { + background-color: var(--wpds-color-fg-content-neutral-weak); + border-radius: 50%; + flex-shrink: 0; + height: 0.666em; + margin-right: 4px; + width: 0.666em; +} diff --git a/projects/plugins/protect/src/js/routes/firewall/firewall-admin-section-hero.tsx b/projects/plugins/protect/src/js/routes/firewall/firewall-admin-section-hero.tsx index 64166f102dfa..b66437dc2d5c 100644 --- a/projects/plugins/protect/src/js/routes/firewall/firewall-admin-section-hero.tsx +++ b/projects/plugins/protect/src/js/routes/firewall/firewall-admin-section-hero.tsx @@ -1,6 +1,5 @@ import { Text } from '@automattic/jetpack-components'; import { __, _x } from '@wordpress/i18n'; -import { Text as UIText } from '@wordpress/ui'; import { useMemo } from 'react'; import AdminSectionHero from '../../components/admin-section-hero'; import useWafData from '../../hooks/use-waf-data'; @@ -84,35 +83,13 @@ const FirewallAdminSectionHero = () => { return ; }, [ status ] ); - const statusColor = 'on' === status ? 'var(--jp-green-50)' : 'var(--jp-gray-50)'; + const indicatorStatus = 'on' === status ? 'active' : 'inactive'; return ( - - - { statusLabel } - + { heading } { subheading } diff --git a/projects/plugins/protect/src/js/routes/scan/history/history-admin-section-hero.tsx b/projects/plugins/protect/src/js/routes/scan/history/history-admin-section-hero.tsx index 8e9db3386d01..07d0461c7cbe 100644 --- a/projects/plugins/protect/src/js/routes/scan/history/history-admin-section-hero.tsx +++ b/projects/plugins/protect/src/js/routes/scan/history/history-admin-section-hero.tsx @@ -1,7 +1,6 @@ import { Text } from '@automattic/jetpack-components'; import { dateI18n } from '@wordpress/date'; import { __, sprintf } from '@wordpress/i18n'; -import { Text as UIText } from '@wordpress/ui'; import { useMemo } from 'react'; import { useParams } from 'react-router'; import AdminSectionHero from '../../../components/admin-section-hero'; @@ -50,29 +49,10 @@ const HistoryAdminSectionHero: FC = () => { - - - { __( 'Active', 'jetpack-protect' ) } - + { numAllThreats > 0 ? sprintf( diff --git a/projects/plugins/protect/src/js/routes/scan/scan-admin-section-hero.tsx b/projects/plugins/protect/src/js/routes/scan/scan-admin-section-hero.tsx index 30a598f15386..616ab29e8c0c 100644 --- a/projects/plugins/protect/src/js/routes/scan/scan-admin-section-hero.tsx +++ b/projects/plugins/protect/src/js/routes/scan/scan-admin-section-hero.tsx @@ -1,7 +1,6 @@ import { Text, useBreakpointMatch } from '@automattic/jetpack-components'; import { dateI18n } from '@wordpress/date'; import { __, _n, _x, sprintf } from '@wordpress/i18n'; -import { Text as UIText } from '@wordpress/ui'; import { useState } from 'react'; import AdminSectionHero from '../../components/admin-section-hero'; import ErrorAdminSectionHero from '../../components/error-admin-section-hero'; @@ -52,29 +51,10 @@ const ScanAdminSectionHero: FC = () => { - - - { __( 'Active', 'jetpack-protect' ) } - + { numThreats > 0 ? sprintf( From 181b147bcf847814c1f4a88941c077511b9171ea Mon Sep 17 00:00:00 2001 From: Christian Gastrell Date: Tue, 12 May 2026 18:09:38 -0300 Subject: [PATCH 3/3] Componentry: fix Status indicator color regression (use *-weak WPDS tokens + hex fallback) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The previous commit switched to --wpds-color-fg-content-success / -error / -warning / -info, but those are the "ink" tokens used as text on tinted backgrounds in alerts/badges — they resolve to near-black hexes (e.g. success = #002900) and are visually indistinguishable from `color: inherit` for a small dot + label. The Status indicator is a standalone color-coded element on a plain admin-page background, so it needs the recognizable shade family — the *-weak tokens: success-weak = #008030 ≈ --jp-green-50 (#008710) error-weak = #cc1818 ≈ --jp-red-50 (#d63638) warning-weak = #926300 ≈ --jp-yellow-* (warm amber) info-weak = #006bd7 ≈ --jp-blue-* (link blue) neutral-weak = #707070 ≈ --jp-gray-50 (#646970) In addition, the legacy Jetpack settings dashboard (which hosts the WAF standalone-mode indicator and the Pro Status panel) does NOT load `@wordpress/theme/design-tokens.css` at all — so any --wpds-* variable resolves to empty/initial there, and the indicator falls back to `color: inherit`. Add a hex fallback inside each var(--wpds-…, #rrggbb) so the legacy dashboard renders the right shade without depending on the design-tokens stylesheet being enqueued. Verified in DevTools on the live dev site: - /wp-admin/admin.php?page=jetpack-protect#/scan → indicator color now rgb(0, 128, 48) (was rgb(0, 41, 0) near-black). - /wp-admin/admin.php?page=jetpack-protect#/firewall → same. - /wp-admin/admin.php?page=jetpack (legacy dashboard) → WPDS token resolves empty but the #008030 fallback paints correctly. Also update the @deprecated JSDoc on the Status component to point at the *-weak tokens and to mention the hex-fallback requirement. --- .../components/components/status/index.tsx | 2 +- .../_inc/client/pro-status/style.module.scss | 22 +++++++++---------- .../jetpack/_inc/client/security/style.scss | 4 ++-- .../admin-section-hero/styles.module.scss | 10 ++++----- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/projects/js-packages/components/components/status/index.tsx b/projects/js-packages/components/components/status/index.tsx index 0921b18ea4a2..a0b4db9bd715 100644 --- a/projects/js-packages/components/components/status/index.tsx +++ b/projects/js-packages/components/components/status/index.tsx @@ -13,7 +13,7 @@ export interface StatusProps { /** * Status component. * - * @deprecated Inline the equivalent JSX using `Text` from `@wordpress/ui` and a small color-coded indicator span. The wrapper renders a flex container at `body-sm` size with `font-weight: 600` and a `0.666em` round indicator coloured by status using WPDS design tokens (`var(--wpds-color-fg-content-success)` for `active`, `--wpds-color-fg-content-error` for `error`, `--wpds-color-fg-content-neutral-weak` for `inactive`, `--wpds-color-fg-content-warning` for `action`, `--wpds-color-fg-content-info` for `initializing`). + * @deprecated Inline the equivalent JSX using `Text` from `@wordpress/ui` and a small color-coded indicator span. The wrapper renders a flex container at `body-sm` size with `font-weight: 600` and a `0.666em` round indicator coloured by status using WPDS design tokens (`var(--wpds-color-fg-content-success-weak)` for `active`, `--wpds-color-fg-content-error-weak` for `error`, `--wpds-color-fg-content-neutral-weak` for `inactive`, `--wpds-color-fg-content-warning-weak` for `action`, `--wpds-color-fg-content-info-weak` for `initializing`). Include a fallback hex for surfaces that don't load `@wordpress/theme/design-tokens.css` (e.g. the legacy Jetpack settings dashboard). * * @param {StatusProps} props - The component properties. * @param {string} props.className - Optional className forwarded to the outer element. diff --git a/projects/plugins/jetpack/_inc/client/pro-status/style.module.scss b/projects/plugins/jetpack/_inc/client/pro-status/style.module.scss index 04a1bfa2290c..829b86a4e3be 100644 --- a/projects/plugins/jetpack/_inc/client/pro-status/style.module.scss +++ b/projects/plugins/jetpack/_inc/client/pro-status/style.module.scss @@ -6,48 +6,48 @@ white-space: nowrap; &.is-active { - color: var(--wpds-color-fg-content-success); + color: var(--wpds-color-fg-content-success-weak, #008030); .indicator { - background-color: var(--wpds-color-fg-content-success); + background-color: var(--wpds-color-fg-content-success-weak, #008030); } } &.is-inactive { - color: var(--wpds-color-fg-content-neutral-weak); + color: var(--wpds-color-fg-content-neutral-weak, #707070); .indicator { - background-color: var(--wpds-color-fg-content-neutral-weak); + background-color: var(--wpds-color-fg-content-neutral-weak, #707070); } } &.is-error { - color: var(--wpds-color-fg-content-error); + color: var(--wpds-color-fg-content-error-weak, #cc1818); .indicator { - background-color: var(--wpds-color-fg-content-error); + background-color: var(--wpds-color-fg-content-error-weak, #cc1818); } } &.is-action { - color: var(--wpds-color-fg-content-warning); + color: var(--wpds-color-fg-content-warning-weak, #926300); .indicator { - background-color: var(--wpds-color-fg-content-warning); + background-color: var(--wpds-color-fg-content-warning-weak, #926300); } } &.is-initializing { - color: var(--wpds-color-fg-content-info); + color: var(--wpds-color-fg-content-info-weak, #006bd7); .indicator { - background-color: var(--wpds-color-fg-content-info); + background-color: var(--wpds-color-fg-content-info-weak, #006bd7); } } } .indicator { - background-color: var(--wpds-color-fg-content-neutral-weak); + background-color: var(--wpds-color-fg-content-neutral-weak, #707070); border-radius: 50%; flex-shrink: 0; height: 0.666em; diff --git a/projects/plugins/jetpack/_inc/client/security/style.scss b/projects/plugins/jetpack/_inc/client/security/style.scss index 647d7019e014..0b9ab21b774f 100644 --- a/projects/plugins/jetpack/_inc/client/security/style.scss +++ b/projects/plugins/jetpack/_inc/client/security/style.scss @@ -10,7 +10,7 @@ .waf__standalone__mode { align-items: center; - color: var(--wpds-color-fg-content-success); + color: var(--wpds-color-fg-content-success-weak, #008030); display: inline-flex; font-weight: 600; line-height: 1.666; @@ -18,7 +18,7 @@ white-space: nowrap; .waf__standalone__mode__indicator { - background-color: var(--wpds-color-fg-content-success); + background-color: var(--wpds-color-fg-content-success-weak, #008030); border-radius: 50%; flex-shrink: 0; height: 0.666em; diff --git a/projects/plugins/protect/src/js/components/admin-section-hero/styles.module.scss b/projects/plugins/protect/src/js/components/admin-section-hero/styles.module.scss index 2e3370f3f646..6d31f53ef1bd 100644 --- a/projects/plugins/protect/src/js/components/admin-section-hero/styles.module.scss +++ b/projects/plugins/protect/src/js/components/admin-section-hero/styles.module.scss @@ -33,24 +33,24 @@ white-space: nowrap; &.is-active { - color: var(--wpds-color-fg-content-success); + color: var(--wpds-color-fg-content-success-weak, #008030); .indicator { - background-color: var(--wpds-color-fg-content-success); + background-color: var(--wpds-color-fg-content-success-weak, #008030); } } &.is-inactive { - color: var(--wpds-color-fg-content-neutral-weak); + color: var(--wpds-color-fg-content-neutral-weak, #707070); .indicator { - background-color: var(--wpds-color-fg-content-neutral-weak); + background-color: var(--wpds-color-fg-content-neutral-weak, #707070); } } } .indicator { - background-color: var(--wpds-color-fg-content-neutral-weak); + background-color: var(--wpds-color-fg-content-neutral-weak, #707070); border-radius: 50%; flex-shrink: 0; height: 0.666em;