From 4a61fd1a6984622efa22200f5b1952ad2677bbcd Mon Sep 17 00:00:00 2001 From: Dmitri Date: Tue, 14 Apr 2026 16:21:22 +0400 Subject: [PATCH] fixed carousel z-indexes issue --- .../Constructor/ConstructorControlsPanel.tsx | 2 +- .../Constructor/ConstructorMenu.tsx | 2 +- .../Constructor/ElementEditorPanel.tsx | 2 +- .../src/components/RuntimePresentation.tsx | 61 ++++++++++--------- .../UiElements/elements/CarouselElement.tsx | 8 +-- frontend/src/pages/constructor.tsx | 51 +++++++++------- 6 files changed, 68 insertions(+), 58 deletions(-) diff --git a/frontend/src/components/Constructor/ConstructorControlsPanel.tsx b/frontend/src/components/Constructor/ConstructorControlsPanel.tsx index 860b34c..985f4a4 100644 --- a/frontend/src/components/Constructor/ConstructorControlsPanel.tsx +++ b/frontend/src/components/Constructor/ConstructorControlsPanel.tsx @@ -35,7 +35,7 @@ const ConstructorControlsPanel: React.FC = ({ }) => { return (
( return (
- {/* Inner canvas: maintains aspect ratio centered in viewport */} + {/* Inner canvas: maintains aspect ratio centered in viewport. + z-[46] creates stacking context above carousel (z-10 bg, z-45 controls) portaled to body. */}
)} - {/* New page content wrapper - fades in for non-transition navigation. - z-1 ensures it's above previous backgrounds (z-0) during fade. + {/* Page background wrapper - z-5 keeps it BELOW carousel slide (z-10). + Fades in for non-transition navigation. onAnimationEnd resets isFadingIn when CSS animation completes. */}
- {/* Background image element - z-1 keeps it below backdrop blur (z-5). - CSS backgroundImage provides instant display. - Use native img for blob URLs to prevent repeated fetch requests from Next.js Image. */} + {/* Background image element */} {backgroundImageUrl && !backgroundVideoUrl && ( -
+
{backgroundImageUrl.startsWith('blob:') ? ( // eslint-disable-next-line @next/next/no-img-element )} - {/* Background video - z-1 keeps it below backdrop blur (z-5) */} + {/* Background video */} {backgroundVideoUrl && (
- {/* End new page content wrapper */} + {/* End page background wrapper */} + + {/* Page elements wrapper - z-[46] keeps it ABOVE carousel slide (z-10) AND carousel controls (z-45). + UI controls (z-50) remain on top. + Fades in together with background. */} +
+ {pageElements.map((element: CanvasElement) => ( + handleElementClick(element)} + resolveUrl={resolveUrlWithBlob} + onGalleryCardClick={(cardIndex) => + handleGalleryCardClick(element, cardIndex) + } + /> + ))} +
+ {/* End page elements wrapper */} {/* Controls: Offline toggle and Fullscreen button */}
diff --git a/frontend/src/components/UiElements/elements/CarouselElement.tsx b/frontend/src/components/UiElements/elements/CarouselElement.tsx index e9addc0..c99059d 100644 --- a/frontend/src/components/UiElements/elements/CarouselElement.tsx +++ b/frontend/src/components/UiElements/elements/CarouselElement.tsx @@ -340,8 +340,8 @@ const CarouselElement: React.FC = ({ }; // Full-width carousel - two layers: - // 1. Background image layer at z-10 (behind canvas elements) - // 2. Navigation/caption layer at z-30 (above everything for clickability) + // 1. Background image layer at z-10 (behind canvas z-[46]) + // 2. Navigation/caption layer at z-[47] (above canvas z-[46], below UI controls z-50) const fullWidthBackground = (
{currentSlide?.imageUrl && ( @@ -359,7 +359,7 @@ const CarouselElement: React.FC = ({ const fullWidthControls = (
@@ -400,7 +400,7 @@ const CarouselElement: React.FC = ({ ); // Full-width mode: use portal to render outside transform hierarchy - // Background at z-10, controls at z-30 for clickability + // Background at z-10, controls at z-[47] for clickability (above canvas z-[46]) if (isFullWidth) { // SSR safety: only use portal when mounted in browser if (!isMounted) { diff --git a/frontend/src/pages/constructor.tsx b/frontend/src/pages/constructor.tsx index e0fb408..b5d537e 100644 --- a/frontend/src/pages/constructor.tsx +++ b/frontend/src/pages/constructor.tsx @@ -1426,7 +1426,7 @@ const ConstructorPage = ({ mode = 'constructor' }: ConstructorPageProps) => {
-
+

{projectName || 'Loading project...'}

@@ -1476,10 +1476,11 @@ const ConstructorPage = ({ mode = 'constructor' }: ConstructorPageProps) => { /> )} + {/* Canvas container: z-[46] creates stacking context above carousel (z-10 bg, z-45 controls) portaled to body */}
{ }} > - { - pageSwitch.markBackgroundReady(); - setIsBackgroundReady(true); - }} - videoAutoplay={backgroundVideoAutoplay} - videoLoop={backgroundVideoLoop} - videoMuted={backgroundVideoMuted} - videoStartTime={backgroundVideoStartTime} - videoEndTime={backgroundVideoEndTime} - /> + {/* Background wrapper - z-5 keeps it BELOW carousel slide (z-10) */} +
+ { + pageSwitch.markBackgroundReady(); + setIsBackgroundReady(true); + }} + videoAutoplay={backgroundVideoAutoplay} + videoLoop={backgroundVideoLoop} + videoMuted={backgroundVideoMuted} + videoStartTime={backgroundVideoStartTime} + videoEndTime={backgroundVideoEndTime} + /> +
- {/* Elements container - z-10 ensures they appear above backdrop layer */} + {/* Elements container - z-[46] keeps it ABOVE carousel slide (z-10) AND carousel controls (z-45). + UI controls (z-50) remain on top. */}
{isLoading ? (