diff --git a/packages/data-stores/src/add-ons/index.ts b/packages/data-stores/src/add-ons/index.ts
index 55590f6551714c..c53300ef837507 100644
--- a/packages/data-stores/src/add-ons/index.ts
+++ b/packages/data-stores/src/add-ons/index.ts
@@ -3,6 +3,7 @@ export { default as useAddOns } from './hooks/use-add-ons';
export { default as useAddOnCheckoutLink } from './hooks/use-add-on-checkout-link';
export { default as useAddOnPurchaseStatus } from './hooks/use-add-on-purchase-status';
export { default as useStorageAddOns } from './hooks/use-storage-add-ons';
+export * from './constants';
/** Types */
export * from './types';
diff --git a/packages/data-stores/src/plans/hooks/use-pricing-meta-for-grid-plans.ts b/packages/data-stores/src/plans/hooks/use-pricing-meta-for-grid-plans.ts
index acc4162a70e2a4..94c6dcb36fa85c 100644
--- a/packages/data-stores/src/plans/hooks/use-pricing-meta-for-grid-plans.ts
+++ b/packages/data-stores/src/plans/hooks/use-pricing-meta-for-grid-plans.ts
@@ -98,20 +98,16 @@ const usePricingMetaForGridPlans = ( {
} else {
planPrices = Object.fromEntries(
planSlugs.map( ( planSlug ) => {
- const availableForPurchase = planAvailabilityForPurchase[ planSlug ];
- const selectedStorageOption = selectedStorageOptions?.[ planSlug ];
- const selectedStorageAddOn = storageAddOns?.find( ( addOn ) => {
- return selectedStorageOption && addOn?.featureSlugs?.includes( selectedStorageOption );
- } );
- const storageAddOnPrices =
- selectedStorageAddOn?.purchased || selectedStorageAddOn?.exceedsSiteStorageLimits
- ? null
- : selectedStorageAddOn?.prices;
- const storageAddOnPriceMonthly = storageAddOnPrices?.monthlyPrice || 0;
- const storageAddOnPriceYearly = storageAddOnPrices?.yearlyPrice || 0;
-
const plan = plans.data?.[ planSlug ];
const sitePlan = sitePlans.data?.[ planSlug ];
+ const selectedStorageOption = selectedStorageOptions?.[ planSlug ];
+ const selectedStorageAddOn = selectedStorageOption
+ ? storageAddOns?.find( ( addOn ) => {
+ return addOn?.featureSlugs?.includes( selectedStorageOption );
+ } )
+ : null;
+ const storageAddOnPriceMonthly = selectedStorageAddOn?.prices?.monthlyPrice || 0;
+ const storageAddOnPriceYearly = selectedStorageAddOn?.prices?.yearlyPrice || 0;
/**
* 0. No plan or sitePlan (when selected site exists): planSlug is for a priceless plan.
@@ -176,7 +172,7 @@ const usePricingMetaForGridPlans = ( {
/**
* 2. Original and Discounted prices for plan available for purchase.
*/
- if ( availableForPurchase ) {
+ if ( planAvailabilityForPurchase[ planSlug ] ) {
const originalPrice = {
monthly: getTotalPrice( plan.pricing.originalPrice.monthly, storageAddOnPriceMonthly ),
full: getTotalPrice( plan.pricing.originalPrice.full, storageAddOnPriceYearly ),
diff --git a/packages/plans-grid-next/src/components/actions.tsx b/packages/plans-grid-next/src/components/actions.tsx
index 0940bc1b32f052..b604974b72a26a 100644
--- a/packages/plans-grid-next/src/components/actions.tsx
+++ b/packages/plans-grid-next/src/components/actions.tsx
@@ -142,10 +142,12 @@ const PlanFeatures2023GridActions = ( {
const canPurchaseStorageAddOns = storageAddOnsForPlan?.some(
( storageAddOn ) => ! storageAddOn?.purchased && ! storageAddOn?.exceedsSiteStorageLimits
);
+
const storageAddOnCheckoutHref = storageAddOnsForPlan?.find(
( addOn ) =>
selectedStorageOptionForPlan && addOn?.featureSlugs?.includes( selectedStorageOptionForPlan )
)?.checkoutLink;
+
const nonDefaultStorageOptionSelected = defaultStorageOption !== selectedStorageOptionForPlan;
let actionButton = (
diff --git a/packages/plans-grid-next/src/components/comparison-grid/index.tsx b/packages/plans-grid-next/src/components/comparison-grid/index.tsx
index 0824bef1008349..4371689f516485 100644
--- a/packages/plans-grid-next/src/components/comparison-grid/index.tsx
+++ b/packages/plans-grid-next/src/components/comparison-grid/index.tsx
@@ -31,7 +31,6 @@ import filterUnusedFeaturesObject from '../../lib/filter-unused-features-object'
import getPlanFeaturesObject from '../../lib/get-plan-features-object';
import { isStorageUpgradeableForPlan } from '../../lib/is-storage-upgradeable-for-plan';
import { sortPlans } from '../../lib/sort-plan-properties';
-import { getStorageStringFromFeature } from '../../util';
import PlanFeatures2023GridActions from '../actions';
import PlanFeatures2023GridHeaderPrice from '../header-price';
import PlanTypeSelector from '../plan-type-selector';
@@ -39,6 +38,7 @@ import { Plans2023Tooltip } from '../plans-2023-tooltip';
import PopularBadge from '../popular-badge';
import BillingTimeframe from '../shared/billing-timeframe';
import { StickyContainer } from '../sticky-container';
+import { PlanStorageLabel, useGetAvailableStorageOptions } from '../storage';
import StorageAddOnDropdown from '../storage-add-on-dropdown';
import type {
GridPlan,
@@ -299,25 +299,6 @@ const PlanSelector = styled.header`
}
`;
-const StorageButton = styled.div`
- background: #f2f2f2;
- border-radius: 5px;
- padding: 4px 0;
- width: -moz-fit-content;
- width: fit-content;
- text-align: center;
- font-size: 0.75rem;
- font-weight: 400;
- line-height: 20px;
- color: var( --studio-gray-90 );
- min-width: 64px;
- margin-top: 10px;
-
- ${ plansGridMediumLarge( css`
- margin-top: 0;
- ` ) }
-`;
-
const FeatureFootnotes = styled.div`
ol {
margin: 2em 0 0 1em;
@@ -584,6 +565,38 @@ const ComparisonGridFeatureGroupRowCell: React.FunctionComponent< {
renderedGridPlans: visibleGridPlans,
} );
+ /**
+ * TODO: Consider centralising `canUpgradeStorageForPlan` behind `availableStorageOptions`
+ */
+ const availableStorageOptions = useGetAvailableStorageOptions()( {
+ storageOptions: gridPlan.features.storageOptions,
+ } );
+ /**
+ * The current plan is not marked as `availableForPurchase`, hence check on `current`.
+ */
+ const canUpgradeStorageForPlan =
+ ( gridPlan.current || gridPlan.availableForPurchase ) &&
+ isStorageUpgradeableForPlan( {
+ intervalType,
+ showUpgradeableStorage,
+ storageOptions: availableStorageOptions,
+ } );
+
+ const storageJSX = canUpgradeStorageForPlan ? (
+
+ ) : (
+ gridPlan.features.storageOptions.map( ( storageOption ) => {
+ if ( ! storageOption?.isAddOn ) {
+ return ;
+ }
+ } )
+ );
+
if ( ! gridPlan ) {
return null;
}
@@ -605,13 +618,6 @@ const ComparisonGridFeatureGroupRowCell: React.FunctionComponent< {
( feature ) => feature.getSlug() === featureSlug
)
: false;
- const storageOptions = gridPlan.features.storageOptions;
- const defaultStorageOption = storageOptions.find( ( option ) => ! option.isAddOn );
- const canUpgradeStorageForPlan = isStorageUpgradeableForPlan( {
- intervalType,
- showUpgradeableStorage,
- storageOptions,
- } );
const cellClasses = classNames(
'plan-comparison-grid__feature-group-row-cell',
@@ -638,18 +644,7 @@ const ComparisonGridFeatureGroupRowCell: React.FunctionComponent< {
{ isStorageFeature ? (
<>
{ translate( 'Storage' ) }
- { canUpgradeStorageForPlan ? (
-
- ) : (
-
- { getStorageStringFromFeature( defaultStorageOption?.slug || '' ) }
-
- ) }
+ { storageJSX }
>
) : (
<>
diff --git a/packages/plans-grid-next/src/components/features-grid/plan-storage-options.tsx b/packages/plans-grid-next/src/components/features-grid/plan-storage-options.tsx
index 2a02a3b2601477..84f4c98680147b 100644
--- a/packages/plans-grid-next/src/components/features-grid/plan-storage-options.tsx
+++ b/packages/plans-grid-next/src/components/features-grid/plan-storage-options.tsx
@@ -5,8 +5,8 @@ import {
} from '@automattic/calypso-products';
import { usePlansGridContext } from '../../grid-context';
import { isStorageUpgradeableForPlan } from '../../lib/is-storage-upgradeable-for-plan';
-import { getStorageStringFromFeature } from '../../util';
import { PlanFeaturesItem } from '../item';
+import { PlanStorageLabel, useGetAvailableStorageOptions } from '../storage';
import StorageAddOnDropdown from '../storage-add-on-dropdown';
type PlanStorageOptionsProps = {
@@ -30,36 +30,43 @@ const PlanStorageOptions = ( {
const {
availableForPurchase,
features: { storageOptions },
+ current,
} = gridPlansIndex[ planSlug ];
- const canUpgradeStorageForPlan = isStorageUpgradeableForPlan( {
- intervalType,
- showUpgradeableStorage,
- storageOptions,
- } );
-
- const storageJSX =
- canUpgradeStorageForPlan && availableForPurchase ? (
-
- ) : (
- storageOptions.map( ( storageOption ) => {
- if ( ! storageOption?.isAddOn ) {
- return (
-
{ storageJSX }
diff --git a/packages/plans-grid-next/src/components/storage-add-on-dropdown.tsx b/packages/plans-grid-next/src/components/storage-add-on-dropdown.tsx
index 1feb74a594594c..9853b5dfacb8ed 100644
--- a/packages/plans-grid-next/src/components/storage-add-on-dropdown.tsx
+++ b/packages/plans-grid-next/src/components/storage-add-on-dropdown.tsx
@@ -6,8 +6,8 @@ import { useTranslate } from 'i18n-calypso';
import { usePlansGridContext } from '../grid-context';
import useDefaultStorageOption from '../hooks/data-store/use-default-storage-option';
import useIsLargeCurrency from '../hooks/use-is-large-currency';
-import { getStorageStringFromFeature } from '../util';
import DropdownOption from './dropdown-option';
+import { useStorageStringFromFeature } from './storage';
import type { PlanSlug, StorageOption, WPComStorageAddOnSlug } from '@automattic/calypso-products';
import type { AddOnMeta } from '@automattic/data-stores';
@@ -19,8 +19,9 @@ type StorageAddOnDropdownProps = {
};
type StorageAddOnOptionProps = {
- title?: string;
+ planSlug: PlanSlug;
price?: string;
+ storageFeature: string;
isLargeCurrency?: boolean;
priceOnSeparateLine?: boolean;
};
@@ -35,16 +36,15 @@ const getStorageOptionPrice = (
};
const StorageAddOnOption = ( {
- title,
+ planSlug,
price,
+ storageFeature,
isLargeCurrency = false,
priceOnSeparateLine,
}: StorageAddOnOptionProps ) => {
const translate = useTranslate();
-
- if ( ! title ) {
- return null;
- }
+ const { siteId } = usePlansGridContext();
+ const title = useStorageStringFromFeature( { storageFeature, siteId, planSlug } ) ?? '';
return (
<>
@@ -114,28 +114,30 @@ export const StorageAddOnDropdown = ( {
}, [] );
const selectControlOptions = storageOptions.map( ( storageOption ) => {
- const title = getStorageStringFromFeature( storageOption.slug ) || '';
- const price = getStorageOptionPrice( storageAddOnsForPlan, storageOption.slug );
return {
key: storageOption.slug,
- name:
,
+ name: (
+
+ ),
};
} );
const selectedOptionKey = selectedStorageOptionForPlan
? selectedStorageOptionForPlan
: defaultStorageOption;
- const selectedOptionPrice =
- selectedOptionKey && getStorageOptionPrice( storageAddOnsForPlan, selectedOptionKey );
- const selectedOptionTitle =
- ( selectedOptionKey && getStorageStringFromFeature( selectedOptionKey ) ) || '';
+ const selectedOptionPrice = getStorageOptionPrice( storageAddOnsForPlan, selectedOptionKey );
const selectedOption = {
key: selectedOptionKey,
name: (
diff --git a/packages/plans-grid-next/src/components/storage/components/plan-storage-label.tsx b/packages/plans-grid-next/src/components/storage/components/plan-storage-label.tsx
new file mode 100644
index 00000000000000..599e280af135dc
--- /dev/null
+++ b/packages/plans-grid-next/src/components/storage/components/plan-storage-label.tsx
@@ -0,0 +1,72 @@
+import {
+ PLAN_BUSINESS,
+ PLAN_ECOMMERCE,
+ PlanSlug,
+ StorageOption,
+} from '@automattic/calypso-products';
+import { AddOns } from '@automattic/data-stores';
+import { formatCurrency } from '@automattic/format-currency';
+import classNames from 'classnames';
+import { useTranslate } from 'i18n-calypso';
+import { usePlansGridContext } from '../../../grid-context';
+import useIsLargeCurrency from '../../../hooks/use-is-large-currency';
+import useStorageStringFromFeature from '../hooks/use-storage-string-from-feature';
+
+interface Props {
+ storageOption: StorageOption;
+ planSlug: PlanSlug;
+}
+
+const ELIGIBLE_PLANS_FOR_STORAGE_UPGRADE = [ PLAN_BUSINESS, PLAN_ECOMMERCE ];
+
+const PlanStorageLabel = ( { storageOption, planSlug }: Props ) => {
+ const translate = useTranslate();
+ const { siteId, gridPlansIndex } = usePlansGridContext();
+ const currencyCode = gridPlansIndex[ planSlug ].pricing.currencyCode;
+ const storageStringFromFeature = useStorageStringFromFeature( {
+ siteId,
+ storageFeature: storageOption.slug,
+ planSlug,
+ } );
+ const storageAddOns = AddOns.useStorageAddOns( { siteId } );
+ const storageAddOnsPurchased = storageAddOns.filter( ( addOn ) => addOn?.purchased );
+ const monthlyAddedCost = storageAddOnsPurchased
+ ? Object.values( storageAddOnsPurchased ).reduce( ( total, addOn ) => {
+ return total + ( addOn?.prices?.monthlyPrice ?? 0 );
+ }, 0 )
+ : 0;
+ const formattedMonthlyAddedCost =
+ monthlyAddedCost &&
+ currencyCode &&
+ formatCurrency( monthlyAddedCost, currencyCode, { isSmallestUnit: true } );
+ const isLargeCurrency = useIsLargeCurrency( {
+ prices: [ monthlyAddedCost ],
+ isAddOn: true,
+ currencyCode: currencyCode ?? 'USD',
+ } );
+
+ const containerClasses = classNames( 'plans-grid-next-plan-storage-label__container', {
+ 'is-row': ! isLargeCurrency,
+ } );
+
+ const volumeJSX = (
+
+ { storageStringFromFeature }
+
+ );
+
+ return formattedMonthlyAddedCost && ELIGIBLE_PLANS_FOR_STORAGE_UPGRADE.includes( planSlug ) ? (
+
+ { volumeJSX }
+
+ { translate( '+ %(formattedMonthlyAddedCost)s/month', {
+ args: { formattedMonthlyAddedCost },
+ } ) }
+
+
+ ) : (
+ volumeJSX
+ );
+};
+
+export default PlanStorageLabel;
diff --git a/packages/plans-grid-next/src/components/storage/hooks/use-get-available-storage-options.ts b/packages/plans-grid-next/src/components/storage/hooks/use-get-available-storage-options.ts
new file mode 100644
index 00000000000000..a5c7961dd87682
--- /dev/null
+++ b/packages/plans-grid-next/src/components/storage/hooks/use-get-available-storage-options.ts
@@ -0,0 +1,45 @@
+import { StorageOption } from '@automattic/calypso-products';
+import { AddOns, Site } from '@automattic/data-stores';
+import { useCallback } from '@wordpress/element';
+import { usePlansGridContext } from '../../../grid-context';
+
+interface CallbackProps {
+ storageOptions: StorageOption[];
+}
+
+/**
+ * Ensures that storage options are filtered based on:
+ * - the available space upgrade on the Site,
+ * so never render something that would exceed that limit (hence fail during checkout)
+ * - storage option being allowed for purchase only once (cannot repurchase same add-on on any site)
+ */
+const useGetAvailableStorageOptions = () => {
+ const { siteId } = usePlansGridContext();
+ const siteMediaStorage = Site.useSiteMediaStorage( { siteIdOrSlug: siteId } );
+ const currentMaxStorage = siteMediaStorage.data?.maxStorageBytes
+ ? siteMediaStorage.data.maxStorageBytes / Math.pow( 1024, 3 )
+ : 0;
+ const availableStorageUpgrade = AddOns.STORAGE_LIMIT - currentMaxStorage;
+ const storageAddOns = AddOns.useStorageAddOns( { siteId } );
+
+ return useCallback(
+ ( { storageOptions }: CallbackProps ) => {
+ return storageOptions.filter( ( storageOption ) => {
+ const storageAddOn = storageAddOns.find(
+ ( addOn ) =>
+ ! addOn?.purchased &&
+ addOn?.featureSlugs?.includes( storageOption?.slug ) &&
+ ! addOn.exceedsSiteStorageLimits
+ );
+
+ // the following may not be necessary if `exceedsSiteStorageLimits` suffices
+ return storageAddOn
+ ? ( storageAddOn?.quantity ?? 0 ) <= availableStorageUpgrade
+ : ! storageOption.isAddOn;
+ } );
+ },
+ [ availableStorageUpgrade, storageAddOns ]
+ );
+};
+
+export default useGetAvailableStorageOptions;
diff --git a/packages/plans-grid-next/src/components/storage/hooks/use-storage-string-from-feature.ts b/packages/plans-grid-next/src/components/storage/hooks/use-storage-string-from-feature.ts
new file mode 100644
index 00000000000000..f8c92a81ace5b2
--- /dev/null
+++ b/packages/plans-grid-next/src/components/storage/hooks/use-storage-string-from-feature.ts
@@ -0,0 +1,91 @@
+import {
+ FEATURE_1GB_STORAGE,
+ FEATURE_6GB_STORAGE,
+ FEATURE_13GB_STORAGE,
+ FEATURE_50GB_STORAGE,
+ FEATURE_200GB_STORAGE,
+ FEATURE_50GB_STORAGE_ADD_ON,
+ FEATURE_100GB_STORAGE_ADD_ON,
+ FEATURE_P2_3GB_STORAGE,
+ FEATURE_P2_13GB_STORAGE,
+ PRODUCT_1GB_SPACE,
+ PlanSlug,
+ PLAN_BUSINESS,
+ PLAN_ECOMMERCE,
+} from '@automattic/calypso-products';
+import { Purchases } from '@automattic/data-stores';
+import { useTranslate } from 'i18n-calypso';
+
+const ELIGIBLE_PLANS_FOR_STORAGE_UPGRADE = [ PLAN_BUSINESS, PLAN_ECOMMERCE ];
+
+const useStorageStringFromFeature = ( {
+ storageFeature,
+ siteId,
+ planSlug,
+}: {
+ storageFeature: string;
+ siteId?: null | number | string;
+ planSlug: PlanSlug;
+} ) => {
+ const translate = useTranslate();
+ const spaceUpgradesPurchased = Purchases.useSitePurchasesByProductSlug( {
+ siteId,
+ productSlug: PRODUCT_1GB_SPACE,
+ } );
+ const purchasedQuantityTotal = spaceUpgradesPurchased
+ ? Object.values( spaceUpgradesPurchased ).reduce( ( total, current ) => {
+ return total + current.purchaseRenewalQuantity;
+ }, 0 )
+ : 0;
+
+ switch ( storageFeature ) {
+ case FEATURE_1GB_STORAGE:
+ return translate( '1 GB' );
+ case FEATURE_6GB_STORAGE:
+ return translate( '6 GB' );
+ case FEATURE_13GB_STORAGE:
+ return translate( '13 GB' );
+ case FEATURE_50GB_STORAGE:
+ /**
+ * TODO: Don't do this here. Diverge and show the version with the green pricing next
+ */
+ return translate( '%(quantity)d GB', {
+ args: {
+ quantity: ELIGIBLE_PLANS_FOR_STORAGE_UPGRADE.includes( planSlug )
+ ? purchasedQuantityTotal + 50
+ : 50,
+ },
+ } );
+ case FEATURE_P2_3GB_STORAGE:
+ return translate( '3 GB' );
+ case FEATURE_P2_13GB_STORAGE:
+ return translate( '13 GB' );
+ // TODO: Remove when upgradeable storage is released in plans 2023
+ case FEATURE_200GB_STORAGE:
+ return translate( '200 GB' );
+ case FEATURE_50GB_STORAGE_ADD_ON:
+ /**
+ * Displayed string is: purchased storage + default 50GB storage + Add-On
+ * TODO: the default 50GB should be coming from plan context, not hardcoded here
+ */
+ return translate( '%(quantity)d GB', {
+ args: {
+ quantity: purchasedQuantityTotal + 50 + 50,
+ },
+ } );
+ case FEATURE_100GB_STORAGE_ADD_ON:
+ /**
+ * Displayed string is: purchased storage + default 50GB storage + Add-On
+ * TODO: the default 50GB should be coming from plan context, not hardcoded here
+ */
+ return translate( '%(quantity)d GB', {
+ args: {
+ quantity: purchasedQuantityTotal + 50 + 100,
+ },
+ } );
+ default:
+ return null;
+ }
+};
+
+export default useStorageStringFromFeature;
diff --git a/packages/plans-grid-next/src/components/storage/index.ts b/packages/plans-grid-next/src/components/storage/index.ts
new file mode 100644
index 00000000000000..5e7513decdfc3f
--- /dev/null
+++ b/packages/plans-grid-next/src/components/storage/index.ts
@@ -0,0 +1,11 @@
+/**
+ * Hooks
+ */
+export { default as useStorageStringFromFeature } from './hooks/use-storage-string-from-feature';
+export { default as useGetAvailableStorageOptions } from './hooks/use-get-available-storage-options';
+
+/**
+ * Components
+ */
+// Consider exporting a single generalised `PlanStorageOptions` component that can be used in both Comparison and Features grid.
+export { default as PlanStorageLabel } from './components/plan-storage-label';
diff --git a/packages/plans-grid-next/src/lib/is-storage-upgradeable-for-plan.ts b/packages/plans-grid-next/src/lib/is-storage-upgradeable-for-plan.ts
index e631e65df46999..6a10e158129374 100644
--- a/packages/plans-grid-next/src/lib/is-storage-upgradeable-for-plan.ts
+++ b/packages/plans-grid-next/src/lib/is-storage-upgradeable-for-plan.ts
@@ -15,4 +15,7 @@ export const isStorageUpgradeableForPlan = ( {
intervalType: string;
showUpgradeableStorage: boolean;
storageOptions: StorageOption[];
-} ) => storageOptions.length > 1 && intervalType === 'yearly' && showUpgradeableStorage;
+} ) =>
+ storageOptions.find( ( option ) => option.isAddOn ) &&
+ intervalType === 'yearly' &&
+ showUpgradeableStorage;
diff --git a/packages/plans-grid-next/src/style.scss b/packages/plans-grid-next/src/style.scss
index ec6c57af423699..be7238f75bce7d 100644
--- a/packages/plans-grid-next/src/style.scss
+++ b/packages/plans-grid-next/src/style.scss
@@ -326,12 +326,6 @@ $mobile-card-max-width: 440px;
padding-bottom: 23px;
}
- &.plan-features-2023-grid__storage {
- padding-top: 0;
- padding-bottom: 32px;
- width: 205px;
- }
-
.plan-features-2023-grid__header-title {
margin-top: 24px;
}
@@ -462,19 +456,6 @@ $mobile-card-max-width: 440px;
}
}
-.storage-add-on-dropdown__offset-price-container {
- width: 100%;
- margin-top: 8px;
- text-align: left;
-
- .storage-add-on-dropdown__offset-price {
- color: var(--studio-green-50);
-
- font-size: 0.75rem;
- font-weight: 500;
- }
-}
-
.plan-features-2023-grid__content {
.plan-features-2023-grid__table-bottom {
margin-top: 54px;
@@ -628,19 +609,11 @@ $mobile-card-max-width: 440px;
padding: 24px 0 6px 20px;
}
- .plan-features-2023-grid__storage {
- .plan-features-2023-grid__storage-buttons {
- background: #f2f2f2;
- /* stylelint-disable-next-line */
- border-radius: 5px;
- padding: 4px 0;
- width: fit-content;
- text-align: center;
- font-size: $font-body-extra-small;
- font-weight: 400;
- line-height: 20px;
- color: var(--studio-gray-90);
- min-width: 64px;
+ &.plan-features-2023-grid__storage {
+ padding: 24px 20px 38px 20px;
+
+ .plan-features-2023-grid__storage-title {
+ margin-bottom: 10px;
}
}
@@ -1056,3 +1029,75 @@ $mobile-card-max-width: 440px;
}
}
}
+
+/**
+ * Storage Add-On Dropdown parts
+ */
+
+.plans-grid-next-plan-storage-label__container {
+ display: flex;
+ gap: 5px;
+ flex-direction: column;
+ align-items: baseline;
+
+ &.is-row {
+ flex-direction: row;
+ }
+
+ /**
+ * Comparison grid overrides
+ * - always render as column/wrapped
+ */
+ .plans-grid-next-comparison-grid & {
+ flex-direction: column;
+ align-items: center;
+ }
+}
+
+.plans-grid-next-plan-storage-label__offset-price {
+ color: var(--studio-green-50);
+ font-size: $font-body-extra-small;
+ font-weight: 500;
+}
+
+.storage-add-on-dropdown__offset-price-container {
+ width: 100%;
+ margin-top: 8px;
+ text-align: left;
+
+ .storage-add-on-dropdown__offset-price {
+ color: var(--studio-green-50);
+ font-size: $font-body-extra-small;
+ font-weight: 500;
+ }
+}
+
+.plan-features-2023-grid__storage-buttons {
+ background: #f2f2f2;
+ color: var(--studio-gray-90);
+ /* stylelint-disable-next-line */
+ border-radius: 5px;
+ padding: 4px 0;
+ text-align: center;
+ font-size: $font-body-extra-small;
+ font-weight: 400;
+ line-height: 20px;
+ width: fit-content;
+ min-width: 64px;
+
+ .plans-grid-next-comparison-grid & {
+ margin-top: 10px;
+
+ @include plans-grid-medium-large {
+ margin-top: 0;
+ }
+ }
+}
+
+.plan-features-2023-grid__storage {
+ .plan-features-2023-grid__plan-spotlight & {
+ padding-top: 0;
+ padding-bottom: 32px;
+ max-width: $table-cell-max-width;
+ }
+}
diff --git a/packages/plans-grid-next/src/util.ts b/packages/plans-grid-next/src/util.ts
deleted file mode 100644
index edd2887be98837..00000000000000
--- a/packages/plans-grid-next/src/util.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-import {
- FEATURE_1GB_STORAGE,
- FEATURE_6GB_STORAGE,
- FEATURE_13GB_STORAGE,
- FEATURE_50GB_STORAGE,
- FEATURE_200GB_STORAGE,
- FEATURE_50GB_STORAGE_ADD_ON,
- FEATURE_100GB_STORAGE_ADD_ON,
- FEATURE_P2_3GB_STORAGE,
- FEATURE_P2_13GB_STORAGE,
-} from '@automattic/calypso-products';
-import { translate } from 'i18n-calypso';
-
-export const getStorageStringFromFeature = ( storageFeature: string ) => {
- switch ( storageFeature ) {
- case FEATURE_1GB_STORAGE:
- return translate( '1 GB' );
- case FEATURE_6GB_STORAGE:
- return translate( '6 GB' );
- case FEATURE_13GB_STORAGE:
- return translate( '13 GB' );
- case FEATURE_50GB_STORAGE:
- return translate( '50 GB' );
- case FEATURE_P2_3GB_STORAGE:
- return translate( '3 GB' );
- case FEATURE_P2_13GB_STORAGE:
- return translate( '13 GB' );
- // TODO: Remove when upgradeable storage is released in plans 2023
- case FEATURE_200GB_STORAGE:
- return translate( '200 GB' );
- // Displayed string is the Add On + default 50GB storage
- case FEATURE_50GB_STORAGE_ADD_ON:
- return translate( '100 GB' );
- case FEATURE_100GB_STORAGE_ADD_ON:
- return translate( '150 GB' );
- default:
- return null;
- }
-};