Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 24 additions & 2 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Significance: patch
Type: added

Port the components package (date range/comparison filter UI components and SCSS) from next-woocommerce-analytics as the internal `ui` package.
16 changes: 16 additions & 0 deletions projects/packages/premium-analytics/eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,21 @@ export default defineConfig(
'jsdoc/require-returns': 'off',
'jsdoc/check-indentation': 'off',
},
},
{
// First UI package in the port: also soften JSDoc rules for the ui
// package and allow the upstream inline-handler JSX style. Temporary —
// tighten these up in a follow-up alongside datetime/formatters.
files: [ 'packages/ui/**' ],
rules: {
'jsdoc/require-jsdoc': 'off',
'jsdoc/require-description': 'off',
'jsdoc/require-param': 'off',
'jsdoc/require-param-description': 'off',
'jsdoc/require-returns': 'off',
'jsdoc/check-indentation': 'off',
'jsdoc/escape-inline-tags': 'off',
'react/jsx-no-bind': 'off',
},
}
);
7 changes: 7 additions & 0 deletions projects/packages/premium-analytics/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,18 @@
},
"dependencies": {
"@automattic/number-formatters": "workspace:*",
"@automattic/ui": "1.0.2",
"@date-fns/tz": "1.4.1",
"@wordpress/boot": "0.13.0",
"@wordpress/components": "33.1.0",
"@wordpress/compose": "7.46.0",
"@wordpress/data": "10.46.0",
"@wordpress/i18n": "^6.9.0",
"@wordpress/icons": "^13.0.0",
"@wordpress/private-apis": "1.46.0",
"@wordpress/route": "0.12.0",
"@wordpress/ui": "0.13.0",
"clsx": "2.1.1",
"date-fns": "4.1.0",
"react": "18.3.1",
"react-dom": "18.3.1"
Expand All @@ -44,6 +50,7 @@
"@babel/core": "7.29.0",
"@types/jest": "30.0.0",
"@typescript/native-preview": "7.0.0-dev.20260225.1",
"@wordpress/base-styles": "8.0.0",
"@wordpress/build": "0.14.0",
"browserslist": "4.28.2"
}
Expand Down
24 changes: 24 additions & 0 deletions projects/packages/premium-analytics/packages/ui/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"name": "@automattic/jetpack-premium-analytics-ui",
"version": "0.1.0",
"private": true,
"type": "module",
"main": "src/index.ts",
"types": "src/index.ts",
"sideEffects": [
"*.scss"
],
"dependencies": {
"@automattic/ui": "1.0.2",
"@jetpack-premium-analytics/datetime": "workspace:*",
"@jetpack-premium-analytics/formatters": "workspace:*",
"@wordpress/components": "33.1.0",
"@wordpress/compose": "7.46.0",
"@wordpress/i18n": "^6.9.0",
"@wordpress/icons": "^13.0.0",
"@wordpress/private-apis": "1.46.0",
"@wordpress/ui": "0.13.0",
"clsx": "2.1.1",
"react": "18.3.1"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
.date-comparison-dropdown {

&__button {
background-color: var(--wpds-color-bg-surface-neutral-strong);
}
}

.date-filters-panel-button {
background-color: var(--wpds-color-bg-surface-neutral-strong);
}

.date-comparison-dropdown__popover {
width: 235px;
}

/* disable animation for the date range popover */
/* stylelint-disable property-no-unknown, selector-pseudo-element-no-unknown */
@media not ( prefers-reduced-motion: reduce ) {

.date-comparison-dropdown__popover {
view-transition-name: next-admin--date-comparison-dropdown;
transition: none !important;
}
}

/* ensure it's above the canvas/stage during the transition */
::view-transition-group(next-admin--date-comparison-dropdown) {
z-index: 3000;
}

/* no animation for the snapshot (avoid "flashing") */
::view-transition-new(next-admin--date-comparison-dropdown),
::view-transition-old(next-admin--date-comparison-dropdown) {
animation: none;
}
/* stylelint-enable property-no-unknown, selector-pseudo-element-no-unknown */
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
/**
* External dependencies
*/
import { formatDateRange } from '@jetpack-premium-analytics/formatters';
import { privateApis as componentsPrivateApis } from '@wordpress/components';
import { sprintf, __ } from '@wordpress/i18n';
import { Button } from '@wordpress/ui';
import { useMemo } from 'react';
/**
* Internal dependencies
*/
import { DateRangePresets } from '../date-range-presets';
import { unlock } from '../lock/unlock';
import type { ComparisonDateRangePreset } from '../use-comparison-date-presets';
import type {
ComparisonPresetId,
DateRangePreset,
PrimaryPresetId,
} from '@jetpack-premium-analytics/datetime';
import './date-comparison-dropdown.scss';

const { Menu } = unlock( componentsPrivateApis );

type DateComparisonDropdownProps = {
/**
* Available comparison presets (e.g., previous-period, previous-month)
*/
presets: ComparisonDateRangePreset[];
/**
* Whether comparison is enabled
*/
enabled: boolean;
/**
* Currently selected comparison preset ID
*/
presetId?: ComparisonPresetId;
/**
* Whether to remove "Compare to:" prefix from button label
*/
removeCompareToPrefix?: boolean;
/**
* Callback when comparison is enabled
*/
onEnable: () => void;
/**
* Callback when a comparison preset is selected
*/
onPresetChange: ( id: ComparisonPresetId ) => void;
/**
* Callback when comparison is cleared
*/
onClear: () => void;
};

export function DateComparisonDropdown( {
presets,
enabled,
presetId,
removeCompareToPrefix = false,
onEnable,
onPresetChange,
onClear,
}: DateComparisonDropdownProps ) {
const selectedPreset = useMemo(
() => ( presetId ? presets.find( p => p.id === presetId ) : undefined ),
[ presets, presetId ]
);

const comparisonRange = selectedPreset?.range;
const hasValidPreset = !! comparisonRange;
const hasPresets = presets.length > 0;

if ( ! enabled ) {
return (
<Menu>
<Menu.TriggerButton
render={
<Button
className="date-filters-panel-button"
variant="outline"
tone="neutral"
size="compact"
id="date-comparison-dropdown-button"
>
{ __( 'No comparison', 'jetpack-premium-analytics' ) }
</Button>
}
/>
<Menu.Popover className="date-comparison-dropdown__popover">
<Menu.Group>
<Menu.CheckboxItem name="comparison-toggle" value="no-comparison" checked={ true }>
<Menu.ItemLabel>
{ __( 'No comparison', 'jetpack-premium-analytics' ) }
</Menu.ItemLabel>
</Menu.CheckboxItem>

<Menu.CheckboxItem
name="comparison-toggle"
value="comparison-to-past"
checked={ false }
onChange={ onEnable }
hideOnClick
>
<Menu.ItemLabel>
{ __( 'Comparison to past', 'jetpack-premium-analytics' ) }
</Menu.ItemLabel>
</Menu.CheckboxItem>
</Menu.Group>
</Menu.Popover>
</Menu>
);
}

let label: string = __( 'Select comparison', 'jetpack-premium-analytics' );
if ( hasValidPreset ) {
if ( removeCompareToPrefix ) {
label = formatDateRange( comparisonRange );
} else {
label = sprintf(
// translators: %s is the comparison range label
__( 'Compare to: %s', 'jetpack-premium-analytics' ),
formatDateRange( comparisonRange )
);
}
}

return (
<Menu>
<Menu.TriggerButton
render={
<Button
className="date-comparison-dropdown__button"
variant="outline"
tone="neutral"
size="compact"
>
{ label }
</Button>
}
/>
<Menu.Popover className="date-comparison-dropdown__popover">
{ hasPresets && (
<DateRangePresets
/*
* DateRangePresets is typed for primary presets, but it only
* reads `id`/`label`/`range` to render each row, so it renders
* comparison presets identically. Cast to the primary-preset
* prop types; the runtime shape matches.
*/
value={ ( presetId ?? null ) as PrimaryPresetId | null }
presets={ presets as unknown as DateRangePreset[] }
hideOnClick
onRangeChange={ ( _range, id ) => {
/*
* Type assertion is safe here because:
* 1. presets is ComparisonDateRangePreset[] (strongly typed)
* 2. DateRangePresets picks id from our presets array
* 3. Therefore id must be ComparisonPresetId
*/
onPresetChange( id as ComparisonPresetId );
} }
onClear={ onClear }
/>
) }
</Menu.Popover>
</Menu>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { DateComparisonDropdown } from './date-comparison-dropdown';
Loading
Loading