원클릭으로
form-design
Design and implement accessible, validated forms with clear error states,
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Design and implement accessible, validated forms with clear error states,
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Consult and write the ARAYA postoffice — the operational-directive channel. Advisory, never a gate: read it at cycle start, append your entry at cycle end, consider its directives, never be blocked by it. Governance acts never travel the postoffice.
Audit and enforce brand compliance across all projects and platforms — logo,
Design REST and GraphQL APIs following OpenAPI 3.1 standards. Produce complete
Connect frontend to backend — type-safe API clients, request/response handling,
Implement authentication and authorization middleware — JWT validation, role-based
Design scalable component architectures — design systems, component libraries,
| name | form-design |
| description | Design and implement accessible, validated forms with clear error states, |
| governance | Constitution ENG-004: Engineering Excellence & Software Craftsmanship Standard |
Design and implement accessible, validated forms with clear error states, loading indicators, and submission handling — forms that users can complete quickly and correctly.
Poorly designed forms frustrate users, generate bad data, and lose conversions. This skill produces forms with real-time validation, clear error messages, keyboard navigation, and accessible markup — forms that guide users to success.
When building any data entry form: login, registration, settings, checkout, search, or data submission.
Form fields with types, validation rules, submission endpoint.
// src/components/UserForm/UserForm.tsx
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
import { Button } from "../Button/Button";
import { Input } from "../Input/Input";
import styles from "./UserForm.module.css";
const userSchema = z.object({
name: z.string().min(1, "Name is required").max(100),
email: z.string().email("Invalid email address"),
role: z.enum(["user", "admin"]),
});
type UserFormData = z.infer<typeof userSchema>;
export function UserForm({ onSubmit }: {
onSubmit: (data: UserFormData) => Promise<void>;
}) {
const {
register,
handleSubmit,
formState: { errors, isSubmitting },
setError,
} = useForm<UserFormData>({
resolver: zodResolver(userSchema),
});
const handleFormSubmit = async (data: UserFormData) => {
try {
await onSubmit(data);
} catch (err) {
setError("root", {
message: err instanceof Error ? err.message : "Submission failed",
});
}
};
return (
<form
onSubmit={handleSubmit(handleFormSubmit)}
className={styles.form}
noValidate
aria-label="User form"
>
<div className={styles.field}>
<label htmlFor="name">Name</label>
<Input
id="name"
{...register("name")}
aria-invalid={!!errors.name}
aria-describedby={errors.name ? "name-error" : undefined}
/>
{errors.name && (
<p id="name-error" className={styles.error} role="alert">
{errors.name.message}
</p>
)}
</div>
<div className={styles.field}>
<label htmlFor="email">Email</label>
<Input
id="email"
type="email"
{...register("email")}
aria-invalid={!!errors.email}
aria-describedby={errors.email ? "email-error" : undefined}
/>
{errors.email && (
<p id="email-error" className={styles.error} role="alert">
{errors.email.message}
</p>
)}
</div>
{errors.root && (
<div className={styles.formError} role="alert">
{errors.root.message}
</div>
)}
<Button type="submit" loading={isSubmitting}>
Create User
</Button>
</form>
);
}
<label> with htmlFor matching input idaria-invalid when error presentaria-describedby pointing to error message elementrole="alert" for screen readersnoValidate to form to use custom validation (not browser default)<label> — placeholder is not a labelnoValidate on <form> — use custom validation, not browser defaultsautocomplete="email", autocomplete="new-password") for UX