Commit ef83ea66be7 for woocommerce
commit ef83ea66be7e1243a72db11154bcd49baeb862e8
Author: Jill Q. <jill.quek@automattic.com>
Date: Wed Jun 10 17:08:12 2026 +0800
Analytics: align Date range and Data status, refine Update now button (#64846)
* Analytics: align Date range and Data status, refine Update now button
- Drop trailing colons on "Date range" and "Data status" labels (WP 7.0 form-label convention).
- Use a consistent "M j at H:i" format for Last updated and Next update values.
- Move the import-status-bar wrapper's compact label/gap from $break-large to $break-wide so it shrinks in lockstep with .woocommerce-filters-filter — fixes the ~5px vertical misalignment between the Date range and Data status boxes at 960–1280px.
- Add flex: 1 to __content and margin-left: auto to __trigger so "Update now" stays right-aligned with flexible whitespace at mid-range widths.
- Remove font-size / font-weight overrides on the trigger so it picks up @wordpress/components Button defaults (13px, regular, accent color).
- Bump bar typography from 11px to 13px, soften the border from $gray-400 to $gray-300, and use --wp-components-color-foreground / -muted with color-studio fallbacks.
- Add white-space: nowrap to __value to prevent two-line wrapping just before the sidebar collapses.
- Wrap __content at <$break-mobile and let bar height grow so "Update now" drops below the values instead of clipping off-screen.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* Update e2e selector to match colon-less "Data status" label
The label dropped its trailing colon to match WP 7.0 form-field
conventions, but the e2e test was still querying for "Data status:".
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* Consolidate identical date-format helpers into one shared formatStatusDate
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Co-authored-by: Chi-Hsuan Huang <chihsuan.tw@gmail.com>
diff --git a/packages/js/components/changelog/sprinkle-analytics-date-range-alignment b/packages/js/components/changelog/sprinkle-analytics-date-range-alignment
new file mode 100644
index 00000000000..9ad9b96745e
--- /dev/null
+++ b/packages/js/components/changelog/sprinkle-analytics-date-range-alignment
@@ -0,0 +1,4 @@
+Significance: patch
+Type: tweak
+
+Drop the trailing colon on the Date range filter label to match WordPress 7.0 form-field labeling.
diff --git a/packages/js/components/src/date-range-filter-picker/index.js b/packages/js/components/src/date-range-filter-picker/index.js
index 410414435ae..2b1651cf524 100644
--- a/packages/js/components/src/date-range-filter-picker/index.js
+++ b/packages/js/components/src/date-range-filter-picker/index.js
@@ -141,7 +141,7 @@ class DateRangeFilterPicker extends Component {
return (
<div className="woocommerce-filters-filter">
<span className="woocommerce-filters-label">
- { __( 'Date range', 'woocommerce' ) }:
+ { __( 'Date range', 'woocommerce' ) }
</span>
<Dropdown
contentClassName={ contentClasses }
diff --git a/plugins/woocommerce/changelog/sprinkle-analytics-date-range-alignment b/plugins/woocommerce/changelog/sprinkle-analytics-date-range-alignment
new file mode 100644
index 00000000000..8636664e5fc
--- /dev/null
+++ b/plugins/woocommerce/changelog/sprinkle-analytics-date-range-alignment
@@ -0,0 +1,4 @@
+Significance: patch
+Type: tweak
+
+Align the Data status box with the Date range filter at mid-range viewports, drop the trailing colons on both labels, use a consistent "M j at H:i" date format, and pick up WP component defaults for the Update now button and bar typography.
diff --git a/plugins/woocommerce/client/admin/client/analytics/components/import-status-bar/import-status-bar.scss b/plugins/woocommerce/client/admin/client/analytics/components/import-status-bar/import-status-bar.scss
index 2d1e38084e8..da9eb807549 100644
--- a/plugins/woocommerce/client/admin/client/analytics/components/import-status-bar/import-status-bar.scss
+++ b/plugins/woocommerce/client/admin/client/analytics/components/import-status-bar/import-status-bar.scss
@@ -16,7 +16,9 @@
font-weight: 400;
}
- @media screen and ( max-width: $break-large ) {
+ // Match the filters' breakpoint so label/gap shrink in lockstep with
+ // .woocommerce-filters-filter — keeps Date Range and Data Status boxes aligned.
+ @media screen and ( max-width: $break-wide ) {
gap: 5px;
&__label {
@@ -29,18 +31,20 @@
.woocommerce-analytics-import-status-bar {
display: flex;
align-items: center;
- border: 1px solid $gray-400;
+ border: 1px solid $gray-300;
border-radius: 4px;
- padding: 16px 12px;
- font-size: 11px;
+ padding: 6px 12px;
+ font-size: 13px;
line-height: 20px;
font-weight: 400;
height: 50px;
+ color: var(--wp-components-color-foreground, #1e1e1e);
&__content {
display: flex;
align-items: center;
gap: 32px;
+ flex: 1;
@media screen and ( max-width: $break-wide ) {
@@ -58,24 +62,36 @@
}
&__label {
- color: $gray-700;
+ color: var(--wp-components-color-foreground-muted, $gray-700);
white-space: nowrap;
}
&__value {
- color: $gray-900;
+ color: var(--wp-components-color-foreground, $gray-900);
+ white-space: nowrap;
}
&__trigger {
- font-size: 11px;
- font-weight: 500;
- line-height: 20px;
// Set a fixed width to prevent layout shift during loading
- width: 88px;
+ width: 100px;
+ // Right-align so flexible whitespace sits between the columns and the button.
+ margin-left: auto;
}
.components-spinner {
height: 8px;
width: 8px;
}
+
+ // At very narrow widths the row can't fit; let the trigger wrap below the values.
+ @media screen and ( max-width: $break-mobile ) {
+ height: auto;
+ min-height: 50px;
+ padding: 8px 12px;
+
+ &__content {
+ flex-wrap: wrap;
+ row-gap: 8px;
+ }
+ }
}
diff --git a/plugins/woocommerce/client/admin/client/analytics/components/import-status-bar/import-status-bar.tsx b/plugins/woocommerce/client/admin/client/analytics/components/import-status-bar/import-status-bar.tsx
index ee76f8d8bf6..667e59fcdc3 100644
--- a/plugins/woocommerce/client/admin/client/analytics/components/import-status-bar/import-status-bar.tsx
+++ b/plugins/woocommerce/client/admin/client/analytics/components/import-status-bar/import-status-bar.tsx
@@ -13,6 +13,31 @@ import { useSettings } from '@woocommerce/data';
import { useImportStatus } from './use-import-status';
import './import-status-bar.scss';
+/**
+ * Format an import status date string for display.
+ *
+ * Shared by the "Last updated" and "Next update" values so the
+ * format stays consistent between the two.
+ *
+ * @param {string|null} date - Date string in 'Y-m-d H:i:s' format (site timezone)
+ * @return {string} Formatted date string or "Never"
+ */
+const formatStatusDate = ( date: string | null ): string => {
+ if ( ! date ) {
+ return __( 'Never', 'woocommerce' );
+ }
+ return dateI18n(
+ /**
+ * translators: PHP date format for the Analytics import status dates,
+ * e.g. "Nov 21 at 12:00". "M j" shows the month and day, "at" is a
+ * literal, "H:i" shows the time (24-hour format).
+ */
+ __( 'M j \\a\\t H:i', 'woocommerce' ),
+ date,
+ undefined
+ );
+};
+
/**
* Analytics Import Status Bar Component
*
@@ -46,36 +71,6 @@ export function ImportStatusBar(): JSX.Element | null {
return null;
}
- /**
- * Format a date string for display
- *
- * @param {string|null} date - Date string in 'Y-m-d H:i:s' format (site timezone)
- * @return {string} Formatted date string or "Never"
- */
- const formatLastProcessedDate = ( date: string | null ): string => {
- if ( ! date ) {
- return __( 'Never', 'woocommerce' );
- }
- return dateI18n( 'M j H:i', date, undefined );
- };
-
- const formatNextScheduledDate = ( date: string | null ): string => {
- if ( ! date ) {
- return __( 'Never', 'woocommerce' );
- }
-
- return dateI18n(
- /**
- * translators: %s: formatted date and time in site timezone.
- * Used to display the next scheduled time for the Analytics import, e.g. "Nov 21 at 12:00".
- * "M j" shows the month and day, "at" as literal, "H:i" shows time (24-hour format).
- */
- __( 'M j \\a\\t H:i', 'woocommerce' ),
- date,
- undefined
- );
- };
-
/**
* Handle manual import trigger
*/
@@ -114,7 +109,7 @@ export function ImportStatusBar(): JSX.Element | null {
return (
<div className="woocommerce-analytics-import-status-bar-wrapper">
<div className="woocommerce-analytics-import-status-bar-wrapper__label">
- { __( 'Data status:', 'woocommerce' ) }
+ { __( 'Data status', 'woocommerce' ) }
</div>
<div
className="woocommerce-analytics-import-status-bar"
@@ -132,7 +127,7 @@ export function ImportStatusBar(): JSX.Element | null {
{ isLoading ? (
<Spinner />
) : (
- formatLastProcessedDate(
+ formatStatusDate(
status?.last_processed_date || null
)
) }
@@ -146,7 +141,7 @@ export function ImportStatusBar(): JSX.Element | null {
{ isLoading ? (
<Spinner />
) : (
- formatNextScheduledDate(
+ formatStatusDate(
status?.next_scheduled || null
)
) }
diff --git a/plugins/woocommerce/tests/e2e-pw/tests/analytics/analytics-overview.spec.ts b/plugins/woocommerce/tests/e2e-pw/tests/analytics/analytics-overview.spec.ts
index d3ec35c9b2d..7d72cf41c36 100644
--- a/plugins/woocommerce/tests/e2e-pw/tests/analytics/analytics-overview.spec.ts
+++ b/plugins/woocommerce/tests/e2e-pw/tests/analytics/analytics-overview.spec.ts
@@ -341,7 +341,7 @@ test.describe(
await page.reload();
// Verify import status bar is visible
- await expect( page.getByText( 'Data status:' ) ).toBeVisible();
+ await expect( page.getByText( 'Data status' ) ).toBeVisible();
// Verify "Update now" button is visible
const updateButton = page.getByRole( 'button', {
name: 'Manually trigger analytics data import',
@@ -385,7 +385,7 @@ test.describe(
await page.reload();
// Verify import status bar wrapper is NOT rendered
- await expect( page.getByText( 'Data status:' ) ).toBeHidden();
+ await expect( page.getByText( 'Data status' ) ).toBeHidden();
} );
}
);