AgentStack
SKILL verified MIT Self-run

Frontend Form Experience

skill-helms-ai-claude-marketplace-frontend-form-experience · by Helms-AI

Form layout, validation timing, error recovery, and multi-step wizard patterns with accessibility built-in

No reviews yet
0 installs
2 views
0.0% view→install

Install

$ agentstack add skill-helms-ai-claude-marketplace-frontend-form-experience

✓ scanned · ✓ verified — works with Claude Code, Cursor, and more.

Security review

✓ Passed

No 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.

Are you the author of Frontend Form Experience? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

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.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet — be the first.

Versions

  • v0.1.0 Imported from the upstream source.