@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
|
@@ -3,9 +3,12 @@ import {
|
|
|
3
3
|
FEATURE_GROUP_ESSENTIAL_FEATURES,
|
|
4
4
|
FEATURE_GROUP_PAYMENT_TRANSACTION_FEES,
|
|
5
5
|
getPlans,
|
|
6
|
+
FEATURE_AI_WRITER_DESIGNER,
|
|
7
|
+
FEATURE_AI_WRITER_DESIGNER_LIMITED,
|
|
8
|
+
FEATURE_REALTIME_BACKUPS_JP,
|
|
6
9
|
} from '@automattic/calypso-products';
|
|
7
10
|
import { Gridicon, JetpackLogo } from '@automattic/components';
|
|
8
|
-
import { AddOns
|
|
11
|
+
import { AddOns } from '@automattic/data-stores';
|
|
9
12
|
import { css } from '@emotion/react';
|
|
10
13
|
import styled from '@emotion/styled';
|
|
11
14
|
import { useRef, useMemo } from '@wordpress/element';
|
|
@@ -24,10 +27,10 @@ import {
|
|
|
24
27
|
import { useInView } from 'react-intersection-observer';
|
|
25
28
|
import { plansGridMediumLarge } from '../../css-mixins';
|
|
26
29
|
import PlansGridContextProvider, { usePlansGridContext } from '../../grid-context';
|
|
27
|
-
import usePlanBillingPeriod from '../../hooks/data-store/use-plan-billing-period';
|
|
28
30
|
import useGridSize from '../../hooks/use-grid-size';
|
|
29
31
|
import useHighlightAdjacencyMatrix from '../../hooks/use-highlight-adjacency-matrix';
|
|
30
32
|
import { useManageTooltipToggle } from '../../hooks/use-manage-tooltip-toggle';
|
|
33
|
+
import { useVisibleGridPlans } from '../../hooks/use-visible-grid-plans';
|
|
31
34
|
import filterUnusedFeaturesObject from '../../lib/filter-unused-features-object';
|
|
32
35
|
import getPlanFeaturesObject from '../../lib/get-plan-features-object';
|
|
33
36
|
import PlanTypeSelector from '../plan-type-selector';
|
|
@@ -57,16 +60,37 @@ import type {
|
|
|
57
60
|
} from '@automattic/calypso-products';
|
|
58
61
|
import './style.scss';
|
|
59
62
|
|
|
63
|
+
// Plans Differentiators Experiment: treat feature variants (e.g., _LIMITED) as the same row
|
|
64
|
+
const FEATURE_ALIASES: Record< string, string[] > = {
|
|
65
|
+
[ FEATURE_AI_WRITER_DESIGNER ]: [ FEATURE_AI_WRITER_DESIGNER_LIMITED ],
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
// Finds a matching feature, checking both the base slug and any aliases
|
|
69
|
+
const findFeatureWithAlias = (
|
|
70
|
+
featureSlug: string | undefined,
|
|
71
|
+
planFeatures: { getSlug: () => string }[]
|
|
72
|
+
) => {
|
|
73
|
+
if ( ! featureSlug ) {
|
|
74
|
+
return undefined;
|
|
75
|
+
}
|
|
76
|
+
const slugsToCheck = [ featureSlug, ...( FEATURE_ALIASES[ featureSlug ] ?? [] ) ];
|
|
77
|
+
return planFeatures.find( ( f ) => slugsToCheck.includes( f.getSlug() ) );
|
|
78
|
+
};
|
|
79
|
+
|
|
60
80
|
const featureGroupRowTitleCellMaxWidth = 450;
|
|
61
81
|
const rowCellMaxWidth = 290;
|
|
62
82
|
|
|
63
83
|
const JetpackIconContainer = styled.div`
|
|
64
|
-
padding-inline-start:
|
|
84
|
+
padding-inline-start: 3px;
|
|
65
85
|
display: inline-block;
|
|
66
86
|
vertical-align: middle;
|
|
67
87
|
line-height: 1;
|
|
68
88
|
`;
|
|
69
89
|
|
|
90
|
+
const TitlePreventOrphans = styled.span`
|
|
91
|
+
white-space: nowrap;
|
|
92
|
+
`;
|
|
93
|
+
|
|
70
94
|
const Title = styled.div< { isHiddenInMobile?: boolean } >`
|
|
71
95
|
font-weight: 500;
|
|
72
96
|
font-size: 20px;
|
|
@@ -97,11 +121,10 @@ const Title = styled.div< { isHiddenInMobile?: boolean } >`
|
|
|
97
121
|
` ) }
|
|
98
122
|
`;
|
|
99
123
|
|
|
100
|
-
const
|
|
124
|
+
const StickyGrid = styled( StickyContainer )< { visiblePlans: number } >`
|
|
101
125
|
display: grid;
|
|
102
126
|
margin: 0 auto;
|
|
103
127
|
background: #fff;
|
|
104
|
-
border: solid 1px #e0e0e0;
|
|
105
128
|
${ ( props ) =>
|
|
106
129
|
props.visiblePlans &&
|
|
107
130
|
css`
|
|
@@ -111,11 +134,21 @@ const Grid = styled.div< { visiblePlans: number } >`
|
|
|
111
134
|
${ plansGridMediumLarge( css`
|
|
112
135
|
border-radius: 5px;
|
|
113
136
|
` ) }
|
|
137
|
+
`;
|
|
114
138
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
139
|
+
const Grid = styled.div< { visiblePlans: number; as?: string } >`
|
|
140
|
+
display: ${ ( props ) => ( props.as === 'tbody' ? 'table-row-group' : 'grid' ) };
|
|
141
|
+
margin: 0 auto;
|
|
142
|
+
background: #fff;
|
|
143
|
+
${ ( props ) =>
|
|
144
|
+
props.visiblePlans &&
|
|
145
|
+
css`
|
|
146
|
+
max-width: ${ rowCellMaxWidth * props.visiblePlans + featureGroupRowTitleCellMaxWidth }px;
|
|
147
|
+
` }
|
|
148
|
+
|
|
149
|
+
${ plansGridMediumLarge( css`
|
|
150
|
+
border-radius: 5px;
|
|
151
|
+
` ) }
|
|
119
152
|
`;
|
|
120
153
|
|
|
121
154
|
const Row = styled.div< {
|
|
@@ -219,7 +252,7 @@ const Cell = styled.div< { textAlign?: 'start' | 'center' | 'end' } >`
|
|
|
219
252
|
border-right: none;
|
|
220
253
|
justify-content: center;
|
|
221
254
|
|
|
222
|
-
&:first-of-type {
|
|
255
|
+
&:first-of-type:not( .popular-plan-parent-class ) {
|
|
223
256
|
padding-inline-start: 0;
|
|
224
257
|
}
|
|
225
258
|
&:last-of-type {
|
|
@@ -233,7 +266,27 @@ const Cell = styled.div< { textAlign?: 'start' | 'center' | 'end' } >`
|
|
|
233
266
|
` ) }
|
|
234
267
|
`;
|
|
235
268
|
|
|
236
|
-
const RowTitleCell = styled.
|
|
269
|
+
const RowTitleCell = styled.td< {
|
|
270
|
+
isPlaceholderHeaderCell?: boolean;
|
|
271
|
+
isFeatureGroupRowTitleCell?: boolean;
|
|
272
|
+
} >`
|
|
273
|
+
display: none;
|
|
274
|
+
font-size: 14px;
|
|
275
|
+
padding-right: 10px;
|
|
276
|
+
${ plansGridMediumLarge( css`
|
|
277
|
+
display: block;
|
|
278
|
+
flex: 1;
|
|
279
|
+
min-width: 290px;
|
|
280
|
+
` ) }
|
|
281
|
+
max-width: ${ ( props ) => {
|
|
282
|
+
if ( props.isPlaceholderHeaderCell || props.isFeatureGroupRowTitleCell ) {
|
|
283
|
+
return `${ featureGroupRowTitleCellMaxWidth }px`;
|
|
284
|
+
}
|
|
285
|
+
return `${ rowCellMaxWidth }px`;
|
|
286
|
+
} };
|
|
287
|
+
`;
|
|
288
|
+
|
|
289
|
+
const RowHeaderCell = styled.th< {
|
|
237
290
|
isPlaceholderHeaderCell?: boolean;
|
|
238
291
|
isFeatureGroupRowTitleCell?: boolean;
|
|
239
292
|
} >`
|
|
@@ -362,7 +415,7 @@ const ComparisonGridHeaderCell = ( {
|
|
|
362
415
|
showRefundPeriod,
|
|
363
416
|
isStuck,
|
|
364
417
|
}: ComparisonGridHeaderCellProps ) => {
|
|
365
|
-
const { gridPlansIndex } = usePlansGridContext();
|
|
418
|
+
const { gridPlansIndex, showBillingDescriptionForIncreasedRenewalPrice } = usePlansGridContext();
|
|
366
419
|
const gridPlan = gridPlansIndex[ planSlug ];
|
|
367
420
|
const highlightAdjacencyMatrix = useHighlightAdjacencyMatrix( {
|
|
368
421
|
renderedGridPlans: visibleGridPlans,
|
|
@@ -389,7 +442,13 @@ const ComparisonGridHeaderCell = ( {
|
|
|
389
442
|
const showPlanSelect = ! allVisible && ! gridPlan.current;
|
|
390
443
|
|
|
391
444
|
return (
|
|
392
|
-
<Cell
|
|
445
|
+
<Cell
|
|
446
|
+
as="th"
|
|
447
|
+
className={ headerClasses }
|
|
448
|
+
textAlign="start"
|
|
449
|
+
{ ...{ scope: 'col' } }
|
|
450
|
+
aria-label={ gridPlan.planTitle as string }
|
|
451
|
+
>
|
|
393
452
|
<PopularBadge
|
|
394
453
|
isInSignup={ isInSignup }
|
|
395
454
|
planSlug={ planSlug }
|
|
@@ -449,6 +508,7 @@ const ComparisonGridHeaderCell = ( {
|
|
|
449
508
|
showMonthlyPrice={ false }
|
|
450
509
|
isStuck={ false }
|
|
451
510
|
visibleGridPlans={ visibleGridPlans }
|
|
511
|
+
showPostButtonText={ showBillingDescriptionForIncreasedRenewalPrice ? false : true }
|
|
452
512
|
/>
|
|
453
513
|
</Cell>
|
|
454
514
|
);
|
|
@@ -484,7 +544,7 @@ const ComparisonGridHeader = forwardRef< HTMLDivElement, ComparisonGridHeaderPro
|
|
|
484
544
|
const { coupon } = usePlansGridContext();
|
|
485
545
|
|
|
486
546
|
return (
|
|
487
|
-
<PlanRow isHiddenInMobile={ isHiddenInMobile } ref={ ref }>
|
|
547
|
+
<PlanRow as="tr" isHiddenInMobile={ isHiddenInMobile } ref={ ref }>
|
|
488
548
|
<RowTitleCell
|
|
489
549
|
key="feature-name"
|
|
490
550
|
className="plan-comparison-grid__header-cell is-placeholder-header-cell"
|
|
@@ -525,6 +585,7 @@ const ComparisonGridHeader = forwardRef< HTMLDivElement, ComparisonGridHeaderPro
|
|
|
525
585
|
);
|
|
526
586
|
}
|
|
527
587
|
);
|
|
588
|
+
ComparisonGridHeader.displayName = 'ComparisonGridHeader';
|
|
528
589
|
|
|
529
590
|
const ComparisonGridFeatureGroupRowCell: React.FunctionComponent< {
|
|
530
591
|
feature?: FeatureObject;
|
|
@@ -560,19 +621,23 @@ const ComparisonGridFeatureGroupRowCell: React.FunctionComponent< {
|
|
|
560
621
|
}
|
|
561
622
|
|
|
562
623
|
const featureSlug = feature?.getSlug();
|
|
624
|
+
const comparisonGridTitle =
|
|
625
|
+
featureSlug === FEATURE_REALTIME_BACKUPS_JP
|
|
626
|
+
? translate( 'Real-time backups', { textOnly: true } )
|
|
627
|
+
: feature?.getAlternativeTitle?.() || feature?.getTitle();
|
|
628
|
+
|
|
629
|
+
const planFeatures = [
|
|
630
|
+
...gridPlan.features.wpcomFeatures,
|
|
631
|
+
...gridPlan.features.jetpackFeatures,
|
|
632
|
+
].filter( ( feature ) =>
|
|
633
|
+
'monthly' === intervalType ? ! feature.availableOnlyForAnnualPlans : true
|
|
634
|
+
);
|
|
563
635
|
|
|
564
|
-
const
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
'monthly' === intervalType ? ! feature.availableOnlyForAnnualPlans : true
|
|
570
|
-
)
|
|
571
|
-
.some( ( feature ) => feature.getSlug() === featureSlug )
|
|
572
|
-
: false );
|
|
573
|
-
|
|
574
|
-
const featureLabel = featureSlug
|
|
575
|
-
? gridPlan?.features?.comparisonGridFeatureLabels?.[ featureSlug ]
|
|
636
|
+
const matchingFeature = findFeatureWithAlias( featureSlug, planFeatures );
|
|
637
|
+
const hasFeature = isStorageFeature || !! matchingFeature;
|
|
638
|
+
const featureLabelSlug = matchingFeature?.getSlug() ?? featureSlug;
|
|
639
|
+
const featureLabel = featureLabelSlug
|
|
640
|
+
? gridPlan?.features?.comparisonGridFeatureLabels?.[ featureLabelSlug ]
|
|
576
641
|
: undefined;
|
|
577
642
|
|
|
578
643
|
const cellClasses = clsx(
|
|
@@ -595,7 +660,7 @@ const ComparisonGridFeatureGroupRowCell: React.FunctionComponent< {
|
|
|
595
660
|
);
|
|
596
661
|
|
|
597
662
|
return (
|
|
598
|
-
<Cell className={ cellClasses } textAlign="center">
|
|
663
|
+
<Cell as="td" className={ cellClasses } textAlign="center">
|
|
599
664
|
{ isStorageFeature ? (
|
|
600
665
|
<>
|
|
601
666
|
<span className="plan-comparison-grid__plan-title">{ translate( 'Storage' ) }</span>
|
|
@@ -618,7 +683,7 @@ const ComparisonGridFeatureGroupRowCell: React.FunctionComponent< {
|
|
|
618
683
|
id={ `${ planSlug }-${ featureSlug }` }
|
|
619
684
|
>
|
|
620
685
|
<span className="plan-comparison-grid__plan-title">
|
|
621
|
-
{
|
|
686
|
+
{ comparisonGridTitle }
|
|
622
687
|
</span>
|
|
623
688
|
</Plans2023Tooltip>
|
|
624
689
|
<span className="plan-comparison-grid__plan-conditional-title">
|
|
@@ -643,9 +708,7 @@ const ComparisonGridFeatureGroupRowCell: React.FunctionComponent< {
|
|
|
643
708
|
activeTooltipId={ activeTooltipId }
|
|
644
709
|
id={ `${ planSlug }-${ featureSlug }` }
|
|
645
710
|
>
|
|
646
|
-
<span className="plan-comparison-grid__plan-title">
|
|
647
|
-
{ feature?.getAlternativeTitle?.() || feature?.getTitle() }
|
|
648
|
-
</span>
|
|
711
|
+
<span className="plan-comparison-grid__plan-title">{ comparisonGridTitle }</span>
|
|
649
712
|
</Plans2023Tooltip>
|
|
650
713
|
{ feature?.getCompareTitle && (
|
|
651
714
|
<span className="plan-comparison-grid__plan-subtitle">
|
|
@@ -663,9 +726,19 @@ const ComparisonGridFeatureGroupRowCell: React.FunctionComponent< {
|
|
|
663
726
|
</span>
|
|
664
727
|
) }
|
|
665
728
|
{ hasFeature && ! featureLabel && (
|
|
666
|
-
<Gridicon
|
|
729
|
+
<Gridicon
|
|
730
|
+
icon="checkmark"
|
|
731
|
+
color="var(--studio-wordpress-blue-50)"
|
|
732
|
+
aria-label={ translate( 'Feature available' ) }
|
|
733
|
+
/>
|
|
734
|
+
) }
|
|
735
|
+
{ ! hasFeature && ! featureLabel && (
|
|
736
|
+
<Gridicon
|
|
737
|
+
icon="minus-small"
|
|
738
|
+
color="#C3C4C7"
|
|
739
|
+
aria-label={ translate( 'Feature not available' ) }
|
|
740
|
+
/>
|
|
667
741
|
) }
|
|
668
|
-
{ ! hasFeature && ! featureLabel && <Gridicon icon="minus-small" color="#C3C4C7" /> }
|
|
669
742
|
</>
|
|
670
743
|
) }
|
|
671
744
|
</>
|
|
@@ -676,6 +749,7 @@ const ComparisonGridFeatureGroupRowCell: React.FunctionComponent< {
|
|
|
676
749
|
|
|
677
750
|
const ComparisonGridFeatureGroupRow: React.FunctionComponent< {
|
|
678
751
|
feature?: FeatureObject | TransformedFeatureObject;
|
|
752
|
+
featureGroupSlug: string;
|
|
679
753
|
isHiddenInMobile: boolean;
|
|
680
754
|
allJetpackFeatures: Set< string >;
|
|
681
755
|
visibleGridPlans: GridPlan[];
|
|
@@ -689,6 +763,7 @@ const ComparisonGridFeatureGroupRow: React.FunctionComponent< {
|
|
|
689
763
|
onStorageAddOnClick?: ( addOnSlug: AddOns.StorageAddOnSlug ) => void;
|
|
690
764
|
} > = ( {
|
|
691
765
|
feature,
|
|
766
|
+
featureGroupSlug,
|
|
692
767
|
isHiddenInMobile,
|
|
693
768
|
allJetpackFeatures,
|
|
694
769
|
visibleGridPlans,
|
|
@@ -707,20 +782,29 @@ const ComparisonGridFeatureGroupRow: React.FunctionComponent< {
|
|
|
707
782
|
} );
|
|
708
783
|
const featureSlug = feature?.getSlug() ?? '';
|
|
709
784
|
const footnote = planFeatureFootnotes?.footnotesByFeature?.[ featureSlug ];
|
|
710
|
-
const tooltipId = `${ feature?.getSlug() }-comparison-grid`;
|
|
785
|
+
const tooltipId = `${ featureGroupSlug }-${ feature?.getSlug() }-comparison-grid`;
|
|
786
|
+
const title =
|
|
787
|
+
featureSlug === FEATURE_REALTIME_BACKUPS_JP
|
|
788
|
+
? // Always display the short title for backups in comparison grid.
|
|
789
|
+
translate( 'Real-time backups', { textOnly: true } )
|
|
790
|
+
: feature?.getTitle?.();
|
|
791
|
+
const headerAriaLabel: string = typeof title === 'string' ? title : '';
|
|
711
792
|
|
|
712
793
|
const { enableFeatureTooltips } = usePlansGridContext();
|
|
713
794
|
|
|
714
795
|
return (
|
|
715
796
|
<Row
|
|
797
|
+
as="tr"
|
|
716
798
|
isHiddenInMobile={ isHiddenInMobile }
|
|
717
799
|
className={ rowClasses }
|
|
718
800
|
isHighlighted={ isHighlighted }
|
|
719
801
|
>
|
|
720
|
-
<
|
|
802
|
+
<RowHeaderCell
|
|
721
803
|
key="feature-name"
|
|
722
804
|
className="is-feature-group-row-title-cell"
|
|
723
805
|
isFeatureGroupRowTitleCell
|
|
806
|
+
scope="row"
|
|
807
|
+
aria-label={ headerAriaLabel }
|
|
724
808
|
>
|
|
725
809
|
{ isStorageFeature ? (
|
|
726
810
|
<Plans2023Tooltip
|
|
@@ -745,32 +829,52 @@ const ComparisonGridFeatureGroupRow: React.FunctionComponent< {
|
|
|
745
829
|
activeTooltipId={ activeTooltipId }
|
|
746
830
|
id={ tooltipId }
|
|
747
831
|
>
|
|
748
|
-
{
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
832
|
+
{ typeof title === 'string' ? (
|
|
833
|
+
<>
|
|
834
|
+
{ title.split( ' ' ).slice( 0, -1 ).join( ' ' ) }
|
|
835
|
+
{ title.includes( ' ' ) ? ' ' : null }
|
|
836
|
+
<TitlePreventOrphans>
|
|
837
|
+
{ title.split( ' ' ).slice( -1 ) }
|
|
838
|
+
{ footnote && (
|
|
839
|
+
<FeatureFootnote>
|
|
840
|
+
<sup>{ footnote }</sup>
|
|
841
|
+
</FeatureFootnote>
|
|
842
|
+
) }
|
|
843
|
+
{ allJetpackFeatures.has( feature.getSlug() ) ? (
|
|
844
|
+
<>
|
|
845
|
+
{ '\u00A0' }
|
|
846
|
+
<JetpackIconContainer>
|
|
847
|
+
<Plans2023Tooltip
|
|
848
|
+
text={ translate(
|
|
849
|
+
'Security, performance, and growth tools—powered by Jetpack.'
|
|
850
|
+
) }
|
|
851
|
+
setActiveTooltipId={ setActiveTooltipId }
|
|
852
|
+
activeTooltipId={ activeTooltipId }
|
|
853
|
+
id={ `jp-${ tooltipId }` }
|
|
854
|
+
>
|
|
855
|
+
<JetpackLogo size={ 16 } />
|
|
856
|
+
</Plans2023Tooltip>
|
|
857
|
+
</JetpackIconContainer>
|
|
858
|
+
</>
|
|
859
|
+
) : null }
|
|
860
|
+
</TitlePreventOrphans>
|
|
861
|
+
</>
|
|
862
|
+
) : (
|
|
863
|
+
<>
|
|
864
|
+
{ feature.getTitle() }
|
|
865
|
+
{ footnote && (
|
|
866
|
+
<FeatureFootnote>
|
|
867
|
+
<sup>{ footnote }</sup>
|
|
868
|
+
</FeatureFootnote>
|
|
869
|
+
) }
|
|
870
|
+
</>
|
|
753
871
|
) }
|
|
754
872
|
</Plans2023Tooltip>
|
|
755
|
-
{ allJetpackFeatures.has( feature.getSlug() ) ? (
|
|
756
|
-
<JetpackIconContainer>
|
|
757
|
-
<Plans2023Tooltip
|
|
758
|
-
text={ translate(
|
|
759
|
-
'Security, performance, and growth tools—powered by Jetpack.'
|
|
760
|
-
) }
|
|
761
|
-
setActiveTooltipId={ setActiveTooltipId }
|
|
762
|
-
activeTooltipId={ activeTooltipId }
|
|
763
|
-
id={ `jp-${ tooltipId }` }
|
|
764
|
-
>
|
|
765
|
-
<JetpackLogo size={ 16 } />
|
|
766
|
-
</Plans2023Tooltip>
|
|
767
|
-
</JetpackIconContainer>
|
|
768
|
-
) : null }
|
|
769
873
|
</>
|
|
770
874
|
) }
|
|
771
875
|
</>
|
|
772
876
|
) }
|
|
773
|
-
</
|
|
877
|
+
</RowHeaderCell>
|
|
774
878
|
{ visibleGridPlans.map( ( { planSlug } ) => (
|
|
775
879
|
<ComparisonGridFeatureGroupRowCell
|
|
776
880
|
key={ planSlug }
|
|
@@ -801,6 +905,7 @@ const FeatureGroup = ( {
|
|
|
801
905
|
featureGroupMap,
|
|
802
906
|
visibleGridPlans,
|
|
803
907
|
planFeatureFootnotes,
|
|
908
|
+
plansLength,
|
|
804
909
|
}: {
|
|
805
910
|
featureGroup: FeatureGroup;
|
|
806
911
|
selectedFeature?: string;
|
|
@@ -815,17 +920,20 @@ const FeatureGroup = ( {
|
|
|
815
920
|
footnoteList: string[];
|
|
816
921
|
footnotesByFeature: Record< string, number >;
|
|
817
922
|
};
|
|
923
|
+
plansLength: number;
|
|
818
924
|
} ) => {
|
|
819
|
-
const { allFeaturesList } = usePlansGridContext();
|
|
925
|
+
const { allFeaturesList, isExperimentVariant } = usePlansGridContext();
|
|
820
926
|
const [ firstSetOfFeatures ] = Object.keys( featureGroupMap );
|
|
821
927
|
const [ visibleFeatureGroups, setVisibleFeatureGroups ] = useState< string[] >( [
|
|
822
928
|
firstSetOfFeatures,
|
|
823
929
|
] );
|
|
824
930
|
const features = featureGroup.getFeatures();
|
|
931
|
+
|
|
825
932
|
const featureObjects = filterUnusedFeaturesObject(
|
|
826
933
|
visibleGridPlans,
|
|
827
|
-
getPlanFeaturesObject( allFeaturesList, features )
|
|
934
|
+
getPlanFeaturesObject( allFeaturesList, features, isExperimentVariant )
|
|
828
935
|
);
|
|
936
|
+
|
|
829
937
|
const isHiddenInMobile = ! visibleFeatureGroups.includes( featureGroup.slug );
|
|
830
938
|
|
|
831
939
|
const allJetpackFeatures = useMemo( () => {
|
|
@@ -871,12 +979,18 @@ const FeatureGroup = ( {
|
|
|
871
979
|
}
|
|
872
980
|
|
|
873
981
|
return (
|
|
874
|
-
<
|
|
982
|
+
<Grid
|
|
983
|
+
as="tbody"
|
|
984
|
+
visiblePlans={ plansLength }
|
|
985
|
+
key={ featureGroup.slug }
|
|
986
|
+
className="plan-comparison-grid__feature-group"
|
|
987
|
+
>
|
|
875
988
|
<TitleRow
|
|
989
|
+
as="tr"
|
|
876
990
|
className="plan-comparison-grid__feature-group-title-row"
|
|
877
991
|
onClick={ handleFeatureGroupToggle }
|
|
878
992
|
>
|
|
879
|
-
<Title isHiddenInMobile={ isHiddenInMobile }>
|
|
993
|
+
<Title as="td" isHiddenInMobile={ isHiddenInMobile }>
|
|
880
994
|
<Gridicon icon="chevron-up" size={ 12 } color="#1E1E1E" />
|
|
881
995
|
<span>{ featureGroup.getTitle() }</span>
|
|
882
996
|
</Title>
|
|
@@ -885,6 +999,7 @@ const FeatureGroup = ( {
|
|
|
885
999
|
<ComparisonGridFeatureGroupRow
|
|
886
1000
|
key={ feature.getSlug() }
|
|
887
1001
|
feature={ feature }
|
|
1002
|
+
featureGroupSlug={ featureGroup.slug }
|
|
888
1003
|
isHiddenInMobile={ isHiddenInMobile }
|
|
889
1004
|
allJetpackFeatures={ allJetpackFeatures }
|
|
890
1005
|
visibleGridPlans={ visibleGridPlans }
|
|
@@ -901,6 +1016,7 @@ const FeatureGroup = ( {
|
|
|
901
1016
|
{ featureGroup.slug === FEATURE_GROUP_ESSENTIAL_FEATURES ? (
|
|
902
1017
|
<ComparisonGridFeatureGroupRow
|
|
903
1018
|
key="feature-storage"
|
|
1019
|
+
featureGroupSlug={ featureGroup.slug }
|
|
904
1020
|
isHiddenInMobile={ isHiddenInMobile }
|
|
905
1021
|
allJetpackFeatures={ allJetpackFeatures }
|
|
906
1022
|
visibleGridPlans={ visibleGridPlans }
|
|
@@ -914,7 +1030,7 @@ const FeatureGroup = ( {
|
|
|
914
1030
|
onStorageAddOnClick={ onStorageAddOnClick }
|
|
915
1031
|
/>
|
|
916
1032
|
) : null }
|
|
917
|
-
</
|
|
1033
|
+
</Grid>
|
|
918
1034
|
);
|
|
919
1035
|
};
|
|
920
1036
|
|
|
@@ -932,88 +1048,21 @@ const ComparisonGrid = ( {
|
|
|
932
1048
|
planTypeSelectorProps,
|
|
933
1049
|
gridSize,
|
|
934
1050
|
siteId,
|
|
1051
|
+
onVisiblePlansCountChange,
|
|
935
1052
|
}: ComparisonGridProps ) => {
|
|
936
|
-
const { gridPlans,
|
|
1053
|
+
const { gridPlans, featureGroupMap } = usePlansGridContext();
|
|
937
1054
|
const [ activeTooltipId, setActiveTooltipId ] = useManageTooltipToggle();
|
|
938
|
-
const [ visiblePlans, setVisiblePlans ] = useState< PlanSlug[] >( [] );
|
|
939
|
-
const currentPlanTerm = Plans.useCurrentPlanTerm( { siteId } );
|
|
940
|
-
const selectedPlanTerm = usePlanBillingPeriod( { intervalType } );
|
|
941
|
-
|
|
942
|
-
useEffect( () => {
|
|
943
|
-
let numPlansToDisplay = gridPlans.length;
|
|
944
|
-
|
|
945
|
-
switch ( gridSize ) {
|
|
946
|
-
case 'large':
|
|
947
|
-
numPlansToDisplay = 4;
|
|
948
|
-
break;
|
|
949
|
-
case 'medium':
|
|
950
|
-
numPlansToDisplay = 3;
|
|
951
|
-
break;
|
|
952
|
-
case 'smedium':
|
|
953
|
-
case 'small':
|
|
954
|
-
numPlansToDisplay = 2;
|
|
955
|
-
break;
|
|
956
|
-
}
|
|
957
1055
|
|
|
958
|
-
|
|
959
|
-
.slice( 0, numPlansToDisplay )
|
|
960
|
-
.map( ( { planSlug } ) => planSlug );
|
|
961
|
-
|
|
962
|
-
const isCurrentPlanVisible =
|
|
963
|
-
!! currentSitePlanSlug && visiblePlanSlugs.includes( currentSitePlanSlug );
|
|
964
|
-
|
|
965
|
-
/**
|
|
966
|
-
* Plans are sorted by least to most expensive unless:
|
|
967
|
-
* - a current plan exists and
|
|
968
|
-
* - the current plan's term matches the selected term and
|
|
969
|
-
* - the current plan would not be displayed due to the number of plans that can be visible at once
|
|
970
|
-
*
|
|
971
|
-
* If those conditions are met:
|
|
972
|
-
* - the current plan is placed at the start of the grid and
|
|
973
|
-
* - the last plan is removed to maintain the expected number of visible plans
|
|
974
|
-
*/
|
|
975
|
-
if ( currentSitePlanSlug && ! isCurrentPlanVisible && currentPlanTerm === selectedPlanTerm ) {
|
|
976
|
-
visiblePlanSlugs = [ currentSitePlanSlug, ...visiblePlanSlugs ].slice( 0, numPlansToDisplay );
|
|
977
|
-
}
|
|
978
|
-
|
|
979
|
-
setVisiblePlans( visiblePlanSlugs );
|
|
980
|
-
}, [
|
|
1056
|
+
const { visibleGridPlans, setVisibleGridPlans } = useVisibleGridPlans( {
|
|
981
1057
|
gridSize,
|
|
982
|
-
gridPlansIndex,
|
|
983
1058
|
currentSitePlanSlug,
|
|
984
|
-
|
|
985
|
-
currentPlanTerm,
|
|
986
|
-
selectedPlanTerm,
|
|
1059
|
+
siteId,
|
|
987
1060
|
intervalType,
|
|
988
|
-
|
|
989
|
-
|
|
990
|
-
const visibleGridPlans = useMemo(
|
|
991
|
-
() =>
|
|
992
|
-
visiblePlans.reduce( ( acc, planSlug ) => {
|
|
993
|
-
const gridPlan = gridPlans.find(
|
|
994
|
-
( gridPlan ) => getPlanClass( gridPlan.planSlug ) === getPlanClass( planSlug )
|
|
995
|
-
);
|
|
996
|
-
|
|
997
|
-
if ( gridPlan ) {
|
|
998
|
-
acc.push( gridPlan );
|
|
999
|
-
}
|
|
1000
|
-
|
|
1001
|
-
return acc;
|
|
1002
|
-
}, [] as GridPlan[] ),
|
|
1003
|
-
[ visiblePlans, gridPlans ]
|
|
1004
|
-
);
|
|
1005
|
-
|
|
1006
|
-
const onPlanChange = useCallback(
|
|
1007
|
-
( currentPlan: PlanSlug, event: ChangeEvent< HTMLSelectElement > ) => {
|
|
1008
|
-
const newPlan = event.currentTarget.value;
|
|
1009
|
-
const newVisiblePlans = visiblePlans.map( ( plan ) =>
|
|
1010
|
-
plan === currentPlan ? ( newPlan as PlanSlug ) : plan
|
|
1011
|
-
);
|
|
1061
|
+
} );
|
|
1012
1062
|
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1016
|
-
);
|
|
1063
|
+
useEffect( () => {
|
|
1064
|
+
onVisiblePlansCountChange?.( visibleGridPlans.length );
|
|
1065
|
+
}, [ visibleGridPlans.length, onVisiblePlansCountChange ] );
|
|
1017
1066
|
|
|
1018
1067
|
const planFeatureFootnotes = useMemo( () => {
|
|
1019
1068
|
// This is the main list of all footnotes. It is displayed at the bottom of the comparison grid.
|
|
@@ -1048,6 +1097,20 @@ const ComparisonGrid = ( {
|
|
|
1048
1097
|
};
|
|
1049
1098
|
}, [ featureGroupMap ] );
|
|
1050
1099
|
|
|
1100
|
+
const onPlanChange = useCallback(
|
|
1101
|
+
( currentPlan: PlanSlug, event: ChangeEvent< HTMLSelectElement > ) => {
|
|
1102
|
+
const newPlanSlug = event.currentTarget.value;
|
|
1103
|
+
const newPlan = gridPlans.find( ( plan ) => plan.planSlug === newPlanSlug );
|
|
1104
|
+
|
|
1105
|
+
if ( newPlan ) {
|
|
1106
|
+
setVisibleGridPlans( ( previousGridPlans ) =>
|
|
1107
|
+
previousGridPlans.map( ( plan ) => ( plan.planSlug === currentPlan ? newPlan : plan ) )
|
|
1108
|
+
);
|
|
1109
|
+
}
|
|
1110
|
+
},
|
|
1111
|
+
[ gridPlans, setVisibleGridPlans ]
|
|
1112
|
+
);
|
|
1113
|
+
|
|
1051
1114
|
// 100px is the padding of the footer row
|
|
1052
1115
|
const [ bottomHeaderRef, isBottomHeaderInView ] = useInView( { rootMargin: '-100px' } );
|
|
1053
1116
|
|
|
@@ -1062,44 +1125,47 @@ const ComparisonGrid = ( {
|
|
|
1062
1125
|
} );
|
|
1063
1126
|
|
|
1064
1127
|
return (
|
|
1065
|
-
<
|
|
1066
|
-
<
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
isInSignup={ isInSignup }
|
|
1078
|
-
onPlanChange={ onPlanChange }
|
|
1079
|
-
currentSitePlanSlug={ currentSitePlanSlug }
|
|
1080
|
-
planActionOverrides={ planActionOverrides }
|
|
1081
|
-
selectedPlan={ selectedPlan }
|
|
1082
|
-
showRefundPeriod={ showRefundPeriod }
|
|
1083
|
-
isStuck={ isStuck }
|
|
1084
|
-
planTypeSelectorProps={ planTypeSelectorProps }
|
|
1085
|
-
/>
|
|
1086
|
-
) }
|
|
1087
|
-
</StickyContainer>
|
|
1088
|
-
{ Object.values( featureGroupMap ).map( ( featureGroup: FeatureGroup ) => (
|
|
1089
|
-
<FeatureGroup
|
|
1090
|
-
key={ featureGroup.slug }
|
|
1091
|
-
featureGroup={ featureGroup }
|
|
1128
|
+
<table className={ classes }>
|
|
1129
|
+
<StickyGrid
|
|
1130
|
+
visiblePlans={ visibleGridPlans.length }
|
|
1131
|
+
element="thead"
|
|
1132
|
+
disabled={ isBottomHeaderInView }
|
|
1133
|
+
stickyClass="is-sticky-header-row"
|
|
1134
|
+
stickyOffset={ stickyRowOffset }
|
|
1135
|
+
zIndex={ 1 }
|
|
1136
|
+
>
|
|
1137
|
+
{ ( isStuck: boolean ) => (
|
|
1138
|
+
<ComparisonGridHeader
|
|
1139
|
+
displayedGridPlans={ gridPlans }
|
|
1092
1140
|
visibleGridPlans={ visibleGridPlans }
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1141
|
+
isInSignup={ isInSignup }
|
|
1142
|
+
onPlanChange={ onPlanChange }
|
|
1143
|
+
currentSitePlanSlug={ currentSitePlanSlug }
|
|
1144
|
+
planActionOverrides={ planActionOverrides }
|
|
1145
|
+
selectedPlan={ selectedPlan }
|
|
1146
|
+
showRefundPeriod={ showRefundPeriod }
|
|
1147
|
+
isStuck={ isStuck }
|
|
1148
|
+
planTypeSelectorProps={ planTypeSelectorProps }
|
|
1101
1149
|
/>
|
|
1102
|
-
)
|
|
1150
|
+
) }
|
|
1151
|
+
</StickyGrid>
|
|
1152
|
+
{ Object.values( featureGroupMap ).map( ( featureGroup: FeatureGroup ) => (
|
|
1153
|
+
<FeatureGroup
|
|
1154
|
+
key={ featureGroup.slug }
|
|
1155
|
+
featureGroup={ featureGroup }
|
|
1156
|
+
visibleGridPlans={ visibleGridPlans }
|
|
1157
|
+
featureGroupMap={ featureGroupMap }
|
|
1158
|
+
selectedFeature={ selectedFeature }
|
|
1159
|
+
intervalType={ intervalType }
|
|
1160
|
+
activeTooltipId={ activeTooltipId }
|
|
1161
|
+
setActiveTooltipId={ setActiveTooltipId }
|
|
1162
|
+
showUpgradeableStorage={ showUpgradeableStorage }
|
|
1163
|
+
onStorageAddOnClick={ onStorageAddOnClick }
|
|
1164
|
+
planFeatureFootnotes={ planFeatureFootnotes }
|
|
1165
|
+
plansLength={ visibleGridPlans.length }
|
|
1166
|
+
/>
|
|
1167
|
+
) ) }
|
|
1168
|
+
<tbody>
|
|
1103
1169
|
<ComparisonGridHeader
|
|
1104
1170
|
displayedGridPlans={ gridPlans }
|
|
1105
1171
|
visibleGridPlans={ visibleGridPlans }
|
|
@@ -1115,20 +1181,22 @@ const ComparisonGrid = ( {
|
|
|
1115
1181
|
ref={ bottomHeaderRef }
|
|
1116
1182
|
planTypeSelectorProps={ planTypeSelectorProps }
|
|
1117
1183
|
/>
|
|
1118
|
-
</
|
|
1184
|
+
</tbody>
|
|
1119
1185
|
|
|
1120
|
-
<
|
|
1186
|
+
<tfoot className="plan-comparison-grid__footer">
|
|
1121
1187
|
{ planFeatureFootnotes?.footnoteList && (
|
|
1122
|
-
<FeatureFootnotes>
|
|
1123
|
-
<
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1188
|
+
<FeatureFootnotes as="tr">
|
|
1189
|
+
<td>
|
|
1190
|
+
<ol>
|
|
1191
|
+
{ planFeatureFootnotes?.footnoteList?.map( ( footnote, index ) => {
|
|
1192
|
+
return <li key={ `${ footnote }-${ index }` }>{ footnote }</li>;
|
|
1193
|
+
} ) }
|
|
1194
|
+
</ol>
|
|
1195
|
+
</td>
|
|
1128
1196
|
</FeatureFootnotes>
|
|
1129
1197
|
) }
|
|
1130
|
-
</
|
|
1131
|
-
</
|
|
1198
|
+
</tfoot>
|
|
1199
|
+
</table>
|
|
1132
1200
|
);
|
|
1133
1201
|
};
|
|
1134
1202
|
|
|
@@ -1159,6 +1227,9 @@ const WrappedComparisonGrid = ( {
|
|
|
1159
1227
|
featureGroupMap,
|
|
1160
1228
|
enableTermSavingsPriceDisplay,
|
|
1161
1229
|
reflectStorageSelectionInPlanPrices,
|
|
1230
|
+
showSimplifiedBillingDescription,
|
|
1231
|
+
showBillingDescriptionForIncreasedRenewalPrice,
|
|
1232
|
+
isExperimentVariant,
|
|
1162
1233
|
...otherProps
|
|
1163
1234
|
}: ComparisonGridExternalProps ) => {
|
|
1164
1235
|
const gridContainerRef = useRef< HTMLDivElement >( null );
|
|
@@ -1194,6 +1265,7 @@ const WrappedComparisonGrid = ( {
|
|
|
1194
1265
|
<div ref={ gridContainerRef } className={ classNames }>
|
|
1195
1266
|
<PlansGridContextProvider
|
|
1196
1267
|
intent={ intent }
|
|
1268
|
+
key={ intent }
|
|
1197
1269
|
siteId={ siteId }
|
|
1198
1270
|
gridPlans={ gridPlans }
|
|
1199
1271
|
useCheckPlanAvailabilityForPurchase={ useCheckPlanAvailabilityForPurchase }
|
|
@@ -1206,6 +1278,11 @@ const WrappedComparisonGrid = ( {
|
|
|
1206
1278
|
hideUnsupportedFeatures={ hideUnsupportedFeatures }
|
|
1207
1279
|
enableTermSavingsPriceDisplay={ enableTermSavingsPriceDisplay }
|
|
1208
1280
|
reflectStorageSelectionInPlanPrices={ reflectStorageSelectionInPlanPrices }
|
|
1281
|
+
showSimplifiedBillingDescription={ showSimplifiedBillingDescription }
|
|
1282
|
+
showBillingDescriptionForIncreasedRenewalPrice={
|
|
1283
|
+
showBillingDescriptionForIncreasedRenewalPrice
|
|
1284
|
+
}
|
|
1285
|
+
isExperimentVariant={ isExperimentVariant }
|
|
1209
1286
|
>
|
|
1210
1287
|
<ComparisonGrid
|
|
1211
1288
|
intervalType={ intervalType }
|