@automattic/jetpack-components 0.41.1 → 0.42.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 +23 -0
- package/components/boost-score-graph/background.tsx +183 -0
- package/components/boost-score-graph/day-highlight-plugin.ts +82 -0
- package/components/boost-score-graph/get-date-format.ts +59 -0
- package/components/boost-score-graph/index.native.js +1 -0
- package/components/boost-score-graph/index.tsx +76 -0
- package/components/boost-score-graph/style-tooltip.scss +52 -0
- package/components/boost-score-graph/style-uplot.scss +5 -0
- package/components/boost-score-graph/style.scss +17 -0
- package/components/boost-score-graph/tooltip.tsx +87 -0
- package/components/boost-score-graph/tooltips-plugin.ts +98 -0
- package/components/boost-score-graph/types/declarations.d.ts +4 -0
- package/components/boost-score-graph/uplot-line-chart.tsx +193 -0
- package/components/boost-score-graph/use-boost-score-transform.ts +36 -0
- package/components/boost-score-graph/use-resize.ts +40 -0
- package/components/gridicon/index.tsx +13 -0
- package/components/{pricing-slider → number-slider}/index.tsx +12 -12
- package/components/{pricing-slider → number-slider}/style.scss +8 -8
- package/components/{pricing-slider → number-slider}/types.ts +2 -2
- package/components/popover/index.tsx +19 -0
- package/components/popover/style.scss +25 -0
- package/components/product-price/index.tsx +5 -5
- package/components/product-price/style.module.scss +8 -1
- package/index.ts +3 -1
- package/package.json +6 -3
- package/.gitattributes +0 -8
- package/components/action-button/stories/index.stories.jsx +0 -38
- package/components/action-button/test/component.jsx +0 -16
- package/components/action-popover/stories/index.stories.jsx +0 -115
- package/components/action-popover/stories/styles.module.scss +0 -7
- package/components/admin-page/stories/index.stories.tsx +0 -35
- package/components/admin-page/stories/style.module.scss +0 -13
- package/components/admin-section/stories/index.stories.tsx +0 -60
- package/components/alert/stories/index.stories.jsx +0 -24
- package/components/automattic-byline-logo/stories/index.stories.tsx +0 -20
- package/components/automattic-byline-logo/test/component.tsx +0 -28
- package/components/boost-score-bar/stories/index.stories.tsx +0 -39
- package/components/boost-score-bar/test/component.tsx +0 -102
- package/components/button/stories/index.mdx +0 -90
- package/components/button/stories/index.stories.tsx +0 -400
- package/components/button/stories/style.module.scss +0 -20
- package/components/contextual-upgrade-trigger/stories/index.stories.tsx +0 -25
- package/components/decorative-card/stories/index.stories.tsx +0 -18
- package/components/dialog/stories/boost.png +0 -0
- package/components/dialog/stories/declaration.d.ts +0 -1
- package/components/dialog/stories/index.stories.tsx +0 -118
- package/components/dialog/stories/js-components.components.dialog.mdx +0 -62
- package/components/dialog/stories/js-components.components.dialog.stories.js +0 -37
- package/components/dialog/stories/style.module.scss +0 -21
- package/components/donut-meter/stories/index.stories.tsx +0 -51
- package/components/donut-meter/test/component.tsx +0 -24
- package/components/gridicon/stories/index.stories.tsx +0 -18
- package/components/icon-tooltip/stories/index.stories.tsx +0 -108
- package/components/icon-tooltip/stories/style.scss +0 -36
- package/components/icon-tooltip/test/component.tsx +0 -15
- package/components/icons/stories/index.stories.tsx +0 -65
- package/components/icons/stories/style.module.scss +0 -33
- package/components/indeterminate-progress-bar/stories/index.stories.tsx +0 -14
- package/components/jetpack-footer/stories/index.stories.tsx +0 -39
- package/components/jetpack-footer/test/__snapshots__/component.tsx.snap +0 -186
- package/components/jetpack-footer/test/component.tsx +0 -159
- package/components/jetpack-logo/stories/index.stories.tsx +0 -20
- package/components/jetpack-logo/test/component.tsx +0 -16
- package/components/jetpack-search-logo/stories/index.stories.tsx +0 -21
- package/components/jetpack-search-logo/test/component.tsx +0 -16
- package/components/jetpack-vaultpress-backup-logo/stories/index.stories.tsx +0 -20
- package/components/jetpack-vaultpress-backup-logo/test/component.tsx +0 -18
- package/components/jetpack-videopress-logo/stories/index.stories.tsx +0 -20
- package/components/jetpack-videopress-logo/test/component.tsx +0 -16
- package/components/layout/stories/index.stories.tsx +0 -145
- package/components/layout/stories/styles.module.scss +0 -22
- package/components/loading-placeholder/stories/index.stories.tsx +0 -78
- package/components/notice/stories/index.stories.jsx +0 -90
- package/components/pricing-card/stories/index.stories.tsx +0 -55
- package/components/pricing-card/test/component.tsx +0 -89
- package/components/pricing-slider/stories/index.stories.tsx +0 -44
- package/components/pricing-slider/test/component.tsx +0 -14
- package/components/pricing-table/stories/index.stories.tsx +0 -74
- package/components/pricing-table/test/component.tsx +0 -41
- package/components/product-offer/stories/index.stories.tsx +0 -104
- package/components/product-price/stories/index.stories.tsx +0 -33
- package/components/product-price/test/component.tsx +0 -26
- package/components/qr-code/stories/index.stories.tsx +0 -32
- package/components/record-meter-bar/stories/index.stories.tsx +0 -39
- package/components/record-meter-bar/test/component.tsx +0 -52
- package/components/spinner/stories/index.stories.jsx +0 -20
- package/components/spinner/test/component.jsx +0 -17
- package/components/split-button/stories/index.stories.tsx +0 -35
- package/components/stat-card/stories/index.mdx +0 -35
- package/components/stat-card/stories/index.stories.tsx +0 -41
- package/components/stat-card/test/component.tsx +0 -24
- package/components/status/stories/index.stories.tsx +0 -44
- package/components/terms-of-service/test/index.test.jsx +0 -52
- package/components/testimonials/test/component.tsx +0 -103
- package/components/text/stories/headings.index.stories.tsx +0 -80
- package/components/text/stories/index.mdx +0 -195
- package/components/text/stories/index.stories.tsx +0 -69
- package/components/text/stories/style.module.scss +0 -64
- package/components/text/stories/title.index.stories.tsx +0 -34
- package/components/theme-provider/stories/index.stories.tsx +0 -164
- package/components/theme-provider/stories/style.module.scss +0 -79
- package/components/toggle-control/stories/index.stories.tsx +0 -83
- package/components/zendesk-chat/stories/index.stories.tsx +0 -15
- package/components/zendesk-chat/test/component.tsx +0 -16
- package/lib/locale/test/index.ts +0 -21
- package/tools/jp-redirect/test/index.tsx +0 -89
- package/tools/pricing-utils/test/index.ts +0 -39
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Internal dependencies
|
|
3
|
-
*/
|
|
4
|
-
import LoadingPlaceholder from '..';
|
|
5
|
-
/**
|
|
6
|
-
* Types
|
|
7
|
-
*/
|
|
8
|
-
import type { ComponentStory, ComponentMeta } from '@storybook/react';
|
|
9
|
-
|
|
10
|
-
export default {
|
|
11
|
-
title: 'JS Packages/Components/Loading Placeholder',
|
|
12
|
-
component: LoadingPlaceholder,
|
|
13
|
-
parameters: {
|
|
14
|
-
layout: 'centered',
|
|
15
|
-
},
|
|
16
|
-
} as ComponentMeta< typeof LoadingPlaceholder >;
|
|
17
|
-
|
|
18
|
-
const Template: ComponentStory< typeof LoadingPlaceholder > = args => (
|
|
19
|
-
<LoadingPlaceholder { ...args } />
|
|
20
|
-
);
|
|
21
|
-
|
|
22
|
-
export const Fluid = Template.bind( {} );
|
|
23
|
-
Fluid.decorators = [
|
|
24
|
-
Story => (
|
|
25
|
-
<div
|
|
26
|
-
style={ {
|
|
27
|
-
width: '200px',
|
|
28
|
-
height: '300px',
|
|
29
|
-
} }
|
|
30
|
-
>
|
|
31
|
-
<Story />
|
|
32
|
-
</div>
|
|
33
|
-
),
|
|
34
|
-
];
|
|
35
|
-
|
|
36
|
-
Fluid.argTypes = {
|
|
37
|
-
width: {
|
|
38
|
-
table: {
|
|
39
|
-
disable: true,
|
|
40
|
-
},
|
|
41
|
-
},
|
|
42
|
-
height: {
|
|
43
|
-
table: {
|
|
44
|
-
disable: true,
|
|
45
|
-
},
|
|
46
|
-
},
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
Fluid.args = {
|
|
50
|
-
width: null,
|
|
51
|
-
height: null,
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
export const Fixed = Template.bind( {} );
|
|
55
|
-
|
|
56
|
-
Fixed.args = {
|
|
57
|
-
width: 200,
|
|
58
|
-
height: 300,
|
|
59
|
-
};
|
|
60
|
-
|
|
61
|
-
Fixed.argTypes = {
|
|
62
|
-
width: {
|
|
63
|
-
control: {
|
|
64
|
-
type: 'range',
|
|
65
|
-
min: 0,
|
|
66
|
-
max: 500,
|
|
67
|
-
step: 1,
|
|
68
|
-
},
|
|
69
|
-
},
|
|
70
|
-
height: {
|
|
71
|
-
control: {
|
|
72
|
-
type: 'range',
|
|
73
|
-
min: 0,
|
|
74
|
-
max: 500,
|
|
75
|
-
step: 1,
|
|
76
|
-
},
|
|
77
|
-
},
|
|
78
|
-
};
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
import { ExternalLink } from '@wordpress/components';
|
|
2
|
-
import Button from '../../button';
|
|
3
|
-
import Notice from '../index';
|
|
4
|
-
|
|
5
|
-
export default {
|
|
6
|
-
title: 'JS Packages/Components/Notice',
|
|
7
|
-
component: Notice,
|
|
8
|
-
argTypes: {
|
|
9
|
-
level: {
|
|
10
|
-
control: {
|
|
11
|
-
type: 'select',
|
|
12
|
-
},
|
|
13
|
-
options: [ 'info', 'success', 'warning', 'error' ],
|
|
14
|
-
},
|
|
15
|
-
hideCloseButton: {
|
|
16
|
-
control: {
|
|
17
|
-
type: 'boolean',
|
|
18
|
-
},
|
|
19
|
-
},
|
|
20
|
-
},
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
const Template = args => <Notice { ...args } />;
|
|
24
|
-
|
|
25
|
-
export const _default = Template.bind( {} );
|
|
26
|
-
_default.args = {
|
|
27
|
-
level: 'info',
|
|
28
|
-
title: 'Improve your hovercraft',
|
|
29
|
-
children:
|
|
30
|
-
'Make your hovercraft better with HoverPack; the best hovercraft upgrade kit on the market.',
|
|
31
|
-
onClose: () => alert( 'Close clicked' ),
|
|
32
|
-
actions: [
|
|
33
|
-
<Button key="install" isPrimary>
|
|
34
|
-
Install now
|
|
35
|
-
</Button>,
|
|
36
|
-
<ExternalLink key="learn-more" href="https://en.wikipedia.org/wiki/Hovercraft">
|
|
37
|
-
Learn more
|
|
38
|
-
</ExternalLink>,
|
|
39
|
-
],
|
|
40
|
-
hideCloseButton: false,
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
export const warning = Template.bind( {} );
|
|
44
|
-
warning.args = {
|
|
45
|
-
level: 'warning',
|
|
46
|
-
title: 'Your hovercraft is full of eels.',
|
|
47
|
-
children: (
|
|
48
|
-
<div>
|
|
49
|
-
Either your vehicle needs to be cleared, or some kind of translation error has occurred.
|
|
50
|
-
</div>
|
|
51
|
-
),
|
|
52
|
-
actions: [
|
|
53
|
-
<Button key="bail" isPrimary>
|
|
54
|
-
Start Bailing
|
|
55
|
-
</Button>,
|
|
56
|
-
<ExternalLink key="learn-more" href="https://en.wikipedia.org/wiki/Hovercraft">
|
|
57
|
-
Learn more
|
|
58
|
-
</ExternalLink>,
|
|
59
|
-
],
|
|
60
|
-
hideCloseButton: false,
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
export const success = Template.bind( {} );
|
|
64
|
-
success.args = {
|
|
65
|
-
level: 'success',
|
|
66
|
-
title: 'Your hovercraft has been upgraded.',
|
|
67
|
-
children: 'Please enjoy your newer, cooler hovercraft.',
|
|
68
|
-
onClose: () => alert( 'Close clicked' ),
|
|
69
|
-
actions: [
|
|
70
|
-
<Button key="start" isPrimary>
|
|
71
|
-
Start crafting
|
|
72
|
-
</Button>,
|
|
73
|
-
],
|
|
74
|
-
hideCloseButton: false,
|
|
75
|
-
};
|
|
76
|
-
|
|
77
|
-
export const error = Template.bind( {} );
|
|
78
|
-
error.args = {
|
|
79
|
-
level: 'error',
|
|
80
|
-
title: 'The eels have stolen your hovercraft.',
|
|
81
|
-
children:
|
|
82
|
-
'We were unable to remove the eels from your hovercraft. Please contact the authorities, as the eels are armed and dangerous.',
|
|
83
|
-
onClose: () => alert( 'Close clicked' ),
|
|
84
|
-
actions: [
|
|
85
|
-
<ExternalLink key="learn-more" href="https://en.wikipedia.org/wiki/Eel">
|
|
86
|
-
Learn more
|
|
87
|
-
</ExternalLink>,
|
|
88
|
-
],
|
|
89
|
-
hideCloseButton: false,
|
|
90
|
-
};
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
import { action } from '@storybook/addon-actions';
|
|
2
|
-
import PricingCard from '../index';
|
|
3
|
-
import type { ComponentStory, ComponentMeta } from '@storybook/react';
|
|
4
|
-
|
|
5
|
-
export default {
|
|
6
|
-
title: 'JS Packages/Components/Pricing Card',
|
|
7
|
-
component: PricingCard,
|
|
8
|
-
// TODO: Storybook Actions are not working. See https://github.com/storybookjs/storybook/issues/7215
|
|
9
|
-
argTypes: {
|
|
10
|
-
onCtaClick: { action: 'clicked' },
|
|
11
|
-
},
|
|
12
|
-
} as ComponentMeta< typeof PricingCard >;
|
|
13
|
-
|
|
14
|
-
// Export additional stories using pre-defined values
|
|
15
|
-
const Template: ComponentStory< typeof PricingCard > = args => <PricingCard { ...args } />;
|
|
16
|
-
|
|
17
|
-
const DefaultArgs = {
|
|
18
|
-
title: 'Jetpack Backup',
|
|
19
|
-
icon: "data:image/svg+xml,%3Csvg width='32' height='32' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill-rule='evenodd' clip-rule='evenodd' d='m21.092 15.164.019-1.703v-.039c0-1.975-1.803-3.866-4.4-3.866-2.17 0-3.828 1.351-4.274 2.943l-.426 1.524-1.581-.065a2.92 2.92 0 0 0-.12-.002c-1.586 0-2.977 1.344-2.977 3.133 0 1.787 1.388 3.13 2.973 3.133H22.399c1.194 0 2.267-1.016 2.267-2.4 0-1.235-.865-2.19-1.897-2.368l-1.677-.29Zm-10.58-3.204a4.944 4.944 0 0 0-.201-.004c-2.75 0-4.978 2.298-4.978 5.133s2.229 5.133 4.978 5.133h12.088c2.357 0 4.267-1.97 4.267-4.4 0-2.18-1.538-3.99-3.556-4.339v-.06c0-3.24-2.865-5.867-6.4-5.867-2.983 0-5.49 1.871-6.199 4.404Z' fill='%23000'/%3E%3C/svg%3E",
|
|
20
|
-
priceBefore: 9,
|
|
21
|
-
priceAfter: 4.5,
|
|
22
|
-
ctaText: 'Get Jetpack Backup',
|
|
23
|
-
infoText:
|
|
24
|
-
'Special introductory pricing, all renewals are at full price. 14 day money back guarantee.',
|
|
25
|
-
onCtaClick: action( 'onCtaClick' ),
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
// Export Default story
|
|
29
|
-
export const _default = Template.bind( {} );
|
|
30
|
-
_default.args = DefaultArgs;
|
|
31
|
-
|
|
32
|
-
export const Minimal = Template.bind( {} );
|
|
33
|
-
Minimal.args = {
|
|
34
|
-
...DefaultArgs,
|
|
35
|
-
icon: null,
|
|
36
|
-
ctaText: null,
|
|
37
|
-
onCtaClick: null,
|
|
38
|
-
infoText: null,
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
const TemplateWithChildren = args => (
|
|
42
|
-
<PricingCard { ...args }>
|
|
43
|
-
<ul>
|
|
44
|
-
<li>Automated real-time backups</li>
|
|
45
|
-
<li>Easy one-click restores</li>
|
|
46
|
-
<li>Complete list of all site changes</li>
|
|
47
|
-
<li>Global server infrastructure</li>
|
|
48
|
-
<li>Best-in-class support</li>
|
|
49
|
-
</ul>
|
|
50
|
-
</PricingCard>
|
|
51
|
-
);
|
|
52
|
-
export const WithChildren = TemplateWithChildren.bind( {} );
|
|
53
|
-
WithChildren.args = {
|
|
54
|
-
...DefaultArgs,
|
|
55
|
-
};
|
|
@@ -1,89 +0,0 @@
|
|
|
1
|
-
import { jest } from '@jest/globals';
|
|
2
|
-
import { render, screen, cleanup } from '@testing-library/react/pure';
|
|
3
|
-
import PricingCard from '../index';
|
|
4
|
-
|
|
5
|
-
// Note we're using @testing-library/react/pure here to disable the automatic cleanup.
|
|
6
|
-
// So be sure to call `cleanup()` for each `render()`.
|
|
7
|
-
/* eslint-disable testing-library/no-render-in-setup */
|
|
8
|
-
|
|
9
|
-
describe( 'PricingCard', () => {
|
|
10
|
-
const testProps = {
|
|
11
|
-
title: 'Dummy Pricing Card',
|
|
12
|
-
icon: 'dummy_icon',
|
|
13
|
-
priceBefore: 9,
|
|
14
|
-
priceAfter: 4.5,
|
|
15
|
-
ctaText: 'Get Dummy Offer',
|
|
16
|
-
infoText: 'Dummy Info Text',
|
|
17
|
-
onCtaClick: jest.fn(),
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
describe( 'Initially', () => {
|
|
21
|
-
let container;
|
|
22
|
-
|
|
23
|
-
beforeAll( () => {
|
|
24
|
-
( { container } = render( <PricingCard { ...testProps } /> ) );
|
|
25
|
-
} );
|
|
26
|
-
afterAll( () => {
|
|
27
|
-
cleanup();
|
|
28
|
-
} );
|
|
29
|
-
|
|
30
|
-
it( 'renders the title', () => {
|
|
31
|
-
expect( screen.getByRole( 'heading' ) ).toHaveTextContent( 'Dummy Pricing Card' );
|
|
32
|
-
} );
|
|
33
|
-
|
|
34
|
-
it( 'renders the icon', () => {
|
|
35
|
-
const img = screen.getByAltText( 'Icon for the product Dummy Pricing Card' );
|
|
36
|
-
expect( img ).toBeInTheDocument();
|
|
37
|
-
expect( img ).toHaveAttribute( 'src', 'dummy_icon' );
|
|
38
|
-
} );
|
|
39
|
-
|
|
40
|
-
it( 'renders the price before', () => {
|
|
41
|
-
// eslint-disable-next-line testing-library/no-node-access
|
|
42
|
-
const node = container.querySelector( '.jp-components__pricing-card__price-before' );
|
|
43
|
-
expect( node ).toBeInTheDocument();
|
|
44
|
-
expect( node ).toHaveTextContent( '$9' );
|
|
45
|
-
} );
|
|
46
|
-
|
|
47
|
-
it( 'renders the price after', () => {
|
|
48
|
-
// eslint-disable-next-line testing-library/no-node-access
|
|
49
|
-
const node = container.querySelector( '.jp-components__pricing-card__price-after' );
|
|
50
|
-
expect( node ).toBeInTheDocument();
|
|
51
|
-
expect( node ).toHaveTextContent( '$4.50' );
|
|
52
|
-
} );
|
|
53
|
-
|
|
54
|
-
it( 'renders the CTA button', () => {
|
|
55
|
-
expect( screen.getByRole( 'button' ) ).toHaveTextContent( 'Get Dummy Offer' );
|
|
56
|
-
} );
|
|
57
|
-
|
|
58
|
-
it( 'renders the info text', () => {
|
|
59
|
-
// eslint-disable-next-line testing-library/no-node-access
|
|
60
|
-
const node = container.querySelector( '.jp-components__pricing-card__info' );
|
|
61
|
-
expect( node ).toBeInTheDocument();
|
|
62
|
-
expect( node ).toHaveTextContent( 'Dummy Info Text' );
|
|
63
|
-
} );
|
|
64
|
-
} );
|
|
65
|
-
|
|
66
|
-
describe( 'When price before and price after match', () => {
|
|
67
|
-
let container;
|
|
68
|
-
|
|
69
|
-
beforeAll( () => {
|
|
70
|
-
( { container } = render( <PricingCard { ...testProps } priceAfter={ 9 } /> ) );
|
|
71
|
-
} );
|
|
72
|
-
afterAll( () => {
|
|
73
|
-
cleanup();
|
|
74
|
-
} );
|
|
75
|
-
|
|
76
|
-
it( "doesn't render the price before", () => {
|
|
77
|
-
// eslint-disable-next-line testing-library/no-node-access
|
|
78
|
-
const node = container.querySelector( '.jp-components__pricing-card__price-before' );
|
|
79
|
-
expect( node ).not.toBeInTheDocument();
|
|
80
|
-
} );
|
|
81
|
-
|
|
82
|
-
it( 'renders the price after', () => {
|
|
83
|
-
// eslint-disable-next-line testing-library/no-node-access
|
|
84
|
-
const node = container.querySelector( '.jp-components__pricing-card__price-after' );
|
|
85
|
-
expect( node ).toBeInTheDocument();
|
|
86
|
-
expect( node ).toHaveTextContent( '$9' );
|
|
87
|
-
} );
|
|
88
|
-
} );
|
|
89
|
-
} );
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { useState } from 'react';
|
|
2
|
-
import PricingSlider from '../index';
|
|
3
|
-
import type { ComponentStory, ComponentMeta } from '@storybook/react';
|
|
4
|
-
|
|
5
|
-
export default {
|
|
6
|
-
title: 'JS Packages/Components/Pricing Slider',
|
|
7
|
-
component: PricingSlider,
|
|
8
|
-
} as ComponentMeta< typeof PricingSlider >;
|
|
9
|
-
|
|
10
|
-
// Export additional stories using pre-defined values
|
|
11
|
-
const Template: ComponentStory< typeof PricingSlider > = args => <PricingSlider { ...args } />;
|
|
12
|
-
|
|
13
|
-
// Export Default story
|
|
14
|
-
export const _default = Template.bind( {} );
|
|
15
|
-
|
|
16
|
-
// Export additional stories using chaning values
|
|
17
|
-
const TemplateWithChangingValue: ComponentStory< typeof PricingSlider > = args => {
|
|
18
|
-
const [ value, setValue ] = useState( 10 );
|
|
19
|
-
const [ endValue, setEndValue ] = useState( 10 );
|
|
20
|
-
const renderThumb = ( props, state ) => {
|
|
21
|
-
return (
|
|
22
|
-
<div { ...props }>
|
|
23
|
-
{ state.valueNow } - { state.valueNow % 2 === 0 ? 'Even' : 'Odd' }
|
|
24
|
-
</div>
|
|
25
|
-
);
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
return (
|
|
29
|
-
<div>
|
|
30
|
-
<PricingSlider
|
|
31
|
-
{ ...args }
|
|
32
|
-
value={ value }
|
|
33
|
-
onChange={ setValue }
|
|
34
|
-
onAfterChange={ setEndValue }
|
|
35
|
-
renderThumb={ renderThumb } // eslint-disable-line react/jsx-no-bind
|
|
36
|
-
/>
|
|
37
|
-
<div>{ `Value on changing: ${ value }` }</div>
|
|
38
|
-
<div>{ `Value on change ends: ${ endValue }` }</div>
|
|
39
|
-
</div>
|
|
40
|
-
);
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
// Export With Default Value story
|
|
44
|
-
export const WithDefaultValue = TemplateWithChangingValue.bind( {} );
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { render, screen } from '@testing-library/react';
|
|
2
|
-
import ResizeObserver from 'resize-observer-polyfill';
|
|
3
|
-
import PricingSlider from '../index';
|
|
4
|
-
|
|
5
|
-
describe( 'PricingSlider', () => {
|
|
6
|
-
beforeAll( () => {
|
|
7
|
-
global.ResizeObserver = ResizeObserver;
|
|
8
|
-
} );
|
|
9
|
-
|
|
10
|
-
it( 'renders the pricing slider', () => {
|
|
11
|
-
render( <PricingSlider /> );
|
|
12
|
-
expect( screen.getByTestId( 'pricing-slider' ) ).toBeInTheDocument();
|
|
13
|
-
} );
|
|
14
|
-
} );
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import Button from '../../button';
|
|
2
|
-
import ProductPrice from '../../product-price';
|
|
3
|
-
import PricingTable, { PricingTableColumn, PricingTableHeader, PricingTableItem } from '../index';
|
|
4
|
-
import type { ComponentStory, ComponentMeta } from '@storybook/react';
|
|
5
|
-
|
|
6
|
-
export default {
|
|
7
|
-
title: 'JS Packages/Components/Pricing Table',
|
|
8
|
-
component: PricingTable,
|
|
9
|
-
subcomponents: { PricingTableColumn, PricingTableHeader, PricingTableItem },
|
|
10
|
-
} as ComponentMeta< typeof PricingTable >;
|
|
11
|
-
|
|
12
|
-
const Template: ComponentStory< typeof PricingTable > = args => {
|
|
13
|
-
return (
|
|
14
|
-
<PricingTable { ...args }>
|
|
15
|
-
<PricingTableColumn primary>
|
|
16
|
-
<PricingTableHeader>
|
|
17
|
-
<ProductPrice
|
|
18
|
-
price={ 9.95 }
|
|
19
|
-
offPrice={ 4.98 }
|
|
20
|
-
legend="/month, billed yearly"
|
|
21
|
-
currency="USD"
|
|
22
|
-
hideDiscountLabel={ args?.hideDiscountLabel }
|
|
23
|
-
/>
|
|
24
|
-
<Button fullWidth>Get Premium</Button>
|
|
25
|
-
</PricingTableHeader>
|
|
26
|
-
<PricingTableItem isIncluded={ true } label={ <strong>Up to 1000</strong> } />
|
|
27
|
-
<PricingTableItem isIncluded={ true } tooltipInfo={ 'This is an info' } />
|
|
28
|
-
<PricingTableItem
|
|
29
|
-
isIncluded={ true }
|
|
30
|
-
tooltipInfo={ 'This is an info with title' }
|
|
31
|
-
tooltipTitle={ 'Small title' }
|
|
32
|
-
/>
|
|
33
|
-
<PricingTableItem isIncluded={ true } />
|
|
34
|
-
<PricingTableItem isIncluded={ true } />
|
|
35
|
-
</PricingTableColumn>
|
|
36
|
-
<PricingTableColumn>
|
|
37
|
-
<PricingTableHeader>
|
|
38
|
-
<ProductPrice price={ 0 } legend="Free forever" currency="USD" hidePriceFraction />
|
|
39
|
-
<Button fullWidth variant="secondary">
|
|
40
|
-
Start for free
|
|
41
|
-
</Button>
|
|
42
|
-
</PricingTableHeader>
|
|
43
|
-
<PricingTableItem isIncluded={ true } label="Up to 300" />
|
|
44
|
-
<PricingTableItem
|
|
45
|
-
isIncluded={ false }
|
|
46
|
-
label="This is not included"
|
|
47
|
-
tooltipInfo="This has a tooltip, so its overwrites the default info on small screens"
|
|
48
|
-
/>
|
|
49
|
-
<PricingTableItem isIncluded={ false } />
|
|
50
|
-
<PricingTableItem isIncluded={ true } />
|
|
51
|
-
<PricingTableItem isIncluded={ true } />
|
|
52
|
-
</PricingTableColumn>
|
|
53
|
-
</PricingTable>
|
|
54
|
-
);
|
|
55
|
-
};
|
|
56
|
-
|
|
57
|
-
const DefaultArgs = {
|
|
58
|
-
title: 'Buy premium, or start for free',
|
|
59
|
-
items: [
|
|
60
|
-
{ name: 'Feature A with limit', tooltipInfo: 'Default info for Feature A' },
|
|
61
|
-
{ name: 'Feature B', tooltipInfo: 'Default info for Feature B' },
|
|
62
|
-
{
|
|
63
|
-
name: 'Feature C with a longer title that will span multiple lines',
|
|
64
|
-
tooltipInfo: 'Default info for Feature C',
|
|
65
|
-
tooltipTitle: 'Title for C',
|
|
66
|
-
},
|
|
67
|
-
{ name: 'Feature D', tooltipInfo: 'Default info for Feature D', tooltipTitle: 'Title for D' },
|
|
68
|
-
{ name: 'Feature E' },
|
|
69
|
-
],
|
|
70
|
-
hideDiscountLabel: false,
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
export const _default = Template.bind( {} );
|
|
74
|
-
_default.args = DefaultArgs;
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { render, screen } from '@testing-library/react';
|
|
2
|
-
import PricingTable, { PricingTableColumn, PricingTableHeader, PricingTableItem } from '../index';
|
|
3
|
-
|
|
4
|
-
describe( 'PricingTable', () => {
|
|
5
|
-
const testProps = {
|
|
6
|
-
title: 'Dummy Pricing Table',
|
|
7
|
-
items: [
|
|
8
|
-
{ name: 'Dummy Item 1', tooltipInfo: 'Default Info' },
|
|
9
|
-
{ name: 'Dummy Item 2', tooltipInfo: 'Default Info' },
|
|
10
|
-
{ name: 'Dummy Item 3', tooltipInfo: 'Default Info' },
|
|
11
|
-
],
|
|
12
|
-
children: (
|
|
13
|
-
<>
|
|
14
|
-
<PricingTableColumn>
|
|
15
|
-
<PricingTableHeader>Header 1</PricingTableHeader>
|
|
16
|
-
<PricingTableItem isIncluded={ true } />
|
|
17
|
-
<PricingTableItem isIncluded={ true } />
|
|
18
|
-
<PricingTableItem isIncluded={ true } />
|
|
19
|
-
</PricingTableColumn>
|
|
20
|
-
<PricingTableColumn>
|
|
21
|
-
<PricingTableHeader>Header 2</PricingTableHeader>
|
|
22
|
-
<PricingTableItem isIncluded={ true } />
|
|
23
|
-
<PricingTableItem isIncluded={ true } />
|
|
24
|
-
<PricingTableItem isIncluded={ false } />
|
|
25
|
-
</PricingTableColumn>
|
|
26
|
-
</>
|
|
27
|
-
),
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
it( 'renders the title', () => {
|
|
31
|
-
render( <PricingTable { ...testProps }></PricingTable> );
|
|
32
|
-
expect( screen.getByRole( 'heading' ) ).toHaveTextContent( 'Dummy Pricing Table' );
|
|
33
|
-
} );
|
|
34
|
-
|
|
35
|
-
it( 'renders all included items', () => {
|
|
36
|
-
render( <PricingTable { ...testProps }></PricingTable> );
|
|
37
|
-
expect( screen.getAllByText( 'Dummy Item 1' ) ).toHaveLength( 2 );
|
|
38
|
-
expect( screen.getAllByText( 'Dummy Item 2' ) ).toHaveLength( 2 );
|
|
39
|
-
expect( screen.getAllByText( 'Dummy Item 3' ) ).toHaveLength( 1 ); // eslint-disable-line jest-dom/prefer-in-document
|
|
40
|
-
} );
|
|
41
|
-
} );
|
|
@@ -1,104 +0,0 @@
|
|
|
1
|
-
import ProductOffer from '..';
|
|
2
|
-
import { IconsCard } from '../icons-card';
|
|
3
|
-
import type { ComponentStory, ComponentMeta } from '@storybook/react';
|
|
4
|
-
|
|
5
|
-
export default {
|
|
6
|
-
title: 'JS Packages/Components/Product Offer',
|
|
7
|
-
component: ProductOffer,
|
|
8
|
-
parameters: {
|
|
9
|
-
actions: { argTypesRegex: '^on.*' },
|
|
10
|
-
layout: 'centered',
|
|
11
|
-
},
|
|
12
|
-
} as ComponentMeta< typeof ProductOffer >;
|
|
13
|
-
|
|
14
|
-
const Template: ComponentStory< typeof ProductOffer > = args => <ProductOffer { ...args } />;
|
|
15
|
-
|
|
16
|
-
export const SecurityBundle = Template.bind( {} );
|
|
17
|
-
SecurityBundle.parameters = {};
|
|
18
|
-
SecurityBundle.args = {
|
|
19
|
-
slug: 'security',
|
|
20
|
-
icon: '',
|
|
21
|
-
name: 'Security',
|
|
22
|
-
title: 'Security',
|
|
23
|
-
subTitle: '',
|
|
24
|
-
description: 'Comprehensive site security, including Backup, Scan, and Anti-spam.',
|
|
25
|
-
isBundle: true,
|
|
26
|
-
isCard: true,
|
|
27
|
-
supportedProducts: [ 'backup', 'scan', 'anti-spam' ],
|
|
28
|
-
features: [
|
|
29
|
-
'Real-time cloud backups with 10GB storage',
|
|
30
|
-
'Automated real-time malware scan',
|
|
31
|
-
'One-click fixes for most threats',
|
|
32
|
-
'Comment & form spam protection',
|
|
33
|
-
],
|
|
34
|
-
pricing: {
|
|
35
|
-
currency: 'USD',
|
|
36
|
-
price: 24.92,
|
|
37
|
-
offPrice: 12.42,
|
|
38
|
-
},
|
|
39
|
-
buttonText: '',
|
|
40
|
-
addProductUrl: '',
|
|
41
|
-
hasRequiredPlan: false,
|
|
42
|
-
isLoading: false,
|
|
43
|
-
error: '',
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
export const JetpackBackup = Template.bind( {} );
|
|
47
|
-
JetpackBackup.parameters = {};
|
|
48
|
-
JetpackBackup.args = {
|
|
49
|
-
slug: 'backup',
|
|
50
|
-
icon: '',
|
|
51
|
-
name: 'Backup',
|
|
52
|
-
title: 'Jepack Backup',
|
|
53
|
-
subTitle: '',
|
|
54
|
-
description:
|
|
55
|
-
'Never lose a word, image, page, or time worrying about your site with automated backups & one-click restores.',
|
|
56
|
-
features: [
|
|
57
|
-
'Real-time cloud backups',
|
|
58
|
-
'10GB of backup storage',
|
|
59
|
-
'30-day archive & activity log',
|
|
60
|
-
'One-click restores',
|
|
61
|
-
],
|
|
62
|
-
isBundle: false,
|
|
63
|
-
isCard: true,
|
|
64
|
-
pricing: {
|
|
65
|
-
currency: 'USD',
|
|
66
|
-
price: 9.66,
|
|
67
|
-
offPrice: 3.95,
|
|
68
|
-
},
|
|
69
|
-
addProductUrl: '',
|
|
70
|
-
hasRequiredPlan: false,
|
|
71
|
-
isLoading: false,
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
export const JetpackProtect = Template.bind( {} );
|
|
75
|
-
JetpackProtect.parameters = {};
|
|
76
|
-
JetpackProtect.args = {
|
|
77
|
-
slug: 'protect',
|
|
78
|
-
icon: 'jetpack',
|
|
79
|
-
title: 'Protect',
|
|
80
|
-
subTitle: 'Protect your site and scan for security vulnerabilities listed in our database.',
|
|
81
|
-
features: [
|
|
82
|
-
'Over 20,000 listed vulnerabilities',
|
|
83
|
-
'Daily automatic scans',
|
|
84
|
-
'Check plugin and theme version status',
|
|
85
|
-
'Easy to navigate and use',
|
|
86
|
-
],
|
|
87
|
-
isBundle: false,
|
|
88
|
-
isCard: true,
|
|
89
|
-
pricing: {
|
|
90
|
-
isFree: true,
|
|
91
|
-
},
|
|
92
|
-
addProductUrl: '',
|
|
93
|
-
hasRequiredPlan: false,
|
|
94
|
-
isLoading: false,
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
const IconsCardTemplate: ComponentStory< typeof IconsCard > = args => <IconsCard { ...args } />;
|
|
98
|
-
|
|
99
|
-
export const IconsCardStory = IconsCardTemplate.bind( {} );
|
|
100
|
-
IconsCardStory.parameters = {};
|
|
101
|
-
IconsCardStory.args = {
|
|
102
|
-
products: [ 'backup', 'scan', 'anti-spam' ],
|
|
103
|
-
};
|
|
104
|
-
IconsCardStory.storyName = 'Icons Card';
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { CURRENCIES } from '@automattic/format-currency';
|
|
2
|
-
import ProductPrice from '../';
|
|
3
|
-
import type { ComponentStory, ComponentMeta } from '@storybook/react';
|
|
4
|
-
|
|
5
|
-
export default {
|
|
6
|
-
title: 'JS Packages/Components/Product Price',
|
|
7
|
-
component: ProductPrice,
|
|
8
|
-
argTypes: {
|
|
9
|
-
currency: {
|
|
10
|
-
control: { type: 'select' },
|
|
11
|
-
options: Object.keys( CURRENCIES ),
|
|
12
|
-
},
|
|
13
|
-
},
|
|
14
|
-
} as ComponentMeta< typeof ProductPrice >;
|
|
15
|
-
|
|
16
|
-
// Export additional stories using pre-defined values
|
|
17
|
-
const Template: ComponentStory< typeof ProductPrice > = args => <ProductPrice { ...args } />;
|
|
18
|
-
|
|
19
|
-
const DefaultArgs = {
|
|
20
|
-
currency: 'USD',
|
|
21
|
-
price: 24.92,
|
|
22
|
-
offPrice: 12.42,
|
|
23
|
-
showNotOffPrice: true,
|
|
24
|
-
isNotConvenientPrice: false,
|
|
25
|
-
hidePriceFraction: false,
|
|
26
|
-
hideDiscountLabel: false,
|
|
27
|
-
promoLabel: 'NEW',
|
|
28
|
-
legend: '/month, paid yearly',
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
// Export Default story
|
|
32
|
-
export const _default = Template.bind( {} );
|
|
33
|
-
_default.args = DefaultArgs;
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
import { render, screen } from '@testing-library/react';
|
|
2
|
-
import ProductPrice from '../index';
|
|
3
|
-
|
|
4
|
-
describe( 'ProductPrice', () => {
|
|
5
|
-
const testProps = {
|
|
6
|
-
currency: 'USD',
|
|
7
|
-
};
|
|
8
|
-
|
|
9
|
-
describe( 'When not hiding the price fraction', () => {
|
|
10
|
-
describe( 'And the fraction is zero', () => {
|
|
11
|
-
it( 'does not render the price fraction', () => {
|
|
12
|
-
render( <ProductPrice { ...testProps } hidePriceFraction={ true } price={ 17.0 } /> );
|
|
13
|
-
|
|
14
|
-
expect( screen.queryByTestId( 'PriceFraction' ) ).not.toBeInTheDocument();
|
|
15
|
-
} );
|
|
16
|
-
} );
|
|
17
|
-
|
|
18
|
-
describe( 'And the fraction is not zero', () => {
|
|
19
|
-
it( 'renders the price fraction', () => {
|
|
20
|
-
render( <ProductPrice { ...testProps } hidePriceFraction={ false } price={ 17.1 } /> );
|
|
21
|
-
|
|
22
|
-
expect( screen.getByTestId( 'PriceFraction' ) ).toBeInTheDocument();
|
|
23
|
-
} );
|
|
24
|
-
} );
|
|
25
|
-
} );
|
|
26
|
-
} );
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import QRCode from '../index';
|
|
2
|
-
|
|
3
|
-
export default {
|
|
4
|
-
title: 'JS Packages/Components/QRCode',
|
|
5
|
-
component: QRCode,
|
|
6
|
-
argTypes: {
|
|
7
|
-
value: {
|
|
8
|
-
control: { type: 'text' },
|
|
9
|
-
},
|
|
10
|
-
size: {
|
|
11
|
-
control: { type: 'number' },
|
|
12
|
-
},
|
|
13
|
-
level: {
|
|
14
|
-
control: { type: 'select' },
|
|
15
|
-
options: [ 'L', 'M', 'Q', 'H' ],
|
|
16
|
-
},
|
|
17
|
-
fgColor: {
|
|
18
|
-
control: { type: 'color' },
|
|
19
|
-
},
|
|
20
|
-
bgColor: {
|
|
21
|
-
control: { type: 'color' },
|
|
22
|
-
},
|
|
23
|
-
renderAs: {
|
|
24
|
-
control: { type: 'select' },
|
|
25
|
-
options: [ 'canvas', 'svg' ],
|
|
26
|
-
},
|
|
27
|
-
},
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
const Template = args => <QRCode { ...args } />;
|
|
31
|
-
|
|
32
|
-
export const _default = Template.bind( {} );
|