@automattic/jetpack-components 0.68.2 → 0.69.1
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 +10 -0
- package/build/components/action-button/index.d.ts +25 -0
- package/build/components/action-button/index.js +48 -0
- package/build/components/action-popover/index.d.ts +6 -0
- package/build/components/action-popover/index.js +38 -0
- package/build/components/action-popover/types.d.ts +20 -0
- package/build/components/action-popover/types.js +1 -0
- package/build/components/admin-page/index.d.ts +12 -0
- package/build/components/admin-page/index.js +44 -0
- package/build/components/admin-page/types.d.ts +56 -0
- package/build/components/admin-page/types.js +1 -0
- package/build/components/admin-section/basic/index.d.ts +10 -0
- package/build/components/admin-section/basic/index.js +12 -0
- package/build/components/admin-section/hero/index.d.ts +10 -0
- package/build/components/admin-section/hero/index.js +12 -0
- package/build/components/admin-section/types.d.ts +8 -0
- package/build/components/admin-section/types.js +1 -0
- package/build/components/alert/index.d.ts +23 -0
- package/build/components/alert/index.js +33 -0
- package/build/components/automattic-byline-logo/index.d.ts +10 -0
- package/build/components/automattic-byline-logo/index.js +13 -0
- package/build/components/automattic-byline-logo/types.d.ts +15 -0
- package/build/components/automattic-byline-logo/types.js +1 -0
- package/build/components/automattic-for-agencies-logo/index.d.ts +11 -0
- package/build/components/automattic-for-agencies-logo/index.js +12 -0
- package/build/components/automattic-icon-logo/index.d.ts +13 -0
- package/build/components/automattic-icon-logo/index.js +13 -0
- package/build/components/badge/index.d.ts +19 -0
- package/build/components/badge/index.js +22 -0
- package/build/components/boost-score-bar/index.d.ts +5 -0
- package/build/components/boost-score-bar/index.js +35 -0
- package/build/components/boost-score-bar/types.d.ts +9 -0
- package/build/components/boost-score-bar/types.js +1 -0
- package/build/components/boost-score-graph/annotations-plugin.d.ts +16 -0
- package/build/components/boost-score-graph/annotations-plugin.js +58 -0
- package/build/components/boost-score-graph/background.d.ts +3 -0
- package/build/components/boost-score-graph/background.js +5 -0
- package/build/components/boost-score-graph/day-highlight-plugin.d.ts +13 -0
- package/build/components/boost-score-graph/day-highlight-plugin.js +69 -0
- package/build/components/boost-score-graph/get-date-format.d.ts +9 -0
- package/build/components/boost-score-graph/get-date-format.js +52 -0
- package/build/components/boost-score-graph/index.d.ts +44 -0
- package/build/components/boost-score-graph/index.js +42 -0
- package/build/components/boost-score-graph/tooltip.d.ts +3 -0
- package/build/components/boost-score-graph/tooltip.js +22 -0
- package/build/components/boost-score-graph/tooltips-plugin.d.ts +15 -0
- package/build/components/boost-score-graph/tooltips-plugin.js +78 -0
- package/build/components/boost-score-graph/uplot-line-chart.d.ts +27 -0
- package/build/components/boost-score-graph/uplot-line-chart.js +187 -0
- package/build/components/boost-score-graph/use-boost-score-transform.d.ts +14 -0
- package/build/components/boost-score-graph/use-boost-score-transform.js +26 -0
- package/build/components/boost-score-graph/use-resize.d.ts +9 -0
- package/build/components/boost-score-graph/use-resize.js +31 -0
- package/build/components/button/index.d.ts +10 -0
- package/build/components/button/index.js +45 -0
- package/build/components/button/types.d.ts +19 -0
- package/build/components/button/types.js +1 -0
- package/build/components/chip/index.d.ts +15 -0
- package/build/components/chip/index.js +16 -0
- package/build/components/contextual-upgrade-trigger/index.d.ts +4 -0
- package/build/components/contextual-upgrade-trigger/index.js +12 -0
- package/build/components/contextual-upgrade-trigger/types.d.ts +9 -0
- package/build/components/contextual-upgrade-trigger/types.js +1 -0
- package/build/components/copy-to-clipboard/index.d.ts +4 -0
- package/build/components/copy-to-clipboard/index.js +40 -0
- package/build/components/copy-to-clipboard/types.d.ts +6 -0
- package/build/components/copy-to-clipboard/types.js +1 -0
- package/build/components/decorative-card/index.d.ts +11 -0
- package/build/components/decorative-card/index.js +13 -0
- package/build/components/decorative-card/types.d.ts +14 -0
- package/build/components/decorative-card/types.js +1 -0
- package/build/components/dialog/index.d.ts +20 -0
- package/build/components/dialog/index.js +31 -0
- package/build/components/diff-viewer/index.d.ts +4 -0
- package/build/components/diff-viewer/index.js +33 -0
- package/build/components/diff-viewer/parse-filename.d.ts +29 -0
- package/build/components/diff-viewer/parse-filename.js +61 -0
- package/build/components/diff-viewer/parse-patch.d.ts +9 -0
- package/build/components/diff-viewer/parse-patch.js +148 -0
- package/build/components/donut-meter/index.d.ts +58 -0
- package/build/components/donut-meter/index.js +36 -0
- package/build/components/global-notices/global-notices.d.ts +11 -0
- package/build/components/global-notices/global-notices.js +19 -0
- package/build/components/global-notices/index.d.ts +3 -0
- package/build/components/global-notices/index.js +3 -0
- package/build/components/global-notices/use-global-notices.d.ts +10 -0
- package/build/components/global-notices/use-global-notices.js +30 -0
- package/build/components/gridicon/index.d.ts +14 -0
- package/build/components/gridicon/index.js +167 -0
- package/build/components/gridicon/types.d.ts +39 -0
- package/build/components/gridicon/types.js +1 -0
- package/build/components/icon-tooltip/index.d.ts +11 -0
- package/build/components/icon-tooltip/index.js +75 -0
- package/build/components/icon-tooltip/types.d.ts +69 -0
- package/build/components/icon-tooltip/types.js +1 -0
- package/build/components/icons/index.d.ts +70 -0
- package/build/components/icons/index.js +86 -0
- package/build/components/icons/types.d.ts +27 -0
- package/build/components/icons/types.js +1 -0
- package/build/components/indeterminate-progress-bar/index.d.ts +10 -0
- package/build/components/indeterminate-progress-bar/index.js +20 -0
- package/build/components/indeterminate-progress-bar/types.d.ts +6 -0
- package/build/components/indeterminate-progress-bar/types.js +1 -0
- package/build/components/jetpack-footer/index.d.ts +11 -0
- package/build/components/jetpack-footer/index.js +71 -0
- package/build/components/jetpack-footer/types.d.ts +47 -0
- package/build/components/jetpack-footer/types.js +1 -0
- package/build/components/jetpack-logo/index.d.ts +4 -0
- package/build/components/jetpack-logo/index.js +10 -0
- package/build/components/jetpack-logo/types.d.ts +7 -0
- package/build/components/jetpack-logo/types.js +1 -0
- package/build/components/jetpack-protect-logo/index.d.ts +4 -0
- package/build/components/jetpack-protect-logo/index.js +10 -0
- package/build/components/jetpack-protect-logo/types.d.ts +7 -0
- package/build/components/jetpack-protect-logo/types.js +1 -0
- package/build/components/jetpack-search-logo/index.d.ts +4 -0
- package/build/components/jetpack-search-logo/index.js +7 -0
- package/build/components/jetpack-search-logo/types.d.ts +7 -0
- package/build/components/jetpack-search-logo/types.js +1 -0
- package/build/components/jetpack-vaultpress-backup-logo/index.d.ts +4 -0
- package/build/components/jetpack-vaultpress-backup-logo/index.js +8 -0
- package/build/components/jetpack-vaultpress-backup-logo/types.d.ts +6 -0
- package/build/components/jetpack-vaultpress-backup-logo/types.js +1 -0
- package/build/components/jetpack-videopress-logo/index.d.ts +4 -0
- package/build/components/jetpack-videopress-logo/index.js +8 -0
- package/build/components/jetpack-videopress-logo/types.d.ts +6 -0
- package/build/components/jetpack-videopress-logo/types.js +1 -0
- package/build/components/layout/col/index.d.ts +10 -0
- package/build/components/layout/col/index.js +42 -0
- package/build/components/layout/container/index.d.ts +4 -0
- package/build/components/layout/container/index.js +30 -0
- package/build/components/layout/types.d.ts +58 -0
- package/build/components/layout/types.js +1 -0
- package/build/components/layout/use-breakpoint-match/index.d.ts +19 -0
- package/build/components/layout/use-breakpoint-match/index.js +50 -0
- package/build/components/loading-placeholder/index.d.ts +8 -0
- package/build/components/loading-placeholder/index.js +7 -0
- package/build/components/marked-lines/index.d.ts +4 -0
- package/build/components/marked-lines/index.js +50 -0
- package/build/components/notice/index.d.ts +29 -0
- package/build/components/notice/index.js +35 -0
- package/build/components/number-control/index.d.ts +10 -0
- package/build/components/number-control/index.js +16 -0
- package/build/components/number-format/index.d.ts +9 -0
- package/build/components/number-format/index.js +13 -0
- package/build/components/number-slider/index.d.ts +12 -0
- package/build/components/number-slider/index.js +43 -0
- package/build/components/number-slider/types.d.ts +50 -0
- package/build/components/number-slider/types.js +1 -0
- package/build/components/popover/index.d.ts +9 -0
- package/build/components/popover/index.js +6 -0
- package/build/components/pricing-card/index.d.ts +11 -0
- package/build/components/pricing-card/index.js +32 -0
- package/build/components/pricing-card/types.d.ts +51 -0
- package/build/components/pricing-card/types.js +1 -0
- package/build/components/pricing-table/index.d.ts +7 -0
- package/build/components/pricing-table/index.js +66 -0
- package/build/components/pricing-table/types.d.ts +68 -0
- package/build/components/pricing-table/types.js +1 -0
- package/build/components/product-offer/icons-card.d.ts +10 -0
- package/build/components/product-offer/icons-card.js +23 -0
- package/build/components/product-offer/index.d.ts +11 -0
- package/build/components/product-offer/index.js +31 -0
- package/build/components/product-offer/product-offer-header.d.ts +9 -0
- package/build/components/product-offer/product-offer-header.js +14 -0
- package/build/components/product-offer/types.d.ts +102 -0
- package/build/components/product-offer/types.js +1 -0
- package/build/components/product-price/index.d.ts +11 -0
- package/build/components/product-price/index.js +32 -0
- package/build/components/product-price/price.d.ts +9 -0
- package/build/components/product-price/price.js +19 -0
- package/build/components/product-price/types.d.ts +61 -0
- package/build/components/product-price/types.js +1 -0
- package/build/components/progress-bar/index.d.ts +10 -0
- package/build/components/progress-bar/index.js +26 -0
- package/build/components/progress-bar/types.d.ts +18 -0
- package/build/components/progress-bar/types.js +1 -0
- package/build/components/qr-code/index.d.ts +46 -0
- package/build/components/qr-code/index.js +21 -0
- package/build/components/radio-control/index.d.ts +24 -0
- package/build/components/radio-control/index.js +8 -0
- package/build/components/record-meter-bar/index.d.ts +62 -0
- package/build/components/record-meter-bar/index.js +40 -0
- package/build/components/spinner/index.d.ts +13 -0
- package/build/components/spinner/index.js +27 -0
- package/build/components/split-button/index.d.ts +4 -0
- package/build/components/split-button/index.js +8 -0
- package/build/components/split-button/types.d.ts +8 -0
- package/build/components/split-button/types.js +1 -0
- package/build/components/stat-card/index.d.ts +9 -0
- package/build/components/stat-card/index.js +27 -0
- package/build/components/stat-card/types.d.ts +29 -0
- package/build/components/stat-card/types.js +1 -0
- package/build/components/status/index.d.ts +8 -0
- package/build/components/status/index.js +18 -0
- package/build/components/terms-of-service/index.d.ts +5 -0
- package/build/components/terms-of-service/index.js +32 -0
- package/build/components/terms-of-service/types.d.ts +23 -0
- package/build/components/terms-of-service/types.js +1 -0
- package/build/components/testimonials/index.d.ts +3 -0
- package/build/components/testimonials/index.js +18 -0
- package/build/components/testimonials/testimonial.d.ts +4 -0
- package/build/components/testimonials/testimonial.js +7 -0
- package/build/components/testimonials/types.d.ts +13 -0
- package/build/components/testimonials/types.js +1 -0
- package/build/components/text/constants.d.ts +14 -0
- package/build/components/text/constants.js +29 -0
- package/build/components/text/index.d.ts +32 -0
- package/build/components/text/index.js +53 -0
- package/build/components/text/types.d.ts +50 -0
- package/build/components/text/types.js +1 -0
- package/build/components/theme-provider/index.d.ts +80 -0
- package/build/components/theme-provider/index.js +129 -0
- package/build/components/theme-provider/types.d.ts +23 -0
- package/build/components/theme-provider/types.js +1 -0
- package/build/components/threat-fixer-button/index.d.ts +17 -0
- package/build/components/threat-fixer-button/index.js +56 -0
- package/build/components/threat-severity-badge/index.d.ts +4 -0
- package/build/components/threat-severity-badge/index.js +13 -0
- package/build/components/threats-data-views/constants.d.ts +33 -0
- package/build/components/threats-data-views/constants.js +37 -0
- package/build/components/threats-data-views/index.d.ts +30 -0
- package/build/components/threats-data-views/index.js +413 -0
- package/build/components/threats-data-views/threats-status-toggle-group-control.d.ts +16 -0
- package/build/components/threats-data-views/threats-status-toggle-group-control.js +95 -0
- package/build/components/toggle-control/index.d.ts +21 -0
- package/build/components/toggle-control/index.js +21 -0
- package/build/components/upsell-banner/index.d.ts +14 -0
- package/build/components/upsell-banner/index.js +21 -0
- package/build/components/upsell-banner/types.d.ts +13 -0
- package/build/components/upsell-banner/types.js +1 -0
- package/build/components/zendesk-chat/constants.d.ts +1 -0
- package/build/components/zendesk-chat/constants.js +2 -0
- package/build/components/zendesk-chat/index.d.ts +3 -0
- package/build/components/zendesk-chat/index.js +27 -0
- package/build/components/zendesk-chat/types.d.ts +11 -0
- package/build/components/zendesk-chat/types.js +1 -0
- package/build/index.d.ts +67 -0
- package/build/index.js +81 -0
- package/build/lib/locale/index.d.ts +13 -0
- package/build/lib/locale/index.js +34 -0
- package/build/tools/get-product-checkout-url/index.d.ts +10 -0
- package/build/tools/get-product-checkout-url/index.js +22 -0
- package/build/tools/get-site-admin-url/index.d.ts +6 -0
- package/build/tools/get-site-admin-url/index.js +13 -0
- package/build/tools/jp-redirect/index.d.ts +20 -0
- package/build/tools/jp-redirect/index.js +50 -0
- package/build/tools/jp-redirect/types.d.ts +39 -0
- package/build/tools/jp-redirect/types.js +1 -0
- package/build/tools/pricing-utils/index.d.ts +8 -0
- package/build/tools/pricing-utils/index.js +9 -0
- package/build/tools/pricing-utils/types.d.ts +12 -0
- package/build/tools/pricing-utils/types.js +1 -0
- package/components/boost-score-graph/uplot-line-chart.tsx +16 -1
- package/components/jetpack-footer/style.scss +5 -0
- package/components/number-slider/index.tsx +8 -2
- package/package.json +19 -12
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { __ } from '@wordpress/i18n';
|
|
3
|
+
import { useMemo, useRef, useCallback } from 'react';
|
|
4
|
+
import uPlot from 'uplot';
|
|
5
|
+
import UplotReact from 'uplot-react';
|
|
6
|
+
import { getUserLocale } from '../../lib/locale/index.js';
|
|
7
|
+
import numberFormat from '../number-format/index.js';
|
|
8
|
+
import { annotationsPlugin } from './annotations-plugin.js';
|
|
9
|
+
import { dayHighlightPlugin } from './day-highlight-plugin.js';
|
|
10
|
+
import getDateFormat from './get-date-format.js';
|
|
11
|
+
import { tooltipsPlugin } from './tooltips-plugin.js';
|
|
12
|
+
import { useBoostScoreTransform } from './use-boost-score-transform.js';
|
|
13
|
+
import useResize from './use-resize.js';
|
|
14
|
+
import './style-uplot.scss';
|
|
15
|
+
const DEFAULT_DIMENSIONS = {
|
|
16
|
+
height: 300,
|
|
17
|
+
width: 600,
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* Creates a series information object for uPlot based on the label and color.
|
|
21
|
+
*
|
|
22
|
+
* @param {string} label - The label for the series.
|
|
23
|
+
* @param {number} score - The last score for the series.
|
|
24
|
+
* @return {object} The series information object.
|
|
25
|
+
*/
|
|
26
|
+
function createSerieInfo(label, score) {
|
|
27
|
+
const { spline } = uPlot.paths;
|
|
28
|
+
return {
|
|
29
|
+
label: label,
|
|
30
|
+
stroke: getColor(score),
|
|
31
|
+
fill: u => {
|
|
32
|
+
const gradient = u.ctx.createLinearGradient(0, 0, 0, DEFAULT_DIMENSIONS.height);
|
|
33
|
+
gradient.addColorStop(0, getColor(score, '44'));
|
|
34
|
+
gradient.addColorStop(1, getColor(score, '11'));
|
|
35
|
+
return gradient;
|
|
36
|
+
},
|
|
37
|
+
width: 2,
|
|
38
|
+
paths: (u, seriesIdx, idx0, idx1) => {
|
|
39
|
+
return spline?.()(u, seriesIdx, idx0, idx1) || null;
|
|
40
|
+
},
|
|
41
|
+
points: {
|
|
42
|
+
show: true,
|
|
43
|
+
},
|
|
44
|
+
value: (self, rawValue) => {
|
|
45
|
+
if (!rawValue) {
|
|
46
|
+
return '-';
|
|
47
|
+
}
|
|
48
|
+
return numberFormat(rawValue);
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Get the color value based on the score.
|
|
54
|
+
*
|
|
55
|
+
* @param {number} score - The score to get the color for.
|
|
56
|
+
* @param {string} opacity - Whether to return a transparent color.
|
|
57
|
+
* @return {string} The color value.
|
|
58
|
+
*/
|
|
59
|
+
function getColor(score, opacity = 'FF') {
|
|
60
|
+
let color = '#D63638'; // bad
|
|
61
|
+
if (score > 70) {
|
|
62
|
+
color = '#069e08'; // good
|
|
63
|
+
}
|
|
64
|
+
else if (score > 50) {
|
|
65
|
+
color = '#faa754'; //mediocre
|
|
66
|
+
}
|
|
67
|
+
return `${color}${opacity}`;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* UplotLineChart component.
|
|
71
|
+
*
|
|
72
|
+
* @param {object} props - The props object for the UplotLineChart component.
|
|
73
|
+
* @param {{ startDate: number, endDate: number }} props.range - The date range of the chart.
|
|
74
|
+
* @param {Period[]} props.periods - The periods to display in the chart.
|
|
75
|
+
* @param {Annotation[]} props.annotations - The annotations to display in the chart.
|
|
76
|
+
* @return {React.Element} The JSX element representing the UplotLineChart component.
|
|
77
|
+
*/
|
|
78
|
+
export default function UplotLineChart({ range, periods, annotations = [] }) {
|
|
79
|
+
const uplot = useRef(null);
|
|
80
|
+
const uplotContainer = useRef(null);
|
|
81
|
+
const width = uplotContainer.current?.clientWidth || DEFAULT_DIMENSIONS.width;
|
|
82
|
+
let lastDesktopScore = 0;
|
|
83
|
+
let lastMobileScore = 0;
|
|
84
|
+
if (periods.length > 0) {
|
|
85
|
+
lastDesktopScore = periods[periods.length - 1].dimensions.desktop_overall_score;
|
|
86
|
+
lastMobileScore = periods[periods.length - 1].dimensions.mobile_overall_score;
|
|
87
|
+
}
|
|
88
|
+
const data = useBoostScoreTransform(periods);
|
|
89
|
+
const options = useMemo(() => {
|
|
90
|
+
const defaultOptions = {
|
|
91
|
+
class: 'boost-score-graph',
|
|
92
|
+
height: DEFAULT_DIMENSIONS.height,
|
|
93
|
+
width: width,
|
|
94
|
+
tzDate: ts => uPlot.tzDate(new Date(ts * 1e3), 'Etc/UTC'),
|
|
95
|
+
fmtDate: (chartDateStringTemplate) => {
|
|
96
|
+
return date => getDateFormat(chartDateStringTemplate, date, getUserLocale());
|
|
97
|
+
},
|
|
98
|
+
padding: [17, 0, 17, 0],
|
|
99
|
+
axes: [
|
|
100
|
+
{
|
|
101
|
+
// x-axis
|
|
102
|
+
grid: {
|
|
103
|
+
show: false,
|
|
104
|
+
},
|
|
105
|
+
ticks: {
|
|
106
|
+
stroke: '#50575E',
|
|
107
|
+
width: 1,
|
|
108
|
+
size: 3,
|
|
109
|
+
},
|
|
110
|
+
},
|
|
111
|
+
{
|
|
112
|
+
// y-axis
|
|
113
|
+
side: 1,
|
|
114
|
+
gap: 8,
|
|
115
|
+
space: 100,
|
|
116
|
+
size: 30,
|
|
117
|
+
grid: {
|
|
118
|
+
stroke: 'rgba(220, 220, 222, 0.5)',
|
|
119
|
+
width: 1,
|
|
120
|
+
},
|
|
121
|
+
ticks: {
|
|
122
|
+
show: false,
|
|
123
|
+
},
|
|
124
|
+
},
|
|
125
|
+
],
|
|
126
|
+
cursor: {
|
|
127
|
+
x: false,
|
|
128
|
+
y: false,
|
|
129
|
+
},
|
|
130
|
+
series: [
|
|
131
|
+
{
|
|
132
|
+
label: __('Date', 'jetpack-components'),
|
|
133
|
+
value: (self, rawValue) => {
|
|
134
|
+
// outputs legend content - value available when mouse is hovering the chart
|
|
135
|
+
if (!rawValue) {
|
|
136
|
+
return '-';
|
|
137
|
+
}
|
|
138
|
+
const date = new Date(rawValue);
|
|
139
|
+
return date.toLocaleDateString(getUserLocale());
|
|
140
|
+
},
|
|
141
|
+
},
|
|
142
|
+
createSerieInfo(__('Desktop', 'jetpack-components'), lastDesktopScore),
|
|
143
|
+
createSerieInfo(__('Mobile', 'jetpack-components'), lastMobileScore),
|
|
144
|
+
],
|
|
145
|
+
scales: {
|
|
146
|
+
x: {
|
|
147
|
+
time: true,
|
|
148
|
+
auto: false,
|
|
149
|
+
range: [range.startDate / 1000, range.endDate / 1000],
|
|
150
|
+
},
|
|
151
|
+
y: {
|
|
152
|
+
range: [0, 100],
|
|
153
|
+
auto: false,
|
|
154
|
+
},
|
|
155
|
+
},
|
|
156
|
+
legend: {
|
|
157
|
+
show: false,
|
|
158
|
+
},
|
|
159
|
+
plugins: [
|
|
160
|
+
annotationsPlugin(annotations),
|
|
161
|
+
tooltipsPlugin(periods),
|
|
162
|
+
dayHighlightPlugin(),
|
|
163
|
+
],
|
|
164
|
+
};
|
|
165
|
+
return {
|
|
166
|
+
...defaultOptions,
|
|
167
|
+
};
|
|
168
|
+
}, [
|
|
169
|
+
width,
|
|
170
|
+
lastDesktopScore,
|
|
171
|
+
lastMobileScore,
|
|
172
|
+
range.startDate,
|
|
173
|
+
range.endDate,
|
|
174
|
+
periods,
|
|
175
|
+
annotations,
|
|
176
|
+
]);
|
|
177
|
+
useResize(uplot, uplotContainer);
|
|
178
|
+
const onCreate = useCallback(chart => {
|
|
179
|
+
return (uplot.current = chart);
|
|
180
|
+
}, []);
|
|
181
|
+
/**
|
|
182
|
+
* Type casting to prevent TypeScript error:
|
|
183
|
+
* TS2604: JSX element type 'UplotReact' does not have any construct or call signatures.
|
|
184
|
+
*/
|
|
185
|
+
const TypedUplotReact = UplotReact;
|
|
186
|
+
return (_jsx("div", { ref: uplotContainer, className: "boost-uplot-container", children: _jsx(TypedUplotReact, { data: data, onCreate: onCreate, options: options }) }));
|
|
187
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Period } from './index.js';
|
|
2
|
+
type ScoreGraphAlignedData = [
|
|
3
|
+
number[],
|
|
4
|
+
number[],
|
|
5
|
+
number[]
|
|
6
|
+
];
|
|
7
|
+
/**
|
|
8
|
+
* Transforms an array of periods into an array of arrays, where the first array is the timestamps, and the rest are the values for each key
|
|
9
|
+
*
|
|
10
|
+
* @param {Period[]} periods - Array of periods to transform
|
|
11
|
+
* @return {ScoreGraphAlignedData | []} - Array of arrays, where the first array is the timestamps, and the rest are the values for each key
|
|
12
|
+
*/
|
|
13
|
+
export declare function useBoostScoreTransform(periods: Period[]): ScoreGraphAlignedData | [];
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
// Extract the value of a dimension from an array of periods
|
|
3
|
+
const getPeriodDimension = function (key, periods) {
|
|
4
|
+
return periods.map(({ dimensions }) => {
|
|
5
|
+
return dimensions[key];
|
|
6
|
+
});
|
|
7
|
+
};
|
|
8
|
+
/**
|
|
9
|
+
* Transforms an array of periods into an array of arrays, where the first array is the timestamps, and the rest are the values for each key
|
|
10
|
+
*
|
|
11
|
+
* @param {Period[]} periods - Array of periods to transform
|
|
12
|
+
* @return {ScoreGraphAlignedData | []} - Array of arrays, where the first array is the timestamps, and the rest are the values for each key
|
|
13
|
+
*/
|
|
14
|
+
export function useBoostScoreTransform(periods) {
|
|
15
|
+
return useMemo(() => {
|
|
16
|
+
if (!periods?.length || !periods[0].dimensions) {
|
|
17
|
+
return [];
|
|
18
|
+
}
|
|
19
|
+
const timestamps = periods.map(({ timestamp }) => timestamp / 1000);
|
|
20
|
+
return [
|
|
21
|
+
timestamps,
|
|
22
|
+
getPeriodDimension('desktop_overall_score', periods),
|
|
23
|
+
getPeriodDimension('mobile_overall_score', periods),
|
|
24
|
+
];
|
|
25
|
+
}, [periods]);
|
|
26
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import uPlot from 'uplot';
|
|
3
|
+
/**
|
|
4
|
+
* Custom hook to handle resizing of uPlot charts.
|
|
5
|
+
*
|
|
6
|
+
* @param {React.RefObject<uPlot>} uplotRef - The ref object for the uPlot instance.
|
|
7
|
+
* @param {React.RefObject<HTMLDivElement>} containerRef - The ref object for the container div.
|
|
8
|
+
*/
|
|
9
|
+
export default function useResize(uplotRef: React.RefObject<uPlot>, containerRef: React.RefObject<HTMLDivElement>): void;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { throttle } from '@wordpress/compose';
|
|
2
|
+
import { useEffect } from 'react';
|
|
3
|
+
const THROTTLE_DURATION = 400; // in ms
|
|
4
|
+
/**
|
|
5
|
+
* Custom hook to handle resizing of uPlot charts.
|
|
6
|
+
*
|
|
7
|
+
* @param {React.RefObject<uPlot>} uplotRef - The ref object for the uPlot instance.
|
|
8
|
+
* @param {React.RefObject<HTMLDivElement>} containerRef - The ref object for the container div.
|
|
9
|
+
*/
|
|
10
|
+
export default function useResize(uplotRef, containerRef) {
|
|
11
|
+
useEffect(() => {
|
|
12
|
+
if (!uplotRef.current || !containerRef.current) {
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
const resizeChart = throttle(() => {
|
|
16
|
+
// Repeat the check since resize can happen much later than event registration.
|
|
17
|
+
if (!uplotRef.current || !containerRef.current) {
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
// Only update width, not height.
|
|
21
|
+
uplotRef.current.setSize({
|
|
22
|
+
height: uplotRef.current.height,
|
|
23
|
+
width: containerRef.current.clientWidth,
|
|
24
|
+
});
|
|
25
|
+
}, THROTTLE_DURATION);
|
|
26
|
+
resizeChart();
|
|
27
|
+
window.addEventListener('resize', resizeChart);
|
|
28
|
+
// Cleanup on unmount.
|
|
29
|
+
return () => window.removeEventListener('resize', resizeChart);
|
|
30
|
+
}, [uplotRef, containerRef]);
|
|
31
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import type { ButtonProps } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Button component
|
|
5
|
+
*
|
|
6
|
+
* @param {ButtonProps} props - Component Props
|
|
7
|
+
* @return {React.ReactNode} Rendered button
|
|
8
|
+
*/
|
|
9
|
+
declare const Button: React.ForwardRefExoticComponent<Omit<ButtonProps, "ref"> & React.RefAttributes<HTMLInputElement>>;
|
|
10
|
+
export default Button;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* External dependencies
|
|
4
|
+
*/
|
|
5
|
+
import { Button as WPButton, Spinner, VisuallyHidden } from '@wordpress/components';
|
|
6
|
+
import { __ } from '@wordpress/i18n';
|
|
7
|
+
import { Icon, external } from '@wordpress/icons';
|
|
8
|
+
import clsx from 'clsx';
|
|
9
|
+
import { forwardRef } from 'react';
|
|
10
|
+
/**
|
|
11
|
+
* Internal dependencies
|
|
12
|
+
*/
|
|
13
|
+
import styles from './style.module.scss';
|
|
14
|
+
/**
|
|
15
|
+
* Button component
|
|
16
|
+
*
|
|
17
|
+
* @param {ButtonProps} props - Component Props
|
|
18
|
+
* @return {React.ReactNode} Rendered button
|
|
19
|
+
*/
|
|
20
|
+
const Button = forwardRef((props, ref) => {
|
|
21
|
+
const { children, variant = 'primary', size = 'normal', weight = 'bold', icon, iconSize, disabled, isDestructive, isLoading, isExternalLink, className: propsClassName, text, fullWidth, ...componentProps } = props;
|
|
22
|
+
const className = clsx(styles.button, propsClassName, {
|
|
23
|
+
[styles.normal]: size === 'normal',
|
|
24
|
+
[styles.small]: size === 'small',
|
|
25
|
+
[styles.icon]: Boolean(icon),
|
|
26
|
+
[styles.loading]: isLoading,
|
|
27
|
+
[styles.regular]: weight === 'regular',
|
|
28
|
+
[styles['full-width']]: fullWidth,
|
|
29
|
+
[styles['is-icon-button']]: Boolean(icon) && !children,
|
|
30
|
+
});
|
|
31
|
+
componentProps.ref = ref;
|
|
32
|
+
const externalIconSize = size === 'normal' ? 20 : 16;
|
|
33
|
+
const externalIcon = isExternalLink && (_jsxs(_Fragment, { children: [_jsx(Icon, { size: externalIconSize, icon: external, className: styles['external-icon'] }), _jsx(VisuallyHidden, { as: "span", children:
|
|
34
|
+
/* translators: accessibility text */
|
|
35
|
+
__('(opens in a new tab)', 'jetpack-components') })] }));
|
|
36
|
+
const externalTarget = isExternalLink ? '_blank' : undefined;
|
|
37
|
+
// ref https://github.com/WordPress/gutenberg/pull/44198
|
|
38
|
+
const hasChildren = children?.[0] &&
|
|
39
|
+
children[0] !== null &&
|
|
40
|
+
// Tooltip should not considered as a child
|
|
41
|
+
children?.[0]?.props?.className !== 'components-tooltip';
|
|
42
|
+
return (_jsxs(WPButton, { target: externalTarget, variant: variant, className: clsx(className, { 'has-text': !!icon && hasChildren }), icon: !isExternalLink ? icon : undefined, iconSize: iconSize, disabled: disabled, "aria-disabled": disabled, isDestructive: isDestructive, text: text, ...componentProps, children: [isLoading && _jsx(Spinner, {}), _jsx("span", { children: children }), externalIcon] }));
|
|
43
|
+
});
|
|
44
|
+
Button.displayName = 'Button';
|
|
45
|
+
export default Button;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { Button } from '@wordpress/components';
|
|
2
|
+
import type React from 'react';
|
|
3
|
+
type JetpackButtonBaseProps = {
|
|
4
|
+
className?: string;
|
|
5
|
+
children?: React.ReactNode;
|
|
6
|
+
disabled?: boolean;
|
|
7
|
+
isDestructive?: boolean;
|
|
8
|
+
isLoading?: boolean;
|
|
9
|
+
isExternalLink?: boolean;
|
|
10
|
+
size?: 'normal' | 'small';
|
|
11
|
+
text?: string;
|
|
12
|
+
variant?: 'primary' | 'secondary' | 'link' | 'tertiary';
|
|
13
|
+
weight?: 'bold' | 'regular';
|
|
14
|
+
fullWidth?: boolean;
|
|
15
|
+
ref?: React.ForwardedRef<unknown>;
|
|
16
|
+
};
|
|
17
|
+
type WPButtonProps = Omit<React.ComponentProps<typeof Button>, 'size' | 'variant'>;
|
|
18
|
+
export type ButtonProps = JetpackButtonBaseProps & WPButtonProps;
|
|
19
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
type ChipProps = {
|
|
3
|
+
text?: string;
|
|
4
|
+
type?: 'new' | 'info';
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Chip component
|
|
8
|
+
*
|
|
9
|
+
* @param {object} props - The component properties.
|
|
10
|
+
* @param {string} props.type - The type new or info
|
|
11
|
+
* @param {string} props.text - Chip text
|
|
12
|
+
* @return {React.ReactElement} The `Chip` component.
|
|
13
|
+
*/
|
|
14
|
+
declare const Chip: React.FC<ChipProps>;
|
|
15
|
+
export default Chip;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import clsx from 'clsx';
|
|
3
|
+
import styles from './style.module.scss';
|
|
4
|
+
/**
|
|
5
|
+
* Chip component
|
|
6
|
+
*
|
|
7
|
+
* @param {object} props - The component properties.
|
|
8
|
+
* @param {string} props.type - The type new or info
|
|
9
|
+
* @param {string} props.text - Chip text
|
|
10
|
+
* @return {React.ReactElement} The `Chip` component.
|
|
11
|
+
*/
|
|
12
|
+
const Chip = ({ type = 'info', text }) => {
|
|
13
|
+
const classes = clsx(styles.chip, styles[`is-${type}`]);
|
|
14
|
+
return _jsx("span", { className: classes, children: text });
|
|
15
|
+
};
|
|
16
|
+
export default Chip;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Icon, arrowRight } from '@wordpress/icons';
|
|
3
|
+
import clsx from 'clsx';
|
|
4
|
+
import IconTooltip from '../icon-tooltip/index.js';
|
|
5
|
+
import Text from '../text/index.js';
|
|
6
|
+
import styles from './style.module.scss';
|
|
7
|
+
const ContextualUpgradeTrigger = ({ description, cta, onClick, href, openInNewTab = false, className, tooltipText = '', }) => {
|
|
8
|
+
const Tag = href !== undefined ? 'a' : 'button';
|
|
9
|
+
const tagProps = Tag === 'a' ? { href, ...(openInNewTab && { target: '_blank' }) } : { onClick };
|
|
10
|
+
return (_jsxs("div", { className: clsx(styles.cut, className), children: [_jsxs("div", { children: [_jsxs("div", { children: [_jsx(Text, { className: styles.description, children: description }), tooltipText && (_jsx(IconTooltip, { className: styles.iconContainer, iconSize: 16, offset: 4, children: _jsx(Text, { variant: "body-small", children: tooltipText }) }))] }), _jsx("div", { children: _jsx(Tag, { ...tagProps, children: _jsx(Text, { className: styles.cta, children: cta }) }) })] }), _jsx(Icon, { icon: arrowRight, className: styles.icon, size: 30 })] }));
|
|
11
|
+
};
|
|
12
|
+
export default ContextualUpgradeTrigger;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { useCopyToClipboard } from '@wordpress/compose';
|
|
3
|
+
import { useState, useRef, useEffect } from '@wordpress/element';
|
|
4
|
+
import { __ } from '@wordpress/i18n';
|
|
5
|
+
import Button from '../button/index.js';
|
|
6
|
+
import { ClipboardIcon, CheckmarkIcon } from '../icons/index.js';
|
|
7
|
+
export const CopyToClipboard = ({ buttonStyle = 'icon', textToCopy, onCopy, ...buttonProps }) => {
|
|
8
|
+
const [hasCopied, setHasCopied] = useState(false);
|
|
9
|
+
const copyTimer = useRef();
|
|
10
|
+
const copyRef = useCopyToClipboard(textToCopy, () => {
|
|
11
|
+
if (copyTimer.current) {
|
|
12
|
+
clearTimeout(copyTimer.current);
|
|
13
|
+
}
|
|
14
|
+
setHasCopied(true);
|
|
15
|
+
onCopy?.();
|
|
16
|
+
copyTimer.current = setTimeout(() => {
|
|
17
|
+
setHasCopied(false);
|
|
18
|
+
copyTimer.current = undefined;
|
|
19
|
+
}, 3000);
|
|
20
|
+
});
|
|
21
|
+
useEffect(() => {
|
|
22
|
+
// Clear copyTimer on component unmount.
|
|
23
|
+
return () => {
|
|
24
|
+
if (copyTimer.current) {
|
|
25
|
+
clearTimeout(copyTimer.current);
|
|
26
|
+
}
|
|
27
|
+
};
|
|
28
|
+
}, []);
|
|
29
|
+
let icon = null;
|
|
30
|
+
let label = null;
|
|
31
|
+
if ('text' !== buttonStyle) {
|
|
32
|
+
icon = hasCopied ? _jsx(CheckmarkIcon, {}) : _jsx(ClipboardIcon, {});
|
|
33
|
+
}
|
|
34
|
+
const defaultLabel = __('Copy to clipboard', 'jetpack-components');
|
|
35
|
+
if ('icon' !== buttonStyle) {
|
|
36
|
+
label = hasCopied ? __('Copied!', 'jetpack-components') : defaultLabel;
|
|
37
|
+
}
|
|
38
|
+
return (_jsx(Button, { "aria-label": defaultLabel, icon: icon, children: label, ref: copyRef, ...buttonProps }));
|
|
39
|
+
};
|
|
40
|
+
export default CopyToClipboard;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { DecorativeCardProps } from './types.js';
|
|
2
|
+
import type React from 'react';
|
|
3
|
+
import './style.scss';
|
|
4
|
+
/**
|
|
5
|
+
* A decorative card used in the disconnection flow.
|
|
6
|
+
*
|
|
7
|
+
* @param {DecorativeCardProps} props - The properties.
|
|
8
|
+
* @return {React.ReactNode} - The DecorativeCard component.
|
|
9
|
+
*/
|
|
10
|
+
declare const DecorativeCard: React.FC<DecorativeCardProps>;
|
|
11
|
+
export default DecorativeCard;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import './style.scss';
|
|
3
|
+
/**
|
|
4
|
+
* A decorative card used in the disconnection flow.
|
|
5
|
+
*
|
|
6
|
+
* @param {DecorativeCardProps} props - The properties.
|
|
7
|
+
* @return {React.ReactNode} - The DecorativeCard component.
|
|
8
|
+
*/
|
|
9
|
+
const DecorativeCard = ({ format = 'horizontal', icon, imageUrl, }) => {
|
|
10
|
+
return (_jsxs("div", { className: 'jp-components__decorative-card ' +
|
|
11
|
+
(format ? 'jp-components__decorative-card--' + format : ''), children: [_jsx("div", { className: "jp-components__decorative-card__image", style: { backgroundImage: imageUrl ? `url( ${imageUrl} )` : '' } }), _jsx("div", { className: "jp-components__decorative-card__content", children: _jsx("div", { className: "jp-components__decorative-card__lines" }) }), icon ? (_jsx("div", { className: "jp-components__decorative-card__icon-container", children: _jsx("span", { className: 'jp-components__decorative-card__icon jp-components__decorative-card__icon--' + icon }) })) : null] }));
|
|
12
|
+
};
|
|
13
|
+
export default DecorativeCard;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export type DecorativeCardProps = {
|
|
2
|
+
/**
|
|
3
|
+
* The format of the card (horizontal or vertical)
|
|
4
|
+
*/
|
|
5
|
+
format?: 'horizontal' | 'vertical';
|
|
6
|
+
/**
|
|
7
|
+
* An icon slug that can be used to show an icon (options are limited to what is in the stylesheet)
|
|
8
|
+
*/
|
|
9
|
+
icon?: 'unlink';
|
|
10
|
+
/**
|
|
11
|
+
* URL for an image to show in the card.
|
|
12
|
+
*/
|
|
13
|
+
imageUrl?: string;
|
|
14
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
type DialogProps = {
|
|
3
|
+
primary: React.ReactNode;
|
|
4
|
+
secondary?: React.ReactNode;
|
|
5
|
+
isTwoSections?: boolean;
|
|
6
|
+
isCard?: boolean;
|
|
7
|
+
containerProps: object;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Dialog component.
|
|
11
|
+
*
|
|
12
|
+
* @param {object} props - React component props.
|
|
13
|
+
* @param {React.ReactNode} props.primary - Primary-section content.
|
|
14
|
+
* @param {React.ReactNode} props.secondary - Secondary-section content.
|
|
15
|
+
* @param {boolean} props.isTwoSections - Handle two sections layout when true.
|
|
16
|
+
* @param {object} props.containerProps - Props to pass to the container component.
|
|
17
|
+
* @return {React.ReactNode} Rendered dialog
|
|
18
|
+
*/
|
|
19
|
+
declare const Dialog: React.FC<DialogProps>;
|
|
20
|
+
export default Dialog;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import clsx from 'clsx';
|
|
3
|
+
import Col from '../layout/col/index.js';
|
|
4
|
+
import Container from '../layout/container/index.js';
|
|
5
|
+
import useBreakpointMatch from '../layout/use-breakpoint-match/index.js';
|
|
6
|
+
import styles from './style.module.scss';
|
|
7
|
+
/**
|
|
8
|
+
* Dialog component.
|
|
9
|
+
*
|
|
10
|
+
* @param {object} props - React component props.
|
|
11
|
+
* @param {React.ReactNode} props.primary - Primary-section content.
|
|
12
|
+
* @param {React.ReactNode} props.secondary - Secondary-section content.
|
|
13
|
+
* @param {boolean} props.isTwoSections - Handle two sections layout when true.
|
|
14
|
+
* @param {object} props.containerProps - Props to pass to the container component.
|
|
15
|
+
* @return {React.ReactNode} Rendered dialog
|
|
16
|
+
*/
|
|
17
|
+
const Dialog = ({ primary, secondary, isTwoSections = false, ...containerProps }) => {
|
|
18
|
+
const [isSmall, isLowerThanLarge] = useBreakpointMatch(['sm', 'lg'], [null, '<']);
|
|
19
|
+
/*
|
|
20
|
+
* By convention, secondary section is not shown when:
|
|
21
|
+
* - layout is a two-sections setup
|
|
22
|
+
* - on mobile breakpoint (sm)
|
|
23
|
+
*/
|
|
24
|
+
const hideSecondarySection = !isTwoSections && isSmall;
|
|
25
|
+
const classNames = clsx({
|
|
26
|
+
[styles['one-section-style']]: !isTwoSections,
|
|
27
|
+
[styles['is-viewport-small']]: isSmall,
|
|
28
|
+
});
|
|
29
|
+
return (_jsxs(Container, { className: classNames, horizontalSpacing: 0, horizontalGap: 0, fluid: false, ...containerProps, children: [!hideSecondarySection && (_jsxs(_Fragment, { children: [_jsx(Col, { sm: 4, md: isLowerThanLarge ? 4 : 5, lg: 7, className: styles.primary, children: primary }), _jsx(Col, { sm: 4, md: isLowerThanLarge ? 4 : 3, lg: 5, className: styles.secondary, children: secondary })] })), hideSecondarySection && _jsx(Col, { children: primary })] }));
|
|
30
|
+
};
|
|
31
|
+
export default Dialog;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Fragment } from 'react';
|
|
3
|
+
import parseFilename from './parse-filename.js';
|
|
4
|
+
import parsePatch from './parse-patch.js';
|
|
5
|
+
import styles from './styles.module.scss';
|
|
6
|
+
const filename = ({ oldFileName, newFileName, }) => {
|
|
7
|
+
const { prev, next } = parseFilename(oldFileName, newFileName);
|
|
8
|
+
if (prev.prefix + prev.path === next.prefix + next.path) {
|
|
9
|
+
return (_jsxs(Fragment, { children: [prev.prefix && (_jsx("span", { className: styles['diff-viewer__path-prefix'], children: prev.prefix })), _jsx("span", { className: styles['diff-viewer__path'], children: prev.path })] }));
|
|
10
|
+
}
|
|
11
|
+
return (_jsxs(Fragment, { children: [!!prev.prefix && (_jsx("span", { className: styles['diff-viewer__path-prefix'], children: prev.prefix })), _jsx("span", { className: styles['diff-viewer__path'], children: prev.path }), ' → ', !!next.prefix && (_jsx("span", { className: styles['diff-viewer__path-prefix'], children: next.prefix })), _jsx("span", { className: styles['diff-viewer__path'], children: next.path })] }));
|
|
12
|
+
};
|
|
13
|
+
export const DiffViewer = ({ diff }) => (_jsx("div", { className: styles['diff-viewer'], children: parsePatch(diff).map((file, fileIndex) => (_jsxs(Fragment, { children: [_jsx("div", { className: styles['diff-viewer__filename'], children: filename(file) }, `file-${fileIndex}`), _jsxs("div", { className: styles['diff-viewer__file'], children: [_jsx("div", { className: styles['diff-viewer__line-numbers'], children: file.hunks.map((hunk, hunkIndex) => {
|
|
14
|
+
let lineOffset = 0;
|
|
15
|
+
return hunk.lines.map((line, index) => (_jsx("div", { children: line[0] === '+' ? '\u00a0' : hunk.oldStart + lineOffset++ }, `${hunkIndex}-${index}`)));
|
|
16
|
+
}) }, "left-numbers"), _jsx("div", { className: styles['diff-viewer__line-numbers'], children: file.hunks.map((hunk, hunkIndex) => {
|
|
17
|
+
let lineOffset = 0;
|
|
18
|
+
return hunk.lines.map((line, index) => (_jsx("div", { children: line[0] === '-' ? '\u00a0' : hunk.newStart + lineOffset++ }, `${hunkIndex}-${index}`)));
|
|
19
|
+
}) }, "right-numbers"), _jsx("div", { className: styles['diff-viewer__lines'], children: file.hunks.map((hunk, hunkIndex) => hunk.lines.map((line, index) => {
|
|
20
|
+
const output = line.slice(1).replace(/^\s*$/, '\u00a0');
|
|
21
|
+
const key = `${hunkIndex}-${index}`;
|
|
22
|
+
switch (line[0]) {
|
|
23
|
+
case ' ':
|
|
24
|
+
return _jsx("div", { children: output }, key);
|
|
25
|
+
case '-':
|
|
26
|
+
return _jsx("del", { children: output }, key);
|
|
27
|
+
case '+':
|
|
28
|
+
return _jsx("ins", { children: output }, key);
|
|
29
|
+
default:
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
})) })] }, `diff-${fileIndex}`)] }, fileIndex))) }));
|
|
33
|
+
export default DiffViewer;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
type ParsedFilename = {
|
|
2
|
+
prefix: string;
|
|
3
|
+
path: string;
|
|
4
|
+
};
|
|
5
|
+
/**
|
|
6
|
+
* Parse the filename from a diff
|
|
7
|
+
*
|
|
8
|
+
* Uses a heuristic to return proper file name indicators
|
|
9
|
+
*
|
|
10
|
+
* It searches for the longest shared prefix and returns
|
|
11
|
+
* whatever remains after that. If the paths are identical
|
|
12
|
+
* it only returns a single filename as we have detected
|
|
13
|
+
* that the diff compares changes to only one file.
|
|
14
|
+
*
|
|
15
|
+
* An exception is made for `a/` and `b/` prefixes often
|
|
16
|
+
* added by `git` and other utilities to separate the left
|
|
17
|
+
* from the right when looking at the contents of a single
|
|
18
|
+
* file over time.
|
|
19
|
+
*
|
|
20
|
+
* @param {string} prev - filename of left contents
|
|
21
|
+
* @param {string} next - filename of right contents
|
|
22
|
+
*
|
|
23
|
+
* @return {object} - parsed filename
|
|
24
|
+
*/
|
|
25
|
+
export default function (prev: string, next: string): {
|
|
26
|
+
prev: ParsedFilename;
|
|
27
|
+
next: ParsedFilename;
|
|
28
|
+
};
|
|
29
|
+
export {};
|