Give builder fields persistent labels, treat description as optional, and validate save-progress email with a real form.

Name stays required; description is a labelled optional textarea. Email uses native validity and form submit. Drop the dead workshop link and fix a few copy errors.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
adilallo
2026-09-10 11:37:41 -06:00
co-authored by Cursor
parent 130663f930
commit 42d83c8b62
33 changed files with 437 additions and 125 deletions
@@ -80,6 +80,8 @@ function CustomMethodCardWizardViewComponent({
<TextArea
appearance="default"
formHeader={false}
showHelpIcon={false}
label={copy.step2.title}
placeholder={copy.step2.fieldPlaceholder}
value={policyDescription}
maxLength={maxDescriptionChars}
@@ -1,6 +1,6 @@
"use client";
import { memo } from "react";
import { memo, useId } from "react";
import { ASSETS, getAssetPath } from "../../../../../lib/assetUtils";
import InputWithCounter from "../../../../components/controls/InputWithCounter";
import TextArea from "../../../../components/controls/TextArea";
@@ -39,6 +39,7 @@ function CustomMethodCardWizardFieldBodiesViewComponent({
onProportionBlockTitleChange,
onProportionDefaultChange,
}: CustomMethodCardWizardFieldBodiesViewProps) {
const placeholderFieldId = useId();
const uploadPreviewTrimmed = uploadAssetPreviewUrl?.trim() ?? "";
const hasUploadPreview = uploadPreviewTrimmed.length > 0;
@@ -53,10 +54,14 @@ function CustomMethodCardWizardFieldBodiesViewComponent({
maxLength={CUSTOM_METHOD_CARD_WIZARD_MAX_FIELD_CHARS}
/>
<div className="flex flex-col gap-2">
<label className="text-[14px] leading-[20px] font-medium text-[var(--color-content-default-primary)]">
<label
htmlFor={placeholderFieldId}
className="text-[14px] leading-[20px] font-medium text-[var(--color-content-default-primary)]"
>
{copy.text.placeholderLabel}
</label>
<TextArea
id={placeholderFieldId}
formHeader={false}
appearance="embedded"
value={textPlaceholderBody}
@@ -84,6 +89,7 @@ function CustomMethodCardWizardFieldBodiesViewComponent({
/>
<TextInput
formHeader={false}
label={copy.badges.blockTitleLabel}
placeholder={copy.badges.blockTitlePlaceholder}
value={badgeBlockTitle}
onChange={(e) => onBadgeBlockTitleChange(e.target.value)}