@automattic/jetpack-components 5.0.1 → 6.1.0
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 +31 -0
- package/build/components/admin-page/index.d.ts +1 -0
- package/build/components/admin-page/index.js +10 -4
- package/build/components/admin-page/page-action-button.d.ts +5 -0
- package/build/components/admin-page/page-action-button.js +44 -0
- package/build/components/admin-page/types.d.ts +4 -0
- package/build/components/automattic-icon-logo/index.d.ts +4 -2
- package/build/components/automattic-icon-logo/index.js +6 -4
- package/build/components/boost-score-bar/index.js +7 -7
- package/build/components/checkbox-card/style.scss +10 -38
- package/build/components/jetpack-footer/index.d.ts +1 -18
- package/build/components/jetpack-footer/index.js +1 -39
- package/build/components/jetpack-footer/jetpack-footer.d.ts +18 -0
- package/build/components/jetpack-footer/jetpack-footer.js +39 -0
- package/build/components/period-selector/index.d.ts +9 -0
- package/build/components/period-selector/index.js +21 -0
- package/build/components/period-selector/types.d.ts +28 -0
- package/build/components/period-selector/types.js +1 -0
- package/build/components/radio-card/index.d.ts +19 -0
- package/build/components/radio-card/index.js +29 -0
- package/build/components/radio-card/style.scss +26 -0
- package/build/components/radio-card/types.d.ts +41 -0
- package/build/components/radio-card/types.js +1 -0
- package/build/components/selectable-card/_selectable-card.scss +57 -0
- package/build/components/terms-of-service/index.js +3 -4
- package/build/components/terms-of-service/styles.scss +5 -2
- package/build/components/terms-of-service/types.d.ts +12 -2
- package/build/index.d.ts +5 -1
- package/build/index.js +3 -1
- package/components/admin-page/index.tsx +11 -3
- package/components/admin-page/page-action-button.tsx +69 -0
- package/components/admin-page/types.ts +5 -0
- package/components/automattic-icon-logo/index.tsx +9 -7
- package/components/boost-score-bar/index.tsx +9 -9
- package/components/checkbox-card/style.scss +10 -38
- package/components/jetpack-footer/README.md +9 -0
- package/components/jetpack-footer/index.tsx +1 -112
- package/components/jetpack-footer/jetpack-footer.tsx +113 -0
- package/components/period-selector/index.tsx +84 -0
- package/components/period-selector/types.ts +29 -0
- package/components/radio-card/index.tsx +72 -0
- package/components/radio-card/style.scss +26 -0
- package/components/radio-card/types.ts +43 -0
- package/components/selectable-card/_selectable-card.scss +57 -0
- package/components/terms-of-service/index.tsx +3 -4
- package/components/terms-of-service/styles.scss +5 -2
- package/components/terms-of-service/types.ts +13 -22
- package/index.ts +5 -1
- package/package.json +23 -14
- package/build/components/number-control/index.d.ts +0 -28
- package/build/components/number-control/index.js +0 -17
- package/components/number-control/index.tsx +0 -45
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { isWpcomPlatformSite, getAdminUrl, getScriptData } from '@automattic/jetpack-script-data';
|
|
2
|
+
import { __ } from '@wordpress/i18n';
|
|
3
|
+
import { Stack, Text, Link } from '@wordpress/ui';
|
|
4
|
+
import clsx from 'clsx';
|
|
5
|
+
import getRedirectUrl from '../../tools/jp-redirect/index.ts';
|
|
6
|
+
import AutomatticBylineLogo from '../automattic-byline-logo/index.tsx';
|
|
7
|
+
import JetpackLogo from '../jetpack-logo/index.tsx';
|
|
8
|
+
import type { JetpackFooterProps, JetpackFooterMenuItem } from './types.ts';
|
|
9
|
+
import type { FC } from 'react';
|
|
10
|
+
|
|
11
|
+
declare global {
|
|
12
|
+
interface Window {
|
|
13
|
+
JetpackNetworkAdminData?: {
|
|
14
|
+
sitesUrl: string;
|
|
15
|
+
settingsUrl: string;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* JetpackFooter component displays a tiny Jetpack logo with the product name on the left and the Automattic Airline "by line" on the right.
|
|
22
|
+
*
|
|
23
|
+
* @param {JetpackFooterProps} props - Component properties.
|
|
24
|
+
* @return {ReactNode} JetpackFooter component.
|
|
25
|
+
*/
|
|
26
|
+
const JetpackFooter: FC< JetpackFooterProps > = ( { className, menu, ...otherProps } ) => {
|
|
27
|
+
let items: JetpackFooterMenuItem[] = [];
|
|
28
|
+
|
|
29
|
+
if (
|
|
30
|
+
getScriptData()?.myJetpack?.isAvailable === true &&
|
|
31
|
+
! isWpcomPlatformSite() &&
|
|
32
|
+
! window?.JetpackNetworkAdminData
|
|
33
|
+
) {
|
|
34
|
+
items = [
|
|
35
|
+
{
|
|
36
|
+
label: __( 'Features', 'jetpack-components' ),
|
|
37
|
+
href: getAdminUrl( 'admin.php?page=my-jetpack#/features' ),
|
|
38
|
+
},
|
|
39
|
+
{
|
|
40
|
+
label: __( 'Help', 'jetpack-components' ),
|
|
41
|
+
href: getAdminUrl( 'admin.php?page=my-jetpack#/help' ),
|
|
42
|
+
},
|
|
43
|
+
...items,
|
|
44
|
+
];
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if ( menu ) {
|
|
48
|
+
items = [ ...items, ...menu ];
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return (
|
|
52
|
+
<Stack
|
|
53
|
+
render={ <footer /> }
|
|
54
|
+
className={ clsx( 'jetpack-footer', className ) }
|
|
55
|
+
aria-label={ __( 'Jetpack', 'jetpack-components' ) }
|
|
56
|
+
role="contentinfo"
|
|
57
|
+
direction="row"
|
|
58
|
+
justify="flex-start"
|
|
59
|
+
align="center"
|
|
60
|
+
wrap="wrap"
|
|
61
|
+
gap="xl"
|
|
62
|
+
{ ...otherProps }
|
|
63
|
+
>
|
|
64
|
+
<Stack className="jetpack-footer__logo" direction="row" gap="sm" align="center">
|
|
65
|
+
<JetpackLogo showText={ false } height={ 16 } aria-hidden="true" />
|
|
66
|
+
<Text variant="body-md">Jetpack</Text>
|
|
67
|
+
</Stack>
|
|
68
|
+
<Stack render={ <ul /> } direction="row" gap="lg" wrap="wrap">
|
|
69
|
+
{ items.map( item => {
|
|
70
|
+
return (
|
|
71
|
+
<li key={ item.label }>
|
|
72
|
+
<Text
|
|
73
|
+
variant="body-md"
|
|
74
|
+
className="jetpack-footer__menu-item"
|
|
75
|
+
render={
|
|
76
|
+
! item.href ? (
|
|
77
|
+
<Link
|
|
78
|
+
render={ <span /> }
|
|
79
|
+
tabIndex={ 0 }
|
|
80
|
+
title={ item.title || '' }
|
|
81
|
+
onClick={ item.onClick || undefined }
|
|
82
|
+
onKeyDown={ item.onKeyDown || undefined }
|
|
83
|
+
role="button"
|
|
84
|
+
/>
|
|
85
|
+
) : (
|
|
86
|
+
<Link
|
|
87
|
+
href={ item.href }
|
|
88
|
+
title={ item.title || '' }
|
|
89
|
+
onClick={ item.onClick || undefined }
|
|
90
|
+
onKeyDown={ item.onKeyDown || undefined }
|
|
91
|
+
/>
|
|
92
|
+
)
|
|
93
|
+
}
|
|
94
|
+
>
|
|
95
|
+
{ item.label }
|
|
96
|
+
</Text>
|
|
97
|
+
</li>
|
|
98
|
+
);
|
|
99
|
+
} ) }
|
|
100
|
+
</Stack>
|
|
101
|
+
<a
|
|
102
|
+
className="jetpack-footer__a8c"
|
|
103
|
+
href={ getRedirectUrl( 'a8c-about' ) }
|
|
104
|
+
rel="noopener noreferrer"
|
|
105
|
+
target="_blank"
|
|
106
|
+
>
|
|
107
|
+
<AutomatticBylineLogo height={ 8 } />
|
|
108
|
+
</a>
|
|
109
|
+
</Stack>
|
|
110
|
+
);
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
export default JetpackFooter;
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { __, isRTL, sprintf } from '@wordpress/i18n';
|
|
2
|
+
import { calendar, chevronLeft, chevronRight } from '@wordpress/icons';
|
|
3
|
+
import { Button, IconButton, Menu, Stack } from '@wordpress/ui';
|
|
4
|
+
import type { PeriodSelectorProps } from './types.ts';
|
|
5
|
+
import type { JSX } from 'react';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* A dropdown of period presets, with optional buttons to step to the previous or next period.
|
|
9
|
+
*
|
|
10
|
+
* @param {PeriodSelectorProps} props - Component props.
|
|
11
|
+
* @return {JSX.Element} The selector.
|
|
12
|
+
*/
|
|
13
|
+
export default function PeriodSelector< Value extends string >( {
|
|
14
|
+
presets,
|
|
15
|
+
value,
|
|
16
|
+
label,
|
|
17
|
+
onChange,
|
|
18
|
+
onPrevious,
|
|
19
|
+
onNext,
|
|
20
|
+
isPreviousDisabled = false,
|
|
21
|
+
isNextDisabled = false,
|
|
22
|
+
disabled = false,
|
|
23
|
+
className,
|
|
24
|
+
}: PeriodSelectorProps< Value > ): JSX.Element {
|
|
25
|
+
const selected = presets.find( preset => preset.value === value );
|
|
26
|
+
const selectedLabel = selected?.label ?? __( 'Select period', 'jetpack-components' );
|
|
27
|
+
const [ previousIcon, nextIcon ] = isRTL()
|
|
28
|
+
? [ chevronRight, chevronLeft ]
|
|
29
|
+
: [ chevronLeft, chevronRight ];
|
|
30
|
+
|
|
31
|
+
return (
|
|
32
|
+
<Stack direction="row" align="center" gap="xs" className={ className }>
|
|
33
|
+
<Menu.Root>
|
|
34
|
+
<Menu.Trigger
|
|
35
|
+
render={ <Button variant="outline" tone="neutral" size="compact" /> }
|
|
36
|
+
disabled={ disabled }
|
|
37
|
+
aria-label={
|
|
38
|
+
label &&
|
|
39
|
+
sprintf(
|
|
40
|
+
/* translators: %1$s: What the control picks, such as "Date range". %2$s: The selected period, such as "Last 30 days". */
|
|
41
|
+
__( '%1$s: %2$s', 'jetpack-components' ),
|
|
42
|
+
label,
|
|
43
|
+
selectedLabel
|
|
44
|
+
)
|
|
45
|
+
}
|
|
46
|
+
>
|
|
47
|
+
<Button.Icon icon={ calendar } />
|
|
48
|
+
{ selectedLabel }
|
|
49
|
+
</Menu.Trigger>
|
|
50
|
+
<Menu.Popup positioner={ <Menu.Positioner align="end" /> } aria-label={ label }>
|
|
51
|
+
<Menu.RadioGroup value={ value } onValueChange={ onChange }>
|
|
52
|
+
{ presets.map( preset => (
|
|
53
|
+
<Menu.RadioItem key={ preset.value } value={ preset.value } closeOnClick>
|
|
54
|
+
<Menu.ItemLabel>{ preset.label }</Menu.ItemLabel>
|
|
55
|
+
</Menu.RadioItem>
|
|
56
|
+
) ) }
|
|
57
|
+
</Menu.RadioGroup>
|
|
58
|
+
</Menu.Popup>
|
|
59
|
+
</Menu.Root>
|
|
60
|
+
{ onPrevious && (
|
|
61
|
+
<IconButton
|
|
62
|
+
variant="outline"
|
|
63
|
+
tone="neutral"
|
|
64
|
+
size="compact"
|
|
65
|
+
icon={ previousIcon }
|
|
66
|
+
label={ __( 'Previous period', 'jetpack-components' ) }
|
|
67
|
+
onClick={ onPrevious }
|
|
68
|
+
disabled={ disabled || isPreviousDisabled }
|
|
69
|
+
/>
|
|
70
|
+
) }
|
|
71
|
+
{ onNext && (
|
|
72
|
+
<IconButton
|
|
73
|
+
variant="outline"
|
|
74
|
+
tone="neutral"
|
|
75
|
+
size="compact"
|
|
76
|
+
icon={ nextIcon }
|
|
77
|
+
label={ __( 'Next period', 'jetpack-components' ) }
|
|
78
|
+
onClick={ onNext }
|
|
79
|
+
disabled={ disabled || isNextDisabled }
|
|
80
|
+
/>
|
|
81
|
+
) }
|
|
82
|
+
</Stack>
|
|
83
|
+
);
|
|
84
|
+
}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export type PeriodPreset< Value extends string = string > = {
|
|
2
|
+
/** Identifies the preset; passed to `onChange`. */
|
|
3
|
+
value: Value;
|
|
4
|
+
/** The preset's name, such as "Last 7 days". */
|
|
5
|
+
label: string;
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export type PeriodSelectorProps< Value extends string = string > = {
|
|
9
|
+
/** The presets the dropdown offers, in order. */
|
|
10
|
+
presets: PeriodPreset< Value >[];
|
|
11
|
+
/** Names what the control picks, such as "Date range"; screen readers hear it before the selected period. */
|
|
12
|
+
label?: string;
|
|
13
|
+
/** The selected preset's value. */
|
|
14
|
+
value: Value;
|
|
15
|
+
/** Called with the chosen preset's value. */
|
|
16
|
+
onChange: ( value: Value ) => void;
|
|
17
|
+
/** Steps to the previous period; the button shows only when set. */
|
|
18
|
+
onPrevious?: () => void;
|
|
19
|
+
/** Steps to the next period; the button shows only when set. */
|
|
20
|
+
onNext?: () => void;
|
|
21
|
+
/** Whether there is no previous period to step to. */
|
|
22
|
+
isPreviousDisabled?: boolean;
|
|
23
|
+
/** Whether there is no next period to step to, such as on the latest one. */
|
|
24
|
+
isNextDisabled?: boolean;
|
|
25
|
+
/** Whether the dropdown and both step buttons are disabled. */
|
|
26
|
+
disabled?: boolean;
|
|
27
|
+
/** Class name for the wrapper. */
|
|
28
|
+
className?: string;
|
|
29
|
+
};
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { useCallback } from '@wordpress/element';
|
|
2
|
+
import { __ } from '@wordpress/i18n';
|
|
3
|
+
import { Card, Field, Link, Radio, Stack, Text } from '@wordpress/ui';
|
|
4
|
+
import clsx from 'clsx';
|
|
5
|
+
import './style.scss';
|
|
6
|
+
import type { RadioCardGridProps, RadioCardProps } from './types.ts';
|
|
7
|
+
import type { JSX } from 'react';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Lays out radio cards in two columns, or one on narrow screens.
|
|
11
|
+
*
|
|
12
|
+
* @param {RadioCardGridProps} props - Component props.
|
|
13
|
+
* @return {JSX.Element} The grid.
|
|
14
|
+
*/
|
|
15
|
+
export function RadioCardGrid( { children, className }: RadioCardGridProps ): JSX.Element {
|
|
16
|
+
return <div className={ clsx( 'jp-radio-card-grid', className ) }>{ children }</div>;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* A card with a radio, picked by a click on its illustration. Render it in a `RadioGroup` inside a `Field.Root`.
|
|
21
|
+
*
|
|
22
|
+
* @param {RadioCardProps} props - Component props.
|
|
23
|
+
* @return {JSX.Element} The card.
|
|
24
|
+
*/
|
|
25
|
+
export default function RadioCard( {
|
|
26
|
+
id,
|
|
27
|
+
value,
|
|
28
|
+
title,
|
|
29
|
+
illustration,
|
|
30
|
+
previewUrl,
|
|
31
|
+
onPreviewClick,
|
|
32
|
+
disabled,
|
|
33
|
+
}: RadioCardProps ): JSX.Element {
|
|
34
|
+
const titleId = `${ id }__title`;
|
|
35
|
+
|
|
36
|
+
const handlePreviewClick = useCallback( () => {
|
|
37
|
+
onPreviewClick?.( value );
|
|
38
|
+
}, [ value, onPreviewClick ] );
|
|
39
|
+
|
|
40
|
+
return (
|
|
41
|
+
<Field.Item disabled={ disabled }>
|
|
42
|
+
<Card.Root className="jp-radio-card">
|
|
43
|
+
<Card.Content>
|
|
44
|
+
<Card.FullBleed className="jp-radio-card__surface">
|
|
45
|
+
{ /* Only the illustration picks the card: the title and link sit outside the label. */ }
|
|
46
|
+
<Field.Label className="jp-radio-card__illustration">{ illustration }</Field.Label>
|
|
47
|
+
<Radio
|
|
48
|
+
id={ id }
|
|
49
|
+
className="jp-radio-card__radio"
|
|
50
|
+
value={ value }
|
|
51
|
+
disabled={ disabled }
|
|
52
|
+
aria-labelledby={ titleId }
|
|
53
|
+
/>
|
|
54
|
+
</Card.FullBleed>
|
|
55
|
+
</Card.Content>
|
|
56
|
+
</Card.Root>
|
|
57
|
+
<Stack gap="xs" direction="column">
|
|
58
|
+
<Text id={ titleId } variant="body-sm">
|
|
59
|
+
{ title }
|
|
60
|
+
</Text>
|
|
61
|
+
{ previewUrl && (
|
|
62
|
+
<Link href={ previewUrl } onClick={ handlePreviewClick }>
|
|
63
|
+
{ __( 'Preview and edit', 'jetpack-components' ) }
|
|
64
|
+
</Link>
|
|
65
|
+
) }
|
|
66
|
+
</Stack>
|
|
67
|
+
</Field.Item>
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export { RadioCard };
|
|
72
|
+
export type { RadioCardProps, RadioCardGridProps };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
@use "../selectable-card/selectable-card";
|
|
2
|
+
|
|
3
|
+
.jp-radio-card-grid {
|
|
4
|
+
|
|
5
|
+
@include selectable-card.grid;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.jp-radio-card {
|
|
9
|
+
|
|
10
|
+
@include selectable-card.card( ":has(.jp-radio-card__radio[data-checked])" );
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
.jp-radio-card__surface {
|
|
14
|
+
|
|
15
|
+
@include selectable-card.surface;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.jp-radio-card__illustration {
|
|
19
|
+
|
|
20
|
+
@include selectable-card.illustration;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.jp-radio-card__radio {
|
|
24
|
+
|
|
25
|
+
@include selectable-card.control;
|
|
26
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import type { ReactNode } from 'react';
|
|
2
|
+
|
|
3
|
+
export type RadioCardProps = {
|
|
4
|
+
/**
|
|
5
|
+
* Id of the radio; the title's id is built from it.
|
|
6
|
+
*/
|
|
7
|
+
id: string;
|
|
8
|
+
/**
|
|
9
|
+
* The value the surrounding `RadioGroup` takes when this card is picked. Also passed to `onPreviewClick`.
|
|
10
|
+
*/
|
|
11
|
+
value: string;
|
|
12
|
+
/**
|
|
13
|
+
* Caption under the card, and the radio's accessible name.
|
|
14
|
+
*/
|
|
15
|
+
title: string;
|
|
16
|
+
/**
|
|
17
|
+
* Picture filling the card, drawn at a 294×192 aspect ratio.
|
|
18
|
+
*/
|
|
19
|
+
illustration?: ReactNode;
|
|
20
|
+
/**
|
|
21
|
+
* Shows a "Preview and edit" link to this URL under the title.
|
|
22
|
+
*/
|
|
23
|
+
previewUrl?: string;
|
|
24
|
+
/**
|
|
25
|
+
* Called with the card's `value` when the "Preview and edit" link is clicked.
|
|
26
|
+
*/
|
|
27
|
+
onPreviewClick?: ( value: string ) => void;
|
|
28
|
+
/**
|
|
29
|
+
* Disables the radio.
|
|
30
|
+
*/
|
|
31
|
+
disabled?: boolean;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export type RadioCardGridProps = {
|
|
35
|
+
/**
|
|
36
|
+
* The `RadioCard`s to lay out.
|
|
37
|
+
*/
|
|
38
|
+
children: ReactNode;
|
|
39
|
+
/**
|
|
40
|
+
* Extra class for the grid.
|
|
41
|
+
*/
|
|
42
|
+
className?: string;
|
|
43
|
+
};
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
@use "@automattic/jetpack-base-styles/gutenberg-base-styles" as gb;
|
|
2
|
+
|
|
3
|
+
// Shared by CheckboxCard and RadioCard, which differ only in their control.
|
|
4
|
+
|
|
5
|
+
@mixin grid {
|
|
6
|
+
display: grid;
|
|
7
|
+
grid-template-columns: repeat(2, minmax(0, 1fr));
|
|
8
|
+
column-gap: var(--wpds-dimension-gap-md);
|
|
9
|
+
row-gap: var(--wpds-dimension-gap-2xl);
|
|
10
|
+
|
|
11
|
+
@media (max-width: 720px) {
|
|
12
|
+
grid-template-columns: minmax(0, 1fr);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
// $selected matches the card while its control is selected.
|
|
17
|
+
@mixin card($selected) {
|
|
18
|
+
|
|
19
|
+
&#{$selected} {
|
|
20
|
+
border-color: var(--wpds-color-stroke-interactive-brand-active);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
&:hover:not(#{$selected}) {
|
|
24
|
+
border-color: var(--wpds-color-stroke-surface-neutral-strong);
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
&:has(:focus-visible) {
|
|
28
|
+
|
|
29
|
+
@include gb.outset-ring__focus();
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
33
|
+
transition: border-color 0.15s ease-out;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
@mixin surface {
|
|
38
|
+
position: relative;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
@mixin illustration {
|
|
42
|
+
display: flex;
|
|
43
|
+
aspect-ratio: 294 / 192;
|
|
44
|
+
background: var(--wpds-color-background-surface-neutral-weak);
|
|
45
|
+
cursor: var(--wpds-cursor-control);
|
|
46
|
+
|
|
47
|
+
> svg {
|
|
48
|
+
inline-size: 100%;
|
|
49
|
+
block-size: 100%;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
@mixin control {
|
|
54
|
+
position: absolute;
|
|
55
|
+
inset-block-start: var(--wpds-dimension-padding-md);
|
|
56
|
+
inset-inline-start: var(--wpds-dimension-padding-md);
|
|
57
|
+
}
|
|
@@ -1,23 +1,22 @@
|
|
|
1
1
|
import { createInterpolateElement } from '@wordpress/element';
|
|
2
2
|
import { __, sprintf } from '@wordpress/i18n';
|
|
3
|
-
import { Link } from '@wordpress/ui';
|
|
3
|
+
import { Link, Text } from '@wordpress/ui';
|
|
4
4
|
import clsx from 'clsx';
|
|
5
5
|
// Deep import rather than the package barrel (`../../index.ts`): the barrel
|
|
6
6
|
// pulls in heavy, asset-importing components (e.g. boost-score-graph) that the
|
|
7
7
|
// wp-build esbuild pipeline can't bundle, which breaks any wp-build dashboard
|
|
8
8
|
// that deep-imports pricing-table (which renders TermsOfService).
|
|
9
9
|
import getRedirectUrl from '../../tools/jp-redirect/index.ts';
|
|
10
|
-
import Text from '../text/index.tsx';
|
|
11
10
|
import type { TermsOfServiceProps } from './types.ts';
|
|
12
11
|
import type { FC, ReactNode } from 'react';
|
|
13
12
|
import './styles.scss';
|
|
14
13
|
|
|
15
14
|
const TermsOfService: FC< TermsOfServiceProps > = ( {
|
|
16
15
|
className,
|
|
16
|
+
variant = 'body-lg',
|
|
17
17
|
multipleButtons,
|
|
18
18
|
agreeButtonLabel,
|
|
19
19
|
isTextOnly,
|
|
20
|
-
...textProps
|
|
21
20
|
} ) => {
|
|
22
21
|
const getTOSContent = () => {
|
|
23
22
|
if ( isTextOnly ) {
|
|
@@ -30,7 +29,7 @@ const TermsOfService: FC< TermsOfServiceProps > = ( {
|
|
|
30
29
|
};
|
|
31
30
|
|
|
32
31
|
return (
|
|
33
|
-
<Text className={ clsx( className, 'terms-of-service' ) }
|
|
32
|
+
<Text variant={ variant } render={ <p /> } className={ clsx( className, 'terms-of-service' ) }>
|
|
34
33
|
{ getTOSContent() }
|
|
35
34
|
</Text>
|
|
36
35
|
);
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
.
|
|
2
|
-
|
|
1
|
+
// No specificity, so any consumer class sets the colour without a tie.
|
|
2
|
+
:where(.terms-of-service) {
|
|
3
3
|
color: var(--jp-black);
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.terms-of-service {
|
|
4
7
|
|
|
5
8
|
.terms-of-service__link {
|
|
6
9
|
white-space: nowrap;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { Text } from '@wordpress/ui';
|
|
2
|
+
import type { ComponentProps } from 'react';
|
|
2
3
|
|
|
3
4
|
type MultipleButtonsProps = {
|
|
4
5
|
/**
|
|
@@ -37,24 +38,14 @@ type OnlyTextProps = {
|
|
|
37
38
|
agreeButtonLabel?: undefined;
|
|
38
39
|
};
|
|
39
40
|
|
|
40
|
-
export type TermsOfServiceProps =
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
| 'pt'
|
|
52
|
-
| 'pr'
|
|
53
|
-
| 'pb'
|
|
54
|
-
| 'pl'
|
|
55
|
-
| 'px'
|
|
56
|
-
| 'py'
|
|
57
|
-
| 'className'
|
|
58
|
-
| 'component'
|
|
59
|
-
> &
|
|
60
|
-
( MultipleButtonsProps | SingleButtonProps | OnlyTextProps );
|
|
41
|
+
export type TermsOfServiceProps = {
|
|
42
|
+
/**
|
|
43
|
+
* HTML class.
|
|
44
|
+
*/
|
|
45
|
+
className?: string;
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* The `@wordpress/ui` Text variant. Defaults to `body-lg`.
|
|
49
|
+
*/
|
|
50
|
+
variant?: ComponentProps< typeof Text >[ 'variant' ];
|
|
51
|
+
} & ( MultipleButtonsProps | SingleButtonProps | OnlyTextProps );
|
package/index.ts
CHANGED
|
@@ -26,12 +26,15 @@ export { default as Gravatar } from './components/gravatar/index.tsx';
|
|
|
26
26
|
export type { GravatarProps } from './components/gravatar/index.tsx';
|
|
27
27
|
export { default as CheckboxCard, CheckboxCardGrid } from './components/checkbox-card/index.tsx';
|
|
28
28
|
export type { CheckboxCardProps, CheckboxCardGridProps } from './components/checkbox-card/types.ts';
|
|
29
|
+
export { default as RadioCard, RadioCardGrid } from './components/radio-card/index.tsx';
|
|
30
|
+
export type { RadioCardProps, RadioCardGridProps } from './components/radio-card/types.ts';
|
|
29
31
|
export { default as IconTooltip } from './components/icon-tooltip/index.tsx';
|
|
30
32
|
export { default as ActionButton } from './components/action-button/index.tsx';
|
|
31
33
|
export { default as PricingCard } from './components/pricing-card/index.tsx';
|
|
32
34
|
export { default as AdminSection } from './components/admin-section/basic/index.tsx';
|
|
33
35
|
export { default as AdminSectionHero } from './components/admin-section/hero/index.tsx';
|
|
34
36
|
export { default as AdminPage } from './components/admin-page/index.tsx';
|
|
37
|
+
export { default as PageActionButton } from './components/admin-page/page-action-button.tsx';
|
|
35
38
|
export { default as DecorativeCard } from './components/decorative-card/index.tsx';
|
|
36
39
|
export { default as Col } from './components/layout/col/index.tsx';
|
|
37
40
|
export { default as Testimonials } from './components/testimonials/index.tsx';
|
|
@@ -41,7 +44,6 @@ export { default as JitmSlot } from './components/jitm-slot/index.tsx';
|
|
|
41
44
|
export * from './components/icons/index.tsx';
|
|
42
45
|
export { default as ThemeProvider } from './components/theme-provider/index.tsx';
|
|
43
46
|
export { default as Text, H2, H3, Title } from './components/text/index.tsx';
|
|
44
|
-
export { default as NumberControl } from './components/number-control/index.tsx';
|
|
45
47
|
export { default as QRCode } from './components/qr-code/index.tsx';
|
|
46
48
|
export { default as Button } from './components/button/index.tsx';
|
|
47
49
|
export type { ButtonProps } from './components/button/types.ts';
|
|
@@ -65,6 +67,8 @@ export { default as ActionPopover } from './components/action-popover/index.tsx'
|
|
|
65
67
|
export { default as UpsellBanner } from './components/upsell-banner/index.tsx';
|
|
66
68
|
export { getUserLocale, cleanLocale } from './lib/locale/index.ts';
|
|
67
69
|
export { default as StatCard } from './components/stat-card/index.tsx';
|
|
70
|
+
export { default as PeriodSelector } from './components/period-selector/index.tsx';
|
|
71
|
+
export type { PeriodPreset, PeriodSelectorProps } from './components/period-selector/types.ts';
|
|
68
72
|
export { default as DiffViewer } from './components/diff-viewer/index.tsx';
|
|
69
73
|
export { default as MarkedLines } from './components/marked-lines/index.tsx';
|
|
70
74
|
export { default as DetailsViewer } from './components/details-viewer/index.tsx';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@automattic/jetpack-components",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "6.1.0",
|
|
4
4
|
"description": "Jetpack Components Package",
|
|
5
5
|
"homepage": "https://github.com/Automattic/jetpack/tree/HEAD/projects/js-packages/components/#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -46,6 +46,11 @@
|
|
|
46
46
|
"types": "./build/components/jetpack-footer/index.d.ts",
|
|
47
47
|
"default": "./build/components/jetpack-footer/index.js"
|
|
48
48
|
},
|
|
49
|
+
"./jetpack-footer/style.scss": "./build/components/jetpack-footer/style.scss",
|
|
50
|
+
"./jetpack-footer/unstyled": {
|
|
51
|
+
"types": "./build/components/jetpack-footer/jetpack-footer.d.ts",
|
|
52
|
+
"default": "./build/components/jetpack-footer/jetpack-footer.js"
|
|
53
|
+
},
|
|
49
54
|
"./jetpack-logo": {
|
|
50
55
|
"types": "./build/components/jetpack-logo/index.d.ts",
|
|
51
56
|
"default": "./build/components/jetpack-logo/index.js"
|
|
@@ -62,6 +67,10 @@
|
|
|
62
67
|
"types": "./build/components/product-price/index.d.ts",
|
|
63
68
|
"default": "./build/components/product-price/index.js"
|
|
64
69
|
},
|
|
70
|
+
"./radio-card": {
|
|
71
|
+
"types": "./build/components/radio-card/index.d.ts",
|
|
72
|
+
"default": "./build/components/radio-card/index.js"
|
|
73
|
+
},
|
|
65
74
|
"./tools/jp-redirect": {
|
|
66
75
|
"types": "./build/tools/jp-redirect/index.d.ts",
|
|
67
76
|
"default": "./build/tools/jp-redirect/index.js"
|
|
@@ -81,7 +90,7 @@
|
|
|
81
90
|
],
|
|
82
91
|
"dependencies": {
|
|
83
92
|
"@automattic/jetpack-api": "^2.2.3",
|
|
84
|
-
"@automattic/jetpack-boost-score-api": "^1.
|
|
93
|
+
"@automattic/jetpack-boost-score-api": "^1.3.0",
|
|
85
94
|
"@automattic/jetpack-script-data": "^0.6.11",
|
|
86
95
|
"@automattic/number-formatters": "^1.2.12",
|
|
87
96
|
"@babel/runtime": "^7",
|
|
@@ -104,35 +113,35 @@
|
|
|
104
113
|
"js-sha256": "0.11.1",
|
|
105
114
|
"prop-types": "^15.7.2",
|
|
106
115
|
"qrcode.react": "4.2.0",
|
|
107
|
-
"social-logos": "^3.4.
|
|
116
|
+
"social-logos": "^3.4.2",
|
|
108
117
|
"uplot": "1.6.31",
|
|
109
118
|
"uplot-react": "1.1.4"
|
|
110
119
|
},
|
|
111
120
|
"devDependencies": {
|
|
112
|
-
"@automattic/jetpack-base-styles": "^1.2.
|
|
121
|
+
"@automattic/jetpack-base-styles": "^1.2.20",
|
|
113
122
|
"@babel/core": "7.29.7",
|
|
114
123
|
"@jest/globals": "30.5.2",
|
|
115
|
-
"@storybook/addon-docs": "10.
|
|
116
|
-
"@storybook/react": "10.
|
|
124
|
+
"@storybook/addon-docs": "10.6.3",
|
|
125
|
+
"@storybook/react": "10.6.3",
|
|
117
126
|
"@testing-library/dom": "10.4.2",
|
|
118
127
|
"@testing-library/react": "16.3.3",
|
|
119
128
|
"@testing-library/user-event": "14.6.8",
|
|
120
129
|
"@types/jest": "30.0.0",
|
|
121
|
-
"@types/react": "
|
|
122
|
-
"@types/react-dom": "
|
|
130
|
+
"@types/react": "19.3.0",
|
|
131
|
+
"@types/react-dom": "19.3.0",
|
|
123
132
|
"@typescript/native-preview": "7.0.0-dev.20260707.2",
|
|
124
133
|
"jest": "30.5.2",
|
|
125
|
-
"react": "
|
|
126
|
-
"react-dom": "
|
|
134
|
+
"react": "19.3.0",
|
|
135
|
+
"react-dom": "19.3.0",
|
|
127
136
|
"require-from-string": "2.0.2",
|
|
128
|
-
"storybook": "10.
|
|
137
|
+
"storybook": "10.6.3",
|
|
129
138
|
"ts-dedent": "2.2.0",
|
|
130
139
|
"typescript": "6.0.3",
|
|
131
|
-
"webpack": "5.
|
|
140
|
+
"webpack": "5.112.2",
|
|
132
141
|
"webpack-cli": "7.2.1"
|
|
133
142
|
},
|
|
134
143
|
"peerDependencies": {
|
|
135
|
-
"react": "^18.0.0",
|
|
136
|
-
"react-dom": "^18.0.0"
|
|
144
|
+
"react": "^18.0.0 || ^19.0.0",
|
|
145
|
+
"react-dom": "^18.0.0 || ^19.0.0"
|
|
137
146
|
}
|
|
138
147
|
}
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
import type { ComponentType, InputHTMLAttributes, ReactNode } from 'react';
|
|
2
|
-
export type NumberControlProps = {
|
|
3
|
-
/**
|
|
4
|
-
* Matches common `@wordpress/components` control props without importing their internal types.
|
|
5
|
-
*/
|
|
6
|
-
label?: ReactNode;
|
|
7
|
-
help?: ReactNode;
|
|
8
|
-
className?: string;
|
|
9
|
-
hideLabelFromVision?: boolean;
|
|
10
|
-
__nextHasNoMarginBottom?: boolean;
|
|
11
|
-
/**
|
|
12
|
-
* TextControl-style signature. (The experimental NumberControl can accept this too.)
|
|
13
|
-
*/
|
|
14
|
-
onChange: (value: string) => void;
|
|
15
|
-
value: string | number;
|
|
16
|
-
__next40pxDefaultSize?: boolean;
|
|
17
|
-
} & Omit<InputHTMLAttributes<HTMLInputElement>, 'onChange' | 'value' | 'className' | 'type' | 'children'>;
|
|
18
|
-
/**
|
|
19
|
-
* This uses the experimental NumberControl from the block
|
|
20
|
-
* editor where available, otherwise it falls back to a
|
|
21
|
-
* standard TextControl, limited to numbers.
|
|
22
|
-
* @type {ComponentType<NumberControlProps>}
|
|
23
|
-
*
|
|
24
|
-
* @param {NumberControlProps} props - the NumberControl component props
|
|
25
|
-
* @return {ReactNode} - NumberControl component
|
|
26
|
-
*/
|
|
27
|
-
declare const NumberControl: ComponentType<NumberControlProps>;
|
|
28
|
-
export default NumberControl;
|