39948-vm/frontend/src/components/ElementSettings/GallerySectionStyleInputs.tsx
2026-04-03 13:45:15 +04:00

398 lines
14 KiB
TypeScript

/**
* GallerySectionStyleInputs
*
* Reusable component for gallery section style inputs.
* Used in the CSS tab to configure wrapper, header, title, span, and card styles.
*/
import React from 'react';
import { FONT_OPTIONS } from '../../lib/fonts';
interface GallerySectionStyleInputsProps {
sectionLabel: string;
prefix: string;
values: Record<string, string | number>;
onChange: (prop: string, value: string | number) => void;
showFont?: boolean;
showColumns?: boolean;
showGap?: boolean;
showBlur?: boolean;
showTitleStyles?: boolean;
showDimensions?: boolean;
showAspectRatio?: boolean;
showTextAlign?: boolean;
}
/**
* Reusable inputs for gallery section styling
*/
const GallerySectionStyleInputs: React.FC<GallerySectionStyleInputsProps> = ({
sectionLabel,
prefix,
values,
onChange,
showFont = false,
showColumns = false,
showGap = false,
showBlur = false,
showTitleStyles = false,
showDimensions = false,
showAspectRatio = false,
showTextAlign = false,
}) => {
return (
<div className='rounded border border-gray-200 p-2 space-y-2'>
<p className='text-[11px] font-semibold text-gray-700'>{sectionLabel}</p>
<div className='grid grid-cols-2 gap-2'>
{/* Background Color */}
<div>
<label className='mb-1 block text-[10px] text-gray-600'>
BG color
</label>
<input
className='w-full rounded border border-gray-300 px-2 py-1 text-xs'
value={values[`${prefix}BackgroundColor`] || ''}
onChange={(e) =>
onChange(`${prefix}BackgroundColor`, e.target.value)
}
placeholder='rgba(0,0,0,0.6)'
/>
</div>
{/* Text Color (not for wrapper) */}
{prefix !== 'galleryWrapper' && !showTitleStyles && (
<div>
<label className='mb-1 block text-[10px] text-gray-600'>
Text color
</label>
<input
className='w-full rounded border border-gray-300 px-2 py-1 text-xs'
value={values[`${prefix}Color`] || ''}
onChange={(e) => onChange(`${prefix}Color`, e.target.value)}
placeholder='#ffffff'
/>
</div>
)}
{/* Padding */}
<div>
<label className='mb-1 block text-[10px] text-gray-600'>
Padding
</label>
<input
className='w-full rounded border border-gray-300 px-2 py-1 text-xs'
value={values[`${prefix}Padding`] || ''}
onChange={(e) => onChange(`${prefix}Padding`, e.target.value)}
placeholder='0.75rem'
/>
</div>
{/* Border Radius */}
<div>
<label className='mb-1 block text-[10px] text-gray-600'>Radius</label>
<input
className='w-full rounded border border-gray-300 px-2 py-1 text-xs'
value={values[`${prefix}BorderRadius`] || ''}
onChange={(e) => onChange(`${prefix}BorderRadius`, e.target.value)}
placeholder='0.75rem'
/>
</div>
{/* Border */}
<div>
<label className='mb-1 block text-[10px] text-gray-600'>Border</label>
<input
className='w-full rounded border border-gray-300 px-2 py-1 text-xs'
value={values[`${prefix}Border`] || ''}
onChange={(e) => onChange(`${prefix}Border`, e.target.value)}
placeholder='1px solid #ccc'
/>
</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) */}
{showGap && (
<div>
<label className='mb-1 block text-[10px] text-gray-600'>Gap</label>
<input
className='w-full rounded border border-gray-300 px-2 py-1 text-xs'
value={values[`${prefix}Gap`] || ''}
onChange={(e) => onChange(`${prefix}Gap`, e.target.value)}
placeholder='0.5rem'
/>
</div>
)}
{/* Backdrop Blur (wrapper only) */}
{showBlur && (
<div>
<label className='mb-1 block text-[10px] text-gray-600'>Blur</label>
<input
className='w-full rounded border border-gray-300 px-2 py-1 text-xs'
value={values[`${prefix}BackdropBlur`] || ''}
onChange={(e) =>
onChange(`${prefix}BackdropBlur`, e.target.value)
}
placeholder='4px'
/>
</div>
)}
{/* Grid Columns (optional) */}
{showColumns && (
<div>
<label className='mb-1 block text-[10px] text-gray-600'>
Columns
</label>
<input
type='number'
min='1'
max='6'
className='w-full rounded border border-gray-300 px-2 py-1 text-xs'
value={values[`${prefix}Columns`] || ''}
onChange={(e) =>
onChange(`${prefix}Columns`, parseInt(e.target.value) || 3)
}
placeholder='3'
/>
</div>
)}
{/* Font Size (optional) */}
{showFont && (
<div>
<label className='mb-1 block text-[10px] text-gray-600'>
Font size
</label>
<input
className='w-full rounded border border-gray-300 px-2 py-1 text-xs'
value={values[`${prefix}FontSize`] || ''}
onChange={(e) => onChange(`${prefix}FontSize`, e.target.value)}
placeholder='0.875rem'
/>
</div>
)}
{/* Font Weight (optional) */}
{showFont && (
<div>
<label className='mb-1 block text-[10px] text-gray-600'>
Font weight
</label>
<input
className='w-full rounded border border-gray-300 px-2 py-1 text-xs'
value={values[`${prefix}FontWeight`] || ''}
onChange={(e) => onChange(`${prefix}FontWeight`, e.target.value)}
placeholder='500'
/>
</div>
)}
</div>
{/* Font Family (optional - full width) */}
{showFont && (
<div>
<label className='mb-1 block text-[10px] text-gray-600'>Font</label>
<select
className='w-full rounded border border-gray-300 px-2 py-1 text-xs'
value={values[`${prefix}FontFamily`] || ''}
onChange={(e) => onChange(`${prefix}FontFamily`, e.target.value)}
>
<option value=''>Not set</option>
{FONT_OPTIONS.map((font) => (
<option key={font.key} value={font.key}>
{font.label}
</option>
))}
</select>
</div>
)}
{/* Header Dimensions (header section only) */}
{showDimensions && (
<>
<p className='text-[10px] text-gray-500 pt-1'>Dimensions:</p>
<div className='grid grid-cols-2 gap-2'>
<div>
<label className='mb-1 block text-[10px] text-gray-600'>
Width
</label>
<input
className='w-full rounded border border-gray-300 px-2 py-1 text-xs'
value={values[`${prefix}Width`] || ''}
onChange={(e) => onChange(`${prefix}Width`, e.target.value)}
placeholder='100%, 300px'
/>
</div>
<div>
<label className='mb-1 block text-[10px] text-gray-600'>
Height
</label>
<input
className='w-full rounded border border-gray-300 px-2 py-1 text-xs'
value={values[`${prefix}Height`] || ''}
onChange={(e) => onChange(`${prefix}Height`, e.target.value)}
placeholder='200px, auto'
/>
</div>
<div>
<label className='mb-1 block text-[10px] text-gray-600'>
Min Height
</label>
<input
className='w-full rounded border border-gray-300 px-2 py-1 text-xs'
value={values[`${prefix}MinHeight`] || ''}
onChange={(e) => onChange(`${prefix}MinHeight`, e.target.value)}
placeholder='150px'
/>
</div>
<div>
<label className='mb-1 block text-[10px] text-gray-600'>
Max Height
</label>
<input
className='w-full rounded border border-gray-300 px-2 py-1 text-xs'
value={values[`${prefix}MaxHeight`] || ''}
onChange={(e) => onChange(`${prefix}MaxHeight`, e.target.value)}
placeholder='400px, 50vh'
/>
</div>
</div>
</>
)}
{/* Card Aspect Ratio and Min Height (cards only) */}
{showAspectRatio && (
<>
<p className='text-[10px] text-gray-500 pt-1'>Card dimensions:</p>
<div className='grid grid-cols-2 gap-2'>
<div>
<label className='mb-1 block text-[10px] text-gray-600'>
Aspect Ratio
</label>
<select
className='w-full rounded border border-gray-300 px-2 py-1 text-xs'
value={values[`${prefix}AspectRatio`] || ''}
onChange={(e) =>
onChange(`${prefix}AspectRatio`, e.target.value)
}
>
<option value=''>4:3 (Default)</option>
<option value='16/9'>16:9 (Widescreen)</option>
<option value='1/1'>1:1 (Square)</option>
<option value='3/2'>3:2</option>
<option value='auto'>Auto</option>
</select>
</div>
<div>
<label className='mb-1 block text-[10px] text-gray-600'>
Min Height
</label>
<input
className='w-full rounded border border-gray-300 px-2 py-1 text-xs'
value={values[`${prefix}MinHeight`] || ''}
onChange={(e) => onChange(`${prefix}MinHeight`, e.target.value)}
placeholder='150px'
/>
</div>
</div>
</>
)}
{/* Card Title Styles (cards only) */}
{showTitleStyles && (
<>
<p className='text-[10px] text-gray-500 pt-1'>Card title overlay:</p>
<div className='grid grid-cols-2 gap-2'>
<div>
<label className='mb-1 block text-[10px] text-gray-600'>
Title color
</label>
<input
className='w-full rounded border border-gray-300 px-2 py-1 text-xs'
value={values.galleryCardTitleColor || ''}
onChange={(e) =>
onChange('galleryCardTitleColor', e.target.value)
}
placeholder='#ffffff'
/>
</div>
<div>
<label className='mb-1 block text-[10px] text-gray-600'>
Title BG
</label>
<input
className='w-full rounded border border-gray-300 px-2 py-1 text-xs'
value={values.galleryCardTitleBackgroundColor || ''}
onChange={(e) =>
onChange('galleryCardTitleBackgroundColor', e.target.value)
}
placeholder='transparent'
/>
</div>
<div>
<label className='mb-1 block text-[10px] text-gray-600'>
Title size
</label>
<input
className='w-full rounded border border-gray-300 px-2 py-1 text-xs'
value={values.galleryCardTitleFontSize || ''}
onChange={(e) =>
onChange('galleryCardTitleFontSize', e.target.value)
}
placeholder='0.75rem'
/>
</div>
<div>
<label className='mb-1 block text-[10px] text-gray-600'>
Title weight
</label>
<input
className='w-full rounded border border-gray-300 px-2 py-1 text-xs'
value={values.galleryCardTitleFontWeight || ''}
onChange={(e) =>
onChange('galleryCardTitleFontWeight', e.target.value)
}
placeholder='700'
/>
</div>
</div>
<div>
<label className='mb-1 block text-[10px] text-gray-600'>
Title shadow
</label>
<input
className='w-full rounded border border-gray-300 px-2 py-1 text-xs'
value={values.galleryCardTitleShadow || ''}
onChange={(e) =>
onChange('galleryCardTitleShadow', e.target.value)
}
placeholder='0 1px 3px rgba(0,0,0,0.5)'
/>
</div>
</>
)}
</div>
);
};
export default GallerySectionStyleInputs;