import * as React from "react"; import type { ControlChangeMeta } from "@repo/ui"; import type { ToolcraftCollectionItemControlSchema, ToolcraftCollectionItemControlsSchema, ToolcraftControlSchema, } from "../../../schema/types"; import { renderBasicControl } from "./controls-panel-basic-renderers"; import { renderCompoundControl } from "./controls-panel-compound-renderers"; type ItemFieldChange = (nextValue: unknown, meta?: ControlChangeMeta) => void; function renderWithoutKeyframeAction({ children, }: { children: React.ReactNode; }): React.ReactNode { return children; } function getFieldName( id: string, control: ToolcraftCollectionItemControlSchema, ): string { if (typeof control.label === "string") { return control.label; } return id .replace(/([a-z0-9])([A-Z])/gu, "$1 $2") .replace(/[-_.]+/gu, " ") .replace(/^./u, (character) => character.toUpperCase()); } function asItemRecord(value: unknown): Record { if (typeof value !== "object" || value === null || Array.isArray(value)) { return {}; } return Object.fromEntries(Object.entries(value)); } export function ControlsPanelCollectionItemField({ colorLabelMode, control, id, name, onChange, target, value, }: { colorLabelMode: "authored" | "hidden"; control: ToolcraftCollectionItemControlSchema; id: string; name: string; onChange: ItemFieldChange; target: string; value: unknown; }): React.JSX.Element { const fieldSchema: ToolcraftControlSchema = { ...control, target }; const shouldShowColorFieldLabel = () => colorLabelMode === "authored" && control.label !== false; const rendered = renderBasicControl({ commit: onChange, control: fieldSchema, id, name, usesHeaderKeyframeAction: false, value, vectorPadShape: "compact", withKeyframeLabelAction: renderWithoutKeyframeAction, }) ?? renderCompoundControl({ commit: onChange, commitWithLabel: () => onChange, control: fieldSchema, id, name, sectionHasOnlyColorFields: false, shouldShowColorFieldLabel, usesHeaderKeyframeAction: false, value, withKeyframeLabelAction: renderWithoutKeyframeAction, }); if (rendered == null) { throw new Error( `Unsupported Toolcraft collection item field: ${control.type}`, ); } return <>{rendered}; } export function ControlsPanelCollectionItemFields({ controls, id, onChange, target, value, }: { controls: ToolcraftCollectionItemControlsSchema; id: string; onChange: ( nextValue: Readonly>, fieldName: string, meta?: ControlChangeMeta, ) => void; target: string; value: unknown; }): React.JSX.Element { const record = asItemRecord(value); return (
{Object.entries(controls).map(([fieldId, field]) => { const fieldName = getFieldName(fieldId, field); return ( onChange({ ...record, [fieldId]: nextValue }, fieldName, meta) } target={target} value={record[fieldId] ?? field.defaultValue} /> ); })}
); }