fix(gallery): leave a visible gap between filter bar and hero header (#624)

When a gallery uses the 'hero' header_style AND the admin enables the
filter bar (search + sort), the search/sort row glued itself to the top
of the hero image. Root cause: HeroHeader carries a decorative `-mt-6`
on its outer div (so it can bleed flush against the page header when
nothing else is above), and that exactly cancelled the wrapper's `mt-6`
between PhotoFilterBar and PhotoGridWithLayouts.

Fix: when the filter bar is shown above a hero header, the grid wrapper
uses `mt-12` instead of `mt-6` so the hero's bleed leaves a 24px net gap
rather than zero. The no-filter-bar case keeps the original flush bleed.

Also tidied up: extract the filter-bar-shown predicate to a named const
so the two reads (conditional render + wrapper class) can't drift apart.
This commit is contained in:
Paul Nothaft
2026-06-17 22:31:04 +02:00
parent a239fec9d7
commit 178d6dafb1
@@ -697,6 +697,9 @@ export const GalleryView: React.FC<GalleryViewProps> = ({ slug, event }) => {
const headerStyle = data?.event?.header_style || theme.headerStyle || 'standard'; const headerStyle = data?.event?.header_style || theme.headerStyle || 'standard';
const isHeroHeader = headerStyle === 'hero'; const isHeroHeader = headerStyle === 'hero';
const showSidebar = theme.controlsStyle === 'sidebar'; const showSidebar = theme.controlsStyle === 'sidebar';
const filterBarShown = !showSidebar
&& settingsData?.gallery_show_filter_bar !== false
&& (data?.photos?.length ?? 0) > 0;
// Full-page layouts (gallery-premium, gallery-story) have their own integrated UI // Full-page layouts (gallery-premium, gallery-story) have their own integrated UI
// Skip all wrapper elements (header, footer, sidebar, filters) for these layouts // Skip all wrapper elements (header, footer, sidebar, filters) for these layouts
@@ -922,7 +925,7 @@ export const GalleryView: React.FC<GalleryViewProps> = ({ slug, event }) => {
filter bar globally, and when the gallery actually has photos filter bar globally, and when the gallery actually has photos
(avoids the empty "Search photos by filename" row in the screenshot (avoids the empty "Search photos by filename" row in the screenshot
from discussion #317). */} from discussion #317). */}
{!showSidebar && settingsData?.gallery_show_filter_bar !== false && (data?.photos?.length ?? 0) > 0 ? ( {filterBarShown ? (
<div className="mt-6"> <div className="mt-6">
<PhotoFilterBar <PhotoFilterBar
categories={data.categories} categories={data.categories}
@@ -945,8 +948,11 @@ export const GalleryView: React.FC<GalleryViewProps> = ({ slug, event }) => {
</div> </div>
) : null} ) : null}
{/* Photo Grid */} {/* Photo Grid — when the hero header sits directly under the filter
<div className={showSidebar ? "mt-6" : "mt-6"}> bar, double the wrapper margin (mt-12) so the hero's decorative
`-mt-6` bleed leaves a visible gap instead of gluing the filter
bar to the hero image (issue #624). */}
<div className={filterBarShown && isHeroHeader ? "mt-12" : "mt-6"}>
<PhotoGridWithLayouts <PhotoGridWithLayouts
photos={filteredPhotos} photos={filteredPhotos}
slug={slug} slug={slug}