diff --git a/apps/studio/components/interfaces/DiskManagement/fields/ComputeSizeField.tsx b/apps/studio/components/interfaces/DiskManagement/fields/ComputeSizeField.tsx index 3ca0fc769a1..e6639c9831a 100644 --- a/apps/studio/components/interfaces/DiskManagement/fields/ComputeSizeField.tsx +++ b/apps/studio/components/interfaces/DiskManagement/fields/ComputeSizeField.tsx @@ -139,6 +139,7 @@ export function ComputeSizeField({ form, disabled }: ComputeSizeFieldProps) { > } > -
- {isLoading ? ( - Array(INITIALLY_VISIBLE_COUNT) - .fill(0) - .map((_, i) => ) - ) : addonsError ? ( - -

{addonsError?.message}

-
- ) : ( - <> - {visibleOptions.map((compute) => { - const lockedMicroDueToPITR = - compute.identifier === 'ci_micro' && !!subscriptionPitr - const lockedNanoDueToPlan = - org?.plan.id !== 'free' && - project?.infra_compute_size !== 'nano' && - compute.identifier === 'ci_nano' +
+
+ {isLoading ? ( + Array(INITIALLY_VISIBLE_COUNT) + .fill(0) + .map((_, i) => ) + ) : addonsError ? ( + +

{addonsError?.message}

+
+ ) : ( + <> + {visibleOptions.map((compute) => { + const lockedMicroDueToPITR = + compute.identifier === 'ci_micro' && !!subscriptionPitr + const lockedNanoDueToPlan = + org?.plan.id !== 'free' && + project?.infra_compute_size !== 'nano' && + compute.identifier === 'ci_nano' - const lockedOption = lockedNanoDueToPlan || lockedMicroDueToPITR + const lockedOption = lockedNanoDueToPlan || lockedMicroDueToPITR - const price = - org?.plan.id !== 'free' && - project?.infra_compute_size === 'nano' && - compute.identifier === 'ci_nano' - ? availableOptions.find( - (option: ComputeAddonVariant) => option.identifier === 'ci_micro' - )?.price - : compute.price + const price = + org?.plan.id !== 'free' && + project?.infra_compute_size === 'nano' && + compute.identifier === 'ci_nano' + ? availableOptions.find( + (option: ComputeAddonVariant) => option.identifier === 'ci_micro' + )?.price + : compute.price - const cpuLabel = (() => { - const cpuCores = compute.meta?.cpu_cores - if (typeof cpuCores === 'number') { - return `${cpuCores}-core CPU` - } - if (cpuCores) { - return `${cpuCores} CPU` - } - return 'CPU' - })() + const cpuLabel = (() => { + const cpuCores = compute.meta?.cpu_cores + if (typeof cpuCores === 'number') { + return `${cpuCores}-core CPU` + } + if (cpuCores) { + return `${cpuCores} CPU` + } + return 'CPU' + })() - return ( - - -
- {showUpgradeBadge && compute.identifier === 'ci_micro' && ( -
- No additional charge -
- )} -
-
- -
- {lockedOption ? ( -
- -
- ) : ( - showComputePrice && ( - <> - - ${price} - - - {' '} - /{' '} - {compute.price_interval === 'monthly' - ? 'month' - : 'hour'} - - - ) - )} + return ( + + +
+ {showUpgradeBadge && compute.identifier === 'ci_micro' && ( +
+ No additional charge
-
- -
-
-
- - - {compute.identifier === 'ci_nano' && 'Up to '} - {compute.meta?.memory_gb ?? 0} GB memory - + )} +
+
+ +
+ {lockedOption ? ( +
+ +
+ ) : ( + showComputePrice && ( + <> + + ${price} + + + {' '} + /{' '} + {compute.price_interval === 'monthly' + ? 'month' + : 'hour'} + + + ) + )}
-
- - {cpuLabel} +
+ +
+
+
+ + + {compute.identifier === 'ci_nano' && 'Up to '} + {compute.meta?.memory_gb ?? 0} GB memory + +
+
+ + {cpuLabel} +
+ + {lockedMicroDueToPITR && ( + + Project has PITR enabled which requires a minimum of Small + compute. Please{' '} + + disable PITR + {' '} + first before selecting Micro + + )} + + } + /> + ) + })} + + {showAllSizes && ( + e.preventDefault()} + className={cn( + 'relative text-sm text-left flex flex-col gap-0 px-0 py-3 [&_label]:w-full group w-full h-[110px]' + )} + label={ + +
+
+ + +
+ Contact Us +
- - {lockedMicroDueToPITR && ( - - Project has PITR enabled which requires a minimum of Small compute. - Please{' '} - - disable PITR - {' '} - first before selecting Micro - - )} - +
+
+
+ + Custom memory +
+
+ + Custom CPU +
+
+
+
+
} /> - ) - })} - - {showAllSizes && ( - e.preventDefault()} - className={cn( - 'relative text-sm text-left flex flex-col gap-0 px-0 py-3 [&_label]:w-full group w-full h-[110px]' - )} - label={ - -
-
- - -
- Contact Us -
-
-
-
-
- - Custom memory -
-
- - Custom CPU -
-
-
-
-
- } - /> - )} - - )} + )} + + )} +
{!isLoading && !addonsError && hasHiddenOptions && ( diff --git a/packages/ui-patterns/src/form/Layout/FormLayout.tsx b/packages/ui-patterns/src/form/Layout/FormLayout.tsx index b6db8bcaec2..863bc0dd6e3 100644 --- a/packages/ui-patterns/src/form/Layout/FormLayout.tsx +++ b/packages/ui-patterns/src/form/Layout/FormLayout.tsx @@ -18,6 +18,14 @@ type Props = { isReactForm?: boolean hideMessage?: boolean name?: string + /** + * For layout="horizontal", switches the label/content split to react to the nearest + * `@container` ancestor's width instead of the viewport width. Use when the layout sits + * inside a narrower column (e.g. next to a sidebar) so it stacks to a single column as + * soon as that column gets tight, rather than waiting for a viewport breakpoint that may + * never reflect the column's actual available space. + */ + isContainerResponsive?: boolean } const ContainerVariants = cva('relative grid gap-10', { @@ -35,7 +43,7 @@ const ContainerVariants = cva('relative grid gap-10', { false: '', }, layout: { - horizontal: 'flex flex-col gap-2 md:grid md:grid-cols-12', + horizontal: 'flex flex-col gap-2', vertical: 'flex flex-col gap-2', flex: 'flex flex-row gap-3', 'flex-row-reverse': @@ -57,8 +65,20 @@ const ContainerVariants = cva('relative grid gap-10', { align: 'right', className: 'justify-between', }, + { + layout: 'horizontal', + responsive: false, + className: 'md:grid md:grid-cols-12', + }, + { + layout: 'horizontal', + responsive: true, + className: '@xl:grid @xl:grid-cols-12', + }, ], - defaultVariants: {}, + defaultVariants: { + responsive: false, + }, }) const LabelContainerVariants = cva('transition-all duration-500 ease-in-out', { @@ -287,6 +307,7 @@ export const FormLayout = React.forwardRef< hideMessage = false, isReactForm, error, + isContainerResponsive = false, ...props }, ref @@ -356,7 +377,10 @@ export const FormLayout = React.forwardRef<
{flex && (