2026-07-12 15:13:35 -07:00
|
|
|
import React, { CSSProperties } from 'react';
|
2026-04-05 18:31:16 -07:00
|
|
|
import { useEditor } from '@craftjs/core';
|
|
|
|
|
import {
|
2026-04-26 21:31:58 -07:00
|
|
|
IMAGE_RADIUS_PRESETS,
|
2026-04-05 18:31:16 -07:00
|
|
|
} from '../../../constants/presets';
|
|
|
|
|
import {
|
|
|
|
|
StylePanelProps,
|
|
|
|
|
SectionLabel,
|
|
|
|
|
PresetButtonGrid,
|
|
|
|
|
TextInputField,
|
2026-07-12 15:13:35 -07:00
|
|
|
useNodeProp,
|
2026-04-05 18:31:16 -07:00
|
|
|
} from './shared';
|
2026-07-12 13:00:10 -07:00
|
|
|
import { AssetPicker } from '../../../ui/AssetPicker';
|
2026-04-05 18:31:16 -07:00
|
|
|
|
|
|
|
|
/* ---------- IMAGE (with upload/browse/drop) ---------- */
|
|
|
|
|
export const ImageStylePanel: React.FC<StylePanelProps> = ({ selectedId, nodeProps }) => {
|
|
|
|
|
const { actions } = useEditor();
|
|
|
|
|
const style: CSSProperties = nodeProps.style || {};
|
|
|
|
|
|
2026-07-12 15:13:35 -07:00
|
|
|
const { setPropStyle } = useNodeProp(selectedId);
|
2026-04-05 18:31:16 -07:00
|
|
|
|
|
|
|
|
const maxWidthPresets = [
|
|
|
|
|
{ label: '25%', value: '25%' },
|
|
|
|
|
{ label: '50%', value: '50%' },
|
|
|
|
|
{ label: '75%', value: '75%' },
|
|
|
|
|
{ label: '100%', value: '100%' },
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
return (
|
|
|
|
|
<>
|
2026-07-12 13:00:10 -07:00
|
|
|
{/* Image source */}
|
2026-04-05 18:31:16 -07:00
|
|
|
<div className="guided-section">
|
|
|
|
|
<SectionLabel>Image Source</SectionLabel>
|
2026-07-12 13:00:10 -07:00
|
|
|
<AssetPicker
|
|
|
|
|
value={nodeProps.src || ''}
|
|
|
|
|
onChange={(url) => actions.setProp(selectedId, (props: any) => { props.src = url; })}
|
|
|
|
|
variant="full"
|
|
|
|
|
/>
|
2026-04-05 18:31:16 -07:00
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/* Alt Text */}
|
|
|
|
|
<TextInputField
|
|
|
|
|
label="Alt Text"
|
|
|
|
|
value={nodeProps.alt || ''}
|
|
|
|
|
placeholder="Describe the image..."
|
|
|
|
|
onChange={(v) => {
|
|
|
|
|
actions.setProp(selectedId, (props: any) => { props.alt = v; });
|
|
|
|
|
}}
|
|
|
|
|
/>
|
|
|
|
|
|
|
|
|
|
{/* Border Radius */}
|
|
|
|
|
<div className="guided-section">
|
|
|
|
|
<SectionLabel>Border Radius</SectionLabel>
|
|
|
|
|
<PresetButtonGrid
|
2026-04-26 21:31:58 -07:00
|
|
|
presets={IMAGE_RADIUS_PRESETS}
|
2026-04-05 18:31:16 -07:00
|
|
|
activeValue={style.borderRadius as string}
|
|
|
|
|
onSelect={(v) => setPropStyle('borderRadius', v)}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
|
|
|
|
|
{/* Max Width */}
|
|
|
|
|
<div className="guided-section">
|
|
|
|
|
<SectionLabel>Max Width</SectionLabel>
|
|
|
|
|
<PresetButtonGrid
|
|
|
|
|
presets={maxWidthPresets}
|
|
|
|
|
activeValue={style.maxWidth as string}
|
|
|
|
|
onSelect={(v) => setPropStyle('maxWidth', v)}
|
|
|
|
|
/>
|
|
|
|
|
</div>
|
|
|
|
|
</>
|
|
|
|
|
);
|
|
|
|
|
};
|