From b7455c04706b0f17d5f7c07e4e4578ec78b3aa7e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Padez?= Date: Sat, 5 Sep 2026 14:25:48 +0100 Subject: [PATCH] contain the pickers and let their lists scroll MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The carousel list ran off the bottom of the window with no way to reach the end of it. There are twenty-odd carousels now — three sections' worth — where there were six when the dialog was written. `max-h-[80svh]` on the dialog and `min-h-0 overflow-y-auto` on the list. Both are needed and the second is the one that is easy to miss: a flex child will not shrink below its content without `min-h-0`, so the list pushes the dialog past the screen and the overflow never engages. A max-height alone would have looked like it did nothing. `svh` rather than `vh`, because on a phone `vh` is the viewport with the browser chrome hidden — a dialog sized in it is taller than what you can see. AddComponentDialog gets the same treatment. Its list is a dozen kinds now and was the same failure waiting for a shorter screen. Co-Authored-By: Claude Opus 5 (1M context) --- web/CarouselPicker.tsx | 16 ++++++++++++++-- web/sections/AddComponentDialog.tsx | 7 +++++-- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/web/CarouselPicker.tsx b/web/CarouselPicker.tsx index e5881d0..aca0075 100644 --- a/web/CarouselPicker.tsx +++ b/web/CarouselPicker.tsx @@ -70,7 +70,19 @@ export const CarouselPicker = ({ return ( !next && onClose()}> - + {/* + Bounded, and the list scrolls inside it. + + `max-h-[80svh]` on the dialog and `min-h-0 overflow-y-auto` on the list. Both are needed: a + flex child will not shrink below its content without `min-h-0`, so the list pushes the dialog + taller than the screen and the overflow never engages — which is what happened here. There are + twenty-odd carousels now and the list ran off the bottom of the window with no way to reach the + end of it. + + `svh` rather than `vh` because on a phone `vh` is the viewport with the browser chrome hidden, + so a dialog sized in it is taller than what you can actually see. + */} + Choose a carousel @@ -92,7 +104,7 @@ export const CarouselPicker = ({

)} -
+
{carousels?.map((carousel) => { const count = Array.isArray(carousel.items) ? carousel.items.length : 0; const current = carousel.id === selected; diff --git a/web/sections/AddComponentDialog.tsx b/web/sections/AddComponentDialog.tsx index 893c1e2..e2ae16a 100644 --- a/web/sections/AddComponentDialog.tsx +++ b/web/sections/AddComponentDialog.tsx @@ -132,12 +132,15 @@ export const AddComponentDialog = ({ template?: boolean; }) => ( !next && onCancel()}> - + {/* Bounded and scrolling, for the same reason CarouselPicker is: the list of kinds has grown to a + dozen and would otherwise run off a short screen with no way to reach the end. `min-h-0` on the + grid is what lets it shrink and the overflow engage. */} + Add a component -
+
{/* `kind === null` is a choice that is not built yet — never a subject block, and it must not be filtered out by a list that only knows about the ones that are. */} {CHOICES.filter((choice) => template || choice.kind === null || !SUBJECT_KINDS.includes(choice.kind)).map(