@automattic/plans-grid-next 1.0.1 → 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 +101 -71
- package/dist/cjs/components/comparison-grid/index.js.map +1 -1
- package/dist/cjs/components/comparison-grid/index.stories.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 +111 -21
- 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 +71 -47
- 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 +10 -2
- 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-billing-period.js +14 -0
- package/dist/cjs/hooks/data-store/use-plan-billing-period.js.map +1 -0
- 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-grid-size.js.map +1 -1
- 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 +8 -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 +102 -72
- package/dist/esm/components/comparison-grid/index.js.map +1 -1
- package/dist/esm/components/comparison-grid/index.stories.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 +111 -21
- 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 +71 -47
- 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 +10 -2
- 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-billing-period.js +12 -0
- package/dist/esm/hooks/data-store/use-plan-billing-period.js.map +1 -0
- 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-grid-size.js.map +1 -1
- 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 +4 -1
- 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/comparison-grid/index.stories.d.ts +2 -2
- package/dist/types/components/dropdown-option.d.ts.map +1 -1
- package/dist/types/components/features-grid/billing-timeframes.d.ts.map +1 -1
- package/dist/types/components/features-grid/client-logo-list/client-list.d.ts.map +1 -1
- package/dist/types/components/features-grid/client-logo-list/index.d.ts.map +1 -1
- package/dist/types/components/features-grid/enterprise-features.d.ts.map +1 -1
- package/dist/types/components/features-grid/index.d.ts.map +1 -1
- package/dist/types/components/features-grid/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/plan-logos.d.ts.map +1 -1
- package/dist/types/components/features-grid/plan-prices.d.ts.map +1 -1
- package/dist/types/components/features-grid/plan-tagline.d.ts.map +1 -1
- package/dist/types/components/features-grid/previous-features-included-title.d.ts.map +1 -1
- package/dist/types/components/features-grid/spotlight-plan.d.ts.map +1 -1
- package/dist/types/components/features-grid/table.d.ts.map +1 -1
- package/dist/types/components/features-grid/top-buttons.d.ts.map +1 -1
- package/dist/types/components/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/header-price-context.d.ts.map +1 -1
- package/dist/types/components/shared/header-price/index.d.ts.map +1 -1
- package/dist/types/components/shared/storage/components/plan-storage.d.ts.map +1 -1
- package/dist/types/components/shared/storage/components/storage-dropdown.d.ts.map +1 -1
- package/dist/types/components/shared/storage/components/storage-feature-label.d.ts.map +1 -1
- package/dist/types/components/shared/storage/hooks/use-plan-storage.d.ts +1 -1
- package/dist/types/components/shared/storage/hooks/use-plan-storage.d.ts.map +1 -1
- package/dist/types/css-mixins.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-plan-for-spotlight.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-billing-period.d.ts +8 -0
- package/dist/types/hooks/data-store/use-plan-billing-period.d.ts.map +1 -0
- package/dist/types/hooks/data-store/use-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-plans-from-types.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-grid-size.d.ts +3 -2
- package/dist/types/hooks/use-grid-size.d.ts.map +1 -1
- package/dist/types/hooks/use-highlight-adjacency-matrix.d.ts.map +1 -1
- package/dist/types/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 +9 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/lib/filter-unused-features-object.d.ts.map +1 -1
- package/dist/types/lib/get-plan-features-object.d.ts +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 +33 -6
- package/dist/types/types.d.ts.map +1 -1
- package/package.json +39 -28
- package/src/_shared.scss +4 -3
- package/src/components/comparison-grid/index.stories.tsx +1 -1
- package/src/components/comparison-grid/index.tsx +263 -158
- 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 +37 -19
- 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 +111 -21
- 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 +71 -47
- 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 +10 -2
- 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-billing-period.tsx +28 -0
- 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-grid-size.ts +3 -2
- package/src/hooks/use-is-large-currency.ts +1 -1
- package/src/hooks/use-visible-grid-plans.tsx +102 -0
- package/src/index.tsx +20 -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 +45 -4
- 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/cjs/lib/sort-plan-properties.js +0 -26
- package/dist/cjs/lib/sort-plan-properties.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/esm/lib/sort-plan-properties.js +0 -23
- package/dist/esm/lib/sort-plan-properties.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/dist/types/lib/sort-plan-properties.d.ts +0 -3
- package/dist/types/lib/sort-plan-properties.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
- package/src/lib/sort-plan-properties.ts +0 -27
- package/src/lib/test/sort-plan-properties.ts +0 -122
|
@@ -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,3 +1,5 @@
|
|
|
1
|
+
@import "@automattic/typography/styles/fonts";
|
|
2
|
+
|
|
1
3
|
.plans-grid-next-header-price {
|
|
2
4
|
padding: 0 20px;
|
|
3
5
|
margin: 0 0 4px 0;
|
|
@@ -23,7 +25,7 @@
|
|
|
23
25
|
|
|
24
26
|
.plan-price__currency-symbol,
|
|
25
27
|
.plan-price__tax-amount {
|
|
26
|
-
color: var(--
|
|
28
|
+
color: var(--studio-gray-20);
|
|
27
29
|
}
|
|
28
30
|
|
|
29
31
|
.plan-price__integer {
|
|
@@ -93,6 +95,12 @@
|
|
|
93
95
|
white-space: nowrap;
|
|
94
96
|
width: fit-content;
|
|
95
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
|
+
|
|
96
104
|
&.is-hidden {
|
|
97
105
|
visibility: hidden;
|
|
98
106
|
}
|
|
@@ -102,7 +110,7 @@
|
|
|
102
110
|
justify-content: flex-end;
|
|
103
111
|
display: flex;
|
|
104
112
|
flex-direction: row-reverse;
|
|
105
|
-
align-items:
|
|
113
|
+
align-items: last baseline;
|
|
106
114
|
gap: 4px;
|
|
107
115
|
|
|
108
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';
|