refactor(builder): remove dead component settings UI
Each component defined a .craft.related.settings panel that was never rendered -- the right panel renders only GuidedStyles (per-type *StylePanel components), never .related.settings. Removed all dead settings components across every component, their settings-only helpers (including the dead uploadToWhp/showBrowser/handleBrowse asset-browse blocks in Logo/Navbar/VideoBlock/FeaturesGrid, and CtasEditor in _cta-helpers), and dropped the now-empty related keys. Render output, .craft props/rules, and toHtml statics are unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -137,230 +137,6 @@ export const ContactForm: UserComponent<ContactFormProps> = ({
|
||||
);
|
||||
};
|
||||
|
||||
/* ---------- Settings panel ---------- */
|
||||
|
||||
const fieldTypes: ContactFormField['type'][] = ['text', 'email', 'tel', 'textarea', 'select'];
|
||||
|
||||
const ContactFormSettings: React.FC = () => {
|
||||
const { actions: { setProp }, props } = useNode((node) => ({
|
||||
props: node.data.props as ContactFormProps,
|
||||
}));
|
||||
|
||||
const fields = props.fields || defaultFields;
|
||||
|
||||
const inputStyle: CSSProperties = {
|
||||
width: '100%', padding: '3px 6px', background: '#27272a', color: '#e4e4e7',
|
||||
border: '1px solid #3f3f46', borderRadius: 4, fontSize: 11,
|
||||
};
|
||||
|
||||
const updateField = (index: number, key: keyof ContactFormField, value: any) => {
|
||||
setProp((p: ContactFormProps) => {
|
||||
const updated = [...(p.fields || defaultFields)];
|
||||
updated[index] = { ...updated[index], [key]: value };
|
||||
p.fields = updated;
|
||||
});
|
||||
};
|
||||
|
||||
const addField = () => {
|
||||
setProp((p: ContactFormProps) => {
|
||||
p.fields = [...(p.fields || defaultFields), { type: 'text', label: 'New Field', name: 'new_field', placeholder: '', required: false }];
|
||||
});
|
||||
};
|
||||
|
||||
const removeField = (index: number) => {
|
||||
setProp((p: ContactFormProps) => {
|
||||
const updated = [...(p.fields || defaultFields)];
|
||||
updated.splice(index, 1);
|
||||
p.fields = updated;
|
||||
});
|
||||
};
|
||||
|
||||
const submitColorPresets = ['#3b82f6', '#10b981', '#ef4444', '#8b5cf6', '#f59e0b', '#18181b', '#0ea5e9', '#ec4899'];
|
||||
|
||||
return (
|
||||
<div style={{ padding: '12px', display: 'flex', flexDirection: 'column', gap: '14px' }}>
|
||||
{/* Form Action */}
|
||||
<div>
|
||||
<label style={{ fontSize: 11, color: '#a1a1aa', display: 'block', marginBottom: 6 }}>Form Action URL</label>
|
||||
<input
|
||||
type="text"
|
||||
value={props.formAction || ''}
|
||||
onChange={(e) => setProp((p: ContactFormProps) => { p.formAction = e.target.value; })}
|
||||
placeholder="https://... or /api/submit"
|
||||
style={{ ...inputStyle, padding: '4px 8px', fontSize: 12 }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Relay recipient */}
|
||||
<div>
|
||||
<label style={{ fontSize: 11, color: '#a1a1aa', display: 'block', marginBottom: 6 }}>Send submissions to (email)</label>
|
||||
<input type="email" value={props.recipientEmail || ''}
|
||||
onChange={(e) => setProp((p: ContactFormProps) => { p.recipientEmail = e.target.value; })}
|
||||
placeholder="you@example.com" style={{ ...inputStyle, padding: '4px 8px', fontSize: 12 }} />
|
||||
<p style={{ fontSize: 10, color: '#71717a', margin: '4px 0 0' }}>
|
||||
Delivered via the site's contact-form relay. Requires the relay to be enabled on this server.
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<label style={{ fontSize: 11, color: '#a1a1aa', display: 'block', marginBottom: 6 }}>Thank-you page URL (optional)</label>
|
||||
<input type="text" value={props.thankYouUrl || ''}
|
||||
onChange={(e) => setProp((p: ContactFormProps) => { p.thankYouUrl = e.target.value; })}
|
||||
placeholder="/thank-you (blank = hosted page)" style={{ ...inputStyle, padding: '4px 8px', fontSize: 12 }} />
|
||||
</div>
|
||||
|
||||
{/* Success Message */}
|
||||
<div>
|
||||
<label style={{ fontSize: 11, color: '#a1a1aa', display: 'block', marginBottom: 6 }}>Success Message</label>
|
||||
<input
|
||||
type="text"
|
||||
value={props.successMessage || ''}
|
||||
onChange={(e) => setProp((p: ContactFormProps) => { p.successMessage = e.target.value; })}
|
||||
style={{ ...inputStyle, padding: '4px 8px', fontSize: 12 }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Submit Button */}
|
||||
<div>
|
||||
<label style={{ fontSize: 11, color: '#a1a1aa', display: 'block', marginBottom: 6 }}>Submit Button Text</label>
|
||||
<input
|
||||
type="text"
|
||||
value={props.submitText || ''}
|
||||
onChange={(e) => setProp((p: ContactFormProps) => { p.submitText = e.target.value; })}
|
||||
style={{ ...inputStyle, padding: '4px 8px', fontSize: 12 }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label style={{ fontSize: 11, color: '#a1a1aa', display: 'block', marginBottom: 6 }}>Submit Button Color</label>
|
||||
<div style={{ display: 'flex', gap: 4, flexWrap: 'wrap' }}>
|
||||
{submitColorPresets.map((c) => (
|
||||
<button
|
||||
key={c}
|
||||
onClick={() => setProp((p: ContactFormProps) => { p.submitColor = c; })}
|
||||
style={{
|
||||
width: 24, height: 24, borderRadius: 4, border: '1px solid #3f3f46',
|
||||
backgroundColor: c, cursor: 'pointer',
|
||||
outline: props.submitColor === c ? '2px solid #3b82f6' : 'none',
|
||||
outlineOffset: 1,
|
||||
}}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Label Color */}
|
||||
<div>
|
||||
<label style={{ fontSize: 11, color: '#a1a1aa', display: 'block', marginBottom: 6 }}>Label Color</label>
|
||||
<input
|
||||
type="color"
|
||||
value={props.labelColor || '#374151'}
|
||||
onChange={(e) => setProp((p: ContactFormProps) => { p.labelColor = e.target.value; })}
|
||||
style={{ width: 32, height: 24, border: '1px solid #3f3f46', borderRadius: 4, cursor: 'pointer', background: 'none', padding: 0 }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Input Background */}
|
||||
<div>
|
||||
<label style={{ fontSize: 11, color: '#a1a1aa', display: 'block', marginBottom: 6 }}>Input Background</label>
|
||||
<input
|
||||
type="color"
|
||||
value={props.inputBg || '#ffffff'}
|
||||
onChange={(e) => setProp((p: ContactFormProps) => { p.inputBg = e.target.value; })}
|
||||
style={{ width: 32, height: 24, border: '1px solid #3f3f46', borderRadius: 4, cursor: 'pointer', background: 'none', padding: 0 }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Input Border */}
|
||||
<div>
|
||||
<label style={{ fontSize: 11, color: '#a1a1aa', display: 'block', marginBottom: 6 }}>Input Border Color</label>
|
||||
<input
|
||||
type="color"
|
||||
value={props.inputBorder || '#d1d5db'}
|
||||
onChange={(e) => setProp((p: ContactFormProps) => { p.inputBorder = e.target.value; })}
|
||||
style={{ width: 32, height: 24, border: '1px solid #3f3f46', borderRadius: 4, cursor: 'pointer', background: 'none', padding: 0 }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* Fields Editor */}
|
||||
<div>
|
||||
<label style={{ fontSize: 11, color: '#a1a1aa', display: 'block', marginBottom: 6 }}>Fields</label>
|
||||
<div style={{ display: 'flex', flexDirection: 'column', gap: 8 }}>
|
||||
{fields.map((field, i) => (
|
||||
<div key={i} style={{ background: '#1e1e22', borderRadius: 6, padding: 8, display: 'flex', flexDirection: 'column', gap: 4 }}>
|
||||
<div style={{ display: 'flex', gap: 4, alignItems: 'center' }}>
|
||||
<select
|
||||
value={field.type}
|
||||
onChange={(e) => updateField(i, 'type', e.target.value)}
|
||||
style={{ ...inputStyle, width: 70, flex: 'none', cursor: 'pointer' }}
|
||||
>
|
||||
{fieldTypes.map((t) => <option key={t} value={t}>{t}</option>)}
|
||||
</select>
|
||||
<input
|
||||
type="text"
|
||||
value={field.label}
|
||||
onChange={(e) => updateField(i, 'label', e.target.value)}
|
||||
placeholder="Label"
|
||||
style={{ ...inputStyle, flex: 1 }}
|
||||
/>
|
||||
<button
|
||||
onClick={() => removeField(i)}
|
||||
style={{ padding: '2px 6px', fontSize: 11, background: '#ef4444', color: '#fff', border: 'none', borderRadius: 4, cursor: 'pointer', flex: 'none' }}
|
||||
>
|
||||
X
|
||||
</button>
|
||||
</div>
|
||||
<div style={{ display: 'flex', gap: 4 }}>
|
||||
<input
|
||||
type="text"
|
||||
value={field.name}
|
||||
onChange={(e) => updateField(i, 'name', e.target.value)}
|
||||
placeholder="name attr"
|
||||
style={{ ...inputStyle, flex: 1 }}
|
||||
/>
|
||||
<input
|
||||
type="text"
|
||||
value={field.placeholder}
|
||||
onChange={(e) => updateField(i, 'placeholder', e.target.value)}
|
||||
placeholder="Placeholder"
|
||||
style={{ ...inputStyle, flex: 1 }}
|
||||
/>
|
||||
</div>
|
||||
<div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
|
||||
<label style={{ fontSize: 10, color: '#a1a1aa', display: 'flex', alignItems: 'center', gap: 4, cursor: 'pointer' }}>
|
||||
<input
|
||||
type="checkbox"
|
||||
checked={field.required}
|
||||
onChange={(e) => updateField(i, 'required', e.target.checked)}
|
||||
/>
|
||||
Required
|
||||
</label>
|
||||
</div>
|
||||
{field.type === 'select' && (
|
||||
<div>
|
||||
<label style={{ fontSize: 10, color: '#a1a1aa', display: 'block', marginBottom: 2 }}>Options (one per line)</label>
|
||||
<textarea
|
||||
value={(field.options || []).join('\n')}
|
||||
onChange={(e) => updateField(i, 'options', e.target.value.split('\n').filter((s: string) => s.trim()))}
|
||||
rows={3}
|
||||
placeholder="Option 1 Option 2 Option 3"
|
||||
style={{ ...inputStyle, resize: 'vertical' }}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<button
|
||||
onClick={addField}
|
||||
style={{ marginTop: 6, width: '100%', padding: '6px', fontSize: 11, background: '#27272a', color: '#e4e4e7', border: '1px solid #3f3f46', borderRadius: 4, cursor: 'pointer' }}
|
||||
>
|
||||
+ Add Field
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
/* ---------- Craft config ---------- */
|
||||
|
||||
ContactForm.craft = {
|
||||
@@ -387,9 +163,6 @@ ContactForm.craft = {
|
||||
canMoveIn: () => false,
|
||||
canMoveOut: () => true,
|
||||
},
|
||||
related: {
|
||||
settings: ContactFormSettings,
|
||||
},
|
||||
};
|
||||
|
||||
/* ---------- HTML export ---------- */
|
||||
|
||||
Reference in New Issue
Block a user