fixed carusel adaptivity issue
This commit is contained in:
parent
4a61fd1a69
commit
4b7fed5914
@ -35,6 +35,8 @@ interface CanvasElementProps {
|
||||
x: number,
|
||||
y: number,
|
||||
) => void;
|
||||
/** Letterbox styles for constraining fullscreen elements to canvas bounds */
|
||||
letterboxStyles?: React.CSSProperties;
|
||||
}
|
||||
|
||||
const CanvasElement: React.FC<CanvasElementProps> = ({
|
||||
@ -47,6 +49,7 @@ const CanvasElement: React.FC<CanvasElementProps> = ({
|
||||
resolveUrl,
|
||||
onGalleryCardClick,
|
||||
onCarouselButtonPositionChange,
|
||||
letterboxStyles,
|
||||
}) => {
|
||||
// Extract effect properties from element
|
||||
const effectProperties: Partial<ElementEffectProperties> = {
|
||||
@ -73,10 +76,16 @@ const CanvasElement: React.FC<CanvasElementProps> = ({
|
||||
isEditMode ? {} : effectProperties,
|
||||
);
|
||||
|
||||
// Clamp position to canvas bounds (0-100%)
|
||||
const clamp = (value: number, min: number, max: number) =>
|
||||
Math.min(Math.max(value, min), max);
|
||||
const xClamped = clamp(element.xPercent ?? 50, 0, 100);
|
||||
const yClamped = clamp(element.yPercent ?? 50, 0, 100);
|
||||
|
||||
// Build base position style
|
||||
let positionStyle: React.CSSProperties = {
|
||||
left: `${element.xPercent}%`,
|
||||
top: `${element.yPercent}%`,
|
||||
left: `${xClamped}%`,
|
||||
top: `${yClamped}%`,
|
||||
transform: 'translate(-50%, -50%)',
|
||||
// Reset button defaults to let UiElementRenderer control styling
|
||||
background: 'transparent',
|
||||
@ -130,6 +139,7 @@ const CanvasElement: React.FC<CanvasElementProps> = ({
|
||||
isDisabled={isDisabled}
|
||||
onGalleryCardClick={onGalleryCardClick}
|
||||
onCarouselButtonPositionChange={onCarouselButtonPositionChange}
|
||||
letterboxStyles={letterboxStyles}
|
||||
/>
|
||||
</button>
|
||||
);
|
||||
|
||||
@ -24,16 +24,24 @@ interface RuntimeElementProps {
|
||||
resolveUrl?: (url: string | undefined) => string;
|
||||
/** Gallery card click handler */
|
||||
onGalleryCardClick?: (cardIndex: number) => void;
|
||||
/** Letterbox styles for constraining fullscreen elements to canvas bounds */
|
||||
letterboxStyles?: React.CSSProperties;
|
||||
}
|
||||
|
||||
// Clamp position to canvas bounds (0-100%)
|
||||
const clamp = (value: number, min: number, max: number) =>
|
||||
Math.min(Math.max(value, min), max);
|
||||
|
||||
const RuntimeElement: React.FC<RuntimeElementProps> = ({
|
||||
element,
|
||||
onClick,
|
||||
resolveUrl,
|
||||
onGalleryCardClick,
|
||||
letterboxStyles,
|
||||
}) => {
|
||||
const xPercent = element.xPercent ?? 0;
|
||||
const yPercent = element.yPercent ?? 0;
|
||||
// Clamp coordinates to canvas bounds
|
||||
const xPercent = clamp(element.xPercent ?? 50, 0, 100);
|
||||
const yPercent = clamp(element.yPercent ?? 50, 0, 100);
|
||||
const rotation = element.rotation ?? 0;
|
||||
|
||||
// Extract effect properties from element
|
||||
@ -101,6 +109,7 @@ const RuntimeElement: React.FC<RuntimeElementProps> = ({
|
||||
element={element}
|
||||
resolveUrl={resolveUrl}
|
||||
onGalleryCardClick={onGalleryCardClick}
|
||||
letterboxStyles={letterboxStyles}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -713,6 +713,7 @@ export default function RuntimePresentation({
|
||||
onGalleryCardClick={(cardIndex) =>
|
||||
handleGalleryCardClick(element, cardIndex)
|
||||
}
|
||||
letterboxStyles={letterboxStyles}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
@ -794,6 +795,7 @@ export default function RuntimePresentation({
|
||||
backHeight={
|
||||
activeGalleryCarousel.element.galleryCarouselBackHeight
|
||||
}
|
||||
letterboxStyles={letterboxStyles}
|
||||
isEditMode={false}
|
||||
/>
|
||||
)}
|
||||
|
||||
@ -44,6 +44,8 @@ interface GalleryCarouselOverlayProps {
|
||||
x: number,
|
||||
y: number,
|
||||
) => void;
|
||||
// Letterbox styles for constraining overlay to canvas bounds
|
||||
letterboxStyles?: React.CSSProperties;
|
||||
}
|
||||
|
||||
const clamp = (value: number, min: number, max: number) =>
|
||||
@ -72,28 +74,38 @@ const GalleryCarouselOverlay: React.FC<GalleryCarouselOverlayProps> = ({
|
||||
backHeight,
|
||||
isEditMode = false,
|
||||
onButtonPositionChange,
|
||||
letterboxStyles,
|
||||
}) => {
|
||||
const resolve = resolveUrl ?? resolveAssetPlaybackUrl;
|
||||
const [currentIndex, setCurrentIndex] = useState(initialIndex);
|
||||
const [draggingButton, setDraggingButton] = useState<
|
||||
'prev' | 'next' | 'back' | null
|
||||
>(null);
|
||||
// Clamp positions to canvas bounds (0-100%)
|
||||
const [positions, setPositions] = useState({
|
||||
prevX,
|
||||
prevY,
|
||||
nextX,
|
||||
nextY,
|
||||
backX,
|
||||
backY,
|
||||
prevX: clamp(prevX, 0, 100),
|
||||
prevY: clamp(prevY, 0, 100),
|
||||
nextX: clamp(nextX, 0, 100),
|
||||
nextY: clamp(nextY, 0, 100),
|
||||
backX: clamp(backX, 0, 100),
|
||||
backY: clamp(backY, 0, 100),
|
||||
});
|
||||
const overlayRef = useRef<HTMLDivElement>(null);
|
||||
const canvasContainerRef = useRef<HTMLDivElement>(null);
|
||||
const touchStartRef = useRef<{ x: number; y: number } | null>(null);
|
||||
const positionsRef = useRef(positions);
|
||||
positionsRef.current = positions;
|
||||
|
||||
// Update positions when props change (e.g., when element is re-selected)
|
||||
// Update positions when props change (clamped to canvas bounds)
|
||||
useEffect(() => {
|
||||
setPositions({ prevX, prevY, nextX, nextY, backX, backY });
|
||||
setPositions({
|
||||
prevX: clamp(prevX, 0, 100),
|
||||
prevY: clamp(prevY, 0, 100),
|
||||
nextX: clamp(nextX, 0, 100),
|
||||
nextY: clamp(nextY, 0, 100),
|
||||
backX: clamp(backX, 0, 100),
|
||||
backY: clamp(backY, 0, 100),
|
||||
});
|
||||
}, [prevX, prevY, nextX, nextY, backX, backY]);
|
||||
|
||||
// Navigation handlers
|
||||
@ -169,10 +181,16 @@ const GalleryCarouselOverlay: React.FC<GalleryCarouselOverlayProps> = ({
|
||||
if (!isEditMode || !draggingButton) return;
|
||||
|
||||
const handleMove = (e: MouseEvent) => {
|
||||
const x = (e.clientX / window.innerWidth) * 100;
|
||||
const y = (e.clientY / window.innerHeight) * 100;
|
||||
const clampedX = clamp(x, 2, 98);
|
||||
const clampedY = clamp(y, 2, 98);
|
||||
// Calculate position relative to canvas container (strict - no viewport fallback)
|
||||
const container = canvasContainerRef.current;
|
||||
if (!container) return;
|
||||
|
||||
const rect = container.getBoundingClientRect();
|
||||
const x = ((e.clientX - rect.left) / rect.width) * 100;
|
||||
const y = ((e.clientY - rect.top) / rect.height) * 100;
|
||||
// Clamp to canvas bounds (0-100%)
|
||||
const clampedX = clamp(x, 0, 100);
|
||||
const clampedY = clamp(y, 0, 100);
|
||||
|
||||
setPositions((prev) => {
|
||||
// Prev and next buttons share the same Y coordinate
|
||||
@ -346,52 +364,59 @@ const GalleryCarouselOverlay: React.FC<GalleryCarouselOverlayProps> = ({
|
||||
onTouchStart={handleTouchStart}
|
||||
onTouchEnd={handleTouchEnd}
|
||||
>
|
||||
{/* Fullscreen image */}
|
||||
{imageUrl && (
|
||||
// eslint-disable-next-line @next/next/no-img-element
|
||||
<img
|
||||
src={imageUrl}
|
||||
alt={currentCard?.title || ''}
|
||||
className='absolute inset-0 h-full w-full object-cover'
|
||||
draggable={false}
|
||||
/>
|
||||
)}
|
||||
{/* Inner container constrained to canvas bounds - no conflicting CSS classes */}
|
||||
<div
|
||||
ref={canvasContainerRef}
|
||||
className='overflow-hidden'
|
||||
style={letterboxStyles || { position: 'absolute', inset: 0 }}
|
||||
>
|
||||
{/* Fullscreen image */}
|
||||
{imageUrl && (
|
||||
// eslint-disable-next-line @next/next/no-img-element
|
||||
<img
|
||||
src={imageUrl}
|
||||
alt={currentCard?.title || ''}
|
||||
className='absolute inset-0 h-full w-full object-contain'
|
||||
draggable={false}
|
||||
/>
|
||||
)}
|
||||
|
||||
{/* Prev button */}
|
||||
{renderNavButton(
|
||||
'prev',
|
||||
positions.prevX,
|
||||
positions.prevY,
|
||||
prevIconUrl,
|
||||
mdiChevronLeft,
|
||||
undefined,
|
||||
prevWidth,
|
||||
prevHeight,
|
||||
)}
|
||||
{/* Prev button */}
|
||||
{renderNavButton(
|
||||
'prev',
|
||||
positions.prevX,
|
||||
positions.prevY,
|
||||
prevIconUrl,
|
||||
mdiChevronLeft,
|
||||
undefined,
|
||||
prevWidth,
|
||||
prevHeight,
|
||||
)}
|
||||
|
||||
{/* Next button */}
|
||||
{renderNavButton(
|
||||
'next',
|
||||
positions.nextX,
|
||||
positions.nextY,
|
||||
nextIconUrl,
|
||||
mdiChevronRight,
|
||||
undefined,
|
||||
nextWidth,
|
||||
nextHeight,
|
||||
)}
|
||||
{/* Next button */}
|
||||
{renderNavButton(
|
||||
'next',
|
||||
positions.nextX,
|
||||
positions.nextY,
|
||||
nextIconUrl,
|
||||
mdiChevronRight,
|
||||
undefined,
|
||||
nextWidth,
|
||||
nextHeight,
|
||||
)}
|
||||
|
||||
{/* Back button */}
|
||||
{renderNavButton(
|
||||
'back',
|
||||
positions.backX,
|
||||
positions.backY,
|
||||
backIconUrl,
|
||||
mdiArrowLeft,
|
||||
backLabel,
|
||||
backWidth,
|
||||
backHeight,
|
||||
)}
|
||||
{/* Back button */}
|
||||
{renderNavButton(
|
||||
'back',
|
||||
positions.backX,
|
||||
positions.backY,
|
||||
backIconUrl,
|
||||
mdiArrowLeft,
|
||||
backLabel,
|
||||
backWidth,
|
||||
backHeight,
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@ -51,6 +51,8 @@ export interface UiElementRendererProps {
|
||||
x: number,
|
||||
y: number,
|
||||
) => void;
|
||||
// Letterbox styles for constraining fullscreen elements to canvas bounds
|
||||
letterboxStyles?: React.CSSProperties;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -67,6 +69,7 @@ export const UiElementRenderer: React.FC<UiElementRendererProps> = ({
|
||||
isDisabled = false,
|
||||
onGalleryCardClick,
|
||||
onCarouselButtonPositionChange,
|
||||
letterboxStyles,
|
||||
}) => {
|
||||
const { className, style } = useElementWrapperStyle({
|
||||
element,
|
||||
@ -97,6 +100,7 @@ export const UiElementRenderer: React.FC<UiElementRendererProps> = ({
|
||||
{...commonProps}
|
||||
isEditMode={isEditMode}
|
||||
onButtonPositionChange={onCarouselButtonPositionChange}
|
||||
letterboxStyles={letterboxStyles}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@ -42,6 +42,8 @@ interface CarouselElementProps {
|
||||
x: number,
|
||||
y: number,
|
||||
) => void;
|
||||
// Letterbox styles for constraining full-width carousel to canvas bounds
|
||||
letterboxStyles?: CSSProperties;
|
||||
}
|
||||
|
||||
const clamp = (value: number, min: number, max: number) =>
|
||||
@ -54,6 +56,7 @@ const CarouselElement: React.FC<CarouselElementProps> = ({
|
||||
style,
|
||||
isEditMode = false,
|
||||
onButtonPositionChange,
|
||||
letterboxStyles,
|
||||
}) => {
|
||||
const resolve = resolveUrl ?? resolveAssetPlaybackUrl;
|
||||
const slides: CarouselSlide[] = element.carouselSlides || [];
|
||||
@ -65,11 +68,12 @@ const CarouselElement: React.FC<CarouselElementProps> = ({
|
||||
const [draggingButton, setDraggingButton] = useState<'prev' | 'next' | null>(
|
||||
null,
|
||||
);
|
||||
// Clamp positions to canvas bounds (0-100%)
|
||||
const [positions, setPositions] = useState({
|
||||
prevX: element.carouselPrevX ?? 5,
|
||||
prevY: element.carouselPrevY ?? 50,
|
||||
nextX: element.carouselNextX ?? 95,
|
||||
nextY: element.carouselNextY ?? 50,
|
||||
prevX: clamp(element.carouselPrevX ?? 5, 0, 100),
|
||||
prevY: clamp(element.carouselPrevY ?? 50, 0, 100),
|
||||
nextX: clamp(element.carouselNextX ?? 95, 0, 100),
|
||||
nextY: clamp(element.carouselNextY ?? 50, 0, 100),
|
||||
});
|
||||
|
||||
// Touch swipe ref
|
||||
@ -78,13 +82,13 @@ const CarouselElement: React.FC<CarouselElementProps> = ({
|
||||
const positionsRef = useRef(positions);
|
||||
positionsRef.current = positions;
|
||||
|
||||
// Update positions when props change
|
||||
// Update positions when props change (clamped to canvas bounds)
|
||||
useEffect(() => {
|
||||
setPositions({
|
||||
prevX: element.carouselPrevX ?? 5,
|
||||
prevY: element.carouselPrevY ?? 50,
|
||||
nextX: element.carouselNextX ?? 95,
|
||||
nextY: element.carouselNextY ?? 50,
|
||||
prevX: clamp(element.carouselPrevX ?? 5, 0, 100),
|
||||
prevY: clamp(element.carouselPrevY ?? 50, 0, 100),
|
||||
nextX: clamp(element.carouselNextX ?? 95, 0, 100),
|
||||
nextY: clamp(element.carouselNextY ?? 50, 0, 100),
|
||||
});
|
||||
}, [
|
||||
element.carouselPrevX,
|
||||
@ -199,10 +203,16 @@ const CarouselElement: React.FC<CarouselElementProps> = ({
|
||||
if (!isEditMode || !draggingButton) return;
|
||||
|
||||
const handleMove = (e: MouseEvent) => {
|
||||
const x = (e.clientX / window.innerWidth) * 100;
|
||||
const y = (e.clientY / window.innerHeight) * 100;
|
||||
const clampedX = clamp(x, 2, 98);
|
||||
const clampedY = clamp(y, 2, 98);
|
||||
// Calculate position relative to canvas container (strict - no viewport fallback)
|
||||
const container = overlayRef.current;
|
||||
if (!container) return;
|
||||
|
||||
const rect = container.getBoundingClientRect();
|
||||
const x = ((e.clientX - rect.left) / rect.width) * 100;
|
||||
const y = ((e.clientY - rect.top) / rect.height) * 100;
|
||||
// Clamp to canvas bounds (0-100%)
|
||||
const clampedX = clamp(x, 0, 100);
|
||||
const clampedY = clamp(y, 0, 100);
|
||||
|
||||
setPositions((prev) => ({
|
||||
...prev,
|
||||
@ -240,11 +250,8 @@ const CarouselElement: React.FC<CarouselElementProps> = ({
|
||||
}, [isEditMode, draggingButton, onButtonPositionChange]);
|
||||
|
||||
// Convert numeric value to canvas units for responsive scaling
|
||||
// Previously used vw/vh but now uses canvas units (--cu) for uniform scaling
|
||||
const toCanvasUnit = (
|
||||
value?: string,
|
||||
dimension: 'width' | 'height' = 'width',
|
||||
): string | undefined => {
|
||||
// All dimensions use canvas units (--cu) for uniform scaling within project bounds
|
||||
const toCanvasUnit = (value?: string): string | undefined => {
|
||||
if (!value || value.trim() === '') return undefined;
|
||||
const trimmed = value.trim();
|
||||
// If value already uses canvas units or calc, preserve it
|
||||
@ -272,10 +279,8 @@ const CarouselElement: React.FC<CarouselElementProps> = ({
|
||||
return toCU(num);
|
||||
};
|
||||
|
||||
// Alias for backward compatibility
|
||||
const toViewportUnit = toCanvasUnit;
|
||||
|
||||
// Render navigation button for full-width mode
|
||||
// Coordinates are clamped to 0-100% to stay within canvas bounds
|
||||
const renderNavButton = (
|
||||
type: 'prev' | 'next',
|
||||
x: number,
|
||||
@ -287,8 +292,12 @@ const CarouselElement: React.FC<CarouselElementProps> = ({
|
||||
) => {
|
||||
const isDragging = draggingButton === type;
|
||||
const hasCustomIcon = iconUrl && iconUrl.trim() !== '';
|
||||
const widthValue = toCanvasUnit(buttonWidth, 'width');
|
||||
const heightValue = toCanvasUnit(buttonHeight, 'height');
|
||||
const widthValue = toCanvasUnit(buttonWidth);
|
||||
const heightValue = toCanvasUnit(buttonHeight);
|
||||
|
||||
// Clamp coordinates to canvas bounds (0-100%)
|
||||
const clampedX = clamp(x, 0, 100);
|
||||
const clampedY = clamp(y, 0, 100);
|
||||
|
||||
// Navigation-style: custom icon fills button (no backdrop)
|
||||
const useNavigationStyle = hasCustomIcon && (widthValue || heightValue);
|
||||
@ -302,8 +311,8 @@ const CarouselElement: React.FC<CarouselElementProps> = ({
|
||||
: 'cursor-pointer hover:scale-105'
|
||||
} ${isDragging ? 'scale-110 z-[60]' : ''}`}
|
||||
style={{
|
||||
left: `${x}%`,
|
||||
top: `${y}%`,
|
||||
left: `${clampedX}%`,
|
||||
top: `${clampedY}%`,
|
||||
transform: 'translate(-50%, -50%)',
|
||||
...(widthValue && { width: widthValue }),
|
||||
...(heightValue && { height: heightValue }),
|
||||
@ -342,60 +351,71 @@ const CarouselElement: React.FC<CarouselElementProps> = ({
|
||||
// Full-width carousel - two layers:
|
||||
// 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)
|
||||
// Both layers use letterboxStyles to constrain content to canvas bounds
|
||||
const fullWidthBackground = (
|
||||
<div className='fixed inset-0 z-10 overflow-hidden bg-black pointer-events-none'>
|
||||
{currentSlide?.imageUrl && (
|
||||
// eslint-disable-next-line @next/next/no-img-element
|
||||
<img
|
||||
src={resolve(currentSlide.imageUrl)}
|
||||
alt={currentSlide.caption || 'Carousel slide'}
|
||||
className='absolute inset-0 w-full h-full object-cover'
|
||||
draggable={false}
|
||||
/>
|
||||
)}
|
||||
{/* Inner container respects letterbox dimensions - overflow:hidden clips content to canvas */}
|
||||
<div
|
||||
className='overflow-hidden'
|
||||
style={letterboxStyles || { position: 'absolute', inset: 0 }}
|
||||
>
|
||||
{currentSlide?.imageUrl && (
|
||||
// eslint-disable-next-line @next/next/no-img-element
|
||||
<img
|
||||
src={resolve(currentSlide.imageUrl)}
|
||||
alt={currentSlide.caption || 'Carousel slide'}
|
||||
className='absolute inset-0 w-full h-full object-contain'
|
||||
draggable={false}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
const fullWidthControls = (
|
||||
<div
|
||||
ref={overlayRef}
|
||||
className='fixed inset-0 z-[47] pointer-events-none'
|
||||
onTouchStart={handleTouchStart}
|
||||
onTouchEnd={handleTouchEnd}
|
||||
>
|
||||
{/* Navigation buttons */}
|
||||
{showNavigation && (
|
||||
<>
|
||||
{renderNavButton(
|
||||
'prev',
|
||||
positions.prevX,
|
||||
positions.prevY,
|
||||
element.carouselPrevIconUrl,
|
||||
mdiChevronLeft,
|
||||
element.carouselPrevWidth,
|
||||
element.carouselPrevHeight,
|
||||
)}
|
||||
{renderNavButton(
|
||||
'next',
|
||||
positions.nextX,
|
||||
positions.nextY,
|
||||
element.carouselNextIconUrl,
|
||||
mdiChevronRight,
|
||||
element.carouselNextWidth,
|
||||
element.carouselNextHeight,
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
<div className='fixed inset-0 z-[47] pointer-events-none'>
|
||||
{/* Inner container respects letterbox dimensions - overflow:hidden clips content to canvas */}
|
||||
<div
|
||||
ref={overlayRef}
|
||||
className='overflow-hidden'
|
||||
style={letterboxStyles || { position: 'absolute', inset: 0 }}
|
||||
onTouchStart={handleTouchStart}
|
||||
onTouchEnd={handleTouchEnd}
|
||||
>
|
||||
{/* Navigation buttons */}
|
||||
{showNavigation && (
|
||||
<>
|
||||
{renderNavButton(
|
||||
'prev',
|
||||
positions.prevX,
|
||||
positions.prevY,
|
||||
element.carouselPrevIconUrl,
|
||||
mdiChevronLeft,
|
||||
element.carouselPrevWidth,
|
||||
element.carouselPrevHeight,
|
||||
)}
|
||||
{renderNavButton(
|
||||
'next',
|
||||
positions.nextX,
|
||||
positions.nextY,
|
||||
element.carouselNextIconUrl,
|
||||
mdiChevronRight,
|
||||
element.carouselNextWidth,
|
||||
element.carouselNextHeight,
|
||||
)}
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* Caption */}
|
||||
{currentSlide?.caption && (
|
||||
<div
|
||||
className='absolute bottom-8 left-0 right-0 text-center text-white text-lg px-4'
|
||||
style={captionFontStyle}
|
||||
>
|
||||
{currentSlide.caption}
|
||||
</div>
|
||||
)}
|
||||
{/* Caption */}
|
||||
{currentSlide?.caption && (
|
||||
<div
|
||||
className='absolute bottom-8 left-0 right-0 text-center text-white text-lg px-4'
|
||||
style={captionFontStyle}
|
||||
>
|
||||
{currentSlide.caption}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
|
||||
@ -1569,6 +1569,7 @@ const ConstructorPage = ({ mode = 'constructor' }: ConstructorPageProps) => {
|
||||
y,
|
||||
)
|
||||
}
|
||||
letterboxStyles={letterboxStyles}
|
||||
/>
|
||||
);
|
||||
})
|
||||
@ -1648,6 +1649,7 @@ const ConstructorPage = ({ mode = 'constructor' }: ConstructorPageProps) => {
|
||||
nextHeight={activeGalleryCarousel.element.galleryCarouselNextHeight}
|
||||
backWidth={activeGalleryCarousel.element.galleryCarouselBackWidth}
|
||||
backHeight={activeGalleryCarousel.element.galleryCarouselBackHeight}
|
||||
letterboxStyles={letterboxStyles}
|
||||
isEditMode={isConstructorEditMode}
|
||||
onButtonPositionChange={handleGalleryCarouselButtonPositionChange}
|
||||
/>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user