@automattic/jetpack-components 0.48.2 → 0.48.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/components/boost-score-graph/annotations-plugin.ts +70 -0
- package/components/boost-score-graph/index.tsx +12 -1
- package/components/boost-score-graph/style-annotation.scss +70 -0
- package/components/boost-score-graph/tooltips-plugin.ts +5 -10
- package/components/boost-score-graph/uplot-line-chart.tsx +19 -5
- package/components/button/index.tsx +11 -2
- package/components/jetpack-footer/index.tsx +13 -1
- package/components/jetpack-footer/style.scss +13 -0
- package/components/jetpack-logo/index.tsx +3 -1
- package/package.json +5 -5
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
### This is a list detailing changes for the Jetpack RNA Components package releases.
|
|
4
4
|
|
|
5
|
+
## [0.48.4] - 2024-02-22
|
|
6
|
+
### Added
|
|
7
|
+
- Adding accesible text for external links on connection page and footer [#35733]
|
|
8
|
+
|
|
9
|
+
### Changed
|
|
10
|
+
- Updated package dependencies. [#35793]
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- Jetpack Logo: prevent VoiceOver on Safari from reading SVG content [#35752]
|
|
14
|
+
|
|
15
|
+
## [0.48.3] - 2024-02-19
|
|
16
|
+
### Added
|
|
17
|
+
- Added support for annotations in graph [#34978]
|
|
18
|
+
|
|
5
19
|
## [0.48.2] - 2024-02-13
|
|
6
20
|
### Changed
|
|
7
21
|
- Updated package dependencies. [#35608]
|
|
@@ -941,6 +955,8 @@
|
|
|
941
955
|
### Changed
|
|
942
956
|
- Update node version requirement to 14.16.1
|
|
943
957
|
|
|
958
|
+
[0.48.4]: https://github.com/Automattic/jetpack-components/compare/0.48.3...0.48.4
|
|
959
|
+
[0.48.3]: https://github.com/Automattic/jetpack-components/compare/0.48.2...0.48.3
|
|
944
960
|
[0.48.2]: https://github.com/Automattic/jetpack-components/compare/0.48.1...0.48.2
|
|
945
961
|
[0.48.1]: https://github.com/Automattic/jetpack-components/compare/0.48.0...0.48.1
|
|
946
962
|
[0.48.0]: https://github.com/Automattic/jetpack-components/compare/0.47.0...0.48.0
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import uPlot from 'uplot';
|
|
2
|
+
import { Annotation } from '.';
|
|
3
|
+
|
|
4
|
+
import './style-annotation.scss';
|
|
5
|
+
|
|
6
|
+
// eslint-disable-next-line jsdoc/require-returns
|
|
7
|
+
/**
|
|
8
|
+
* Custom tooltips plugin for uPlot.
|
|
9
|
+
*
|
|
10
|
+
* @param {Annotation[]} annotations - The periods to display in the tooltip.
|
|
11
|
+
*/
|
|
12
|
+
export function annotationsPlugin( annotations: Annotation[] ) {
|
|
13
|
+
let containerEl, annotationsContainer;
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Initialize the plugin
|
|
17
|
+
*
|
|
18
|
+
* @param {uPlot} u - The uPlot instance.
|
|
19
|
+
*/
|
|
20
|
+
function init( u: uPlot ) {
|
|
21
|
+
containerEl = u.under;
|
|
22
|
+
|
|
23
|
+
annotationsContainer = document.createElement( 'div' );
|
|
24
|
+
|
|
25
|
+
annotationsContainer.classList.add( 'jb-graph-annotations' );
|
|
26
|
+
|
|
27
|
+
const annotationEl = document.createElement( 'div' );
|
|
28
|
+
annotationEl.classList.add( 'jb-graph-annotations__annotation' );
|
|
29
|
+
|
|
30
|
+
annotations.forEach( annotation => {
|
|
31
|
+
const lineEl = document.createElement( 'div' );
|
|
32
|
+
lineEl.classList.add( 'jb-graph-annotations__line' );
|
|
33
|
+
lineEl.addEventListener( 'mouseenter', () => {
|
|
34
|
+
annotationEl.innerHTML = annotation.text;
|
|
35
|
+
annotationEl.style.display = 'block';
|
|
36
|
+
annotationEl.style.left = u.valToPos( annotation.timestamp / 1000, 'x' ) + 'px';
|
|
37
|
+
} );
|
|
38
|
+
lineEl.addEventListener( 'mouseleave', () => {
|
|
39
|
+
annotationEl.style.display = 'none';
|
|
40
|
+
} );
|
|
41
|
+
|
|
42
|
+
annotation.line = lineEl;
|
|
43
|
+
annotationsContainer.appendChild( lineEl );
|
|
44
|
+
} );
|
|
45
|
+
|
|
46
|
+
containerEl.appendChild( annotationsContainer );
|
|
47
|
+
u.over.appendChild( annotationEl );
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Called when the chart is resized.
|
|
52
|
+
* @param {uPlot} u - The uPlot instance.
|
|
53
|
+
*/
|
|
54
|
+
function setSize( u: uPlot ) {
|
|
55
|
+
annotations.forEach( annotation => {
|
|
56
|
+
const annotationEl = annotation.line;
|
|
57
|
+
|
|
58
|
+
uPlot.assign( annotationEl.style, {
|
|
59
|
+
left: u.valToPos( annotation.timestamp / 1000, 'x' ) + 'px',
|
|
60
|
+
} );
|
|
61
|
+
} );
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return {
|
|
65
|
+
hooks: {
|
|
66
|
+
init,
|
|
67
|
+
setSize,
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
}
|
|
@@ -17,8 +17,14 @@ export interface Period {
|
|
|
17
17
|
mobile_tbt: number;
|
|
18
18
|
};
|
|
19
19
|
}
|
|
20
|
+
export interface Annotation {
|
|
21
|
+
timestamp: number;
|
|
22
|
+
text: string;
|
|
23
|
+
line?: HTMLElement;
|
|
24
|
+
}
|
|
20
25
|
export interface BoostScoreGraphProps {
|
|
21
26
|
periods?: Period[];
|
|
27
|
+
annotations?: Annotation[];
|
|
22
28
|
startDate?: number;
|
|
23
29
|
endDate?: number;
|
|
24
30
|
title?: string;
|
|
@@ -42,6 +48,7 @@ export type ScoreGraphAlignedData = [
|
|
|
42
48
|
*/
|
|
43
49
|
export const BoostScoreGraph: FunctionComponent< BoostScoreGraphProps > = ( {
|
|
44
50
|
periods = [],
|
|
51
|
+
annotations = [],
|
|
45
52
|
startDate = 0,
|
|
46
53
|
endDate = 0,
|
|
47
54
|
title,
|
|
@@ -80,7 +87,11 @@ export const BoostScoreGraph: FunctionComponent< BoostScoreGraphProps > = ( {
|
|
|
80
87
|
<Background />
|
|
81
88
|
</div>
|
|
82
89
|
) : (
|
|
83
|
-
<UplotLineChart
|
|
90
|
+
<UplotLineChart
|
|
91
|
+
periods={ periods }
|
|
92
|
+
annotations={ annotations }
|
|
93
|
+
range={ { startDate, endDate } }
|
|
94
|
+
/>
|
|
84
95
|
) }
|
|
85
96
|
</div>
|
|
86
97
|
);
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
$black: #101517;
|
|
2
|
+
$white: #ffffff;
|
|
3
|
+
|
|
4
|
+
.jb-graph-annotations {
|
|
5
|
+
pointer-events: none;
|
|
6
|
+
position: relative;
|
|
7
|
+
left: 0;
|
|
8
|
+
top: 0;
|
|
9
|
+
height: 100%;
|
|
10
|
+
width: 100%;
|
|
11
|
+
overflow: visible;
|
|
12
|
+
|
|
13
|
+
&__line {
|
|
14
|
+
position: absolute;
|
|
15
|
+
width: 10px;
|
|
16
|
+
height: 100%;
|
|
17
|
+
transform: translateX(-50%);
|
|
18
|
+
pointer-events: all;
|
|
19
|
+
width: 10px;
|
|
20
|
+
z-index: 1;
|
|
21
|
+
|
|
22
|
+
/*
|
|
23
|
+
* The actual line is a pseudo element because we want to give a bigger hover area.
|
|
24
|
+
*/
|
|
25
|
+
&::after {
|
|
26
|
+
position: absolute;
|
|
27
|
+
content: '';
|
|
28
|
+
display: block;
|
|
29
|
+
width: 2px;
|
|
30
|
+
height: 100%;
|
|
31
|
+
background: rgba(146, 175, 215, 0.5);
|
|
32
|
+
left: calc(50% - 1px);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
&:hover {
|
|
36
|
+
&::after {
|
|
37
|
+
background: rgba(146, 175, 215, 1);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
&__annotation {
|
|
43
|
+
&::after {
|
|
44
|
+
content: '';
|
|
45
|
+
width: 0;
|
|
46
|
+
height: 0;
|
|
47
|
+
border-left: 8px solid transparent;
|
|
48
|
+
border-right: 8px solid transparent;
|
|
49
|
+
border-bottom: 8px solid $black;
|
|
50
|
+
position: absolute;
|
|
51
|
+
top: -7px;
|
|
52
|
+
left: 50%;
|
|
53
|
+
transform: translateX(-50%);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
display: none;
|
|
57
|
+
top: 100%;
|
|
58
|
+
background-color: $black;
|
|
59
|
+
color: $white;
|
|
60
|
+
width: fit-content;
|
|
61
|
+
padding: 16px 24px;
|
|
62
|
+
border-radius: 4px;
|
|
63
|
+
font-size: 14px;
|
|
64
|
+
position: relative;
|
|
65
|
+
box-shadow: 0px 1px 2px 0px rgba(0, 0, 0, 0.05);
|
|
66
|
+
text-align: center;
|
|
67
|
+
transform: translateX(-50%);
|
|
68
|
+
z-index: 2;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
@@ -20,13 +20,14 @@ export function tooltipsPlugin( periods ) {
|
|
|
20
20
|
* @param {object} _opts - Options for the uPlot instance.
|
|
21
21
|
*/
|
|
22
22
|
function init( u, _opts ) {
|
|
23
|
-
const
|
|
23
|
+
const container = u.over;
|
|
24
24
|
reactDom = ReactDOM.createRoot( reactRoot );
|
|
25
25
|
reactRoot.style.position = 'absolute';
|
|
26
26
|
reactRoot.style.bottom = -20 + 'px';
|
|
27
27
|
reactRoot.style.translate = '-50% calc( 100% - 20px )';
|
|
28
|
+
reactRoot.style.zIndex = '1000';
|
|
28
29
|
|
|
29
|
-
|
|
30
|
+
container.appendChild( reactRoot );
|
|
30
31
|
|
|
31
32
|
/**
|
|
32
33
|
* Hides all tooltips.
|
|
@@ -42,21 +43,15 @@ export function tooltipsPlugin( periods ) {
|
|
|
42
43
|
reactRoot.style.display = null;
|
|
43
44
|
}
|
|
44
45
|
|
|
45
|
-
|
|
46
|
+
container.addEventListener( 'mouseleave', () => {
|
|
46
47
|
if ( ! u.cursor._lock ) {
|
|
47
48
|
hideTips();
|
|
48
49
|
}
|
|
49
50
|
} );
|
|
50
51
|
|
|
51
|
-
|
|
52
|
+
container.addEventListener( 'mouseenter', () => {
|
|
52
53
|
showTips();
|
|
53
54
|
} );
|
|
54
|
-
|
|
55
|
-
if ( u.cursor.left < 0 ) {
|
|
56
|
-
hideTips();
|
|
57
|
-
} else {
|
|
58
|
-
showTips();
|
|
59
|
-
}
|
|
60
55
|
}
|
|
61
56
|
|
|
62
57
|
/**
|
|
@@ -4,13 +4,13 @@ import uPlot from 'uplot';
|
|
|
4
4
|
import UplotReact from 'uplot-react';
|
|
5
5
|
import { getUserLocale } from '../../lib/locale';
|
|
6
6
|
import numberFormat from '../number-format';
|
|
7
|
+
import { annotationsPlugin } from './annotations-plugin';
|
|
7
8
|
import { dayHighlightPlugin } from './day-highlight-plugin';
|
|
8
9
|
import getDateFormat from './get-date-format';
|
|
9
10
|
import { tooltipsPlugin } from './tooltips-plugin';
|
|
10
11
|
import { useBoostScoreTransform } from './use-boost-score-transform';
|
|
11
12
|
import useResize from './use-resize';
|
|
12
|
-
import { Period } from '.';
|
|
13
|
-
|
|
13
|
+
import { type Annotation, Period } from '.';
|
|
14
14
|
import './style-uplot.scss';
|
|
15
15
|
|
|
16
16
|
const DEFAULT_DIMENSIONS = {
|
|
@@ -20,6 +20,7 @@ const DEFAULT_DIMENSIONS = {
|
|
|
20
20
|
|
|
21
21
|
interface UplotChartProps {
|
|
22
22
|
periods: Period[];
|
|
23
|
+
annotations?: Annotation[];
|
|
23
24
|
options?: Partial< uPlot.Options >;
|
|
24
25
|
legendContainer?: React.RefObject< HTMLDivElement >;
|
|
25
26
|
solidFill?: boolean;
|
|
@@ -88,9 +89,10 @@ function getColor( score: number, opacity = 'FF' ) {
|
|
|
88
89
|
* @param {object} props - The props object for the UplotLineChart component.
|
|
89
90
|
* @param {{ startDate: number, endDate: number }} props.range - The date range of the chart.
|
|
90
91
|
* @param {Period[]} props.periods - The periods to display in the chart.
|
|
92
|
+
* @param {Annotation[]} props.annotations - The annotations to display in the chart.
|
|
91
93
|
* @returns {React.Element} The JSX element representing the UplotLineChart component.
|
|
92
94
|
*/
|
|
93
|
-
export default function UplotLineChart( { range, periods }: UplotChartProps ) {
|
|
95
|
+
export default function UplotLineChart( { range, periods, annotations = [] }: UplotChartProps ) {
|
|
94
96
|
const uplot = useRef< uPlot | null >( null );
|
|
95
97
|
const uplotContainer = useRef( null );
|
|
96
98
|
|
|
@@ -176,12 +178,24 @@ export default function UplotLineChart( { range, periods }: UplotChartProps ) {
|
|
|
176
178
|
legend: {
|
|
177
179
|
show: false,
|
|
178
180
|
},
|
|
179
|
-
plugins: [
|
|
181
|
+
plugins: [
|
|
182
|
+
annotationsPlugin( annotations ),
|
|
183
|
+
tooltipsPlugin( periods ),
|
|
184
|
+
dayHighlightPlugin(),
|
|
185
|
+
],
|
|
180
186
|
};
|
|
181
187
|
return {
|
|
182
188
|
...defaultOptions,
|
|
183
189
|
};
|
|
184
|
-
}, [
|
|
190
|
+
}, [
|
|
191
|
+
width,
|
|
192
|
+
lastDesktopScore,
|
|
193
|
+
lastMobileScore,
|
|
194
|
+
range.startDate,
|
|
195
|
+
range.endDate,
|
|
196
|
+
periods,
|
|
197
|
+
annotations,
|
|
198
|
+
] );
|
|
185
199
|
|
|
186
200
|
useResize( uplot, uplotContainer );
|
|
187
201
|
const onCreate = useCallback( chart => {
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* External dependencies
|
|
3
3
|
*/
|
|
4
|
-
import { Button as WPButton, Spinner } from '@wordpress/components';
|
|
4
|
+
import { Button as WPButton, Spinner, VisuallyHidden } from '@wordpress/components';
|
|
5
|
+
import { __ } from '@wordpress/i18n';
|
|
5
6
|
import { Icon, external } from '@wordpress/icons';
|
|
6
7
|
import classNames from 'classnames';
|
|
7
8
|
import React, { forwardRef } from 'react';
|
|
@@ -49,7 +50,15 @@ const Button = forwardRef< HTMLInputElement, ButtonProps >( ( props, ref ) => {
|
|
|
49
50
|
|
|
50
51
|
const externalIconSize = size === 'normal' ? 20 : 16;
|
|
51
52
|
const externalIcon = isExternalLink && (
|
|
52
|
-
|
|
53
|
+
<>
|
|
54
|
+
<Icon size={ externalIconSize } icon={ external } className={ styles[ 'external-icon' ] } />
|
|
55
|
+
<VisuallyHidden as="span">
|
|
56
|
+
{
|
|
57
|
+
/* translators: accessibility text */
|
|
58
|
+
__( '(opens in a new tab)', 'jetpack' )
|
|
59
|
+
}
|
|
60
|
+
</VisuallyHidden>
|
|
61
|
+
</>
|
|
53
62
|
);
|
|
54
63
|
const externalTarget = isExternalLink ? '_blank' : undefined;
|
|
55
64
|
|
|
@@ -16,6 +16,18 @@ const JetpackIcon: React.FC = () => (
|
|
|
16
16
|
<JetpackLogo logoColor="#000" showText={ false } height={ 16 } aria-hidden="true" />
|
|
17
17
|
);
|
|
18
18
|
|
|
19
|
+
const ExternalIcon: React.FC = () => (
|
|
20
|
+
<>
|
|
21
|
+
<Icon icon={ external } size={ 16 } />
|
|
22
|
+
<span className="jp-dashboard-footer__accessible-external-link">
|
|
23
|
+
{
|
|
24
|
+
/* translators: accessibility text */
|
|
25
|
+
__( '(opens in a new tab)', 'jetpack' )
|
|
26
|
+
}
|
|
27
|
+
</span>
|
|
28
|
+
</>
|
|
29
|
+
);
|
|
30
|
+
|
|
19
31
|
/**
|
|
20
32
|
* JetpackFooter component displays a tiny Jetpack logo with the product name on the left and the Automattic Airline "by line" on the right.
|
|
21
33
|
*
|
|
@@ -139,7 +151,7 @@ const JetpackFooter: React.FC< JetpackFooterProps > = ( {
|
|
|
139
151
|
tabIndex={ isButton ? 0 : undefined }
|
|
140
152
|
>
|
|
141
153
|
{ item.label }
|
|
142
|
-
{ isExternalLink && <
|
|
154
|
+
{ isExternalLink && <ExternalIcon /> }
|
|
143
155
|
</a>
|
|
144
156
|
</li>
|
|
145
157
|
);
|
|
@@ -71,6 +71,19 @@
|
|
|
71
71
|
}
|
|
72
72
|
}
|
|
73
73
|
|
|
74
|
+
.jp-dashboard-footer__accessible-external-link {
|
|
75
|
+
border: 0px;
|
|
76
|
+
clip: rect(1px, 1px, 1px, 1px);
|
|
77
|
+
clip-path: inset(50%);
|
|
78
|
+
height: 1px;
|
|
79
|
+
margin: -1px;
|
|
80
|
+
overflow: hidden;
|
|
81
|
+
padding: 0px;
|
|
82
|
+
position: absolute;
|
|
83
|
+
width: 1px;
|
|
84
|
+
overflow-wrap: normal;
|
|
85
|
+
}
|
|
86
|
+
|
|
74
87
|
.jp-dashboard-footer__jp-item {
|
|
75
88
|
padding-inline-end: 1rem;
|
|
76
89
|
|
|
@@ -22,8 +22,10 @@ const JetpackLogo: React.FC< JetpackLogoProps > = ( {
|
|
|
22
22
|
aria-labelledby="jetpack-logo-title"
|
|
23
23
|
height={ height }
|
|
24
24
|
{ ...otherProps }
|
|
25
|
+
// role="img" is required to prevent VoiceOver on Safari reading the content of the SVG
|
|
26
|
+
role="img"
|
|
25
27
|
>
|
|
26
|
-
<
|
|
28
|
+
<title id="jetpack-logo-title">{ __( 'Jetpack Logo', 'jetpack' ) }</title>
|
|
27
29
|
<path
|
|
28
30
|
fill={ logoColor }
|
|
29
31
|
d="M16,0C7.2,0,0,7.2,0,16s7.2,16,16,16s16-7.2,16-16S24.8,0,16,0z M15,19H7l8-16V19z M17,29V13h8L17,29z"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@automattic/jetpack-components",
|
|
3
|
-
"version": "0.48.
|
|
3
|
+
"version": "0.48.4",
|
|
4
4
|
"description": "Jetpack Components Package",
|
|
5
5
|
"author": "Automattic",
|
|
6
6
|
"license": "GPL-2.0-or-later",
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
},
|
|
16
16
|
"dependencies": {
|
|
17
17
|
"@automattic/format-currency": "1.0.1",
|
|
18
|
-
"@automattic/jetpack-boost-score-api": "^0.1.
|
|
18
|
+
"@automattic/jetpack-boost-score-api": "^0.1.24",
|
|
19
19
|
"@babel/runtime": "^7",
|
|
20
20
|
"@wordpress/browserslist-config": "5.34.0",
|
|
21
21
|
"@wordpress/components": "26.0.0",
|
|
@@ -38,9 +38,9 @@
|
|
|
38
38
|
"@babel/core": "7.23.5",
|
|
39
39
|
"@babel/preset-react": "7.23.3",
|
|
40
40
|
"@jest/globals": "29.4.3",
|
|
41
|
-
"@storybook/addon-actions": "7.6.
|
|
42
|
-
"@storybook/blocks": "7.6.
|
|
43
|
-
"@storybook/react": "7.6.
|
|
41
|
+
"@storybook/addon-actions": "7.6.17",
|
|
42
|
+
"@storybook/blocks": "7.6.17",
|
|
43
|
+
"@storybook/react": "7.6.17",
|
|
44
44
|
"@testing-library/dom": "9.3.4",
|
|
45
45
|
"@testing-library/react": "14.2.0",
|
|
46
46
|
"@testing-library/user-event": "14.5.2",
|