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..a0b4db9bd715 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-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.
+ * @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..829b86a4e3be
--- /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(--wpds-color-fg-content-success-weak, #008030);
+
+ .indicator {
+ background-color: var(--wpds-color-fg-content-success-weak, #008030);
+ }
+ }
+
+ &.is-inactive {
+ color: var(--wpds-color-fg-content-neutral-weak, #707070);
+
+ .indicator {
+ background-color: var(--wpds-color-fg-content-neutral-weak, #707070);
+ }
+ }
+
+ &.is-error {
+ color: var(--wpds-color-fg-content-error-weak, #cc1818);
+
+ .indicator {
+ background-color: var(--wpds-color-fg-content-error-weak, #cc1818);
+ }
+ }
+
+ &.is-action {
+ color: var(--wpds-color-fg-content-warning-weak, #926300);
+
+ .indicator {
+ background-color: var(--wpds-color-fg-content-warning-weak, #926300);
+ }
+ }
+
+ &.is-initializing {
+ color: var(--wpds-color-fg-content-info-weak, #006bd7);
+
+ .indicator {
+ background-color: var(--wpds-color-fg-content-info-weak, #006bd7);
+ }
+ }
+}
+
+.indicator {
+ background-color: var(--wpds-color-fg-content-neutral-weak, #707070);
+ border-radius: 50%;
+ flex-shrink: 0;
+ height: 0.666em;
+ margin-right: 4px;
+ width: 0.666em;
+}
diff --git a/projects/plugins/jetpack/_inc/client/security/style.scss b/projects/plugins/jetpack/_inc/client/security/style.scss
index 38e89cc74342..0b9ab21b774f 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-weak, #008030);
+ 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-weak, #008030);
+ 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..2c73cbb4907d 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,10 @@ export const Waf = class extends Component {
{ _x( 'Firewall', 'Settings header', 'jetpack' ) }
{ this.props.settings?.standaloneMode && (
-
+
+
+ { __( '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/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 7d5b4f8066c9..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,4 +1,4 @@
-import { Status, Text } from '@automattic/jetpack-components';
+import { Text } from '@automattic/jetpack-components';
import AdminSectionHero from '..';
import InProgressAnimation from '../../in-progress-animation';
@@ -11,7 +11,7 @@ export const Default = args => ;
Default.args = {
main: (
<>
-
+
{ '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..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
@@ -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-weak, #008030);
+
+ .indicator {
+ background-color: var(--wpds-color-fg-content-success-weak, #008030);
+ }
+ }
+
+ &.is-inactive {
+ color: var(--wpds-color-fg-content-neutral-weak, #707070);
+
+ .indicator {
+ background-color: var(--wpds-color-fg-content-neutral-weak, #707070);
+ }
+ }
+}
+
+.indicator {
+ background-color: var(--wpds-color-fg-content-neutral-weak, #707070);
+ 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 a8efa2587de9..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,4 +1,4 @@
-import { Status, Text } from '@automattic/jetpack-components';
+import { Text } from '@automattic/jetpack-components';
import { __, _x } from '@wordpress/i18n';
import { useMemo } from 'react';
import AdminSectionHero from '../../components/admin-section-hero';
@@ -83,11 +83,13 @@ const FirewallAdminSectionHero = () => {
return ;
}, [ status ] );
+ const indicatorStatus = 'on' === status ? 'active' : 'inactive';
+
return (
-
+
{ 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..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,4 +1,4 @@
-import { Status, Text } from '@automattic/jetpack-components';
+import { Text } from '@automattic/jetpack-components';
import { dateI18n } from '@wordpress/date';
import { __, sprintf } from '@wordpress/i18n';
import { useMemo } from 'react';
@@ -49,7 +49,10 @@ const HistoryAdminSectionHero: FC = () => {
-
+
{ 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..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,4 +1,4 @@
-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 { useState } from 'react';
@@ -51,7 +51,10 @@ const ScanAdminSectionHero: FC = () => {
-
+
{ numThreats > 0
? sprintf(