'use client'; import { useState, type ReactNode } from 'react'; import type { SlideBackground } from '@openmaic/dsl'; export interface BackgroundInsertPickerLabels { readonly solid: string; readonly image: string; readonly color: string; } export interface BackgroundInsertPickerProps { readonly background?: SlideBackground; readonly labels?: Partial; readonly renderImagePicker?: (onPick: (src: string) => void) => ReactNode; readonly onChange: (background: SlideBackground) => void; } const DEFAULT_LABELS: BackgroundInsertPickerLabels = { solid: 'Solid', image: 'Image', color: 'Background color', }; function isColor(value: string) { return /^#[0-9a-f]{6}$/i.test(value); } export function BackgroundInsertPicker({ background, labels: labelOverrides, renderImagePicker, onChange, }: BackgroundInsertPickerProps) { const labels = { ...DEFAULT_LABELS, ...labelOverrides }; const [tab, setTab] = useState(background?.type === 'image' ? 'image' : 'solid'); const [color, setColor] = useState( background?.type === 'solid' && background.color ? background.color : '#ffffff', ); const backgroundType = background?.type ?? 'solid'; const backgroundColor = background?.type === 'solid' ? background.color : undefined; const [syncedBackground, setSyncedBackground] = useState({ type: backgroundType, color: backgroundColor, }); if (backgroundType !== syncedBackground.type || backgroundColor !== syncedBackground.color) { setSyncedBackground({ type: backgroundType, color: backgroundColor }); if (backgroundType === 'image') setTab('image'); if (backgroundColor) setColor(backgroundColor); } const applyColor = (nextColor: string) => { setColor(nextColor); if (isColor(nextColor)) onChange({ type: 'solid', color: nextColor }); }; return (
{tab === 'solid' ? ( ) : (
{renderImagePicker?.((src) => onChange({ type: 'image', image: { src, size: 'cover' } }))}
)}
); }