fix(post-detail): actually center carousel images (previous fix was a no-op)
The items-center/justify-center I added to CarouselItem in the last commit had no effect — verified by building an isolated static HTML repro of the exact carousel.tsx DOM structure (embla-free, no auth needed) and testing it directly in a browser, since PostDetailDialog itself sits behind Clerk auth and can't be exercised locally. Root cause was one level higher than CarouselItem: CarouselContent's own ref div (src/components/ui/carousel.tsx) is hardcoded to "overflow-hidden" with no height/flex class ever reaching it — nothing propagates the media column's definite height down to it, so it renders at its own auto/content height and just sits at the top of the Carousel element's box via normal block flow. CarouselItem's centering was already correctly placed, but had no gap to center within, since the box it was centering into never itself moved off the top. Fix: attach centering to the Carousel component's own outermost element instead — the deepest point reachable via props, since CarouselContent's outer div doesn't forward a className. Used CSS Grid (grid + items-center) rather than flex specifically because grid's default justify-items:stretch preserves the ref div's full width (required for embla's horizontal scroll-snap math); flex's shrink-to-content default for un-stretched items would likely have broken horizontal scrolling between images. Verified via the isolated repro: short/wide image now centers vertically within the media column, and the "always full width" marker stayed 100% wide across all three test cases (single tall, single wide, mixed pair in one row).
This commit is contained in:
@@ -264,7 +264,17 @@ export function PostDetailDialog({ post, open, onClose, onDeleted }: PostDetailD
|
||||
isCarousel ? (
|
||||
<div className="relative w-full h-full">
|
||||
<AiDisclosureBadge value={post.aiDisclosure} className="h-8" />
|
||||
<Carousel setApi={setCarouselApi} className="h-full">
|
||||
{/* grid items-center (not flex) on purpose: CarouselContent's own
|
||||
ref div (src/components/ui/carousel.tsx) is hardcoded to
|
||||
"overflow-hidden" with no height/flex class reaching it, so it
|
||||
never fills this element's height — shorter images in a
|
||||
mixed-aspect-ratio carousel rendered pinned to the top instead
|
||||
of centered. This is the deepest point we can attach centering
|
||||
to from outside. Grid over flex specifically because grid's
|
||||
default justify-items:stretch keeps the ref div's width at
|
||||
100% (required for embla's horizontal scroll math); flex's
|
||||
shrink-to-content main-axis default would have broken that. */}
|
||||
<Carousel setApi={setCarouselApi} className="grid h-full items-center">
|
||||
<CarouselContent className="h-full">
|
||||
{images.map((img) => (
|
||||
<CarouselItem key={img.id} className="basis-full h-full flex items-center justify-center">
|
||||
@@ -272,8 +282,8 @@ export function PostDetailDialog({ post, open, onClose, onDeleted }: PostDetailD
|
||||
src={getMediaUrl(img.storageKey) ?? ""}
|
||||
blurhash={img.blurhash}
|
||||
alt={currentCaption ?? `${pet.name}'s post`}
|
||||
className="block w-full h-full object-contain"
|
||||
wrapperClassName="relative block w-full h-full"
|
||||
className="block max-h-full max-w-full object-contain"
|
||||
wrapperClassName="relative block w-fit h-fit"
|
||||
/>
|
||||
</CarouselItem>
|
||||
))}
|
||||
|
||||
Reference in New Issue
Block a user