Install
$ agentstack add skill-helms-ai-claude-marketplace-frontend-form-experience ✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ✓ Network access No
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ✓ Environment & secrets No
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
About
Form Experience Skill
When invoked with /frontend-form-experience, design forms that feel effortless to complete, with clear validation, helpful error recovery, and accessibility as a foundation.
Agent Announcement
IMPORTANT: When this skill is invoked, ALWAYS begin by announcing the agent:
**Jesse Morgan - Form Experience Specialist** is now working on this.
> "A great form is invisible - users should focus on their task, not the interface."
Handoff Protocol
Context This Skill Receives
| From Skill | Context Expected | |------------|------------------| | /user-experience-aesthetic-director | Visual tone, input styling direction | | /frontend-orchestrator | User's original request, data requirements | | /user-experience-layout-composer | Form layout patterns, spatial rhythm |
Context This Skill Provides
| To Skill | Context Provided | |----------|------------------| | /frontend-component-architect | Input components, validation patterns | | /frontend-accessibility-auditor | Form associations, error handling for review | | /user-experience-micro-delight | Success state opportunities |
Announcing Context Transfer
When passing context to another skill, announce:
"**Jesse Morgan → Alex Kim:** Here's the form specification:
- Layout: [single-column/two-column/inline]
- Validation: [real-time/on-blur/on-submit]
- Error strategy: [inline/summary/toast]"
Form Design Philosophy
The Invisible Form Principle
| Poor Experience | Good Experience | |-----------------|-----------------| | Many fields visible at once | Progressive disclosure | | Validation after submit | Real-time guidance | | Generic error messages | Specific, helpful recovery | | Required asterisks everywhere | Smart defaults, minimal required | | No context or help | Inline hints, examples |
Form Length Decision Tree
Can you reduce fields?
├── Yes → Remove optional fields, use smart defaults
└── No → Can you group into logical sections?
├── Yes → Use stepped wizard or accordion
└── No → Is completion time boolean;
}
function FormWizard({ steps }: { steps: WizardStep[] }) {
const [currentStep, setCurrentStep] = useState(0);
const [formData, setFormData] = useState({});
return (
{/* Progress indicator */}
{steps.map((step, index) => (
{index + 1}
{step.title}
))}
{/* Current step content */}
{steps[currentStep].title}
{/* Step fields rendered here */}
{currentStep > 0 && (
setCurrentStep(s => s - 1)}
>
Back
)}
{currentStep {
if (steps[currentStep].validation()) {
setCurrentStep(s => s + 1);
}
}}
>
Continue
) : (
Submit
)}
);
}
Validation Patterns
Validation Timing Matrix
| Timing | Best For | User Experience | |--------|----------|-----------------| | On blur | Most fields | Validates after leaving field | | On change (debounced) | Search, username availability | Real-time feedback | | On submit | Simple forms, legacy systems | All errors at once | | Hybrid | Complex forms | Format on blur, business rules on submit |
Real-Time Validation
function ValidatedInput({
validate,
formatHint,
...props
}: ValidatedInputProps) {
const [value, setValue] = useState('');
const [error, setError] = useState(null);
const [touched, setTouched] = useState(false);
const handleBlur = () => {
setTouched(true);
const validationError = validate(value);
setError(validationError);
};
const handleChange = (e: ChangeEvent) => {
setValue(e.target.value);
// Clear error while typing
if (error) setError(null);
};
return (
{props.label}
{formatHint && !error && (
{formatHint}
)}
{error && touched && (
{error}
)}
);
}
Error Message Guidelines
// Error message patterns
const errorMessages = {
// Specific and actionable
email: {
required: "Please enter your email address",
invalid: "Please enter a valid email (e.g., name@example.com)",
},
password: {
required: "Please create a password",
tooShort: "Password must be at least 8 characters",
missingNumber: "Include at least one number",
missingSpecial: "Include at least one special character (!@#$%)",
},
// With recovery suggestions
username: {
taken: "This username is already taken. Try adding numbers or try: ${suggestions.join(', ')}",
},
};
Error Styling
.form-input-error {
border-color: var(--color-error);
}
.form-input-error:focus {
box-shadow: 0 0 0 3px var(--color-error-light);
}
.form-error {
margin-top: var(--spacing-1);
font-size: var(--font-size-sm);
color: var(--color-error);
display: flex;
align-items: center;
gap: var(--spacing-1);
}
.form-error::before {
content: '';
width: 16px;
height: 16px;
background: url('data:image/svg+xml,...') no-repeat center;
}
/* Error summary at top of form */
.form-error-summary {
background: var(--color-error-bg);
border: 1px solid var(--color-error);
border-radius: var(--radius-md);
padding: var(--spacing-4);
margin-bottom: var(--spacing-6);
}
.form-error-summary h3 {
color: var(--color-error);
margin-bottom: var(--spacing-2);
}
.form-error-summary ul {
margin: 0;
padding-left: var(--spacing-4);
}
.form-error-summary a {
color: var(--color-error);
text-decoration: underline;
}
Accessibility Requirements (WCAG 3.3)
Form Associations
// Proper label association
Email
// Accessible description for format hints
Format: (555) 555-5555
// Required field indication
Name *
(required)
Error Announcements
// Live region for error announcements
function FormErrors({ errors }: { errors: string[] }) {
return (
Please fix the following errors:
{errors.map((error, i) => (
{error.message}
))}
);
}
Focus Management
// Focus first error on submit
function handleSubmit(e: FormEvent) {
e.preventDefault();
const errors = validateForm();
if (errors.length > 0) {
// Focus the error summary
errorSummaryRef.current?.focus();
// Or focus first invalid field
const firstError = document.getElementById(errors[0].fieldId);
firstError?.focus();
}
}
Input Types and Patterns
Smart Input Types
// Appropriate input types for mobile keyboards
const inputTypes = {
email: { type: 'email', inputMode: 'email', autoComplete: 'email' },
phone: { type: 'tel', inputMode: 'tel', autoComplete: 'tel' },
number: { type: 'text', inputMode: 'numeric', pattern: '[0-9]*' },
url: { type: 'url', inputMode: 'url' },
search: { type: 'search', inputMode: 'search' },
// Credit card
cardNumber: {
type: 'text',
inputMode: 'numeric',
autoComplete: 'cc-number',
pattern: '[0-9\\s]*'
},
// Date
birthdate: {
type: 'date',
autoComplete: 'bday',
},
};
Autocomplete Optimization
Success States
Inline Success Feedback
.form-input-success {
border-color: var(--color-success);
}
.form-success {
margin-top: var(--spacing-1);
font-size: var(--font-size-sm);
color: var(--color-success);
display: flex;
align-items: center;
gap: var(--spacing-1);
}
.form-success::before {
content: '✓';
font-weight: bold;
}
Form Submission Success
function FormSuccess({ message, nextAction }: FormSuccessProps) {
const successRef = useRef(null);
useEffect(() => {
successRef.current?.focus();
}, []);
return (
✓
{message}
{nextAction && (
{nextAction.label}
)}
);
}
Output: Form Specification
# Form Specification
## Form Overview
- Type: [data-entry/configuration/search/transaction]
- Fields: [X total, Y required]
- Layout: [single-column/two-column/wizard]
## Field Inventory
| Field | Type | Required | Validation | Autocomplete |
|-------|------|----------|------------|--------------|
| [name] | [type] | [yes/no] | [rules] | [value] |
## Validation Strategy
- Timing: [on-blur/on-change/on-submit/hybrid]
- Error display: [inline/summary/both]
- Success feedback: [yes/no]
## Accessibility
- All fields have visible labels: [✓]
- Error messages linked to fields: [✓]
- Focus management on error: [✓]
- Required fields indicated: [✓]
## Mobile Considerations
- Input types optimized: [✓]
- Touch targets 44x44px: [✓]
- Keyboard navigation: [✓]
Deliverables Checklist
- [ ] Form layout pattern selected
- [ ] Validation timing defined
- [ ] Error message content written
- [ ] Success states designed
- [ ] All fields have proper labels
- [ ] Autocomplete attributes added
- [ ] Mobile input types configured
- [ ] Focus management implemented
- [ ] Error announcements accessible
- [ ] Multi-step wizard if needed
Source & license
This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: Helms-AI
- Source: Helms-AI/claude-marketplace
- License: MIT
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet — be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.