@automattic/plans-grid-next 1.0.0 → 1.0.2
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/dist/cjs/__mocks__/wpcom-proxy-request.js +3 -4
- package/dist/cjs/__mocks__/wpcom-proxy-request.js.map +1 -1
- package/dist/cjs/_shared.scss +9 -4
- package/dist/cjs/components/comparison-grid/index.js +62 -50
- package/dist/cjs/components/comparison-grid/index.js.map +1 -1
- package/dist/cjs/components/comparison-grid/index.stories.js +1 -0
- package/dist/cjs/components/comparison-grid/index.stories.js.map +1 -1
- package/dist/cjs/components/comparison-grid/style.scss +0 -17
- package/dist/cjs/components/dropdown-option.js +1 -1
- package/dist/cjs/components/features-grid/index.js +21 -6
- package/dist/cjs/components/features-grid/index.js.map +1 -1
- package/dist/cjs/components/features-grid/index.stories.js +1 -0
- package/dist/cjs/components/features-grid/index.stories.js.map +1 -1
- package/dist/cjs/components/features-grid/style.scss +6 -21
- package/dist/cjs/components/item.js +1 -2
- package/dist/cjs/components/item.js.map +1 -1
- package/dist/cjs/components/plan-button/style.scss +12 -11
- package/dist/cjs/components/plan-type-selector/hooks/use-interval-options.js +1 -1
- package/dist/cjs/components/plan-type-selector/hooks/use-interval-options.js.map +1 -1
- package/dist/cjs/components/plan-type-selector/hooks/use-max-discount.js +1 -1
- package/dist/cjs/components/plan-type-selector/hooks/use-max-discount.js.map +1 -1
- package/dist/cjs/components/plan-type-selector/hooks/use-max-discounts-for-plan-terms.js +1 -1
- package/dist/cjs/components/plan-type-selector/hooks/use-max-discounts-for-plan-terms.js.map +1 -1
- package/dist/cjs/components/plan-type-selector/style.scss +3 -1
- package/dist/cjs/components/shared/billing-timeframe/index.js +13 -5
- package/dist/cjs/components/shared/billing-timeframe/index.js.map +1 -1
- package/dist/cjs/components/shared/header-price/style.scss +4 -2
- package/dist/cjs/components/shared/storage/hooks/use-default-storage-option.js +1 -1
- package/dist/cjs/components/shared/storage/hooks/use-default-storage-option.js.map +1 -1
- package/dist/cjs/components/shared/storage/hooks/use-purchased-storage-add-on.js +1 -1
- package/dist/cjs/components/shared/storage/hooks/use-purchased-storage-add-on.js.map +1 -1
- package/dist/cjs/components/shared/storage/index.js +3 -2
- package/dist/cjs/components/shared/storage/index.js.map +1 -1
- package/dist/cjs/components/sticky-container.js +66 -6
- package/dist/cjs/components/sticky-container.js.map +1 -1
- package/dist/cjs/hooks/data-store/is-popular-plan.js +1 -2
- package/dist/cjs/hooks/data-store/is-popular-plan.js.map +1 -1
- package/dist/cjs/hooks/data-store/use-grid-plans-for-features-grid.js +14 -11
- package/dist/cjs/hooks/data-store/use-grid-plans-for-features-grid.js.map +1 -1
- package/dist/cjs/hooks/data-store/use-plan-billing-description.js +2 -2
- package/dist/cjs/hooks/data-store/use-plan-billing-description.js.map +1 -1
- package/dist/cjs/hooks/data-store/use-plan-billing-period.js +14 -0
- package/dist/cjs/hooks/data-store/use-plan-billing-period.js.map +1 -0
- package/dist/cjs/hooks/use-grid-size.js +2 -4
- package/dist/cjs/hooks/use-grid-size.js.map +1 -1
- package/dist/cjs/hooks/use-is-large-currency.js +1 -1
- package/dist/cjs/hooks/use-is-large-currency.js.map +1 -1
- package/dist/cjs/hooks/use-manage-tooltip-toggle.js +1 -2
- package/dist/cjs/hooks/use-manage-tooltip-toggle.js.map +1 -1
- package/dist/cjs/hooks/use-plan-pricing-info-from-grid-plans.js +1 -2
- package/dist/cjs/hooks/use-plan-pricing-info-from-grid-plans.js.map +1 -1
- package/dist/cjs/index.js +3 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/lib/get-plan-pricing-info-from-grid-plans.js +1 -2
- package/dist/cjs/lib/get-plan-pricing-info-from-grid-plans.js.map +1 -1
- package/dist/cjs/lib/is-same-plan.js +1 -2
- package/dist/cjs/lib/is-same-plan.js.map +1 -1
- package/dist/cjs/lib/touch-detect/index.js +1 -2
- package/dist/cjs/lib/touch-detect/index.js.map +1 -1
- package/dist/esm/_shared.scss +9 -4
- package/dist/esm/components/comparison-grid/index.js +62 -50
- package/dist/esm/components/comparison-grid/index.js.map +1 -1
- package/dist/esm/components/comparison-grid/index.stories.js +1 -0
- package/dist/esm/components/comparison-grid/index.stories.js.map +1 -1
- package/dist/esm/components/comparison-grid/style.scss +0 -17
- package/dist/esm/components/dropdown-option.js +1 -1
- package/dist/esm/components/features-grid/index.js +21 -6
- package/dist/esm/components/features-grid/index.js.map +1 -1
- package/dist/esm/components/features-grid/index.stories.js +1 -0
- package/dist/esm/components/features-grid/index.stories.js.map +1 -1
- package/dist/esm/components/features-grid/style.scss +6 -21
- package/dist/esm/components/plan-button/style.scss +12 -11
- package/dist/esm/components/plan-type-selector/style.scss +3 -1
- package/dist/esm/components/shared/billing-timeframe/index.js +14 -6
- package/dist/esm/components/shared/billing-timeframe/index.js.map +1 -1
- package/dist/esm/components/shared/header-price/style.scss +4 -2
- package/dist/esm/components/sticky-container.js +66 -5
- package/dist/esm/components/sticky-container.js.map +1 -1
- package/dist/esm/hooks/data-store/use-grid-plans-for-features-grid.js +14 -11
- package/dist/esm/hooks/data-store/use-grid-plans-for-features-grid.js.map +1 -1
- package/dist/esm/hooks/data-store/use-plan-billing-description.js +1 -1
- package/dist/esm/hooks/data-store/use-plan-billing-period.js +12 -0
- package/dist/esm/hooks/data-store/use-plan-billing-period.js.map +1 -0
- package/dist/esm/hooks/use-grid-size.js +0 -1
- package/dist/esm/hooks/use-grid-size.js.map +1 -1
- package/dist/esm/index.js +2 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/tsconfig-cjs.tsbuildinfo +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/dist/types/components/comparison-grid/index.d.ts +1 -1
- package/dist/types/components/comparison-grid/index.d.ts.map +1 -1
- package/dist/types/components/comparison-grid/index.stories.d.ts +5 -3
- package/dist/types/components/comparison-grid/index.stories.d.ts.map +1 -1
- package/dist/types/components/dropdown-option.d.ts +0 -1
- package/dist/types/components/dropdown-option.d.ts.map +1 -1
- package/dist/types/components/features-grid/billing-timeframes.d.ts.map +1 -1
- package/dist/types/components/features-grid/client-logo-list/client-list.d.ts +0 -1
- package/dist/types/components/features-grid/client-logo-list/client-list.d.ts.map +1 -1
- package/dist/types/components/features-grid/client-logo-list/index.d.ts.map +1 -1
- package/dist/types/components/features-grid/enterprise-features.d.ts.map +1 -1
- package/dist/types/components/features-grid/index.d.ts.map +1 -1
- package/dist/types/components/features-grid/index.stories.d.ts +5 -1
- package/dist/types/components/features-grid/index.stories.d.ts.map +1 -1
- package/dist/types/components/features-grid/mobile-free-domain.d.ts.map +1 -1
- package/dist/types/components/features-grid/plan-features-list.d.ts.map +1 -1
- package/dist/types/components/features-grid/plan-headers.d.ts.map +1 -1
- package/dist/types/components/features-grid/plan-logos.d.ts.map +1 -1
- package/dist/types/components/features-grid/plan-prices.d.ts.map +1 -1
- package/dist/types/components/features-grid/plan-tagline.d.ts.map +1 -1
- package/dist/types/components/features-grid/previous-features-included-title.d.ts.map +1 -1
- package/dist/types/components/features-grid/spotlight-plan.d.ts.map +1 -1
- package/dist/types/components/features-grid/table.d.ts.map +1 -1
- package/dist/types/components/features-grid/top-buttons.d.ts.map +1 -1
- package/dist/types/components/plan-button/index.d.ts +10 -10
- package/dist/types/components/plan-button/index.d.ts.map +1 -1
- package/dist/types/components/plan-div-td-container.d.ts +0 -1
- package/dist/types/components/plan-div-td-container.d.ts.map +1 -1
- package/dist/types/components/plan-logo.d.ts +0 -1
- package/dist/types/components/plan-logo.d.ts.map +1 -1
- package/dist/types/components/plan-type-selector/components/interval-type-dropdown.d.ts +0 -1
- package/dist/types/components/plan-type-selector/components/interval-type-dropdown.d.ts.map +1 -1
- package/dist/types/components/plan-type-selector/components/interval-type-selector.d.ts +0 -1
- package/dist/types/components/plan-type-selector/components/interval-type-selector.d.ts.map +1 -1
- package/dist/types/components/plan-type-selector/hooks/use-max-discounts-for-plan-terms.d.ts.map +1 -1
- package/dist/types/components/plans-2023-tooltip.d.ts.map +1 -1
- package/dist/types/components/popular-badge.d.ts +0 -1
- package/dist/types/components/popular-badge.d.ts.map +1 -1
- package/dist/types/components/shared/action-button/index.d.ts.map +1 -1
- package/dist/types/components/shared/billing-timeframe/index.d.ts.map +1 -1
- package/dist/types/components/shared/header-price/header-price-context.d.ts +0 -1
- package/dist/types/components/shared/header-price/header-price-context.d.ts.map +1 -1
- package/dist/types/components/shared/header-price/index.d.ts.map +1 -1
- package/dist/types/components/shared/storage/components/plan-storage.d.ts.map +1 -1
- package/dist/types/components/shared/storage/components/storage-dropdown.d.ts.map +1 -1
- package/dist/types/components/shared/storage/components/storage-feature-label.d.ts.map +1 -1
- package/dist/types/components/shared/storage/hooks/use-storage-string.d.ts +0 -1
- package/dist/types/components/shared/storage/hooks/use-storage-string.d.ts.map +1 -1
- package/dist/types/components/sticky-container.d.ts +22 -0
- package/dist/types/components/sticky-container.d.ts.map +1 -1
- package/dist/types/css-mixins.d.ts.map +1 -1
- package/dist/types/grid-context.d.ts +0 -1
- package/dist/types/grid-context.d.ts.map +1 -1
- package/dist/types/hooks/data-store/types.d.ts +1 -0
- package/dist/types/hooks/data-store/types.d.ts.map +1 -1
- package/dist/types/hooks/data-store/use-grid-plan-for-spotlight.d.ts.map +1 -1
- package/dist/types/hooks/data-store/use-grid-plans-for-comparison-grid.d.ts.map +1 -1
- package/dist/types/hooks/data-store/use-grid-plans-for-features-grid.d.ts +1 -1
- package/dist/types/hooks/data-store/use-grid-plans-for-features-grid.d.ts.map +1 -1
- package/dist/types/hooks/data-store/use-grid-plans.d.ts +1 -1
- package/dist/types/hooks/data-store/use-grid-plans.d.ts.map +1 -1
- package/dist/types/hooks/data-store/use-highlight-labels.d.ts +0 -1
- package/dist/types/hooks/data-store/use-highlight-labels.d.ts.map +1 -1
- package/dist/types/hooks/data-store/use-plan-billing-description.d.ts +0 -1
- package/dist/types/hooks/data-store/use-plan-billing-description.d.ts.map +1 -1
- package/dist/types/hooks/data-store/use-plan-billing-period.d.ts +8 -0
- package/dist/types/hooks/data-store/use-plan-billing-period.d.ts.map +1 -0
- package/dist/types/hooks/data-store/use-plans-from-types.d.ts.map +1 -1
- package/dist/types/hooks/use-grid-size.d.ts +3 -3
- package/dist/types/hooks/use-grid-size.d.ts.map +1 -1
- package/dist/types/hooks/use-highlight-adjacency-matrix.d.ts.map +1 -1
- package/dist/types/index.d.ts +2 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/lib/filter-unused-features-object.d.ts.map +1 -1
- package/dist/types/lib/get-plan-features-object.d.ts.map +1 -1
- package/dist/types/types.d.ts +5 -5
- package/dist/types/types.d.ts.map +1 -1
- package/package.json +16 -15
- package/src/_shared.scss +9 -4
- package/src/components/comparison-grid/index.stories.tsx +2 -1
- package/src/components/comparison-grid/index.tsx +69 -55
- package/src/components/comparison-grid/style.scss +0 -17
- package/src/components/dropdown-option.tsx +1 -1
- package/src/components/features-grid/index.stories.tsx +1 -0
- package/src/components/features-grid/index.tsx +22 -9
- package/src/components/features-grid/style.scss +6 -21
- package/src/components/plan-button/style.scss +12 -11
- package/src/components/plan-type-selector/style.scss +3 -1
- package/src/components/shared/billing-timeframe/index.tsx +15 -7
- package/src/components/shared/header-price/style.scss +4 -2
- package/src/components/sticky-container.tsx +74 -3
- package/src/components/test/billing-timeframe.tsx +2 -2
- package/src/hooks/data-store/types.ts +1 -0
- package/src/hooks/data-store/use-grid-plans-for-features-grid.ts +14 -10
- package/src/hooks/data-store/use-plan-billing-description.tsx +1 -1
- package/src/hooks/data-store/use-plan-billing-period.tsx +28 -0
- package/src/hooks/use-grid-size.ts +3 -3
- package/src/index.tsx +2 -0
- package/src/types.ts +5 -4
- package/dist/cjs/lib/sort-plan-properties.js +0 -39
- package/dist/cjs/lib/sort-plan-properties.js.map +0 -1
- package/dist/esm/lib/sort-plan-properties.js +0 -35
- package/dist/esm/lib/sort-plan-properties.js.map +0 -1
- package/dist/types/lib/sort-plan-properties.d.ts +0 -3
- package/dist/types/lib/sort-plan-properties.d.ts.map +0 -1
- package/src/lib/sort-plan-properties.ts +0 -46
- package/src/lib/test/sort-plan-properties.ts +0 -104
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
padding: 10px 12px;
|
|
7
7
|
border: unset;
|
|
8
8
|
text-align: center;
|
|
9
|
+
text-wrap: balance;
|
|
9
10
|
width: 100%;
|
|
10
11
|
color: var(--color-text-inverted);
|
|
11
12
|
|
|
@@ -20,7 +21,7 @@
|
|
|
20
21
|
box-shadow: 0 0 0 2px var(--studio-white), 0 0 0 4px var(--studio-wordpress-blue-50);
|
|
21
22
|
}
|
|
22
23
|
|
|
23
|
-
&:hover {
|
|
24
|
+
&:hover:not([disabled]) {
|
|
24
25
|
background-color: var(--studio-wordpress-blue-60);
|
|
25
26
|
}
|
|
26
27
|
|
|
@@ -33,7 +34,7 @@
|
|
|
33
34
|
box-shadow: 0 0 0 2px var(--studio-white), 0 0 0 4px var(--studio-wordpress-blue-60);
|
|
34
35
|
}
|
|
35
36
|
|
|
36
|
-
&:hover {
|
|
37
|
+
&:hover:not([disabled]) {
|
|
37
38
|
background-color: var(--studio-wordpress-blue-70);
|
|
38
39
|
}
|
|
39
40
|
}
|
|
@@ -45,30 +46,30 @@
|
|
|
45
46
|
box-shadow: 0 0 0 2px var(--studio-white), 0 0 0 4px var(--studio-wordpress-blue-70);
|
|
46
47
|
}
|
|
47
48
|
|
|
48
|
-
&:hover {
|
|
49
|
+
&:hover:not([disabled]) {
|
|
49
50
|
background-color: var(--studio-wordpress-blue-80);
|
|
50
51
|
}
|
|
51
52
|
}
|
|
52
53
|
|
|
53
54
|
&.is-business-plan {
|
|
54
|
-
background-color: var(--studio-woocommerce-purple-
|
|
55
|
+
background-color: var(--studio-woocommerce-purple-60);
|
|
55
56
|
|
|
56
57
|
&:focus {
|
|
57
|
-
box-shadow: 0 0 0 2px var(--studio-white), 0 0 0 4px var(--studio-woocommerce-purple-
|
|
58
|
+
box-shadow: 0 0 0 2px var(--studio-white), 0 0 0 4px var(--studio-woocommerce-purple-60);
|
|
58
59
|
}
|
|
59
60
|
|
|
60
|
-
&:hover {
|
|
61
|
+
&:hover:not([disabled]) {
|
|
61
62
|
background-color: var(--studio-woocommerce-purple-70);
|
|
62
63
|
}
|
|
63
64
|
|
|
64
65
|
+ .button.is-borderless {
|
|
65
66
|
background: transparent;
|
|
66
67
|
font-size: $font-body-small;
|
|
67
|
-
color: var(--studio-woocommerce-purple-
|
|
68
|
+
color: var(--studio-woocommerce-purple-60);
|
|
68
69
|
text-decoration: none;
|
|
69
70
|
|
|
70
71
|
&:focus {
|
|
71
|
-
box-shadow: 0 0 0 2px var(--studio-white), 0 0 0 4px var(--studio-woocommerce-purple-
|
|
72
|
+
box-shadow: 0 0 0 2px var(--studio-white), 0 0 0 4px var(--studio-woocommerce-purple-60);
|
|
72
73
|
}
|
|
73
74
|
}
|
|
74
75
|
}
|
|
@@ -101,14 +102,14 @@
|
|
|
101
102
|
}
|
|
102
103
|
|
|
103
104
|
&.is-ecommerce-plan {
|
|
104
|
-
background-color: var(--studio-woocommerce-purple-
|
|
105
|
+
background-color: var(--studio-woocommerce-purple-40);
|
|
105
106
|
|
|
106
107
|
&:focus {
|
|
107
|
-
box-shadow: 0 0 0 2px var(--studio-white), 0 0 0 4px var(--studio-woocommerce-purple-
|
|
108
|
+
box-shadow: 0 0 0 2px var(--studio-white), 0 0 0 4px var(--studio-woocommerce-purple-40);
|
|
108
109
|
}
|
|
109
110
|
|
|
110
111
|
&:hover {
|
|
111
|
-
background-color: var(--studio-woocommerce-purple-
|
|
112
|
+
background-color: var(--studio-woocommerce-purple-50);
|
|
112
113
|
}
|
|
113
114
|
}
|
|
114
115
|
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
isFreePlan,
|
|
6
6
|
} from '@automattic/calypso-products';
|
|
7
7
|
import styled from '@emotion/styled';
|
|
8
|
-
import { useTranslate, formatCurrency } from 'i18n-calypso';
|
|
8
|
+
import { useTranslate, formatCurrency, fixMe } from 'i18n-calypso';
|
|
9
9
|
import { usePlansGridContext } from '../../../grid-context';
|
|
10
10
|
import usePlanBillingDescription from '../../../hooks/data-store/use-plan-billing-description';
|
|
11
11
|
import type { GridPlan } from '../../../types';
|
|
@@ -78,14 +78,22 @@ const BillingTimeframe = ( { showRefundPeriod, planSlug }: Props ) => {
|
|
|
78
78
|
}
|
|
79
79
|
|
|
80
80
|
if ( isWpcomEnterpriseGridPlan( planSlug ) ) {
|
|
81
|
-
const price = formatCurrency( 25000, 'USD' );
|
|
81
|
+
const price = formatCurrency( 25000, 'USD', { stripZeros: true } );
|
|
82
82
|
|
|
83
83
|
return (
|
|
84
|
-
<div
|
|
85
|
-
{
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
84
|
+
<div>
|
|
85
|
+
{ fixMe( {
|
|
86
|
+
text: 'Starts at {{b}}%(price)s{{/b}} annually',
|
|
87
|
+
newCopy: translate( 'Starts at {{b}}%(price)s{{/b}} annually', {
|
|
88
|
+
args: { price },
|
|
89
|
+
components: { b: <b /> },
|
|
90
|
+
comment: 'Translators: the price is in US dollars for all users (US$25,000)',
|
|
91
|
+
} ),
|
|
92
|
+
oldCopy: translate( 'Starts at {{b}}%(price)s{{/b}} yearly', {
|
|
93
|
+
args: { price },
|
|
94
|
+
components: { b: <b /> },
|
|
95
|
+
comment: 'Translators: the price is in US dollars for all users (US$25,000)',
|
|
96
|
+
} ),
|
|
89
97
|
} ) }
|
|
90
98
|
</div>
|
|
91
99
|
);
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
@import "@automattic/typography/styles/variables";
|
|
2
|
+
|
|
1
3
|
.plans-grid-next-header-price {
|
|
2
4
|
padding: 0 20px;
|
|
3
5
|
margin: 0 0 4px 0;
|
|
@@ -76,9 +78,9 @@
|
|
|
76
78
|
}
|
|
77
79
|
|
|
78
80
|
.plans-grid-next-header-price__badge {
|
|
79
|
-
background-color: var(--studio-green-
|
|
81
|
+
background-color: var(--studio-green-5);
|
|
80
82
|
border-radius: 4px;
|
|
81
|
-
color: var(--studio-green-
|
|
83
|
+
color: var(--studio-green-80);
|
|
82
84
|
display: inline-block;
|
|
83
85
|
font-size: 0.75rem;
|
|
84
86
|
font-weight: 500;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Global, css } from '@emotion/react';
|
|
2
2
|
import styled from '@emotion/styled';
|
|
3
3
|
import clsx from 'clsx';
|
|
4
|
-
import { useRef, type ElementType, useState, useLayoutEffect, ReactNode } from 'react';
|
|
4
|
+
import { useRef, type ElementType, useState, useLayoutEffect, ReactNode, useEffect } from 'react';
|
|
5
5
|
|
|
6
6
|
type Props = {
|
|
7
7
|
/**
|
|
@@ -41,17 +41,19 @@ type Props = {
|
|
|
41
41
|
const styles = ( {
|
|
42
42
|
disabled,
|
|
43
43
|
stickyOffset,
|
|
44
|
+
stickyPadding,
|
|
44
45
|
zIndex,
|
|
45
46
|
}: {
|
|
46
47
|
disabled: boolean;
|
|
47
48
|
stickyOffset: number;
|
|
49
|
+
stickyPadding: number;
|
|
48
50
|
zIndex: number;
|
|
49
51
|
} ) =>
|
|
50
52
|
disabled
|
|
51
53
|
? ''
|
|
52
54
|
: css`
|
|
53
55
|
position: sticky;
|
|
54
|
-
top: ${ stickyOffset + 'px' };
|
|
56
|
+
top: ${ stickyOffset - stickyPadding + 'px' };
|
|
55
57
|
z-index: ${ zIndex };
|
|
56
58
|
`;
|
|
57
59
|
|
|
@@ -59,6 +61,28 @@ const Container = styled.div`
|
|
|
59
61
|
${ styles }
|
|
60
62
|
`;
|
|
61
63
|
|
|
64
|
+
/**
|
|
65
|
+
* Renders a sticky container.
|
|
66
|
+
*
|
|
67
|
+
* The following is an illustration on how the container's top property is calculated.
|
|
68
|
+
*
|
|
69
|
+
* +~~~~~~~~ stickyParent (where the container scrolls)
|
|
70
|
+
* stickyOffset ~~~~~~~~~~+ |
|
|
71
|
+
* (e.g. masterbar) | |
|
|
72
|
+
* v v
|
|
73
|
+
* +------#-----------------+
|
|
74
|
+
* | # |<~~~~~~~+~~~~~ stickyPadding
|
|
75
|
+
* | +----#--------------+ |
|
|
76
|
+
* | | # @ |<~+~~~~~ stickyParent's content area
|
|
77
|
+
* | | # @ | |
|
|
78
|
+
* | | # @ <~~~~~~~~+~~+~~~~~ the container's top
|
|
79
|
+
* | | # @ | | (= stickyOffset - stickyPadding)
|
|
80
|
+
* | | ============= | |
|
|
81
|
+
* | | ^ | |
|
|
82
|
+
* | | | | |
|
|
83
|
+
* | | +~~~~~~~~~~~~~+~~+~~~~~ the container
|
|
84
|
+
* | | | |
|
|
85
|
+
*/
|
|
62
86
|
export function StickyContainer( props: Props ) {
|
|
63
87
|
const {
|
|
64
88
|
stickyOffset = 0,
|
|
@@ -70,8 +94,53 @@ export function StickyContainer( props: Props ) {
|
|
|
70
94
|
} = props;
|
|
71
95
|
|
|
72
96
|
const stickyRef = useRef( null );
|
|
97
|
+
const [ stickyParent, setStickyParent ] = useState< HTMLElement | null >( null );
|
|
98
|
+
const [ stickyPadding, setStickyPadding ] = useState( 0 );
|
|
73
99
|
const [ isStuck, setIsStuck ] = useState( false );
|
|
74
100
|
|
|
101
|
+
/**
|
|
102
|
+
* Calculate the first scrollable parent and its padding-top.
|
|
103
|
+
*/
|
|
104
|
+
useEffect( () => {
|
|
105
|
+
if ( ! stickyRef.current || typeof getComputedStyle === 'undefined' ) {
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
let scrollParent = stickyRef.current as HTMLElement | null;
|
|
110
|
+
while ( scrollParent ) {
|
|
111
|
+
const style = getComputedStyle( scrollParent );
|
|
112
|
+
const overflowY = style.overflowY;
|
|
113
|
+
if ( overflowY === 'auto' || overflowY === 'scroll' || overflowY === 'overlay' ) {
|
|
114
|
+
break;
|
|
115
|
+
}
|
|
116
|
+
scrollParent = scrollParent.parentElement;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const receiveScrollParent = ( el: HTMLElement ) => {
|
|
120
|
+
const styles = getComputedStyle( el );
|
|
121
|
+
const paddingTop = parseFloat( styles.paddingTop );
|
|
122
|
+
setStickyParent( scrollParent );
|
|
123
|
+
setStickyPadding( paddingTop );
|
|
124
|
+
};
|
|
125
|
+
|
|
126
|
+
if ( scrollParent ) {
|
|
127
|
+
scrollParent.style.position = 'relative';
|
|
128
|
+
receiveScrollParent( scrollParent );
|
|
129
|
+
|
|
130
|
+
if ( typeof ResizeObserver !== 'undefined' ) {
|
|
131
|
+
const observer = new ResizeObserver(
|
|
132
|
+
( [ parent ]: Parameters< ResizeObserverCallback >[ 0 ] ) => {
|
|
133
|
+
receiveScrollParent( parent.target as HTMLElement );
|
|
134
|
+
}
|
|
135
|
+
);
|
|
136
|
+
observer.observe( scrollParent );
|
|
137
|
+
return () => {
|
|
138
|
+
observer.disconnect();
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}, [] );
|
|
143
|
+
|
|
75
144
|
/**
|
|
76
145
|
* This effect sets the value of `isStuck` state when it detects that
|
|
77
146
|
* the element is sticky.
|
|
@@ -102,6 +171,7 @@ export function StickyContainer( props: Props ) {
|
|
|
102
171
|
}
|
|
103
172
|
},
|
|
104
173
|
{
|
|
174
|
+
root: stickyParent,
|
|
105
175
|
rootMargin: `-${ stickyOffset + 1 }px 0px 0px 0px`,
|
|
106
176
|
threshold: [ 0, 1 ],
|
|
107
177
|
}
|
|
@@ -114,7 +184,7 @@ export function StickyContainer( props: Props ) {
|
|
|
114
184
|
return () => {
|
|
115
185
|
observer.disconnect();
|
|
116
186
|
};
|
|
117
|
-
}, [ disabled, stickyOffset ] );
|
|
187
|
+
}, [ disabled, stickyParent, stickyOffset, stickyPadding ] );
|
|
118
188
|
|
|
119
189
|
const isStuckFinalState = ! disabled && isStuck;
|
|
120
190
|
return (
|
|
@@ -135,6 +205,7 @@ export function StickyContainer( props: Props ) {
|
|
|
135
205
|
as={ element }
|
|
136
206
|
ref={ stickyRef }
|
|
137
207
|
stickyOffset={ stickyOffset }
|
|
208
|
+
stickyPadding={ stickyPadding }
|
|
138
209
|
disabled={ disabled }
|
|
139
210
|
className={ clsx( { [ stickyClass ]: isStuckFinalState } ) }
|
|
140
211
|
zIndex={ zIndex }
|
|
@@ -49,7 +49,7 @@ describe( 'BillingTimeframe', () => {
|
|
|
49
49
|
jest.clearAllMocks();
|
|
50
50
|
} );
|
|
51
51
|
|
|
52
|
-
test(
|
|
52
|
+
test( 'should show savings with yearly when plan is monthly', () => {
|
|
53
53
|
const planMonthlyPricing = {
|
|
54
54
|
currencyCode: 'USD',
|
|
55
55
|
originalPrice: { full: 120, monthly: 10 },
|
|
@@ -309,7 +309,7 @@ describe( 'BillingTimeframe', () => {
|
|
|
309
309
|
expect( getByText( /Refundable within 7 days. No questions asked./ ) ).toBeInTheDocument();
|
|
310
310
|
} );
|
|
311
311
|
|
|
312
|
-
test(
|
|
312
|
+
test( "refund period can't be shown for free plan", () => {
|
|
313
313
|
const pricing = {
|
|
314
314
|
currencyCode: 'USD',
|
|
315
315
|
originalPrice: { full: 0, monthly: 0 },
|
|
@@ -10,6 +10,7 @@ export interface UseGridPlansParams {
|
|
|
10
10
|
eligibleForFreeHostingTrial?: boolean;
|
|
11
11
|
hasRedeemedDomainCredit?: boolean;
|
|
12
12
|
hiddenPlans?: HiddenPlans;
|
|
13
|
+
hideCurrentPlan?: boolean;
|
|
13
14
|
intent?: PlansIntent;
|
|
14
15
|
isDisplayingPlansNeededForFeature?: boolean;
|
|
15
16
|
isInSignup?: boolean;
|
|
@@ -10,6 +10,7 @@ const useGridPlansForFeaturesGrid = ( {
|
|
|
10
10
|
eligibleForFreeHostingTrial,
|
|
11
11
|
hasRedeemedDomainCredit,
|
|
12
12
|
hiddenPlans,
|
|
13
|
+
hideCurrentPlan,
|
|
13
14
|
intent,
|
|
14
15
|
isDisplayingPlansNeededForFeature,
|
|
15
16
|
isInSignup,
|
|
@@ -62,18 +63,21 @@ const useGridPlansForFeaturesGrid = ( {
|
|
|
62
63
|
}
|
|
63
64
|
|
|
64
65
|
return gridPlans.reduce( ( acc, gridPlan ) => {
|
|
65
|
-
if ( gridPlan.isVisible ) {
|
|
66
|
-
return
|
|
67
|
-
...acc,
|
|
68
|
-
{
|
|
69
|
-
...gridPlan,
|
|
70
|
-
features: planFeaturesForFeaturesGrid[ gridPlan.planSlug ],
|
|
71
|
-
},
|
|
72
|
-
];
|
|
66
|
+
if ( ! gridPlan.isVisible ) {
|
|
67
|
+
return acc;
|
|
73
68
|
}
|
|
74
|
-
|
|
69
|
+
if ( hideCurrentPlan && gridPlan.current ) {
|
|
70
|
+
return acc;
|
|
71
|
+
}
|
|
72
|
+
return [
|
|
73
|
+
...acc,
|
|
74
|
+
{
|
|
75
|
+
...gridPlan,
|
|
76
|
+
features: planFeaturesForFeaturesGrid[ gridPlan.planSlug ],
|
|
77
|
+
},
|
|
78
|
+
];
|
|
75
79
|
}, [] as GridPlan[] );
|
|
76
|
-
}, [ gridPlans, planFeaturesForFeaturesGrid ] );
|
|
80
|
+
}, [ gridPlans, planFeaturesForFeaturesGrid, hideCurrentPlan ] );
|
|
77
81
|
};
|
|
78
82
|
|
|
79
83
|
export default useGridPlansForFeaturesGrid;
|
|
@@ -73,7 +73,7 @@ export default function usePlanBillingDescription( {
|
|
|
73
73
|
yearlyVariantMaybeDiscountedPrice &&
|
|
74
74
|
yearlyVariantMaybeDiscountedPrice < originalPrice.monthly
|
|
75
75
|
) {
|
|
76
|
-
return translate(
|
|
76
|
+
return translate( 'Save %(discountRate)s%% by paying annually', {
|
|
77
77
|
args: {
|
|
78
78
|
discountRate: Math.floor(
|
|
79
79
|
( 100 * ( originalPrice.monthly - yearlyVariantMaybeDiscountedPrice ) ) /
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import {
|
|
2
|
+
TERMS_LIST,
|
|
3
|
+
TERM_ANNUALLY,
|
|
4
|
+
TERM_BIENNIALLY,
|
|
5
|
+
TERM_MONTHLY,
|
|
6
|
+
TERM_TRIENNIALLY,
|
|
7
|
+
} from '@automattic/calypso-products';
|
|
8
|
+
import { EFFECTIVE_TERMS_LIST } from '../../constants';
|
|
9
|
+
import type { SupportedUrlFriendlyTermType } from '../../types';
|
|
10
|
+
|
|
11
|
+
const usePlanBillingPeriod = ( {
|
|
12
|
+
intervalType,
|
|
13
|
+
defaultValue,
|
|
14
|
+
}: {
|
|
15
|
+
intervalType: SupportedUrlFriendlyTermType;
|
|
16
|
+
defaultValue?: ( typeof TERMS_LIST )[ number ];
|
|
17
|
+
} ) => {
|
|
18
|
+
const plans: Record< SupportedUrlFriendlyTermType, ( typeof EFFECTIVE_TERMS_LIST )[ number ] > = {
|
|
19
|
+
monthly: TERM_MONTHLY,
|
|
20
|
+
yearly: TERM_ANNUALLY,
|
|
21
|
+
'2yearly': TERM_BIENNIALLY,
|
|
22
|
+
'3yearly': TERM_TRIENNIALLY,
|
|
23
|
+
} as const;
|
|
24
|
+
|
|
25
|
+
return plans[ intervalType ] || defaultValue || TERM_ANNUALLY;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
export default usePlanBillingPeriod;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useLayoutEffect, useState } from '@wordpress/element';
|
|
2
|
-
import
|
|
2
|
+
import { GridSize } from '../types';
|
|
3
3
|
|
|
4
4
|
interface Props {
|
|
5
5
|
containerRef: React.MutableRefObject< HTMLDivElement | null >;
|
|
@@ -9,7 +9,7 @@ interface Props {
|
|
|
9
9
|
* but they could be used in the future in a containment context.
|
|
10
10
|
* The keys are the labels, the values are the minimum widths.
|
|
11
11
|
*/
|
|
12
|
-
containerBreakpoints: Map<
|
|
12
|
+
containerBreakpoints: Map< GridSize, number >;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
15
|
/**
|
|
@@ -17,7 +17,7 @@ interface Props {
|
|
|
17
17
|
* and the breakpoints passed through as props.
|
|
18
18
|
*/
|
|
19
19
|
export default function useGridSize( { containerRef, containerBreakpoints }: Props ) {
|
|
20
|
-
const [ gridSize, setGridSize ] = useState<
|
|
20
|
+
const [ gridSize, setGridSize ] = useState< GridSize | null >( null );
|
|
21
21
|
|
|
22
22
|
useLayoutEffect( () => {
|
|
23
23
|
if ( ! containerRef.current ) {
|
package/src/index.tsx
CHANGED
|
@@ -9,6 +9,7 @@ import useGridPlans, { usePlanTypesWithIntent } from './hooks/data-store/use-gri
|
|
|
9
9
|
import useGridPlansForComparisonGrid from './hooks/data-store/use-grid-plans-for-comparison-grid';
|
|
10
10
|
import useGridPlansForFeaturesGrid from './hooks/data-store/use-grid-plans-for-features-grid';
|
|
11
11
|
import usePlanBillingDescription from './hooks/data-store/use-plan-billing-description';
|
|
12
|
+
import usePlanBillingPeriod from './hooks/data-store/use-plan-billing-period';
|
|
12
13
|
import usePlanFeaturesForGridPlans from './hooks/data-store/use-plan-features-for-grid-plans';
|
|
13
14
|
import usePlansFromTypes from './hooks/data-store/use-plans-from-types';
|
|
14
15
|
import useRestructuredPlanFeaturesForComparisonGrid from './hooks/data-store/use-restructured-plan-features-for-comparison-grid';
|
|
@@ -33,6 +34,7 @@ export {
|
|
|
33
34
|
useGridPlansForFeaturesGrid,
|
|
34
35
|
useGridPlansForComparisonGrid,
|
|
35
36
|
useGridPlanForSpotlight,
|
|
37
|
+
usePlanBillingPeriod,
|
|
36
38
|
usePlanBillingDescription,
|
|
37
39
|
usePlanFeaturesForGridPlans,
|
|
38
40
|
usePlansFromTypes,
|
package/src/types.ts
CHANGED
|
@@ -51,7 +51,7 @@ export interface GridPlan {
|
|
|
51
51
|
* Grid Component Types:
|
|
52
52
|
***********************/
|
|
53
53
|
|
|
54
|
-
export type GridSize = 'small' | 'medium' | 'large';
|
|
54
|
+
export type GridSize = 'small' | 'smedium' | 'medium' | 'large' | 'xlarge';
|
|
55
55
|
|
|
56
56
|
export type PlansIntent =
|
|
57
57
|
| 'plans-affiliate'
|
|
@@ -104,8 +104,9 @@ export interface CommonGridProps {
|
|
|
104
104
|
siteId?: number | null;
|
|
105
105
|
isInSignup: boolean;
|
|
106
106
|
isInAdmin: boolean;
|
|
107
|
+
isInSiteDashboard: boolean;
|
|
107
108
|
onStorageAddOnClick?: ( addOnSlug: AddOns.StorageAddOnSlug ) => void;
|
|
108
|
-
currentSitePlanSlug?:
|
|
109
|
+
currentSitePlanSlug?: PlanSlug | null;
|
|
109
110
|
hideUnavailableFeatures?: boolean; // used to hide features that are not available, instead of strike-through as explained in #76206
|
|
110
111
|
planActionOverrides?: PlanActionOverrides;
|
|
111
112
|
// Value of the `?feature=` query param, so we can highlight a given feature and hide plans without it.
|
|
@@ -116,7 +117,7 @@ export interface CommonGridProps {
|
|
|
116
117
|
// only used for comparison grid
|
|
117
118
|
planTypeSelectorProps?: PlanTypeSelectorProps;
|
|
118
119
|
gridContainerRef?: React.MutableRefObject< HTMLDivElement | null >;
|
|
119
|
-
gridSize?:
|
|
120
|
+
gridSize?: GridSize;
|
|
120
121
|
}
|
|
121
122
|
|
|
122
123
|
export interface FeaturesGridProps extends CommonGridProps {
|
|
@@ -133,7 +134,7 @@ export interface FeaturesGridProps extends CommonGridProps {
|
|
|
133
134
|
export interface ComparisonGridProps extends CommonGridProps {
|
|
134
135
|
// Value of the `?plan=` query param, so we can highlight a given plan.
|
|
135
136
|
selectedPlan?: string;
|
|
136
|
-
intervalType:
|
|
137
|
+
intervalType: SupportedUrlFriendlyTermType;
|
|
137
138
|
}
|
|
138
139
|
|
|
139
140
|
export type UseActionCallback = ( {
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.sortPlans = void 0;
|
|
4
|
-
const calypso_products_1 = require("@automattic/calypso-products");
|
|
5
|
-
const is_popular_plan_1 = require("../hooks/data-store/is-popular-plan");
|
|
6
|
-
function sortPlans(gridPlans, currentSitePlanProductSlug, isMobile) {
|
|
7
|
-
let firstPlanIndex = -1;
|
|
8
|
-
// Try to find the current paid plan in the plans list
|
|
9
|
-
if (currentSitePlanProductSlug && !(0, calypso_products_1.isFreePlan)(currentSitePlanProductSlug)) {
|
|
10
|
-
firstPlanIndex = gridPlans.findIndex((gridPlan) => {
|
|
11
|
-
return gridPlan.planSlug === currentSitePlanProductSlug;
|
|
12
|
-
});
|
|
13
|
-
}
|
|
14
|
-
if (firstPlanIndex < 0) {
|
|
15
|
-
// Site is on a free plan or the current plan is not in the list. Try to find the popular plan.
|
|
16
|
-
firstPlanIndex = gridPlans.findIndex(({ planSlug }) => {
|
|
17
|
-
return (0, is_popular_plan_1.isPopularPlan)(planSlug);
|
|
18
|
-
});
|
|
19
|
-
// If the popular plan exists, on mobile, it will be second plan for comparison.
|
|
20
|
-
if (firstPlanIndex > 0 && isMobile) {
|
|
21
|
-
firstPlanIndex = firstPlanIndex - 1;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
if (firstPlanIndex < 0) {
|
|
25
|
-
return gridPlans;
|
|
26
|
-
}
|
|
27
|
-
return [
|
|
28
|
-
// The first plan
|
|
29
|
-
gridPlans[firstPlanIndex],
|
|
30
|
-
// Rest of the plans in default order
|
|
31
|
-
...gridPlans.slice(firstPlanIndex + 1),
|
|
32
|
-
// Leftover plans (before the first plan) in descending order of value
|
|
33
|
-
...gridPlans.slice(0, firstPlanIndex).sort((planA, planB) => {
|
|
34
|
-
return ((planB?.pricing.originalPrice.full || 0) - (planA?.pricing.originalPrice.full || 0));
|
|
35
|
-
}),
|
|
36
|
-
].filter((gridPlan) => Boolean(gridPlan));
|
|
37
|
-
}
|
|
38
|
-
exports.sortPlans = sortPlans;
|
|
39
|
-
//# sourceMappingURL=sort-plan-properties.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sort-plan-properties.js","sourceRoot":"","sources":["../../../src/lib/sort-plan-properties.ts"],"names":[],"mappings":";;;AAAA,mEAA0D;AAC1D,yEAAoE;AAGpE,SAAgB,SAAS,CACxB,SAAqB,EACrB,0BAA0C,EAC1C,QAAkB;IAElB,IAAI,cAAc,GAAG,CAAC,CAAC,CAAC;IAExB,sDAAsD;IACtD,IAAK,0BAA0B,IAAI,CAAE,IAAA,6BAAU,EAAE,0BAA0B,CAAE,EAAG,CAAC;QAChF,cAAc,GAAG,SAAS,CAAC,SAAS,CAAE,CAAE,QAAQ,EAAG,EAAE;YACpD,OAAO,QAAQ,CAAC,QAAQ,KAAK,0BAA0B,CAAC;QACzD,CAAC,CAAE,CAAC;IACL,CAAC;IAED,IAAK,cAAc,GAAG,CAAC,EAAG,CAAC;QAC1B,+FAA+F;QAC/F,cAAc,GAAG,SAAS,CAAC,SAAS,CAAE,CAAE,EAAE,QAAQ,EAAE,EAAG,EAAE;YACxD,OAAO,IAAA,+BAAa,EAAE,QAAQ,CAAE,CAAC;QAClC,CAAC,CAAE,CAAC;QACJ,gFAAgF;QAChF,IAAK,cAAc,GAAG,CAAC,IAAI,QAAQ,EAAG,CAAC;YACtC,cAAc,GAAG,cAAc,GAAG,CAAC,CAAC;QACrC,CAAC;IACF,CAAC;IAED,IAAK,cAAc,GAAG,CAAC,EAAG,CAAC;QAC1B,OAAO,SAAS,CAAC;IAClB,CAAC;IAED,OAAO;QACN,iBAAiB;QACjB,SAAS,CAAE,cAAc,CAAE;QAC3B,qCAAqC;QACrC,GAAG,SAAS,CAAC,KAAK,CAAE,cAAc,GAAG,CAAC,CAAE;QACxC,sEAAsE;QACtE,GAAG,SAAS,CAAC,KAAK,CAAE,CAAC,EAAE,cAAc,CAAE,CAAC,IAAI,CAAE,CAAE,KAAK,EAAE,KAAK,EAAG,EAAE;YAChE,OAAO,CACN,CAAE,KAAK,EAAE,OAAO,CAAC,aAAa,CAAC,IAAI,IAAI,CAAC,CAAE,GAAG,CAAE,KAAK,EAAE,OAAO,CAAC,aAAa,CAAC,IAAI,IAAI,CAAC,CAAE,CACvF,CAAC;QACH,CAAC,CAAE;KACH,CAAC,MAAM,CAAE,CAAE,QAAQ,EAAG,EAAE,CAAC,OAAO,CAAE,QAAQ,CAAE,CAAE,CAAC;AACjD,CAAC;AAzCD,8BAyCC"}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { isFreePlan } from '@automattic/calypso-products';
|
|
2
|
-
import { isPopularPlan } from '../hooks/data-store/is-popular-plan';
|
|
3
|
-
export function sortPlans(gridPlans, currentSitePlanProductSlug, isMobile) {
|
|
4
|
-
let firstPlanIndex = -1;
|
|
5
|
-
// Try to find the current paid plan in the plans list
|
|
6
|
-
if (currentSitePlanProductSlug && !isFreePlan(currentSitePlanProductSlug)) {
|
|
7
|
-
firstPlanIndex = gridPlans.findIndex((gridPlan) => {
|
|
8
|
-
return gridPlan.planSlug === currentSitePlanProductSlug;
|
|
9
|
-
});
|
|
10
|
-
}
|
|
11
|
-
if (firstPlanIndex < 0) {
|
|
12
|
-
// Site is on a free plan or the current plan is not in the list. Try to find the popular plan.
|
|
13
|
-
firstPlanIndex = gridPlans.findIndex(({ planSlug }) => {
|
|
14
|
-
return isPopularPlan(planSlug);
|
|
15
|
-
});
|
|
16
|
-
// If the popular plan exists, on mobile, it will be second plan for comparison.
|
|
17
|
-
if (firstPlanIndex > 0 && isMobile) {
|
|
18
|
-
firstPlanIndex = firstPlanIndex - 1;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
if (firstPlanIndex < 0) {
|
|
22
|
-
return gridPlans;
|
|
23
|
-
}
|
|
24
|
-
return [
|
|
25
|
-
// The first plan
|
|
26
|
-
gridPlans[firstPlanIndex],
|
|
27
|
-
// Rest of the plans in default order
|
|
28
|
-
...gridPlans.slice(firstPlanIndex + 1),
|
|
29
|
-
// Leftover plans (before the first plan) in descending order of value
|
|
30
|
-
...gridPlans.slice(0, firstPlanIndex).sort((planA, planB) => {
|
|
31
|
-
return ((planB?.pricing.originalPrice.full || 0) - (planA?.pricing.originalPrice.full || 0));
|
|
32
|
-
}),
|
|
33
|
-
].filter((gridPlan) => Boolean(gridPlan));
|
|
34
|
-
}
|
|
35
|
-
//# sourceMappingURL=sort-plan-properties.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sort-plan-properties.js","sourceRoot":"","sources":["../../../src/lib/sort-plan-properties.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,8BAA8B,CAAC;AAC1D,OAAO,EAAE,aAAa,EAAE,MAAM,qCAAqC,CAAC;AAGpE,MAAM,UAAU,SAAS,CACxB,SAAqB,EACrB,0BAA0C,EAC1C,QAAkB;IAElB,IAAI,cAAc,GAAG,CAAC,CAAC,CAAC;IAExB,sDAAsD;IACtD,IAAK,0BAA0B,IAAI,CAAE,UAAU,CAAE,0BAA0B,CAAE,EAAG,CAAC;QAChF,cAAc,GAAG,SAAS,CAAC,SAAS,CAAE,CAAE,QAAQ,EAAG,EAAE;YACpD,OAAO,QAAQ,CAAC,QAAQ,KAAK,0BAA0B,CAAC;QACzD,CAAC,CAAE,CAAC;IACL,CAAC;IAED,IAAK,cAAc,GAAG,CAAC,EAAG,CAAC;QAC1B,+FAA+F;QAC/F,cAAc,GAAG,SAAS,CAAC,SAAS,CAAE,CAAE,EAAE,QAAQ,EAAE,EAAG,EAAE;YACxD,OAAO,aAAa,CAAE,QAAQ,CAAE,CAAC;QAClC,CAAC,CAAE,CAAC;QACJ,gFAAgF;QAChF,IAAK,cAAc,GAAG,CAAC,IAAI,QAAQ,EAAG,CAAC;YACtC,cAAc,GAAG,cAAc,GAAG,CAAC,CAAC;QACrC,CAAC;IACF,CAAC;IAED,IAAK,cAAc,GAAG,CAAC,EAAG,CAAC;QAC1B,OAAO,SAAS,CAAC;IAClB,CAAC;IAED,OAAO;QACN,iBAAiB;QACjB,SAAS,CAAE,cAAc,CAAE;QAC3B,qCAAqC;QACrC,GAAG,SAAS,CAAC,KAAK,CAAE,cAAc,GAAG,CAAC,CAAE;QACxC,sEAAsE;QACtE,GAAG,SAAS,CAAC,KAAK,CAAE,CAAC,EAAE,cAAc,CAAE,CAAC,IAAI,CAAE,CAAE,KAAK,EAAE,KAAK,EAAG,EAAE;YAChE,OAAO,CACN,CAAE,KAAK,EAAE,OAAO,CAAC,aAAa,CAAC,IAAI,IAAI,CAAC,CAAE,GAAG,CAAE,KAAK,EAAE,OAAO,CAAC,aAAa,CAAC,IAAI,IAAI,CAAC,CAAE,CACvF,CAAC;QACH,CAAC,CAAE;KACH,CAAC,MAAM,CAAE,CAAE,QAAQ,EAAG,EAAE,CAAC,OAAO,CAAE,QAAQ,CAAE,CAAE,CAAC;AACjD,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sort-plan-properties.d.ts","sourceRoot":"","sources":["../../../src/lib/sort-plan-properties.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEzC,wBAAgB,SAAS,CACxB,SAAS,EAAE,QAAQ,EAAE,EACrB,0BAA0B,CAAC,EAAE,MAAM,GAAG,IAAI,EAC1C,QAAQ,CAAC,EAAE,OAAO,GAChB,QAAQ,EAAE,CAqCZ"}
|
|
@@ -1,46 +0,0 @@
|
|
|
1
|
-
import { isFreePlan } from '@automattic/calypso-products';
|
|
2
|
-
import { isPopularPlan } from '../hooks/data-store/is-popular-plan';
|
|
3
|
-
import type { GridPlan } from '../types';
|
|
4
|
-
|
|
5
|
-
export function sortPlans(
|
|
6
|
-
gridPlans: GridPlan[],
|
|
7
|
-
currentSitePlanProductSlug?: string | null,
|
|
8
|
-
isMobile?: boolean
|
|
9
|
-
): GridPlan[] {
|
|
10
|
-
let firstPlanIndex = -1;
|
|
11
|
-
|
|
12
|
-
// Try to find the current paid plan in the plans list
|
|
13
|
-
if ( currentSitePlanProductSlug && ! isFreePlan( currentSitePlanProductSlug ) ) {
|
|
14
|
-
firstPlanIndex = gridPlans.findIndex( ( gridPlan ) => {
|
|
15
|
-
return gridPlan.planSlug === currentSitePlanProductSlug;
|
|
16
|
-
} );
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
if ( firstPlanIndex < 0 ) {
|
|
20
|
-
// Site is on a free plan or the current plan is not in the list. Try to find the popular plan.
|
|
21
|
-
firstPlanIndex = gridPlans.findIndex( ( { planSlug } ) => {
|
|
22
|
-
return isPopularPlan( planSlug );
|
|
23
|
-
} );
|
|
24
|
-
// If the popular plan exists, on mobile, it will be second plan for comparison.
|
|
25
|
-
if ( firstPlanIndex > 0 && isMobile ) {
|
|
26
|
-
firstPlanIndex = firstPlanIndex - 1;
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
if ( firstPlanIndex < 0 ) {
|
|
31
|
-
return gridPlans;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
return [
|
|
35
|
-
// The first plan
|
|
36
|
-
gridPlans[ firstPlanIndex ],
|
|
37
|
-
// Rest of the plans in default order
|
|
38
|
-
...gridPlans.slice( firstPlanIndex + 1 ),
|
|
39
|
-
// Leftover plans (before the first plan) in descending order of value
|
|
40
|
-
...gridPlans.slice( 0, firstPlanIndex ).sort( ( planA, planB ) => {
|
|
41
|
-
return (
|
|
42
|
-
( planB?.pricing.originalPrice.full || 0 ) - ( planA?.pricing.originalPrice.full || 0 )
|
|
43
|
-
);
|
|
44
|
-
} ),
|
|
45
|
-
].filter( ( gridPlan ) => Boolean( gridPlan ) );
|
|
46
|
-
}
|