39948-vm/frontend/src/components/ElementSettings/StyleSettingsSection.tsx
2026-07-02 13:03:05 +02:00

261 lines
8.7 KiB
TypeScript

/**
* StyleSettingsSection
*
* CSS styling fields for UI elements.
* Used in element-type-defaults, project-element-defaults, and constructor pages.
*/
import React from 'react';
import FormField from '../FormField';
import type { StyleSettingsSectionProps } from './types';
import {
opacityToPercentInput,
percentInputToOpacityValue,
} from '../../lib/opacityPercent';
const StyleSettingsSection: React.FC<StyleSettingsSectionProps> = ({
values,
onChange,
}) => {
return (
<div className='space-y-3'>
<h3 className='text-sm font-semibold'>View & Stylization</h3>
<p className='text-xs text-gray-500'>
Dimensions are saved as % of canvas, border and radius as px.
</p>
<div className='grid gap-3 md:grid-cols-2'>
<FormField label='Width (%)'>
<input
type='number'
step='0.1'
min='0'
value={values.width || ''}
onChange={(event) => onChange('width', event.target.value)}
placeholder='e.g. 24'
/>
</FormField>
<FormField label='Height (%)'>
<input
type='number'
step='0.1'
min='0'
value={values.height || ''}
onChange={(event) => onChange('height', event.target.value)}
placeholder='e.g. 8'
/>
</FormField>
<FormField label='Min width (%)'>
<input
type='number'
step='0.1'
min='0'
value={values.minWidth || ''}
onChange={(event) => onChange('minWidth', event.target.value)}
/>
</FormField>
<FormField label='Max width (%)'>
<input
type='number'
step='0.1'
min='0'
value={values.maxWidth || ''}
onChange={(event) => onChange('maxWidth', event.target.value)}
/>
</FormField>
<FormField label='Min height (%)'>
<input
type='number'
step='0.1'
min='0'
value={values.minHeight || ''}
onChange={(event) => onChange('minHeight', event.target.value)}
/>
</FormField>
<FormField label='Max height (%)'>
<input
type='number'
step='0.1'
min='0'
value={values.maxHeight || ''}
onChange={(event) => onChange('maxHeight', event.target.value)}
/>
</FormField>
<FormField label='Margin'>
<input
value={values.margin || ''}
onChange={(event) => onChange('margin', event.target.value)}
placeholder='e.g. 0 auto / 0.5rem'
/>
</FormField>
<FormField label='Padding'>
<input
value={values.padding || ''}
onChange={(event) => onChange('padding', event.target.value)}
placeholder='e.g. 0.5rem 0.75rem'
/>
</FormField>
<FormField label='Gap'>
<input
value={values.gap || ''}
onChange={(event) => onChange('gap', event.target.value)}
/>
</FormField>
<FormField label='Font size'>
<input
value={values.fontSize || ''}
onChange={(event) => onChange('fontSize', event.target.value)}
placeholder='e.g. 0.875rem / clamp(...)'
/>
</FormField>
<FormField label='Line height'>
<input
value={values.lineHeight || ''}
onChange={(event) => onChange('lineHeight', event.target.value)}
/>
</FormField>
<FormField label='Font weight'>
<input
value={values.fontWeight || ''}
onChange={(event) => onChange('fontWeight', event.target.value)}
placeholder='e.g. 500 / bold'
/>
</FormField>
<FormField label='Border width (px)'>
<input
type='number'
step='1'
min='0'
value={values.border || ''}
onChange={(event) => onChange('border', event.target.value)}
placeholder='empty = none'
/>
</FormField>
<FormField label='Border radius (px)'>
<input
type='number'
step='1'
min='0'
value={values.borderRadius || ''}
onChange={(event) => onChange('borderRadius', event.target.value)}
placeholder='empty = 0'
/>
</FormField>
<FormField label='Opacity (%)'>
<input
type='number'
step='0.1'
min='0'
max='100'
value={opacityToPercentInput(values.opacity)}
onChange={(event) =>
onChange(
'opacity',
percentInputToOpacityValue(event.target.value),
)
}
placeholder='50'
/>
</FormField>
<FormField label='Shadow'>
<input
value={values.boxShadow || ''}
onChange={(event) => onChange('boxShadow', event.target.value)}
placeholder='e.g. 0 4px 12px rgba(...)'
/>
</FormField>
<FormField label='Display'>
<select
value={values.display || ''}
onChange={(event) => onChange('display', event.target.value)}
>
<option value=''>Not set</option>
<option value='block'>block</option>
<option value='inline-block'>inline-block</option>
<option value='flex'>flex</option>
<option value='inline-flex'>inline-flex</option>
<option value='grid'>grid</option>
<option value='none'>none</option>
</select>
</FormField>
<FormField label='Position'>
<select
value={values.position || ''}
onChange={(event) => onChange('position', event.target.value)}
>
<option value=''>Not set</option>
<option value='static'>static</option>
<option value='relative'>relative</option>
<option value='absolute'>absolute</option>
<option value='fixed'>fixed</option>
<option value='sticky'>sticky</option>
</select>
</FormField>
<FormField label='Justify content'>
<select
value={values.justifyContent || ''}
onChange={(event) => onChange('justifyContent', event.target.value)}
>
<option value=''>Not set</option>
<option value='flex-start'>flex-start</option>
<option value='center'>center</option>
<option value='flex-end'>flex-end</option>
<option value='space-between'>space-between</option>
<option value='space-around'>space-around</option>
<option value='space-evenly'>space-evenly</option>
</select>
</FormField>
<FormField label='Align items'>
<select
value={values.alignItems || ''}
onChange={(event) => onChange('alignItems', event.target.value)}
>
<option value=''>Not set</option>
<option value='stretch'>stretch</option>
<option value='flex-start'>flex-start</option>
<option value='center'>center</option>
<option value='flex-end'>flex-end</option>
<option value='baseline'>baseline</option>
</select>
</FormField>
<FormField label='Text align'>
<select
value={values.textAlign || ''}
onChange={(event) => onChange('textAlign', event.target.value)}
>
<option value=''>Not set</option>
<option value='left'>left</option>
<option value='center'>center</option>
<option value='right'>right</option>
<option value='justify'>justify</option>
</select>
</FormField>
<FormField label='z-index'>
<input
value={values.zIndex || ''}
onChange={(event) => onChange('zIndex', event.target.value)}
placeholder='e.g. 1 / 10'
/>
</FormField>
<FormField label='Background color'>
<input
value={values.backgroundColor || ''}
onChange={(event) =>
onChange('backgroundColor', event.target.value)
}
placeholder='e.g. #E7DDB5 / rgba(...)'
/>
</FormField>
<FormField label='Text color'>
<input
value={values.color || ''}
onChange={(event) => onChange('color', event.target.value)}
placeholder='e.g. #131C22 / inherit'
/>
</FormField>
</div>
</div>
);
};
export default StyleSettingsSection;