gallery text align setting added

This commit is contained in:
Dmitri 2026-04-03 13:45:15 +04:00
parent ce68bad8ba
commit ce5a472b61
7 changed files with 86 additions and 9 deletions

File diff suppressed because one or more lines are too long

View File

@ -614,12 +614,15 @@ export function ElementEditorPanel({
selectedElement.galleryHeaderMinHeight || '', selectedElement.galleryHeaderMinHeight || '',
galleryHeaderMaxHeight: galleryHeaderMaxHeight:
selectedElement.galleryHeaderMaxHeight || '', selectedElement.galleryHeaderMaxHeight || '',
galleryHeaderTextAlign:
selectedElement.galleryHeaderTextAlign || 'center',
}} }}
onChange={(prop, value) => onChange={(prop, value) =>
onUpdateElement({ [prop]: value || undefined }) onUpdateElement({ [prop]: value || undefined })
} }
showFont showFont
showDimensions showDimensions
showTextAlign
/> />
<GallerySectionStyleInputs <GallerySectionStyleInputs
sectionLabel='Title' sectionLabel='Title'
@ -641,11 +644,14 @@ export function ElementEditorPanel({
selectedElement.galleryTitleBorderRadius || '', selectedElement.galleryTitleBorderRadius || '',
galleryTitleBorder: galleryTitleBorder:
selectedElement.galleryTitleBorder || '', selectedElement.galleryTitleBorder || '',
galleryTitleTextAlign:
selectedElement.galleryTitleTextAlign || 'center',
}} }}
onChange={(prop, value) => onChange={(prop, value) =>
onUpdateElement({ [prop]: value || undefined }) onUpdateElement({ [prop]: value || undefined })
} }
showFont showFont
showTextAlign
/> />
<GallerySectionStyleInputs <GallerySectionStyleInputs
sectionLabel='Info Spans' sectionLabel='Info Spans'
@ -672,6 +678,8 @@ export function ElementEditorPanel({
selectedElement.gallerySpanColumns || selectedElement.gallerySpanColumns ||
selectedElement.galleryColumns || selectedElement.galleryColumns ||
3, 3,
gallerySpanTextAlign:
selectedElement.gallerySpanTextAlign || 'center',
}} }}
onChange={(prop, value) => onChange={(prop, value) =>
onUpdateElement({ [prop]: value || undefined }) onUpdateElement({ [prop]: value || undefined })
@ -679,6 +687,7 @@ export function ElementEditorPanel({
showFont showFont
showGap showGap
showColumns showColumns
showTextAlign
/> />
<GallerySectionStyleInputs <GallerySectionStyleInputs
sectionLabel='Image Cards' sectionLabel='Image Cards'

View File

@ -20,6 +20,7 @@ interface GallerySectionStyleInputsProps {
showTitleStyles?: boolean; showTitleStyles?: boolean;
showDimensions?: boolean; showDimensions?: boolean;
showAspectRatio?: boolean; showAspectRatio?: boolean;
showTextAlign?: boolean;
} }
/** /**
@ -37,6 +38,7 @@ const GallerySectionStyleInputs: React.FC<GallerySectionStyleInputsProps> = ({
showTitleStyles = false, showTitleStyles = false,
showDimensions = false, showDimensions = false,
showAspectRatio = false, showAspectRatio = false,
showTextAlign = false,
}) => { }) => {
return ( return (
<div className='rounded border border-gray-200 p-2 space-y-2'> <div className='rounded border border-gray-200 p-2 space-y-2'>
@ -108,6 +110,24 @@ const GallerySectionStyleInputs: React.FC<GallerySectionStyleInputsProps> = ({
/> />
</div> </div>
{/* Text Alignment (optional) */}
{showTextAlign && (
<div>
<label className='mb-1 block text-[10px] text-gray-600'>
Align
</label>
<select
className='w-full rounded border border-gray-300 px-2 py-1 text-xs'
value={values[`${prefix}TextAlign`] || 'center'}
onChange={(e) => onChange(`${prefix}TextAlign`, e.target.value)}
>
<option value='left'>Left</option>
<option value='center'>Center</option>
<option value='right'>Right</option>
</select>
</div>
)}
{/* Gap (optional) */} {/* Gap (optional) */}
{showGap && ( {showGap && (
<div> <div>

View File

@ -25,6 +25,18 @@ import {
} from '../../../lib/gallerySectionStyles'; } from '../../../lib/gallerySectionStyles';
import { useBackdropEffect } from '../../../hooks/useBackdropEffect'; import { useBackdropEffect } from '../../../hooks/useBackdropEffect';
/** Convert CSS textAlign to flexbox justifyContent */
const textAlignToJustify = (textAlign?: string): string => {
switch (textAlign) {
case 'left':
return 'flex-start';
case 'right':
return 'flex-end';
default:
return 'center';
}
};
interface GalleryElementProps { interface GalleryElementProps {
element: CanvasElement; element: CanvasElement;
resolveUrl?: (url: string | undefined) => string; resolveUrl?: (url: string | undefined) => string;
@ -173,11 +185,7 @@ const GalleryElement: React.FC<GalleryElementProps> = ({
) : null} ) : null}
{/* Title */} {/* Title */}
{title && ( {title && <div style={titleStyle}>{title}</div>}
<div className='text-center' style={titleStyle}>
{title}
</div>
)}
{/* Info spans */} {/* Info spans */}
{infoSpans.length > 0 && ( {infoSpans.length > 0 && (
@ -191,8 +199,13 @@ const GalleryElement: React.FC<GalleryElementProps> = ({
return ( return (
<div <div
key={span.id} key={span.id}
className='text-center flex items-center justify-center' className='flex items-center'
style={spanItemStyle} style={{
...spanItemStyle,
justifyContent: textAlignToJustify(
spanStyle.textAlign as string,
),
}}
> >
{span.iconUrl ? ( {span.iconUrl ? (
// eslint-disable-next-line @next/next/no-img-element // eslint-disable-next-line @next/next/no-img-element

View File

@ -30,6 +30,7 @@ export const GALLERY_SECTION_DEFAULTS: Record<
fontSize: '1.5rem', // text-2xl fontSize: '1.5rem', // text-2xl
fontWeight: '700', // font-bold fontWeight: '700', // font-bold
padding: '0.25rem 0.5rem', // px-1 py-2 padding: '0.25rem 0.5rem', // px-1 py-2
textAlign: 'center',
}, },
title: { title: {
backgroundColor: '#fefce8', // bg-amber-50 backgroundColor: '#fefce8', // bg-amber-50
@ -38,6 +39,7 @@ export const GALLERY_SECTION_DEFAULTS: Record<
fontWeight: '600', // font-semibold fontWeight: '600', // font-semibold
padding: '0.5rem 0.75rem', // py-2 px-3 padding: '0.5rem 0.75rem', // py-2 px-3
borderRadius: '0.5rem', // rounded-lg borderRadius: '0.5rem', // rounded-lg
textAlign: 'center',
}, },
span: { span: {
backgroundColor: '#334155', // bg-slate-700 backgroundColor: '#334155', // bg-slate-700
@ -46,6 +48,7 @@ export const GALLERY_SECTION_DEFAULTS: Record<
fontWeight: '500', // font-medium fontWeight: '500', // font-medium
padding: '0.5rem', // py-2 px-2 padding: '0.5rem', // py-2 px-2
borderRadius: '0.5rem', // rounded-lg borderRadius: '0.5rem', // rounded-lg
textAlign: 'center',
}, },
card: { card: {
borderRadius: '0.5rem', // rounded-lg borderRadius: '0.5rem', // rounded-lg
@ -215,6 +218,14 @@ export function buildGalleryHeaderStyle(
normalizePxValue, normalizePxValue,
); );
// Text alignment with center default
applyWithDefault(
style,
'textAlign',
element.galleryHeaderTextAlign,
defaults.textAlign,
);
return style; return style;
} }
@ -270,6 +281,14 @@ export function buildGalleryTitleStyle(
} }
} }
// Text alignment with center default
applyWithDefault(
style,
'textAlign',
element.galleryTitleTextAlign,
defaults.textAlign,
);
return style; return style;
} }
@ -321,6 +340,14 @@ export function buildGallerySpanStyle(
} }
} }
// Text alignment with center default
applyWithDefault(
style,
'textAlign',
element.gallerySpanTextAlign,
defaults.textAlign,
);
return style; return style;
} }
@ -473,6 +500,7 @@ export const GALLERY_SECTION_STYLE_PROPS = [
'galleryHeaderHeight', 'galleryHeaderHeight',
'galleryHeaderMinHeight', 'galleryHeaderMinHeight',
'galleryHeaderMaxHeight', 'galleryHeaderMaxHeight',
'galleryHeaderTextAlign',
// Title // Title
'galleryTitleBackgroundColor', 'galleryTitleBackgroundColor',
'galleryTitleColor', 'galleryTitleColor',
@ -482,6 +510,7 @@ export const GALLERY_SECTION_STYLE_PROPS = [
'galleryTitlePadding', 'galleryTitlePadding',
'galleryTitleBorderRadius', 'galleryTitleBorderRadius',
'galleryTitleBorder', 'galleryTitleBorder',
'galleryTitleTextAlign',
// Spans // Spans
'gallerySpanBackgroundColor', 'gallerySpanBackgroundColor',
'gallerySpanColor', 'gallerySpanColor',
@ -493,6 +522,7 @@ export const GALLERY_SECTION_STYLE_PROPS = [
'gallerySpanBorder', 'gallerySpanBorder',
'gallerySpanGap', 'gallerySpanGap',
'gallerySpanColumns', 'gallerySpanColumns',
'gallerySpanTextAlign',
// Cards // Cards
'galleryCardBackgroundColor', 'galleryCardBackgroundColor',
'galleryCardBorderRadius', 'galleryCardBorderRadius',

View File

@ -1321,7 +1321,9 @@ const ConstructorPage = ({ mode = 'constructor' }: ConstructorPageProps) => {
<div className='absolute inset-0 z-10'> <div className='absolute inset-0 z-10'>
{isLoading ? ( {isLoading ? (
<div className='absolute inset-0 flex items-center justify-center'> <div className='absolute inset-0 flex items-center justify-center'>
<p className='text-sm text-gray-500'>Loading constructor...</p> <p className='text-sm text-gray-500'>
Loading constructor...
</p>
</div> </div>
) : pages.length === 0 ? ( ) : pages.length === 0 ? (
<div className='absolute inset-0 flex items-center justify-center'> <div className='absolute inset-0 flex items-center justify-center'>

View File

@ -115,6 +115,7 @@ export interface CanvasElement extends BaseCanvasElement {
galleryHeaderHeight?: string; galleryHeaderHeight?: string;
galleryHeaderMinHeight?: string; galleryHeaderMinHeight?: string;
galleryHeaderMaxHeight?: string; galleryHeaderMaxHeight?: string;
galleryHeaderTextAlign?: 'left' | 'center' | 'right';
// Gallery Section Styles - Title // Gallery Section Styles - Title
galleryTitleBackgroundColor?: string; galleryTitleBackgroundColor?: string;
galleryTitleColor?: string; galleryTitleColor?: string;
@ -123,6 +124,7 @@ export interface CanvasElement extends BaseCanvasElement {
galleryTitlePadding?: string; galleryTitlePadding?: string;
galleryTitleBorderRadius?: string; galleryTitleBorderRadius?: string;
galleryTitleBorder?: string; galleryTitleBorder?: string;
galleryTitleTextAlign?: 'left' | 'center' | 'right';
// Gallery Section Styles - Spans // Gallery Section Styles - Spans
gallerySpanBackgroundColor?: string; gallerySpanBackgroundColor?: string;
gallerySpanColor?: string; gallerySpanColor?: string;
@ -134,6 +136,7 @@ export interface CanvasElement extends BaseCanvasElement {
gallerySpanBorder?: string; gallerySpanBorder?: string;
gallerySpanGap?: string; gallerySpanGap?: string;
gallerySpanColumns?: number; gallerySpanColumns?: number;
gallerySpanTextAlign?: 'left' | 'center' | 'right';
// Gallery Section Styles - Cards // Gallery Section Styles - Cards
galleryCardBackgroundColor?: string; galleryCardBackgroundColor?: string;
galleryCardBorderRadius?: string; galleryCardBorderRadius?: string;