@automattic/jetpack-components 0.68.2 → 0.69.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 +5 -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 +12 -5
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import clsx from 'clsx';
|
|
3
|
+
import React from 'react';
|
|
4
|
+
import ReactSlider from 'react-slider';
|
|
5
|
+
import './style.scss';
|
|
6
|
+
/**
|
|
7
|
+
* Generate Number Slider
|
|
8
|
+
* More support from the original ReactSlider component: https://zillow.github.io/react-slider/
|
|
9
|
+
*
|
|
10
|
+
* @param {NumberSliderProps} props - Props
|
|
11
|
+
* @return {React.ReactElement} - JSX element
|
|
12
|
+
*/
|
|
13
|
+
const NumberSlider = ({ className, maxValue = 100, minValue = 0, step = 1, value, onChange, onBeforeChange, onAfterChange, renderThumb, }) => {
|
|
14
|
+
const [isThumbHolding, setIsThumbHolding] = React.useState(false);
|
|
15
|
+
const componentClassName = clsx('jp-components-number-slider', className, {
|
|
16
|
+
'jp-components-number-slider--is-holding': isThumbHolding,
|
|
17
|
+
});
|
|
18
|
+
const onBeforeChangeCallback = beforeValue => {
|
|
19
|
+
setIsThumbHolding(true);
|
|
20
|
+
if (typeof onBeforeChange === 'function') {
|
|
21
|
+
onBeforeChange(beforeValue);
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
const onAfterChangeCallback = afterValue => {
|
|
25
|
+
setIsThumbHolding(false);
|
|
26
|
+
if (typeof onAfterChange === 'function') {
|
|
27
|
+
onAfterChange(afterValue);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
const renderThumbCallback = renderThumb
|
|
31
|
+
? renderThumb
|
|
32
|
+
: (props, state) => {
|
|
33
|
+
const { key, ...otherProps } = props;
|
|
34
|
+
return (_jsx("div", { ...otherProps, children: state.valueNow }, key));
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* Type casting to prevent TypeScript error:
|
|
38
|
+
* TS2604: JSX element type 'ReactSlider' does not have any construct or call signatures.
|
|
39
|
+
*/
|
|
40
|
+
const TypedReactSlider = ReactSlider;
|
|
41
|
+
return (_jsx("div", { className: componentClassName, "data-testid": "number-slider", children: _jsx(TypedReactSlider, { className: "jp-components-number-slider__control", thumbClassName: "jp-components-number-slider__thumb", thumbActiveClassName: "jp-components-number-slider__thumb--is-active", trackClassName: "jp-components-number-slider__track", value: value, max: maxValue, min: minValue, step: step, renderThumb: renderThumbCallback, onChange: onChange, onBeforeChange: onBeforeChangeCallback, onAfterChange: onAfterChangeCallback }) }));
|
|
42
|
+
};
|
|
43
|
+
export default NumberSlider;
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import type { HTMLProps, RefCallback } from 'react';
|
|
2
|
+
interface HTMLPropsWithRefCallback<T> extends HTMLProps<T> {
|
|
3
|
+
ref: RefCallback<T>;
|
|
4
|
+
}
|
|
5
|
+
export type NumberSliderProps = {
|
|
6
|
+
/**
|
|
7
|
+
* The wrapper class name of this NumberSlider component.
|
|
8
|
+
*/
|
|
9
|
+
className?: string;
|
|
10
|
+
/**
|
|
11
|
+
* The maximum value of the slider.
|
|
12
|
+
*/
|
|
13
|
+
maxValue?: number;
|
|
14
|
+
/**
|
|
15
|
+
* The minimum value of the slider.
|
|
16
|
+
*/
|
|
17
|
+
minValue?: number;
|
|
18
|
+
/**
|
|
19
|
+
* The initial value of the slider.
|
|
20
|
+
*/
|
|
21
|
+
value?: number;
|
|
22
|
+
/**
|
|
23
|
+
* The step value of the slider.
|
|
24
|
+
*/
|
|
25
|
+
step?: number;
|
|
26
|
+
/**
|
|
27
|
+
* Callback called on every value change.
|
|
28
|
+
* The function will be called with two arguments, the first being the new value(s) the second being thumb index.
|
|
29
|
+
*/
|
|
30
|
+
onChange?: (value: number) => void;
|
|
31
|
+
/**
|
|
32
|
+
* Callback called before starting to move a thumb. The callback will only be called if the action will result in a change.
|
|
33
|
+
* The function will be called with two arguments, the first being the initial value(s) the second being thumb index.
|
|
34
|
+
*/
|
|
35
|
+
onBeforeChange?: (value: number) => void;
|
|
36
|
+
/**
|
|
37
|
+
* Callback called only after moving a thumb has ended. The callback will only be called if the action resulted in a change.
|
|
38
|
+
* The function will be called with two arguments, the first being the result value(s) the second being thumb index.
|
|
39
|
+
*/
|
|
40
|
+
onAfterChange?: (value: number) => void;
|
|
41
|
+
/**
|
|
42
|
+
* Node to render on the slider.
|
|
43
|
+
*/
|
|
44
|
+
renderThumb?: (props: HTMLPropsWithRefCallback<HTMLDivElement>, state: {
|
|
45
|
+
index: number;
|
|
46
|
+
value: number | ReadonlyArray<number>;
|
|
47
|
+
valueNow: number;
|
|
48
|
+
}) => React.JSX.Element | null;
|
|
49
|
+
};
|
|
50
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/// <reference types="react" resolution-mode="require"/>
|
|
2
|
+
import './style.scss';
|
|
3
|
+
type PopoverProps = {
|
|
4
|
+
action: React.ReactNode;
|
|
5
|
+
icon?: React.ReactNode;
|
|
6
|
+
children?: React.ReactNode;
|
|
7
|
+
};
|
|
8
|
+
declare const Popover: React.FC<PopoverProps>;
|
|
9
|
+
export default Popover;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import './style.scss';
|
|
3
|
+
const Popover = ({ icon, children, action }) => {
|
|
4
|
+
return (_jsxs("div", { className: "jp-popover", children: [_jsx("div", { className: "jp-popover__icon", children: icon }), _jsx("div", { className: "jp-popover__body", children: children }), _jsx("div", { className: "jp-popover__action", children: action })] }));
|
|
5
|
+
};
|
|
6
|
+
export default Popover;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { PricingCardProps } from './types.js';
|
|
2
|
+
import type React from 'react';
|
|
3
|
+
import './style.scss';
|
|
4
|
+
/**
|
|
5
|
+
* The Pricing card component.
|
|
6
|
+
*
|
|
7
|
+
* @param {PricingCardProps} props -- The component props.
|
|
8
|
+
* @return {React.ReactNode} The rendered component.
|
|
9
|
+
*/
|
|
10
|
+
declare const PricingCard: React.FC<PricingCardProps>;
|
|
11
|
+
export default PricingCard;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { getCurrencyObject } from '@automattic/format-currency';
|
|
3
|
+
import { Button } from '@wordpress/components';
|
|
4
|
+
import { sprintf, __ } from '@wordpress/i18n';
|
|
5
|
+
import { LoadingPlaceholder } from '@automattic/jetpack-components';
|
|
6
|
+
import TermsOfService from '../terms-of-service/index.js';
|
|
7
|
+
import './style.scss';
|
|
8
|
+
/**
|
|
9
|
+
* Whether or not to display a price's decimal part in the UI.
|
|
10
|
+
* Needed as `getCurrencyObject` will always return the decimal part populated even if it
|
|
11
|
+
* doesn't exist.
|
|
12
|
+
*
|
|
13
|
+
* @param {CurrencyObject} currencyObject -- A currency object returned from `getCurrencyObject`.
|
|
14
|
+
* @return {boolean} Whether or not to display the price decimal part.
|
|
15
|
+
*/
|
|
16
|
+
const showPriceDecimals = (currencyObject) => {
|
|
17
|
+
return currencyObject.fraction.indexOf('00') === -1;
|
|
18
|
+
};
|
|
19
|
+
/**
|
|
20
|
+
* The Pricing card component.
|
|
21
|
+
*
|
|
22
|
+
* @param {PricingCardProps} props -- The component props.
|
|
23
|
+
* @return {React.ReactNode} The rendered component.
|
|
24
|
+
*/
|
|
25
|
+
const PricingCard = ({ currencyCode = 'USD', priceDetails = __('/month, paid yearly', 'jetpack-components'), ...props }) => {
|
|
26
|
+
const currencyObjectBefore = getCurrencyObject(props.priceBefore, currencyCode);
|
|
27
|
+
const currencyObjectAfter = getCurrencyObject(props.priceAfter, currencyCode);
|
|
28
|
+
return (_jsxs("div", { className: "jp-components__pricing-card", children: [props.icon && (_jsx("div", { className: "jp-components__pricing-card__icon", children: 'string' === typeof props.icon ? (_jsx("img", { src: props.icon, alt: sprintf(
|
|
29
|
+
/* translators: placeholder is a product name */
|
|
30
|
+
__('Icon for the product %s', 'jetpack-components'), props.title) })) : (props.icon) })), _jsx("h1", { className: "jp-components__pricing-card__title", children: props.title }), _jsxs("div", { className: "jp-components__pricing-card__pricing", children: [props.priceAfter === 0 && _jsx(LoadingPlaceholder, { width: "100%", height: 48 }), props.priceBefore !== props.priceAfter && props.priceAfter > 0 && (_jsxs("div", { className: "jp-components__pricing-card__price-before", children: [_jsx("span", { className: "jp-components__pricing-card__currency", children: currencyObjectBefore.symbol }), _jsx("span", { className: "jp-components__pricing-card__price", children: currencyObjectBefore.integer }), showPriceDecimals(currencyObjectBefore) && (_jsxs("span", { className: "jp-components__pricing-card__price-decimal", children: [' ', currencyObjectBefore.fraction] })), _jsx("div", { className: "jp-components__pricing-card__price-strikethrough" })] })), props.priceAfter > 0 && (_jsxs(_Fragment, { children: [_jsxs("div", { className: "jp-components__pricing-card__price-after", children: [_jsx("span", { className: "jp-components__pricing-card__currency", children: currencyObjectAfter.symbol }), _jsx("span", { className: "jp-components__pricing-card__price", children: currencyObjectAfter.integer }), showPriceDecimals(currencyObjectAfter) && (_jsx("span", { className: "jp-components__pricing-card__price-decimal", children: currencyObjectAfter.fraction }))] }), _jsx("span", { className: "jp-components__pricing-card__price-details", children: priceDetails })] }))] }), props.children && (_jsx("div", { className: "jp-components__pricing-card__extra-content-wrapper", children: props.children })), props.tosText && _jsx("div", { className: "jp-components__pricing-card__tos", children: props.tosText }), props.ctaText && (_jsxs(_Fragment, { children: [!props.tosText && (_jsx("div", { className: "jp-components__pricing-card__tos", children: _jsx(TermsOfService, { agreeButtonLabel: props.ctaText }) })), _jsx("div", { className: "jp-components__pricing-card__cta", children: _jsx(Button, { className: "jp-components__pricing-card__button", label: props.ctaText, onClick: props.onCtaClick, children: props.ctaText }) })] })), props.infoText && (_jsx("div", { className: "jp-components__pricing-card__info", children: props.infoText }))] }));
|
|
31
|
+
};
|
|
32
|
+
export default PricingCard;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* External dependencies
|
|
3
|
+
*/
|
|
4
|
+
import type { Button } from '@wordpress/components';
|
|
5
|
+
import type React from 'react';
|
|
6
|
+
export type PricingCardProps = {
|
|
7
|
+
/**
|
|
8
|
+
* The Title.
|
|
9
|
+
*/
|
|
10
|
+
title: string;
|
|
11
|
+
/**
|
|
12
|
+
* The Icon.
|
|
13
|
+
*/
|
|
14
|
+
icon?: string | React.ReactNode;
|
|
15
|
+
/**
|
|
16
|
+
* Price before discount.
|
|
17
|
+
*/
|
|
18
|
+
priceBefore: number;
|
|
19
|
+
/**
|
|
20
|
+
* Price after discount.
|
|
21
|
+
*/
|
|
22
|
+
priceAfter: number;
|
|
23
|
+
/**
|
|
24
|
+
* Price details.
|
|
25
|
+
*/
|
|
26
|
+
priceDetails?: string;
|
|
27
|
+
/**
|
|
28
|
+
* The Currency code, eg 'USD'.
|
|
29
|
+
*/
|
|
30
|
+
currencyCode?: string;
|
|
31
|
+
/**
|
|
32
|
+
* The CTA copy.
|
|
33
|
+
*/
|
|
34
|
+
ctaText?: string;
|
|
35
|
+
/**
|
|
36
|
+
* The CTA callback to be called on click.
|
|
37
|
+
*/
|
|
38
|
+
onCtaClick?: React.ComponentProps<typeof Button>['onClick'];
|
|
39
|
+
/**
|
|
40
|
+
* Optional informative text.
|
|
41
|
+
*/
|
|
42
|
+
infoText?: React.ReactNode;
|
|
43
|
+
/**
|
|
44
|
+
* The TOS copy.
|
|
45
|
+
*/
|
|
46
|
+
tosText?: React.ReactNode;
|
|
47
|
+
/**
|
|
48
|
+
* Optional Child nodes
|
|
49
|
+
*/
|
|
50
|
+
children?: React.ReactNode;
|
|
51
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { PricingTableProps, PricingTableColumnProps, PricingTableHeaderProps, PricingTableItemProps } from './types.js';
|
|
3
|
+
export declare const PricingTableItem: React.FC<PricingTableItemProps>;
|
|
4
|
+
export declare const PricingTableHeader: React.FC<PricingTableHeaderProps>;
|
|
5
|
+
export declare const PricingTableColumn: React.FC<PricingTableColumnProps>;
|
|
6
|
+
declare const PricingTable: React.FC<PricingTableProps>;
|
|
7
|
+
export default PricingTable;
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { __, sprintf } from '@wordpress/i18n';
|
|
3
|
+
import { Icon, check, closeSmall } from '@wordpress/icons';
|
|
4
|
+
import clsx from 'clsx';
|
|
5
|
+
import { createContext, useContext, Children, cloneElement, } from 'react';
|
|
6
|
+
import IconTooltip from '../icon-tooltip/index.js';
|
|
7
|
+
import useBreakpointMatch from '../layout/use-breakpoint-match/index.js';
|
|
8
|
+
import TermsOfService from '../terms-of-service/index.js';
|
|
9
|
+
import Text from '../text/index.js';
|
|
10
|
+
import styles from './styles.module.scss';
|
|
11
|
+
const INCLUDED_TEXT = __('Included', 'jetpack-components');
|
|
12
|
+
const NOT_INCLUDED_TEXT = __('Not included', 'jetpack-components');
|
|
13
|
+
const COMING_SOON_TEXT = __('Coming soon', 'jetpack-components');
|
|
14
|
+
const PricingTableContext = createContext(undefined);
|
|
15
|
+
const getItemLabels = (isComingSoon, isIncluded, featureNameLabel) => {
|
|
16
|
+
if (isComingSoon) {
|
|
17
|
+
return {
|
|
18
|
+
lg: COMING_SOON_TEXT,
|
|
19
|
+
// translators: Name of the current feature
|
|
20
|
+
default: sprintf(__('%s coming soon', 'jetpack-components'), featureNameLabel),
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
return {
|
|
24
|
+
lg: isIncluded ? INCLUDED_TEXT : NOT_INCLUDED_TEXT,
|
|
25
|
+
default: isIncluded
|
|
26
|
+
? featureNameLabel
|
|
27
|
+
: sprintf(
|
|
28
|
+
/* translators: Name of the current feature */
|
|
29
|
+
__('%s not included', 'jetpack-components'), featureNameLabel),
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
export const PricingTableItem = ({ isIncluded = false, isComingSoon = false, index = 0, label = null, tooltipInfo, tooltipTitle, tooltipClassName = '', }) => {
|
|
33
|
+
const [isLg] = useBreakpointMatch('lg');
|
|
34
|
+
const item = useContext(PricingTableContext)[index];
|
|
35
|
+
const showTick = isComingSoon || isIncluded;
|
|
36
|
+
const featureNameLabel = item.name;
|
|
37
|
+
const defaultTooltipInfo = item.tooltipInfo;
|
|
38
|
+
const defaultTooltipTitle = item.tooltipTitle;
|
|
39
|
+
const showTooltip = tooltipInfo || (!isLg && defaultTooltipInfo);
|
|
40
|
+
const labels = getItemLabels(isComingSoon, isIncluded, featureNameLabel);
|
|
41
|
+
const defaultLabel = isLg ? labels.lg : labels.default;
|
|
42
|
+
return (_jsxs("div", { className: clsx(styles.item, styles.value), children: [_jsx(Icon, { className: clsx(styles.icon, showTick ? styles['icon-check'] : styles['icon-cross']), size: 32, icon: showTick ? check : closeSmall }), _jsx(Text, { variant: "body-small", children: label || defaultLabel }), showTooltip && (_jsx(IconTooltip, { title: tooltipTitle ? tooltipTitle : defaultTooltipTitle, iconClassName: styles['popover-icon'], className: clsx(styles.popover, tooltipClassName), placement: 'bottom-end', iconSize: 14, offset: 4, wide: Boolean(tooltipTitle && tooltipInfo), children: _jsx(Text, { variant: "body-small", component: "div", children: tooltipInfo || defaultTooltipInfo }) }))] }));
|
|
43
|
+
};
|
|
44
|
+
export const PricingTableHeader = ({ children }) => (_jsx("div", { className: styles.header, children: children }));
|
|
45
|
+
export const PricingTableColumn = ({ primary = false, children, }) => {
|
|
46
|
+
let index = 0;
|
|
47
|
+
return (_jsx("div", { className: clsx(styles.card, { [styles['is-primary']]: primary }), children: Children.map(children, child => {
|
|
48
|
+
const item = child;
|
|
49
|
+
if (item.type === PricingTableItem) {
|
|
50
|
+
index++;
|
|
51
|
+
return cloneElement(item, { index: index - 1 });
|
|
52
|
+
}
|
|
53
|
+
return item;
|
|
54
|
+
}) }));
|
|
55
|
+
};
|
|
56
|
+
const PricingTable = ({ title, items, children, showIntroOfferDisclaimer = false, }) => {
|
|
57
|
+
const [isLg] = useBreakpointMatch('lg');
|
|
58
|
+
return (_jsxs(PricingTableContext.Provider, { value: items, children: [_jsx("div", { className: clsx(styles.container, { [styles['is-viewport-large']]: isLg }), style: {
|
|
59
|
+
'--rows': items.length + 1,
|
|
60
|
+
'--columns': Children.toArray(children).length + 1,
|
|
61
|
+
}, children: _jsxs("div", { className: styles.table, children: [_jsx(Text, { variant: "headline-small", children: title }), isLg &&
|
|
62
|
+
items.map((item, i) => (_jsxs("div", { className: clsx(styles.item, {
|
|
63
|
+
[styles['last-feature']]: i === items.length - 1,
|
|
64
|
+
}), children: [_jsx(Text, { variant: "body-small", children: _jsx("strong", { children: item.name }) }), item.tooltipInfo && (_jsx(IconTooltip, { title: item.tooltipTitle, iconClassName: styles['popover-icon'], className: styles.popover, placement: item.tooltipPlacement ? item.tooltipPlacement : 'bottom-end', iconSize: 14, offset: 4, wide: Boolean(item.tooltipTitle && item.tooltipInfo), children: _jsx(Text, { variant: "body-small", children: item.tooltipInfo }) }))] }, i))), children] }) }), _jsx("div", { className: styles['tos-container'], children: _jsxs("div", { className: styles.tos, children: [showIntroOfferDisclaimer && (_jsx(Text, { variant: "body-small", children: __('Reduced pricing is a limited offer for the first year and renews at regular price.', 'jetpack-components') })), _jsx(TermsOfService, { multipleButtons: true })] }) })] }));
|
|
65
|
+
};
|
|
66
|
+
export default PricingTable;
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/// <reference types="react" resolution-mode="require"/>
|
|
2
|
+
import type { Placement } from '../icon-tooltip/types.js';
|
|
3
|
+
export type PricingTableProps = {
|
|
4
|
+
/**
|
|
5
|
+
* Title of the pricing table.
|
|
6
|
+
*/
|
|
7
|
+
title: string;
|
|
8
|
+
/**
|
|
9
|
+
* Array of items to display in the pricing table.
|
|
10
|
+
*/
|
|
11
|
+
items: {
|
|
12
|
+
name: string;
|
|
13
|
+
tooltipInfo?: React.ReactNode;
|
|
14
|
+
tooltipTitle?: string;
|
|
15
|
+
tooltipPlacement?: Placement;
|
|
16
|
+
}[];
|
|
17
|
+
/**
|
|
18
|
+
* The columns to add to the table.
|
|
19
|
+
*/
|
|
20
|
+
children: React.ReactNode;
|
|
21
|
+
/**
|
|
22
|
+
* Whether to show the intro offer disclaimer text with the ToS.
|
|
23
|
+
*/
|
|
24
|
+
showIntroOfferDisclaimer?: boolean;
|
|
25
|
+
};
|
|
26
|
+
export type PricingTableColumnProps = {
|
|
27
|
+
/**
|
|
28
|
+
* Whether the column has the primary style.
|
|
29
|
+
*/
|
|
30
|
+
primary?: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Items to show in a column.
|
|
33
|
+
*/
|
|
34
|
+
children: React.ReactElement[];
|
|
35
|
+
};
|
|
36
|
+
export type PricingTableHeaderProps = {
|
|
37
|
+
/**
|
|
38
|
+
* Items to show in a header.
|
|
39
|
+
*/
|
|
40
|
+
children: React.ReactNode;
|
|
41
|
+
};
|
|
42
|
+
export type PricingTableItemProps = {
|
|
43
|
+
/**
|
|
44
|
+
* Whether or not the item is included in the column.
|
|
45
|
+
*/
|
|
46
|
+
isIncluded: boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Whether the feature is coming soon. Takes precedence over isIncluded.
|
|
49
|
+
*/
|
|
50
|
+
isComingSoon?: boolean;
|
|
51
|
+
/**
|
|
52
|
+
* A custom label to display instead of the default one.
|
|
53
|
+
*/
|
|
54
|
+
label?: string | number | React.ReactElement;
|
|
55
|
+
/**
|
|
56
|
+
* Index of the item, relative to other PricingTableItem components. Internal use only.
|
|
57
|
+
*/
|
|
58
|
+
index?: number;
|
|
59
|
+
tooltipInfo?: React.ReactNode;
|
|
60
|
+
/**
|
|
61
|
+
* Title for the popover, not required.
|
|
62
|
+
*/
|
|
63
|
+
tooltipTitle?: string;
|
|
64
|
+
/**
|
|
65
|
+
* Class name for the popover, not required.
|
|
66
|
+
*/
|
|
67
|
+
tooltipClassName?: string;
|
|
68
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { IconsCardProps } from './types.js';
|
|
3
|
+
/**
|
|
4
|
+
* Icons composition for a bundle product,
|
|
5
|
+
* based on the list of supported products.
|
|
6
|
+
*
|
|
7
|
+
* @param {IconsCardProps} props - Component props.
|
|
8
|
+
* @return {React.ReactNode} Bundle product icons react component.
|
|
9
|
+
*/
|
|
10
|
+
export declare const IconsCard: React.FC<IconsCardProps>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Icon, plus } from '@wordpress/icons';
|
|
3
|
+
import { Fragment } from 'react';
|
|
4
|
+
import { getIconBySlug } from '../icons/index.js';
|
|
5
|
+
import styles from './style.module.scss';
|
|
6
|
+
/**
|
|
7
|
+
* Icons composition for a bundle product,
|
|
8
|
+
* based on the list of supported products.
|
|
9
|
+
*
|
|
10
|
+
* @param {IconsCardProps} props - Component props.
|
|
11
|
+
* @return {React.ReactNode} Bundle product icons react component.
|
|
12
|
+
*/
|
|
13
|
+
export const IconsCard = ({ products, icon, size = 24 }) => {
|
|
14
|
+
if (icon) {
|
|
15
|
+
const CustomIcon = getIconBySlug(icon);
|
|
16
|
+
return (_jsx("div", { className: styles['product-bundle-icons'], children: _jsx(CustomIcon, { size: size }) }));
|
|
17
|
+
}
|
|
18
|
+
return (_jsx("div", { className: styles['product-bundle-icons'], children: products.map((product, index) => {
|
|
19
|
+
const ProductIcon = getIconBySlug(product);
|
|
20
|
+
const ProIcon = ProductIcon ? ProductIcon : () => null;
|
|
21
|
+
return (_jsxs(Fragment, { children: [_jsx(ProIcon, { size: size }), index !== products.length - 1 && (_jsx(Icon, { className: styles['plus-icon'], icon: plus, size: 16 }, `icon-plugs${index * 2 + 1}`))] }, index));
|
|
22
|
+
}) }));
|
|
23
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { ProductOfferProps } from './types.js';
|
|
2
|
+
import type React from 'react';
|
|
3
|
+
/**
|
|
4
|
+
* Product Detail component.
|
|
5
|
+
*
|
|
6
|
+
* @param {ProductOfferProps} props - Component props.
|
|
7
|
+
* @return {React.ReactNode} - ProductOffer react component.
|
|
8
|
+
*/
|
|
9
|
+
declare const ProductOffer: React.FC<ProductOfferProps>;
|
|
10
|
+
export default ProductOffer;
|
|
11
|
+
export * from './icons-card.js';
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { __, sprintf } from '@wordpress/i18n';
|
|
3
|
+
import { Icon, check } from '@wordpress/icons';
|
|
4
|
+
import clsx from 'clsx';
|
|
5
|
+
import Alert from '../alert/index.js';
|
|
6
|
+
import Button from '../button/index.js';
|
|
7
|
+
import { CheckmarkIcon } from '../icons/index.js';
|
|
8
|
+
import ProductPrice from '../product-price/index.js';
|
|
9
|
+
import Text, { H3, Title } from '../text/index.js';
|
|
10
|
+
import { IconsCard } from './icons-card.js';
|
|
11
|
+
import { ProductOfferHeader } from './product-offer-header.js';
|
|
12
|
+
import styles from './style.module.scss';
|
|
13
|
+
/**
|
|
14
|
+
* Product Detail component.
|
|
15
|
+
*
|
|
16
|
+
* @param {ProductOfferProps} props - Component props.
|
|
17
|
+
* @return {React.ReactNode} - ProductOffer react component.
|
|
18
|
+
*/
|
|
19
|
+
const ProductOffer = ({ addProductUrl, buttonDisclaimer, buttonText = '', className, description, error = '', features, hasRequiredPlan, icon, isBundle = false, isCard, isLoading, onAdd, pricing = {}, slug, subTitle = '', supportedProducts, title = '', }) => {
|
|
20
|
+
const { isFree, price, currency, offPrice } = pricing;
|
|
21
|
+
const needsPurchase = !isFree && !hasRequiredPlan;
|
|
22
|
+
const defautlButtonText = sprintf(
|
|
23
|
+
/* translators: placeholder is product name. */
|
|
24
|
+
__('Add %s', 'jetpack-components'), title);
|
|
25
|
+
return (_jsxs("div", { className: clsx(styles.wrapper, className, {
|
|
26
|
+
[styles['is-bundle-card']]: isBundle,
|
|
27
|
+
[styles['is-card']]: isCard || isBundle, // is card when is bundle.
|
|
28
|
+
}), children: [isBundle && _jsx(ProductOfferHeader, {}), _jsxs("div", { className: styles['card-container'], children: [_jsx(IconsCard, { icon: icon, products: supportedProducts?.length ? supportedProducts : [slug], size: 32 }), _jsx(H3, { children: title }), subTitle && _jsx(Title, { mb: 3, children: subTitle }), description && _jsx(Text, { mb: 3, children: description }), _jsx("ul", { className: styles.features, children: features.map((feature, id) => (_jsxs(Text, { component: "li", variant: "body", children: [_jsx(Icon, { icon: check, size: 24, className: styles.check }), feature] }, `feature-${id}`))) }), needsPurchase && (_jsx(ProductPrice, { price: price, offPrice: offPrice, currency: currency })), isFree && _jsx(H3, { children: __('Free', 'jetpack-components') }), _jsx(Alert, { level: "error", showIcon: !!error, children: error }), buttonDisclaimer, (!isBundle || (isBundle && !hasRequiredPlan)) && (_jsx(Button, { onClick: addProductUrl ? null : onAdd, isLoading: isLoading, disabled: isLoading, variant: isLoading || !isBundle ? 'primary' : 'secondary', className: styles['add-button'], ...(addProductUrl ? { href: addProductUrl } : {}), children: buttonText || defautlButtonText })), isBundle && hasRequiredPlan && (_jsxs("div", { className: styles['product-has-required-plan'], children: [_jsx(CheckmarkIcon, { size: 36 }), _jsx(Text, { children: __('Active on your site', 'jetpack-components') })] }))] })] }));
|
|
29
|
+
};
|
|
30
|
+
export default ProductOffer;
|
|
31
|
+
export * from './icons-card.js';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ProductOfferHeaderProps } from './types.js';
|
|
2
|
+
import type React from 'react';
|
|
3
|
+
/**
|
|
4
|
+
* Product Detail Card Header component.
|
|
5
|
+
*
|
|
6
|
+
* @param {ProductOfferHeaderProps} props - Component props.
|
|
7
|
+
* @return {React.ReactNode} ProductOfferHeader react component.
|
|
8
|
+
*/
|
|
9
|
+
export declare const ProductOfferHeader: React.FC<ProductOfferHeaderProps>;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { __ } from '@wordpress/i18n';
|
|
3
|
+
import { Icon, starFilled as star } from '@wordpress/icons';
|
|
4
|
+
import Text from '../text/index.js';
|
|
5
|
+
import styles from './style.module.scss';
|
|
6
|
+
/**
|
|
7
|
+
* Product Detail Card Header component.
|
|
8
|
+
*
|
|
9
|
+
* @param {ProductOfferHeaderProps} props - Component props.
|
|
10
|
+
* @return {React.ReactNode} ProductOfferHeader react component.
|
|
11
|
+
*/
|
|
12
|
+
export const ProductOfferHeader = ({ title = __('Popular upgrade', 'jetpack-components'), }) => {
|
|
13
|
+
return (_jsxs("div", { className: styles['card-header'], children: [_jsx(Icon, { icon: star, className: styles['product-bundle-icon'], size: 24 }), _jsx(Text, { variant: "label", children: title })] }));
|
|
14
|
+
};
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/// <reference types="react" resolution-mode="require"/>
|
|
2
|
+
import { ProductPriceProps } from '../product-price/types.js';
|
|
3
|
+
import type { JetpackIconSlug } from '../icons/index.js';
|
|
4
|
+
export type ProductOfferProps = {
|
|
5
|
+
/**
|
|
6
|
+
* Product slug.
|
|
7
|
+
*/
|
|
8
|
+
slug?: JetpackIconSlug;
|
|
9
|
+
/**
|
|
10
|
+
* Product name.
|
|
11
|
+
*/
|
|
12
|
+
name?: string;
|
|
13
|
+
/**
|
|
14
|
+
* Custom Icon slug.
|
|
15
|
+
*/
|
|
16
|
+
icon?: JetpackIconSlug;
|
|
17
|
+
/**
|
|
18
|
+
* Product title.
|
|
19
|
+
*/
|
|
20
|
+
title?: string;
|
|
21
|
+
/**
|
|
22
|
+
* Product sub-title.
|
|
23
|
+
*/
|
|
24
|
+
subTitle?: string;
|
|
25
|
+
/**
|
|
26
|
+
* Product description.
|
|
27
|
+
*/
|
|
28
|
+
description?: string;
|
|
29
|
+
/**
|
|
30
|
+
* Features list of the product.
|
|
31
|
+
*/
|
|
32
|
+
features?: Array<string>;
|
|
33
|
+
/**
|
|
34
|
+
* Add the styles to look like a card.
|
|
35
|
+
*/
|
|
36
|
+
isCard?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Whether or not the product is a bundle.
|
|
39
|
+
*/
|
|
40
|
+
isBundle?: boolean;
|
|
41
|
+
/**
|
|
42
|
+
* List of supported products (for bundles).
|
|
43
|
+
*/
|
|
44
|
+
supportedProducts?: Array<JetpackIconSlug>;
|
|
45
|
+
/**
|
|
46
|
+
* Product Pricing object.
|
|
47
|
+
*/
|
|
48
|
+
pricing?: Pricing;
|
|
49
|
+
/**
|
|
50
|
+
* Whether or not the product has the required plan.
|
|
51
|
+
*/
|
|
52
|
+
hasRequiredPlan?: boolean;
|
|
53
|
+
/**
|
|
54
|
+
* Applies the isLoading style to the component.
|
|
55
|
+
*/
|
|
56
|
+
isLoading?: boolean;
|
|
57
|
+
/**
|
|
58
|
+
* A className to be concat with default ones.
|
|
59
|
+
*/
|
|
60
|
+
className?: string;
|
|
61
|
+
/**
|
|
62
|
+
* Callback function to be executed on click on Add button.
|
|
63
|
+
*/
|
|
64
|
+
onAdd?: VoidFunction;
|
|
65
|
+
/**
|
|
66
|
+
* The checkout URL to add/buy the product.
|
|
67
|
+
*/
|
|
68
|
+
addProductUrl?: string;
|
|
69
|
+
/**
|
|
70
|
+
* The text to be displayed on the Add button.
|
|
71
|
+
*/
|
|
72
|
+
buttonText?: string;
|
|
73
|
+
/**
|
|
74
|
+
* Content displayed below the Add button.
|
|
75
|
+
*/
|
|
76
|
+
buttonDisclaimer?: React.ReactNode;
|
|
77
|
+
/**
|
|
78
|
+
* Error message.
|
|
79
|
+
*/
|
|
80
|
+
error?: string;
|
|
81
|
+
};
|
|
82
|
+
export type Pricing = Pick<ProductPriceProps, 'currency' | 'offPrice' | 'price'> & {
|
|
83
|
+
/**
|
|
84
|
+
* Whether it is a free product
|
|
85
|
+
*/
|
|
86
|
+
isFree?: boolean;
|
|
87
|
+
};
|
|
88
|
+
export type IconsCardProps = {
|
|
89
|
+
/**
|
|
90
|
+
* Custom icon slug.
|
|
91
|
+
*/
|
|
92
|
+
icon: JetpackIconSlug;
|
|
93
|
+
/**
|
|
94
|
+
* List of supported products.
|
|
95
|
+
*/
|
|
96
|
+
products: Array<JetpackIconSlug>;
|
|
97
|
+
/**
|
|
98
|
+
* Icon size.
|
|
99
|
+
*/
|
|
100
|
+
size: number;
|
|
101
|
+
};
|
|
102
|
+
export type ProductOfferHeaderProps = Pick<ProductOfferProps, 'title'>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ProductPriceProps } from './types.js';
|
|
2
|
+
import type React from 'react';
|
|
3
|
+
/**
|
|
4
|
+
* React component to render the price.
|
|
5
|
+
*
|
|
6
|
+
* @param {ProductPriceProps} props - Component props.
|
|
7
|
+
* @return {React.ReactNode} Price react component.
|
|
8
|
+
*/
|
|
9
|
+
declare const ProductPrice: React.FC<ProductPriceProps>;
|
|
10
|
+
export default ProductPrice;
|
|
11
|
+
export * from './price.js';
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
/*
|
|
3
|
+
* External dependencies
|
|
4
|
+
*/
|
|
5
|
+
import { __ } from '@wordpress/i18n';
|
|
6
|
+
import clsx from 'clsx';
|
|
7
|
+
/*
|
|
8
|
+
* Internal dependencies
|
|
9
|
+
*/
|
|
10
|
+
import Text from '../text/index.js';
|
|
11
|
+
import { Price } from './price.js';
|
|
12
|
+
import styles from './style.module.scss';
|
|
13
|
+
/**
|
|
14
|
+
* React component to render the price.
|
|
15
|
+
*
|
|
16
|
+
* @param {ProductPriceProps} props - Component props.
|
|
17
|
+
* @return {React.ReactNode} Price react component.
|
|
18
|
+
*/
|
|
19
|
+
const ProductPrice = ({ price, offPrice, currency = '', showNotOffPrice = true, hideDiscountLabel = true, promoLabel = '', legend = __('/month, paid yearly', 'jetpack-components'), isNotConvenientPrice = false, hidePriceFraction = false, children, }) => {
|
|
20
|
+
if ((price == null && offPrice == null) || !currency) {
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
showNotOffPrice = showNotOffPrice && offPrice != null;
|
|
24
|
+
const discount = typeof price === 'number' && typeof offPrice === 'number'
|
|
25
|
+
? Math.floor(((price - offPrice) / price) * 100)
|
|
26
|
+
: 0;
|
|
27
|
+
const showDiscountLabel = !hideDiscountLabel && discount && discount > 0;
|
|
28
|
+
const discountElt = showDiscountLabel ? discount + __('% off', 'jetpack-components') : null;
|
|
29
|
+
return (_jsxs(_Fragment, { children: [_jsx("div", { className: styles.container, children: _jsxs("div", { className: clsx(styles['price-container'], 'product-price_container'), children: [_jsx(Price, { value: offPrice ?? price, currency: currency, isOff: !isNotConvenientPrice, hidePriceFraction: hidePriceFraction }), showNotOffPrice && (_jsx(Price, { value: price, currency: currency, isOff: false, hidePriceFraction: hidePriceFraction })), discountElt && (_jsx(Text, { className: clsx(styles['promo-label'], 'product-price_promo_label'), children: discountElt }))] }) }), _jsxs("div", { className: styles.footer, children: [children ? (children) : (_jsx(Text, { className: clsx(styles.legend, 'product-price_legend'), children: legend })), promoLabel && (_jsx(Text, { className: clsx(styles['promo-label'], 'product-price_promo_label'), children: promoLabel }))] })] }));
|
|
30
|
+
};
|
|
31
|
+
export default ProductPrice;
|
|
32
|
+
export * from './price.js';
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { PriceProps } from './types.js';
|
|
2
|
+
import type React from 'react';
|
|
3
|
+
/**
|
|
4
|
+
* React component to render a Price composition.
|
|
5
|
+
*
|
|
6
|
+
* @param {PriceProps} props - Component props.
|
|
7
|
+
* @return {React.ReactNode} -Price react component.
|
|
8
|
+
*/
|
|
9
|
+
export declare const Price: React.FC<PriceProps>;
|