@automattic/plans-grid-next 1.0.2 → 1.0.3
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 +4 -1
- package/dist/cjs/_shared.scss +4 -3
- package/dist/cjs/components/comparison-grid/index.js +99 -92
- package/dist/cjs/components/comparison-grid/index.js.map +1 -1
- package/dist/cjs/components/comparison-grid/style.scss +10 -2
- package/dist/cjs/components/features-grid/client-logo-list/client-list.js +0 -12
- package/dist/cjs/components/features-grid/client-logo-list/client-list.js.map +1 -1
- package/dist/cjs/components/features-grid/index.js +9 -6
- package/dist/cjs/components/features-grid/index.js.map +1 -1
- package/dist/cjs/components/features-grid/plan-features-list.js +10 -3
- package/dist/cjs/components/features-grid/plan-features-list.js.map +1 -1
- package/dist/cjs/components/features-grid/plan-headers.js +2 -2
- package/dist/cjs/components/features-grid/plan-headers.js.map +1 -1
- package/dist/cjs/components/features-grid/plan-tagline.js +1 -1
- package/dist/cjs/components/features-grid/plan-tagline.js.map +1 -1
- package/dist/cjs/components/features-grid/style.scss +107 -19
- package/dist/cjs/components/features-grid/table.js +1 -1
- package/dist/cjs/components/features-grid/table.js.map +1 -1
- package/dist/cjs/components/features.js +43 -4
- package/dist/cjs/components/features.js.map +1 -1
- package/dist/cjs/components/item.js +1 -1
- package/dist/cjs/components/item.js.map +1 -1
- package/dist/cjs/components/plan-button/index.js +5 -3
- package/dist/cjs/components/plan-button/index.js.map +1 -1
- package/dist/cjs/components/plan-button/style.scss +75 -51
- package/dist/cjs/components/plan-div-td-container.js +4 -1
- package/dist/cjs/components/plan-div-td-container.js.map +1 -1
- package/dist/cjs/components/plan-logo.js +6 -3
- package/dist/cjs/components/plan-logo.js.map +1 -1
- package/dist/cjs/components/plan-type-selector/components/interval-type-dropdown.js +12 -1
- package/dist/cjs/components/plan-type-selector/components/interval-type-dropdown.js.map +1 -1
- package/dist/cjs/components/plan-type-selector/hooks/use-max-discount.js +4 -33
- 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 +11 -13
- package/dist/cjs/components/plan-type-selector/hooks/use-max-discounts-for-plan-terms.js.map +1 -1
- package/dist/cjs/components/plans-2023-tooltip.js +16 -5
- package/dist/cjs/components/plans-2023-tooltip.js.map +1 -1
- package/dist/cjs/components/shared/action-button/index.js +22 -7
- package/dist/cjs/components/shared/action-button/index.js.map +1 -1
- package/dist/cjs/components/shared/action-button/style.scss +4 -0
- package/dist/cjs/components/shared/billing-timeframe/index.js +8 -4
- package/dist/cjs/components/shared/billing-timeframe/index.js.map +1 -1
- package/dist/cjs/components/shared/header-price/index.js +60 -15
- package/dist/cjs/components/shared/header-price/index.js.map +1 -1
- package/dist/cjs/components/shared/header-price/style.scss +9 -3
- package/dist/cjs/components/shared/storage/components/plan-storage.js +2 -2
- package/dist/cjs/components/shared/storage/components/plan-storage.js.map +1 -1
- package/dist/cjs/components/shared/storage/components/storage-dropdown.js +29 -6
- package/dist/cjs/components/shared/storage/components/storage-dropdown.js.map +1 -1
- package/dist/cjs/components/shared/storage/components/storage-feature-label.js +2 -1
- package/dist/cjs/components/shared/storage/components/storage-feature-label.js.map +1 -1
- package/dist/cjs/components/shared/storage/hooks/use-plan-storage.js +2 -0
- package/dist/cjs/components/shared/storage/hooks/use-plan-storage.js.map +1 -1
- package/dist/cjs/fixtures/sites-purchases.js +2 -4
- package/dist/cjs/fixtures/sites-purchases.js.map +1 -1
- package/dist/cjs/grid-context.js +4 -1
- package/dist/cjs/grid-context.js.map +1 -1
- package/dist/cjs/hooks/data-store/get-renewal-pricing-text.js +50 -0
- package/dist/cjs/hooks/data-store/get-renewal-pricing-text.js.map +1 -0
- package/dist/cjs/hooks/data-store/use-grid-plans-for-comparison-grid.js +6 -1
- package/dist/cjs/hooks/data-store/use-grid-plans-for-comparison-grid.js.map +1 -1
- package/dist/cjs/hooks/data-store/use-grid-plans-for-features-grid.js +6 -1
- package/dist/cjs/hooks/data-store/use-grid-plans-for-features-grid.js.map +1 -1
- package/dist/cjs/hooks/data-store/use-grid-plans.js +175 -21
- package/dist/cjs/hooks/data-store/use-grid-plans.js.map +1 -1
- package/dist/cjs/hooks/data-store/use-highlight-labels.js +13 -4
- package/dist/cjs/hooks/data-store/use-highlight-labels.js.map +1 -1
- package/dist/cjs/hooks/data-store/use-plan-billing-description.js +68 -13
- package/dist/cjs/hooks/data-store/use-plan-billing-description.js.map +1 -1
- package/dist/cjs/hooks/data-store/use-plan-features-for-grid-plans.js +76 -2
- package/dist/cjs/hooks/data-store/use-plan-features-for-grid-plans.js.map +1 -1
- package/dist/cjs/hooks/data-store/use-restructured-plan-features-for-comparison-grid.js +60 -12
- package/dist/cjs/hooks/data-store/use-restructured-plan-features-for-comparison-grid.js.map +1 -1
- package/dist/cjs/hooks/data-store/use-title-badges.js +19 -0
- package/dist/cjs/hooks/data-store/use-title-badges.js.map +1 -0
- package/dist/cjs/hooks/use-is-large-currency.js +2 -2
- package/dist/cjs/hooks/use-is-large-currency.js.map +1 -1
- package/dist/cjs/hooks/use-visible-grid-plans.js +70 -0
- package/dist/cjs/hooks/use-visible-grid-plans.js.map +1 -0
- package/dist/cjs/index.js +6 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/lib/get-plan-features-object.js +15 -2
- package/dist/cjs/lib/get-plan-features-object.js.map +1 -1
- package/dist/cjs/lib/plan-pricing-utils.js +135 -0
- package/dist/cjs/lib/plan-pricing-utils.js.map +1 -0
- package/dist/esm/_shared.scss +4 -3
- package/dist/esm/components/comparison-grid/index.js +100 -93
- package/dist/esm/components/comparison-grid/index.js.map +1 -1
- package/dist/esm/components/comparison-grid/style.scss +10 -2
- package/dist/esm/components/features-grid/client-logo-list/client-list.js +0 -12
- package/dist/esm/components/features-grid/client-logo-list/client-list.js.map +1 -1
- package/dist/esm/components/features-grid/index.js +9 -6
- package/dist/esm/components/features-grid/index.js.map +1 -1
- package/dist/esm/components/features-grid/plan-features-list.js +10 -3
- package/dist/esm/components/features-grid/plan-features-list.js.map +1 -1
- package/dist/esm/components/features-grid/plan-headers.js +3 -3
- package/dist/esm/components/features-grid/plan-headers.js.map +1 -1
- package/dist/esm/components/features-grid/plan-tagline.js +1 -1
- package/dist/esm/components/features-grid/plan-tagline.js.map +1 -1
- package/dist/esm/components/features-grid/style.scss +107 -19
- package/dist/esm/components/features-grid/table.js +1 -1
- package/dist/esm/components/features-grid/table.js.map +1 -1
- package/dist/esm/components/features.js +44 -5
- package/dist/esm/components/features.js.map +1 -1
- package/dist/esm/components/item.js +1 -1
- package/dist/esm/components/item.js.map +1 -1
- package/dist/esm/components/plan-button/index.js +5 -3
- package/dist/esm/components/plan-button/index.js.map +1 -1
- package/dist/esm/components/plan-button/style.scss +75 -51
- package/dist/esm/components/plan-div-td-container.js +4 -1
- package/dist/esm/components/plan-div-td-container.js.map +1 -1
- package/dist/esm/components/plan-logo.js +7 -4
- package/dist/esm/components/plan-logo.js.map +1 -1
- package/dist/esm/components/plan-type-selector/components/interval-type-dropdown.js +12 -1
- package/dist/esm/components/plan-type-selector/components/interval-type-dropdown.js.map +1 -1
- package/dist/esm/components/plan-type-selector/hooks/use-max-discount.js +3 -33
- package/dist/esm/components/plan-type-selector/hooks/use-max-discount.js.map +1 -1
- package/dist/esm/components/plan-type-selector/hooks/use-max-discounts-for-plan-terms.js +11 -13
- package/dist/esm/components/plan-type-selector/hooks/use-max-discounts-for-plan-terms.js.map +1 -1
- package/dist/esm/components/plans-2023-tooltip.js +16 -5
- package/dist/esm/components/plans-2023-tooltip.js.map +1 -1
- package/dist/esm/components/shared/action-button/index.js +22 -7
- package/dist/esm/components/shared/action-button/index.js.map +1 -1
- package/dist/esm/components/shared/action-button/style.scss +4 -0
- package/dist/esm/components/shared/billing-timeframe/index.js +8 -4
- package/dist/esm/components/shared/billing-timeframe/index.js.map +1 -1
- package/dist/esm/components/shared/header-price/index.js +60 -15
- package/dist/esm/components/shared/header-price/index.js.map +1 -1
- package/dist/esm/components/shared/header-price/style.scss +9 -3
- package/dist/esm/components/shared/storage/components/plan-storage.js +2 -2
- package/dist/esm/components/shared/storage/components/plan-storage.js.map +1 -1
- package/dist/esm/components/shared/storage/components/storage-dropdown.js +30 -7
- package/dist/esm/components/shared/storage/components/storage-dropdown.js.map +1 -1
- package/dist/esm/components/shared/storage/components/storage-feature-label.js +2 -1
- package/dist/esm/components/shared/storage/components/storage-feature-label.js.map +1 -1
- package/dist/esm/components/shared/storage/hooks/use-plan-storage.js +3 -1
- package/dist/esm/components/shared/storage/hooks/use-plan-storage.js.map +1 -1
- package/dist/esm/fixtures/sites-purchases.js +2 -4
- package/dist/esm/fixtures/sites-purchases.js.map +1 -1
- package/dist/esm/grid-context.js +4 -1
- package/dist/esm/grid-context.js.map +1 -1
- package/dist/esm/hooks/data-store/get-renewal-pricing-text.js +47 -0
- package/dist/esm/hooks/data-store/get-renewal-pricing-text.js.map +1 -0
- package/dist/esm/hooks/data-store/use-grid-plans-for-comparison-grid.js +6 -1
- package/dist/esm/hooks/data-store/use-grid-plans-for-comparison-grid.js.map +1 -1
- package/dist/esm/hooks/data-store/use-grid-plans-for-features-grid.js +6 -1
- package/dist/esm/hooks/data-store/use-grid-plans-for-features-grid.js.map +1 -1
- package/dist/esm/hooks/data-store/use-grid-plans.js +176 -22
- package/dist/esm/hooks/data-store/use-grid-plans.js.map +1 -1
- package/dist/esm/hooks/data-store/use-highlight-labels.js +14 -5
- package/dist/esm/hooks/data-store/use-highlight-labels.js.map +1 -1
- package/dist/esm/hooks/data-store/use-plan-billing-description.js +66 -11
- package/dist/esm/hooks/data-store/use-plan-billing-description.js.map +1 -1
- package/dist/esm/hooks/data-store/use-plan-features-for-grid-plans.js +77 -3
- package/dist/esm/hooks/data-store/use-plan-features-for-grid-plans.js.map +1 -1
- package/dist/esm/hooks/data-store/use-restructured-plan-features-for-comparison-grid.js +59 -11
- package/dist/esm/hooks/data-store/use-restructured-plan-features-for-comparison-grid.js.map +1 -1
- package/dist/esm/hooks/data-store/use-title-badges.js +17 -0
- package/dist/esm/hooks/data-store/use-title-badges.js.map +1 -0
- package/dist/esm/hooks/use-is-large-currency.js +1 -1
- package/dist/esm/hooks/use-is-large-currency.js.map +1 -1
- package/dist/esm/hooks/use-visible-grid-plans.js +66 -0
- package/dist/esm/hooks/use-visible-grid-plans.js.map +1 -0
- package/dist/esm/index.js +2 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/lib/get-plan-features-object.js +15 -2
- package/dist/esm/lib/get-plan-features-object.js.map +1 -1
- package/dist/esm/lib/plan-pricing-utils.js +129 -0
- package/dist/esm/lib/plan-pricing-utils.js.map +1 -0
- 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/features-grid/client-logo-list/client-list.d.ts.map +1 -1
- package/dist/types/components/features-grid/index.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 +2 -0
- package/dist/types/components/features-grid/plan-headers.d.ts.map +1 -1
- package/dist/types/components/features-grid/table.d.ts.map +1 -1
- package/dist/types/components/features.d.ts.map +1 -1
- package/dist/types/components/item.d.ts +2 -1
- package/dist/types/components/item.d.ts.map +1 -1
- package/dist/types/components/plan-button/index.d.ts +2 -1
- package/dist/types/components/plan-button/index.d.ts.map +1 -1
- package/dist/types/components/plan-div-td-container.d.ts +2 -0
- package/dist/types/components/plan-div-td-container.d.ts.map +1 -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.map +1 -1
- package/dist/types/components/plan-type-selector/hooks/use-max-discount.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/shared/action-button/index.d.ts +2 -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/index.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-plan-storage.d.ts +1 -1
- package/dist/types/components/shared/storage/hooks/use-plan-storage.d.ts.map +1 -1
- package/dist/types/fixtures/sites-purchases.d.ts +2 -4
- package/dist/types/fixtures/sites-purchases.d.ts.map +1 -1
- package/dist/types/grid-context.d.ts +4 -1
- package/dist/types/grid-context.d.ts.map +1 -1
- package/dist/types/hooks/data-store/get-renewal-pricing-text.d.ts +14 -0
- package/dist/types/hooks/data-store/get-renewal-pricing-text.d.ts.map +1 -0
- package/dist/types/hooks/data-store/types.d.ts +21 -0
- package/dist/types/hooks/data-store/types.d.ts.map +1 -1
- package/dist/types/hooks/data-store/use-grid-plans-for-comparison-grid.d.ts +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.map +1 -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.map +1 -1
- package/dist/types/hooks/data-store/use-plan-features-for-grid-plans.d.ts +4 -1
- package/dist/types/hooks/data-store/use-plan-features-for-grid-plans.d.ts.map +1 -1
- package/dist/types/hooks/data-store/use-restructured-plan-features-for-comparison-grid.d.ts +4 -1
- package/dist/types/hooks/data-store/use-restructured-plan-features-for-comparison-grid.d.ts.map +1 -1
- package/dist/types/hooks/data-store/use-title-badges.d.ts +9 -0
- package/dist/types/hooks/data-store/use-title-badges.d.ts.map +1 -0
- package/dist/types/hooks/use-visible-grid-plans.d.ts +14 -0
- package/dist/types/hooks/use-visible-grid-plans.d.ts.map +1 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/lib/get-plan-features-object.d.ts +1 -1
- package/dist/types/lib/get-plan-features-object.d.ts.map +1 -1
- package/dist/types/lib/plan-pricing-utils.d.ts +105 -0
- package/dist/types/lib/plan-pricing-utils.d.ts.map +1 -0
- package/dist/types/types.d.ts +29 -2
- package/dist/types/types.d.ts.map +1 -1
- package/package.json +38 -28
- package/src/_shared.scss +4 -3
- package/src/components/comparison-grid/index.tsx +258 -181
- package/src/components/comparison-grid/style.scss +10 -2
- package/src/components/features-grid/client-logo-list/client-list.tsx +0 -25
- package/src/components/features-grid/index.tsx +35 -18
- package/src/components/features-grid/plan-features-list.tsx +15 -4
- package/src/components/features-grid/plan-headers.tsx +10 -3
- package/src/components/features-grid/plan-tagline.tsx +1 -1
- package/src/components/features-grid/style.scss +107 -19
- package/src/components/features-grid/table.tsx +4 -2
- package/src/components/features.tsx +66 -6
- package/src/components/item.tsx +6 -3
- package/src/components/plan-button/index.tsx +7 -1
- package/src/components/plan-button/style.scss +75 -51
- package/src/components/plan-div-td-container.tsx +6 -2
- package/src/components/plan-logo.tsx +16 -9
- package/src/components/plan-type-selector/components/interval-type-dropdown.tsx +14 -1
- package/src/components/plan-type-selector/hooks/use-max-discount.ts +8 -47
- package/src/components/plan-type-selector/hooks/use-max-discounts-for-plan-terms.ts +19 -17
- package/src/components/plans-2023-tooltip.tsx +17 -5
- package/src/components/shared/action-button/index.tsx +46 -5
- package/src/components/shared/action-button/style.scss +4 -0
- package/src/components/shared/billing-timeframe/index.tsx +12 -7
- package/src/components/shared/header-price/index.tsx +129 -27
- package/src/components/shared/header-price/style.scss +9 -3
- package/src/components/shared/storage/components/plan-storage.tsx +2 -2
- package/src/components/shared/storage/components/storage-dropdown.tsx +36 -15
- package/src/components/shared/storage/components/storage-feature-label.tsx +2 -1
- package/src/components/shared/storage/hooks/use-plan-storage.ts +3 -0
- package/src/components/test/actions-button.tsx +5 -0
- package/src/components/test/billing-timeframe.tsx +1 -1
- package/src/components/test/header-price.tsx +342 -4
- package/src/fixtures/sites-purchases.ts +2 -4
- package/src/grid-context.tsx +9 -0
- package/src/hooks/data-store/get-renewal-pricing-text.ts +73 -0
- package/src/hooks/data-store/types.ts +21 -0
- package/src/hooks/data-store/use-grid-plans-for-comparison-grid.ts +10 -0
- package/src/hooks/data-store/use-grid-plans-for-features-grid.ts +10 -0
- package/src/hooks/data-store/use-grid-plans.tsx +189 -23
- package/src/hooks/data-store/use-highlight-labels.ts +12 -3
- package/src/hooks/data-store/use-plan-billing-description.tsx +80 -15
- package/src/hooks/data-store/use-plan-features-for-grid-plans.ts +135 -1
- package/src/hooks/data-store/use-restructured-plan-features-for-comparison-grid.ts +93 -20
- package/src/hooks/data-store/use-title-badges.ts +31 -0
- package/src/hooks/test/use-visible-grid-plans.tsx +116 -0
- package/src/hooks/use-is-large-currency.ts +1 -1
- package/src/hooks/use-visible-grid-plans.tsx +102 -0
- package/src/index.tsx +18 -0
- package/src/lib/get-plan-features-object.ts +23 -2
- package/src/lib/plan-pricing-utils.ts +211 -0
- package/src/lib/test/plan-pricing-utils.ts +594 -0
- package/src/style-imports.d.ts +3 -0
- package/src/types.ts +41 -0
- package/dist/cjs/components/features-grid/mobile-free-domain.js +0 -25
- package/dist/cjs/components/features-grid/mobile-free-domain.js.map +0 -1
- package/dist/cjs/lib/get-plan-pricing-info-from-grid-plans.js +0 -15
- package/dist/cjs/lib/get-plan-pricing-info-from-grid-plans.js.map +0 -1
- package/dist/esm/components/features-grid/mobile-free-domain.js +0 -23
- package/dist/esm/components/features-grid/mobile-free-domain.js.map +0 -1
- package/dist/esm/lib/get-plan-pricing-info-from-grid-plans.js +0 -12
- package/dist/esm/lib/get-plan-pricing-info-from-grid-plans.js.map +0 -1
- package/dist/types/components/features-grid/mobile-free-domain.d.ts +0 -8
- package/dist/types/components/features-grid/mobile-free-domain.d.ts.map +0 -1
- package/dist/types/lib/get-plan-pricing-info-from-grid-plans.d.ts +0 -9
- package/dist/types/lib/get-plan-pricing-info-from-grid-plans.d.ts.map +0 -1
- package/src/components/features-grid/mobile-free-domain.tsx +0 -51
- package/src/lib/get-plan-pricing-info-from-grid-plans.ts +0 -31
|
@@ -6,8 +6,10 @@ import {
|
|
|
6
6
|
isWpcomEnterpriseGridPlan,
|
|
7
7
|
} from '@automattic/calypso-products';
|
|
8
8
|
import { AddOns, WpcomPlansUI } from '@automattic/data-stores';
|
|
9
|
+
import { formatCurrency } from '@automattic/number-formatters';
|
|
9
10
|
import { useSelect } from '@wordpress/data';
|
|
10
|
-
import
|
|
11
|
+
import clsx from 'clsx';
|
|
12
|
+
import { useTranslate } from 'i18n-calypso';
|
|
11
13
|
import { usePlansGridContext } from '../../../grid-context';
|
|
12
14
|
import useIsLargeCurrency from '../../../hooks/use-is-large-currency';
|
|
13
15
|
import { usePlanPricingInfoFromGridPlans } from '../../../hooks/use-plan-pricing-info-from-grid-plans';
|
|
@@ -28,6 +30,7 @@ type ActionButtonProps = {
|
|
|
28
30
|
showMonthlyPrice: boolean;
|
|
29
31
|
isStuck: boolean;
|
|
30
32
|
visibleGridPlans: GridPlan[];
|
|
33
|
+
showPostButtonText?: boolean;
|
|
31
34
|
};
|
|
32
35
|
|
|
33
36
|
const ActionButton = ( {
|
|
@@ -38,12 +41,14 @@ const ActionButton = ( {
|
|
|
38
41
|
isStuck,
|
|
39
42
|
isInSignup,
|
|
40
43
|
isMonthlyPlan,
|
|
44
|
+
showPostButtonText = true,
|
|
41
45
|
}: ActionButtonProps ) => {
|
|
42
46
|
const translate = useTranslate();
|
|
43
47
|
const {
|
|
44
48
|
gridPlansIndex,
|
|
45
49
|
siteId,
|
|
46
50
|
helpers: { useAction },
|
|
51
|
+
showBillingDescriptionForIncreasedRenewalPrice,
|
|
47
52
|
} = usePlansGridContext();
|
|
48
53
|
const {
|
|
49
54
|
current,
|
|
@@ -80,7 +85,7 @@ const ActionButton = ( {
|
|
|
80
85
|
);
|
|
81
86
|
|
|
82
87
|
const {
|
|
83
|
-
primary: { callback, text, status, variant },
|
|
88
|
+
primary: { callback, text, status, variant, ariaLabel },
|
|
84
89
|
postButtonText,
|
|
85
90
|
} = useAction( {
|
|
86
91
|
availableForPurchase,
|
|
@@ -93,6 +98,8 @@ const ActionButton = ( {
|
|
|
93
98
|
cartItemForPlan,
|
|
94
99
|
currentPlanBillingPeriod,
|
|
95
100
|
selectedStorageAddOn,
|
|
101
|
+
pricing: gridPlansIndex[ planSlug ]?.pricing,
|
|
102
|
+
isMonthlyPlan,
|
|
96
103
|
} );
|
|
97
104
|
const {
|
|
98
105
|
primary: { callback: freeTrialCallback, text: freeTrialText },
|
|
@@ -108,6 +115,8 @@ const ActionButton = ( {
|
|
|
108
115
|
cartItemForPlan: { product_slug: freeTrialPlanSlug ?? PLAN_FREE },
|
|
109
116
|
currentPlanBillingPeriod,
|
|
110
117
|
selectedStorageAddOn,
|
|
118
|
+
pricing: gridPlansIndex[ freeTrialPlanSlug ?? PLAN_FREE ]?.pricing,
|
|
119
|
+
isMonthlyPlan,
|
|
111
120
|
} );
|
|
112
121
|
|
|
113
122
|
const busy = status === 'blocked';
|
|
@@ -131,6 +140,7 @@ const ActionButton = ( {
|
|
|
131
140
|
busy={ busy }
|
|
132
141
|
disabled={ ! callback || 'disabled' === status }
|
|
133
142
|
classes={ variant === 'secondary' ? 'is-secondary' : '' }
|
|
143
|
+
ariaLabel={ String( ariaLabel || '' ) }
|
|
134
144
|
>
|
|
135
145
|
{ text }
|
|
136
146
|
</PlanButton>
|
|
@@ -159,6 +169,7 @@ const ActionButton = ( {
|
|
|
159
169
|
classes="is-storage-upgradeable"
|
|
160
170
|
href={ storageAddOnCheckoutHref }
|
|
161
171
|
busy={ busy }
|
|
172
|
+
ariaLabel={ translate( 'Upgrade storage for this plan' ).toString() }
|
|
162
173
|
>
|
|
163
174
|
{ translate( 'Upgrade' ) }
|
|
164
175
|
</PlanButton>
|
|
@@ -171,7 +182,13 @@ const ActionButton = ( {
|
|
|
171
182
|
{ freeTrialText }
|
|
172
183
|
</PlanButton>
|
|
173
184
|
{ ! isStuck && ( // along side with the free trial CTA, we also provide an option for purchasing the plan directly here
|
|
174
|
-
<PlanButton
|
|
185
|
+
<PlanButton
|
|
186
|
+
planSlug={ planSlug }
|
|
187
|
+
onClick={ callback }
|
|
188
|
+
busy={ busy }
|
|
189
|
+
borderless
|
|
190
|
+
ariaLabel={ String( ariaLabel || '' ) }
|
|
191
|
+
>
|
|
175
192
|
{ text }
|
|
176
193
|
</PlanButton>
|
|
177
194
|
) }
|
|
@@ -184,15 +201,39 @@ const ActionButton = ( {
|
|
|
184
201
|
busy={ busy }
|
|
185
202
|
onClick={ callback }
|
|
186
203
|
current={ current }
|
|
204
|
+
ariaLabel={ String( ariaLabel || '' ) }
|
|
187
205
|
>
|
|
188
206
|
{ text }
|
|
189
207
|
</PlanButton>
|
|
190
|
-
{ postButtonText && (
|
|
191
|
-
<span
|
|
208
|
+
{ showPostButtonText && postButtonText && (
|
|
209
|
+
<span
|
|
210
|
+
className={ clsx( 'plans-grid-next-action-button__label', {
|
|
211
|
+
'is-left-aligned': showBillingDescriptionForIncreasedRenewalPrice,
|
|
212
|
+
} ) }
|
|
213
|
+
>
|
|
214
|
+
{ postButtonText }
|
|
215
|
+
</span>
|
|
192
216
|
) }
|
|
193
217
|
</>
|
|
194
218
|
);
|
|
195
219
|
}
|
|
220
|
+
} else if (
|
|
221
|
+
showPostButtonText &&
|
|
222
|
+
postButtonText &&
|
|
223
|
+
showBillingDescriptionForIncreasedRenewalPrice
|
|
224
|
+
) {
|
|
225
|
+
actionButton = (
|
|
226
|
+
<>
|
|
227
|
+
{ actionButton }
|
|
228
|
+
<span
|
|
229
|
+
className={ clsx( 'plans-grid-next-action-button__label', {
|
|
230
|
+
'is-left-aligned': showBillingDescriptionForIncreasedRenewalPrice,
|
|
231
|
+
} ) }
|
|
232
|
+
>
|
|
233
|
+
{ postButtonText }
|
|
234
|
+
</span>
|
|
235
|
+
</>
|
|
236
|
+
);
|
|
196
237
|
}
|
|
197
238
|
|
|
198
239
|
return (
|
|
@@ -4,8 +4,9 @@ import {
|
|
|
4
4
|
isWooExpressPlan,
|
|
5
5
|
isFreePlan,
|
|
6
6
|
} from '@automattic/calypso-products';
|
|
7
|
+
import { formatCurrency } from '@automattic/number-formatters';
|
|
7
8
|
import styled from '@emotion/styled';
|
|
8
|
-
import { useTranslate,
|
|
9
|
+
import { useTranslate, fixMe } from 'i18n-calypso';
|
|
9
10
|
import { usePlansGridContext } from '../../../grid-context';
|
|
10
11
|
import usePlanBillingDescription from '../../../hooks/data-store/use-plan-billing-description';
|
|
11
12
|
import type { GridPlan } from '../../../types';
|
|
@@ -18,6 +19,10 @@ const DiscountPromotion = styled.div`
|
|
|
18
19
|
margin-top: 6px;
|
|
19
20
|
`;
|
|
20
21
|
|
|
22
|
+
const BillingTimeframeContainer = styled.p`
|
|
23
|
+
margin-bottom: 0;
|
|
24
|
+
`;
|
|
25
|
+
|
|
21
26
|
interface RefundNoticeProps {
|
|
22
27
|
showRefundPeriod?: boolean;
|
|
23
28
|
planSlug: string;
|
|
@@ -70,10 +75,10 @@ const BillingTimeframe = ( { showRefundPeriod, planSlug }: Props ) => {
|
|
|
70
75
|
( ! introOffer || introOffer.isOfferComplete )
|
|
71
76
|
) {
|
|
72
77
|
return (
|
|
73
|
-
<
|
|
78
|
+
<BillingTimeframeContainer>
|
|
74
79
|
<div>{ billingTimeframe }</div>
|
|
75
80
|
<DiscountPromotion>{ planBillingDescription }</DiscountPromotion>
|
|
76
|
-
</
|
|
81
|
+
</BillingTimeframeContainer>
|
|
77
82
|
);
|
|
78
83
|
}
|
|
79
84
|
|
|
@@ -81,7 +86,7 @@ const BillingTimeframe = ( { showRefundPeriod, planSlug }: Props ) => {
|
|
|
81
86
|
const price = formatCurrency( 25000, 'USD', { stripZeros: true } );
|
|
82
87
|
|
|
83
88
|
return (
|
|
84
|
-
<
|
|
89
|
+
<BillingTimeframeContainer>
|
|
85
90
|
{ fixMe( {
|
|
86
91
|
text: 'Starts at {{b}}%(price)s{{/b}} annually',
|
|
87
92
|
newCopy: translate( 'Starts at {{b}}%(price)s{{/b}} annually', {
|
|
@@ -95,19 +100,19 @@ const BillingTimeframe = ( { showRefundPeriod, planSlug }: Props ) => {
|
|
|
95
100
|
comment: 'Translators: the price is in US dollars for all users (US$25,000)',
|
|
96
101
|
} ),
|
|
97
102
|
} ) }
|
|
98
|
-
</
|
|
103
|
+
</BillingTimeframeContainer>
|
|
99
104
|
);
|
|
100
105
|
}
|
|
101
106
|
|
|
102
107
|
return (
|
|
103
|
-
<
|
|
108
|
+
<BillingTimeframeContainer>
|
|
104
109
|
{ description }
|
|
105
110
|
<RefundNotice
|
|
106
111
|
showRefundPeriod={ showRefundPeriod }
|
|
107
112
|
planSlug={ planSlug }
|
|
108
113
|
billingPeriod={ billingPeriod }
|
|
109
114
|
/>
|
|
110
|
-
</
|
|
115
|
+
</BillingTimeframeContainer>
|
|
111
116
|
);
|
|
112
117
|
};
|
|
113
118
|
|
|
@@ -13,6 +13,11 @@ import { useTranslate } from 'i18n-calypso';
|
|
|
13
13
|
import { usePlansGridContext } from '../../../grid-context';
|
|
14
14
|
import useIsLargeCurrency from '../../../hooks/use-is-large-currency';
|
|
15
15
|
import { usePlanPricingInfoFromGridPlans } from '../../../hooks/use-plan-pricing-info-from-grid-plans';
|
|
16
|
+
import {
|
|
17
|
+
calculateDiscountPercentage,
|
|
18
|
+
fromPricingMetaForGridPlan,
|
|
19
|
+
getPlanPriceForDuration,
|
|
20
|
+
} from '../../../lib/plan-pricing-utils';
|
|
16
21
|
import { useHeaderPriceContext } from './header-price-context';
|
|
17
22
|
import type { GridPlan } from '../../../types';
|
|
18
23
|
import './style.scss';
|
|
@@ -51,11 +56,18 @@ const HeaderPrice = ( { planSlug, visibleGridPlans }: HeaderPriceProps ) => {
|
|
|
51
56
|
siteId,
|
|
52
57
|
coupon,
|
|
53
58
|
helpers,
|
|
59
|
+
showBillingDescriptionForIncreasedRenewalPrice,
|
|
60
|
+
isExperimentVariant,
|
|
54
61
|
} = usePlansGridContext();
|
|
62
|
+
|
|
63
|
+
const pricingBadgeClassName = clsx( 'plans-grid-next-header-price__badge', {
|
|
64
|
+
'is-plan-differentiators-experiment-badge': isExperimentVariant,
|
|
65
|
+
} );
|
|
55
66
|
const { isAnyPlanPriceDiscounted, setIsAnyPlanPriceDiscounted } = useHeaderPriceContext();
|
|
56
67
|
const {
|
|
57
68
|
current,
|
|
58
69
|
pricing: { currencyCode, originalPrice, discountedPrice, introOffer, billingPeriod },
|
|
70
|
+
isMonthlyPlan,
|
|
59
71
|
} = gridPlansIndex[ planSlug ];
|
|
60
72
|
const isPricedPlan = null !== originalPrice.monthly;
|
|
61
73
|
|
|
@@ -68,11 +80,12 @@ const HeaderPrice = ( { planSlug, visibleGridPlans }: HeaderPriceProps ) => {
|
|
|
68
80
|
const isGridPlanOnIntroOffer = introOffer && ! introOffer.isOfferComplete;
|
|
69
81
|
|
|
70
82
|
const { prices } = usePlanPricingInfoFromGridPlans( { gridPlans: visibleGridPlans } );
|
|
71
|
-
const isLargeCurrency =
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
83
|
+
const isLargeCurrency =
|
|
84
|
+
useIsLargeCurrency( {
|
|
85
|
+
prices,
|
|
86
|
+
currencyCode: currencyCode || 'USD',
|
|
87
|
+
ignoreWhitespace: true,
|
|
88
|
+
} ) && ! showBillingDescriptionForIncreasedRenewalPrice; // a temporary fix to handle an issue with isLargeCurrency logic for intro offers
|
|
76
89
|
|
|
77
90
|
const termVariantPlanSlug = useTermVariantPlanSlugForSavings( { planSlug, billingPeriod } );
|
|
78
91
|
const termVariantPricing = Plans.usePricingMetaForGridPlans( {
|
|
@@ -83,19 +96,24 @@ const HeaderPrice = ( { planSlug, visibleGridPlans }: HeaderPriceProps ) => {
|
|
|
83
96
|
useCheckPlanAvailabilityForPurchase: helpers?.useCheckPlanAvailabilityForPurchase,
|
|
84
97
|
} )?.[ termVariantPlanSlug ?? '' ];
|
|
85
98
|
|
|
86
|
-
const
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
const
|
|
90
|
-
|
|
91
|
-
|
|
99
|
+
const termVariantInfo = termVariantPricing
|
|
100
|
+
? fromPricingMetaForGridPlan( termVariantPricing )
|
|
101
|
+
: null;
|
|
102
|
+
const currentPlanInfo = fromPricingMetaForGridPlan( gridPlansIndex[ planSlug ].pricing );
|
|
103
|
+
let savings =
|
|
104
|
+
termVariantInfo && currentPlanInfo
|
|
105
|
+
? calculateDiscountPercentage(
|
|
106
|
+
getPlanPriceForDuration( termVariantInfo, currentPlanInfo.termMonths ),
|
|
107
|
+
getPlanPriceForDuration( currentPlanInfo, currentPlanInfo.termMonths )
|
|
108
|
+
) ?? 0
|
|
92
109
|
: 0;
|
|
93
110
|
|
|
94
111
|
useEffect( () => {
|
|
95
112
|
if (
|
|
96
113
|
isGridPlanOneTimeDiscounted ||
|
|
97
114
|
isGridPlanOnIntroOffer ||
|
|
98
|
-
( enableTermSavingsPriceDisplay && savings )
|
|
115
|
+
( enableTermSavingsPriceDisplay && savings ) ||
|
|
116
|
+
( showBillingDescriptionForIncreasedRenewalPrice && !! termVariantPricing )
|
|
99
117
|
) {
|
|
100
118
|
setIsAnyPlanPriceDiscounted( true );
|
|
101
119
|
}
|
|
@@ -105,6 +123,8 @@ const HeaderPrice = ( { planSlug, visibleGridPlans }: HeaderPriceProps ) => {
|
|
|
105
123
|
isGridPlanOneTimeDiscounted,
|
|
106
124
|
savings,
|
|
107
125
|
setIsAnyPlanPriceDiscounted,
|
|
126
|
+
showBillingDescriptionForIncreasedRenewalPrice,
|
|
127
|
+
termVariantPricing,
|
|
108
128
|
] );
|
|
109
129
|
|
|
110
130
|
if ( isWpcomEnterpriseGridPlan( planSlug ) || ! isPricedPlan ) {
|
|
@@ -112,13 +132,41 @@ const HeaderPrice = ( { planSlug, visibleGridPlans }: HeaderPriceProps ) => {
|
|
|
112
132
|
}
|
|
113
133
|
|
|
114
134
|
if ( isGridPlanOnIntroOffer ) {
|
|
135
|
+
// Use the monthly plan price for renewal pricing, instead of the intro offer renewal price
|
|
136
|
+
const compareToMonthlyPrice =
|
|
137
|
+
( showBillingDescriptionForIncreasedRenewalPrice && termVariantPricing
|
|
138
|
+
? termVariantPricing.originalPrice.monthly
|
|
139
|
+
: originalPrice.monthly ) ?? 0;
|
|
140
|
+
const monthlyPrice =
|
|
141
|
+
typeof discountedPrice.monthly === 'number'
|
|
142
|
+
? discountedPrice.monthly
|
|
143
|
+
: introOffer.rawPrice.monthly;
|
|
144
|
+
// Recalculate the savings for Monthly plans with introductory offers
|
|
145
|
+
// since we are comparing the introductory price with the same plan
|
|
146
|
+
// renewal price, instead of comparing yearly to monthly costs for
|
|
147
|
+
// the same period.
|
|
148
|
+
if (
|
|
149
|
+
showBillingDescriptionForIncreasedRenewalPrice &&
|
|
150
|
+
compareToMonthlyPrice > monthlyPrice &&
|
|
151
|
+
isMonthlyPlan
|
|
152
|
+
) {
|
|
153
|
+
savings = calculateDiscountPercentage( compareToMonthlyPrice, monthlyPrice ) ?? 0;
|
|
154
|
+
}
|
|
115
155
|
return (
|
|
116
156
|
<div className="plans-grid-next-header-price">
|
|
117
157
|
{ ! current && (
|
|
118
|
-
<div className=
|
|
119
|
-
{
|
|
158
|
+
<div className={ pricingBadgeClassName }>
|
|
159
|
+
{ showBillingDescriptionForIncreasedRenewalPrice
|
|
160
|
+
? translate( 'Save %(savings)d%%', {
|
|
161
|
+
args: { savings },
|
|
162
|
+
comment: 'Example: Save 35%',
|
|
163
|
+
} )
|
|
164
|
+
: translate( 'Special Offer' ) }
|
|
120
165
|
</div>
|
|
121
166
|
) }
|
|
167
|
+
{ current && visibleGridPlans.length > 1 && (
|
|
168
|
+
<div className={ clsx( pricingBadgeClassName, 'is-hidden' ) }>' '</div>
|
|
169
|
+
) }
|
|
122
170
|
<div
|
|
123
171
|
className={ clsx( 'plans-grid-next-header-price__pricing-group', {
|
|
124
172
|
'is-large-currency': isLargeCurrency,
|
|
@@ -126,22 +174,18 @@ const HeaderPrice = ( { planSlug, visibleGridPlans }: HeaderPriceProps ) => {
|
|
|
126
174
|
>
|
|
127
175
|
<PlanPrice
|
|
128
176
|
currencyCode={ currencyCode }
|
|
129
|
-
rawPrice={
|
|
177
|
+
rawPrice={ compareToMonthlyPrice }
|
|
130
178
|
displayPerMonthNotation={ false }
|
|
131
|
-
isLargeCurrency
|
|
179
|
+
isLargeCurrency={ isLargeCurrency }
|
|
132
180
|
isSmallestUnit
|
|
133
181
|
priceDisplayWrapperClassName="plans-grid-next-header-price__display-wrapper"
|
|
134
182
|
original
|
|
135
183
|
/>
|
|
136
184
|
<PlanPrice
|
|
137
185
|
currencyCode={ currencyCode }
|
|
138
|
-
rawPrice={
|
|
139
|
-
typeof discountedPrice.monthly === 'number'
|
|
140
|
-
? discountedPrice.monthly
|
|
141
|
-
: introOffer.rawPrice.monthly
|
|
142
|
-
}
|
|
186
|
+
rawPrice={ monthlyPrice }
|
|
143
187
|
displayPerMonthNotation={ false }
|
|
144
|
-
isLargeCurrency
|
|
188
|
+
isLargeCurrency={ isLargeCurrency }
|
|
145
189
|
isSmallestUnit
|
|
146
190
|
priceDisplayWrapperClassName="plans-grid-next-header-price__display-wrapper"
|
|
147
191
|
discounted
|
|
@@ -151,12 +195,61 @@ const HeaderPrice = ( { planSlug, visibleGridPlans }: HeaderPriceProps ) => {
|
|
|
151
195
|
);
|
|
152
196
|
}
|
|
153
197
|
|
|
154
|
-
|
|
198
|
+
// Handle cases where a plan is ineligible for intro offer, but we still
|
|
199
|
+
// want to show the crossed-out monthly price.
|
|
200
|
+
if ( showBillingDescriptionForIncreasedRenewalPrice && termVariantPricing ) {
|
|
201
|
+
const compareToMonthlyPrice = termVariantPricing.originalPrice.monthly ?? 0;
|
|
202
|
+
const monthlyPrice =
|
|
203
|
+
typeof discountedPrice.monthly === 'number'
|
|
204
|
+
? discountedPrice.monthly
|
|
205
|
+
: originalPrice.monthly ?? 0;
|
|
155
206
|
return (
|
|
156
207
|
<div className="plans-grid-next-header-price">
|
|
157
|
-
|
|
158
|
-
{
|
|
208
|
+
{ ! current && savings > 0 && (
|
|
209
|
+
<div className={ pricingBadgeClassName }>
|
|
210
|
+
{ translate( 'Save %(savings)d%%', {
|
|
211
|
+
args: { savings },
|
|
212
|
+
comment: 'Example: Save 35%',
|
|
213
|
+
} ) }
|
|
214
|
+
</div>
|
|
215
|
+
) }
|
|
216
|
+
{ ( ( ! current && savings <= 0 ) || ( current && visibleGridPlans.length > 1 ) ) && (
|
|
217
|
+
<div className={ clsx( pricingBadgeClassName, 'is-hidden' ) }>' '</div>
|
|
218
|
+
) }
|
|
219
|
+
<div
|
|
220
|
+
className={ clsx( 'plans-grid-next-header-price__pricing-group', {
|
|
221
|
+
'is-large-currency': isLargeCurrency,
|
|
222
|
+
} ) }
|
|
223
|
+
>
|
|
224
|
+
{ compareToMonthlyPrice > monthlyPrice && (
|
|
225
|
+
<PlanPrice
|
|
226
|
+
currencyCode={ currencyCode }
|
|
227
|
+
rawPrice={ compareToMonthlyPrice }
|
|
228
|
+
displayPerMonthNotation={ false }
|
|
229
|
+
isLargeCurrency={ isLargeCurrency }
|
|
230
|
+
isSmallestUnit
|
|
231
|
+
priceDisplayWrapperClassName="plans-grid-next-header-price__display-wrapper"
|
|
232
|
+
original
|
|
233
|
+
/>
|
|
234
|
+
) }
|
|
235
|
+
<PlanPrice
|
|
236
|
+
currencyCode={ currencyCode }
|
|
237
|
+
rawPrice={ monthlyPrice }
|
|
238
|
+
displayPerMonthNotation={ false }
|
|
239
|
+
isLargeCurrency={ isLargeCurrency }
|
|
240
|
+
isSmallestUnit
|
|
241
|
+
priceDisplayWrapperClassName="plans-grid-next-header-price__display-wrapper"
|
|
242
|
+
discounted
|
|
243
|
+
/>
|
|
159
244
|
</div>
|
|
245
|
+
</div>
|
|
246
|
+
);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
if ( isGridPlanOneTimeDiscounted ) {
|
|
250
|
+
return (
|
|
251
|
+
<div className="plans-grid-next-header-price">
|
|
252
|
+
<div className={ pricingBadgeClassName }>{ translate( 'One time discount' ) }</div>
|
|
160
253
|
<div
|
|
161
254
|
className={ clsx( 'plans-grid-next-header-price__pricing-group', {
|
|
162
255
|
'is-large-currency': isLargeCurrency,
|
|
@@ -188,7 +281,7 @@ const HeaderPrice = ( { planSlug, visibleGridPlans }: HeaderPriceProps ) => {
|
|
|
188
281
|
if ( enableTermSavingsPriceDisplay && termVariantPricing && savings ) {
|
|
189
282
|
return (
|
|
190
283
|
<div className="plans-grid-next-header-price">
|
|
191
|
-
<div className=
|
|
284
|
+
<div className={ pricingBadgeClassName }>
|
|
192
285
|
{ translate( 'Save %(savings)d%%', {
|
|
193
286
|
args: { savings },
|
|
194
287
|
comment: 'Example: Save 35%',
|
|
@@ -225,7 +318,16 @@ const HeaderPrice = ( { planSlug, visibleGridPlans }: HeaderPriceProps ) => {
|
|
|
225
318
|
if ( isAnyPlanPriceDiscounted ) {
|
|
226
319
|
return (
|
|
227
320
|
<div className="plans-grid-next-header-price">
|
|
228
|
-
|
|
321
|
+
{ showBillingDescriptionForIncreasedRenewalPrice && savings ? (
|
|
322
|
+
<div className={ pricingBadgeClassName }>
|
|
323
|
+
{ translate( 'Save %(savings)d%%', {
|
|
324
|
+
args: { savings },
|
|
325
|
+
comment: 'Example: Save 35%',
|
|
326
|
+
} ) }
|
|
327
|
+
</div>
|
|
328
|
+
) : (
|
|
329
|
+
<div className={ clsx( pricingBadgeClassName, 'is-hidden' ) }>' '</div>
|
|
330
|
+
) }
|
|
229
331
|
{ isLargeCurrency ? (
|
|
230
332
|
<div className="plans-grid-next-header-price__pricing-group is-large-currency">
|
|
231
333
|
<PlanPrice
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
@import "@automattic/typography/styles/
|
|
1
|
+
@import "@automattic/typography/styles/fonts";
|
|
2
2
|
|
|
3
3
|
.plans-grid-next-header-price {
|
|
4
4
|
padding: 0 20px;
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
|
|
26
26
|
.plan-price__currency-symbol,
|
|
27
27
|
.plan-price__tax-amount {
|
|
28
|
-
color: var(--
|
|
28
|
+
color: var(--studio-gray-20);
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
.plan-price__integer {
|
|
@@ -95,6 +95,12 @@
|
|
|
95
95
|
white-space: nowrap;
|
|
96
96
|
width: fit-content;
|
|
97
97
|
|
|
98
|
+
// Same colors as Badge type="info-green" (@automattic/components); only for pricing differentiators experiment (non-control).
|
|
99
|
+
&.is-plan-differentiators-experiment-badge {
|
|
100
|
+
background-color: rgba(184, 230, 191, 0.64);
|
|
101
|
+
color: var(--studio-green-80);
|
|
102
|
+
}
|
|
103
|
+
|
|
98
104
|
&.is-hidden {
|
|
99
105
|
visibility: hidden;
|
|
100
106
|
}
|
|
@@ -104,7 +110,7 @@
|
|
|
104
110
|
justify-content: flex-end;
|
|
105
111
|
display: flex;
|
|
106
112
|
flex-direction: row-reverse;
|
|
107
|
-
align-items:
|
|
113
|
+
align-items: last baseline;
|
|
108
114
|
gap: 4px;
|
|
109
115
|
|
|
110
116
|
&.is-large-currency {
|
|
@@ -21,7 +21,7 @@ const PlanStorage = ( {
|
|
|
21
21
|
showUpgradeableStorage,
|
|
22
22
|
}: Props ) => {
|
|
23
23
|
const { siteId, gridPlansIndex } = usePlansGridContext();
|
|
24
|
-
const { availableForPurchase, current } = gridPlansIndex[ planSlug ];
|
|
24
|
+
const { availableForPurchase, current, planTitle } = gridPlansIndex[ planSlug ];
|
|
25
25
|
const availableStorageAddOns = AddOns.useAvailableStorageAddOns( { siteId } );
|
|
26
26
|
|
|
27
27
|
if ( ! options?.isTableCell && isWpcomEnterpriseGridPlan( planSlug ) ) {
|
|
@@ -38,7 +38,7 @@ const PlanStorage = ( {
|
|
|
38
38
|
ELIGIBLE_PLANS_FOR_STORAGE_UPGRADE.includes( planSlug );
|
|
39
39
|
|
|
40
40
|
return (
|
|
41
|
-
<div className="plans-grid-next-plan-storage">
|
|
41
|
+
<div className="plans-grid-next-plan-storage" data-plan-title={ planTitle }>
|
|
42
42
|
{ canUpgradeStorageForPlan ? (
|
|
43
43
|
<StorageDropdown planSlug={ planSlug } onStorageAddOnClick={ onStorageAddOnClick } />
|
|
44
44
|
) : (
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable jsx-a11y/tabindex-no-positive */
|
|
1
2
|
import { type AddOnMeta, AddOns, WpcomPlansUI } from '@automattic/data-stores';
|
|
2
3
|
import { CustomSelectControl } from '@wordpress/components';
|
|
3
4
|
import { useDispatch, useSelect } from '@wordpress/data';
|
|
@@ -40,14 +41,19 @@ const StorageDropdownOption = ( {
|
|
|
40
41
|
const addOnStorageString = useStorageString( addOnStorage || 0 );
|
|
41
42
|
|
|
42
43
|
const title = addOnStorage
|
|
43
|
-
? translate( '%(planStorageString)s + %(addOnStorageString)s', {
|
|
44
|
+
? translate( '%(planStorageString)s + %(addOnStorageString)s storage', {
|
|
44
45
|
args: {
|
|
45
46
|
planStorageString,
|
|
46
47
|
addOnStorageString,
|
|
47
48
|
},
|
|
49
|
+
comment: 'Storage option with add-on. Example: "50GB + 100GB storage"',
|
|
48
50
|
} )
|
|
49
|
-
: planStorageString
|
|
51
|
+
: translate( '%(planStorageString)s storage', {
|
|
52
|
+
args: { planStorageString },
|
|
53
|
+
comment: 'Storage option. Example: "50GB storage"',
|
|
54
|
+
} );
|
|
50
55
|
|
|
56
|
+
// Only show price for add-on options, not for the base plan storage
|
|
51
57
|
const priceString =
|
|
52
58
|
price && addOnStorage
|
|
53
59
|
? translate( '%(price)s/month, billed yearly', {
|
|
@@ -55,13 +61,13 @@ const StorageDropdownOption = ( {
|
|
|
55
61
|
comment:
|
|
56
62
|
'The cost of a storage add on per month. Example reads as "$50/month, billed yearly"',
|
|
57
63
|
} )
|
|
58
|
-
:
|
|
64
|
+
: null;
|
|
59
65
|
|
|
60
66
|
return priceOnSeparateLine ? (
|
|
61
67
|
<span className="plans-grid-next-storage-dropdown__option-title">{ title }</span>
|
|
62
68
|
) : (
|
|
63
69
|
<DropdownOption className="plans-grid-next-storage-dropdown__option" title={ title }>
|
|
64
|
-
<div>{ priceString }</div>
|
|
70
|
+
{ priceString && <div>{ priceString }</div> }
|
|
65
71
|
</DropdownOption>
|
|
66
72
|
);
|
|
67
73
|
};
|
|
@@ -137,18 +143,30 @@ const StorageDropdown = ( { planSlug, onStorageAddOnClick }: StorageDropdownProp
|
|
|
137
143
|
);
|
|
138
144
|
const selectedStorageAddOnStorage = selectedStorageAddOn?.quantity ?? 0;
|
|
139
145
|
|
|
146
|
+
const planStorageString = useStorageString( planStorage );
|
|
147
|
+
const selectedAddOnStorageString = useStorageString( selectedStorageAddOnStorage );
|
|
148
|
+
const accessibleOptionName = selectedStorageAddOnStorage
|
|
149
|
+
? translate( '%(planStorageString)s + %(addOnStorageString)s storage', {
|
|
150
|
+
args: {
|
|
151
|
+
planStorageString,
|
|
152
|
+
addOnStorageString: selectedAddOnStorageString,
|
|
153
|
+
},
|
|
154
|
+
comment: 'Storage amount display with add-on. Example: "50GB + 100GB storage"',
|
|
155
|
+
} )
|
|
156
|
+
: translate( '%(planStorageString)s storage', {
|
|
157
|
+
args: { planStorageString },
|
|
158
|
+
comment: 'Storage amount display. Example: "50GB storage"',
|
|
159
|
+
} );
|
|
160
|
+
|
|
140
161
|
const selectedOption = {
|
|
141
162
|
key: selectedStorageOptionForPlan,
|
|
142
|
-
name:
|
|
143
|
-
<StorageDropdownOption
|
|
144
|
-
price={ selectedStorageAddOn?.prices?.formattedMonthlyPrice }
|
|
145
|
-
planStorage={ planStorage }
|
|
146
|
-
addOnStorage={ selectedStorageAddOnStorage }
|
|
147
|
-
priceOnSeparateLine
|
|
148
|
-
/>
|
|
149
|
-
) as unknown as string,
|
|
163
|
+
name: accessibleOptionName as string,
|
|
150
164
|
};
|
|
151
165
|
|
|
166
|
+
const accessibleDescription = translate( 'Currently selected storage option: %(storageOption)s', {
|
|
167
|
+
args: { storageOption: accessibleOptionName },
|
|
168
|
+
} );
|
|
169
|
+
|
|
152
170
|
const handleOnChange = useCallback(
|
|
153
171
|
( { selectedItem }: { selectedItem: { key: string } } ) => {
|
|
154
172
|
const addOnSlug = selectedItem?.key as AddOns.StorageAddOnSlug;
|
|
@@ -162,15 +180,18 @@ const StorageDropdown = ( { planSlug, onStorageAddOnClick }: StorageDropdownProp
|
|
|
162
180
|
);
|
|
163
181
|
|
|
164
182
|
return (
|
|
165
|
-
|
|
183
|
+
// eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex
|
|
184
|
+
<div tabIndex={ 1 }>
|
|
166
185
|
<CustomSelectControl
|
|
167
186
|
__next40pxDefaultSize
|
|
168
187
|
hideLabelFromVision
|
|
169
188
|
options={ selectControlOptions || [] }
|
|
170
189
|
value={ selectedOption }
|
|
171
190
|
onChange={ handleOnChange }
|
|
172
|
-
label=
|
|
191
|
+
label={ translate( 'Storage options for this plan' ) }
|
|
192
|
+
describedBy={ accessibleDescription as string }
|
|
173
193
|
/>
|
|
194
|
+
|
|
174
195
|
{ selectedStorageAddOn?.prices?.formattedMonthlyPrice && (
|
|
175
196
|
<div className="plans-grid-next-storage-dropdown__addon-offset-price-container">
|
|
176
197
|
<span className="plans-grid-next-storage-dropdown__addon-offset-price">
|
|
@@ -180,7 +201,7 @@ const StorageDropdown = ( { planSlug, onStorageAddOnClick }: StorageDropdownProp
|
|
|
180
201
|
</span>
|
|
181
202
|
</div>
|
|
182
203
|
) }
|
|
183
|
-
|
|
204
|
+
</div>
|
|
184
205
|
);
|
|
185
206
|
};
|
|
186
207
|
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { PlanSlug } from '@automattic/calypso-products';
|
|
2
|
+
import { formatCurrency } from '@automattic/number-formatters';
|
|
2
3
|
import clsx from 'clsx';
|
|
3
|
-
import {
|
|
4
|
+
import { useTranslate } from 'i18n-calypso';
|
|
4
5
|
import { usePlansGridContext } from '../../../../grid-context';
|
|
5
6
|
import useIsLargeCurrency from '../../../../hooks/use-is-large-currency';
|
|
6
7
|
import usePlanStorage from '../hooks/use-plan-storage';
|
|
@@ -3,6 +3,7 @@ import {
|
|
|
3
3
|
FEATURE_6GB_STORAGE,
|
|
4
4
|
FEATURE_13GB_STORAGE,
|
|
5
5
|
FEATURE_50GB_STORAGE,
|
|
6
|
+
FEATURE_100GB_STORAGE,
|
|
6
7
|
FEATURE_200GB_STORAGE,
|
|
7
8
|
FEATURE_P2_3GB_STORAGE,
|
|
8
9
|
FEATURE_P2_13GB_STORAGE,
|
|
@@ -27,6 +28,8 @@ function usePlanStorage( planSlug: PlanSlug ) {
|
|
|
27
28
|
return 13;
|
|
28
29
|
case FEATURE_50GB_STORAGE:
|
|
29
30
|
return 50;
|
|
31
|
+
case FEATURE_100GB_STORAGE:
|
|
32
|
+
return 100;
|
|
30
33
|
case FEATURE_P2_3GB_STORAGE:
|
|
31
34
|
return 3;
|
|
32
35
|
case FEATURE_P2_13GB_STORAGE:
|
|
@@ -10,6 +10,7 @@ jest.mock( '@wordpress/data', () => ( {
|
|
|
10
10
|
createReduxStore: jest.fn(),
|
|
11
11
|
createSelector: jest.fn(),
|
|
12
12
|
register: jest.fn(),
|
|
13
|
+
registerStore: jest.fn(),
|
|
13
14
|
useDispatch: jest.fn(),
|
|
14
15
|
} ) );
|
|
15
16
|
jest.mock( '@wordpress/element', () => ( {
|
|
@@ -26,6 +27,10 @@ jest.mock( '@automattic/data-stores', () => ( {
|
|
|
26
27
|
Purchases: {
|
|
27
28
|
useSitePurchasesByProductSlug: jest.fn(),
|
|
28
29
|
},
|
|
30
|
+
Plans: {
|
|
31
|
+
...jest.requireActual( '@automattic/data-stores' ).Plans,
|
|
32
|
+
usePricingMetaForGridPlans: jest.fn(),
|
|
33
|
+
},
|
|
29
34
|
} ) );
|
|
30
35
|
jest.mock( 'i18n-calypso', () => ( {
|
|
31
36
|
...jest.requireActual( 'i18n-calypso' ),
|
|
@@ -34,8 +34,8 @@ import {
|
|
|
34
34
|
PLAN_TRIENNIAL_PERIOD,
|
|
35
35
|
} from '@automattic/calypso-products';
|
|
36
36
|
import { Plans } from '@automattic/data-stores';
|
|
37
|
+
import { formatCurrency } from '@automattic/number-formatters';
|
|
37
38
|
import { render } from '@testing-library/react';
|
|
38
|
-
import { formatCurrency } from 'i18n-calypso';
|
|
39
39
|
import React from 'react';
|
|
40
40
|
import { usePlansGridContext } from '../../grid-context';
|
|
41
41
|
import BillingTimeframe from '../shared/billing-timeframe';
|