feat(builder): unify StylePanel image fields on AssetPicker

Replace the ad-hoc upload/browse/URL blocks in ImageStylePanel, HeroStylePanel
(bgImage + bgVideo), BackgroundSectionStylePanel, NavStylePanel (standalone
Logo imageSrc + Navbar logoImage), MediaStylePanel (Gallery/ContentSlider
array items), and FeaturesEditor (per-feature image) with the shared
AssetPicker component, dropping each panel's duplicated local
showBrowser/browserAssets/handleUpload state and inline asset-browser JSX.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-12 13:00:10 -07:00
parent c50b385661
commit 4674a99ec9
6 changed files with 56 additions and 347 deletions
@@ -18,6 +18,7 @@ import {
smallInputStyle,
sectionGap,
} from './shared';
import { AssetPicker } from '../../../ui/AssetPicker';
/* ---------- MEDIA (Video / Gallery / Map / Slider) ---------- */
export const MediaStylePanel: React.FC<StylePanelProps> = ({ selectedId, nodeProps }) => {
@@ -97,13 +98,17 @@ export const MediaStylePanel: React.FC<StylePanelProps> = ({ selectedId, nodePro
renderItem={(item: any, index: number) => (
<div style={{ display: 'flex', flexDirection: 'column', gap: 3 }}>
{item.src !== undefined && (
<input type="text" value={item.src || ''} onChange={(e) => {
actions.setProp(selectedId, (props: any) => {
const updated = [...(props.images || [])];
updated[index] = { ...updated[index], src: e.target.value };
props.images = updated;
});
}} placeholder="Image URL" style={smallInputStyle} />
<AssetPicker
variant="compact"
value={item.src || ''}
onChange={(url) => {
actions.setProp(selectedId, (props: any) => {
const updated = [...(props.images || [])];
updated[index] = { ...updated[index], src: url };
props.images = updated;
});
}}
/>
)}
{item.caption !== undefined && (
<input type="text" value={item.caption || ''} onChange={(e) => {
@@ -149,13 +154,17 @@ export const MediaStylePanel: React.FC<StylePanelProps> = ({ selectedId, nodePro
}} placeholder="Text" rows={2} style={{ ...smallInputStyle, resize: 'vertical' }} />
)}
{item.image !== undefined && (
<input type="text" value={item.image || ''} onChange={(e) => {
actions.setProp(selectedId, (props: any) => {
const updated = [...(props.slides || [])];
updated[index] = { ...updated[index], image: e.target.value };
props.slides = updated;
});
}} placeholder="Image URL" style={smallInputStyle} />
<AssetPicker
variant="compact"
value={item.image || ''}
onChange={(url) => {
actions.setProp(selectedId, (props: any) => {
const updated = [...(props.slides || [])];
updated[index] = { ...updated[index], image: url };
props.slides = updated;
});
}}
/>
)}
</div>
)}