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
+25 -4
View File
@@ -1,10 +1,31 @@
/** RFC 5321 max mailbox length (no angle brackets). */
export const EMAIL_MAX_LEN = 254;
/** Pragmatic check for the create-flow “save progress” email field (draft + footer enablement). */
/**
* Fallback when `HTMLInputElement.checkValidity()` is unavailable (SSR).
* Matches the HTML living standards type=email pattern closely enough
* for the save-progress field; the live input is the source of truth in
* the browser.
*/
const EMAIL_FALLBACK_PATTERN =
/^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
/**
* Whether a create-flow save-progress email would pass a required
* `type="email"` inputs `checkValidity()`. Does not trim: native
* validity rejects leading or trailing spaces.
*/
export function isValidCreateFlowSaveEmail(value: unknown): boolean {
if (typeof value !== "string") return false;
const t = value.trim();
if (t.length === 0 || t.length > EMAIL_MAX_LEN) return false;
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(t);
if (value.length === 0 || value.length > EMAIL_MAX_LEN) return false;
// Native type=email rejects whitespace; jsdoms checkValidity does not.
if (/\s/.test(value)) return false;
if (typeof document === "undefined") {
return EMAIL_FALLBACK_PATTERN.test(value);
}
const input = document.createElement("input");
input.type = "email";
input.required = true;
input.value = value;
return input.checkValidity();
}