Skip to content

Pending Review

Pending Review from User Experience (UX)

Form Component

Overview

The PWC Form component provides a comprehensive form container with built-in validation, error handling, and state management. Built with Lit web components and context API, it offers seamless integration with all form field components while providing consistent layout, submission handling, and user feedback patterns.

Core Capabilities

  • Form Context Management - Centralized state management for form data, validation, loading, and submission states

  • Validation Integration - Automatic validation coordination across all form fields with real-time feedback

  • Error Handling - Built-in error display with toast notifications and graceful failure recovery

  • Loading States - Skeleton loading during data fetch and submission processing with disabled state management

  • Responsive Layout - Flexible sizing options and responsive design that adapts to different screen sizes and containers

  • Keyboard Support - Enter key submission and full keyboard navigation with proper focus management

When to use Form:

  • Data entry interfaces requiring validation, error handling, and structured submission workflows

  • Settings and configuration pages with multiple related form fields and save/cancel actions

  • User registration, profile editing, and account management interfaces with complex validation rules

  • Multi-section forms with grouped fields and progressive disclosure patterns

When not to use Form:

  • Simple single-field inputs like search boxes that don't require comprehensive form handling

  • Read-only data displays that should use display components instead of form structures

  • Navigation interfaces where buttons should trigger routing rather than form submission

Basic Implementation

import React from 'react';
import { PwcForm, PwcFormSection, PwcInput, PwcHeading, PwcSubmitEvent } from "@progress-i360/pwc-react";

function MyComponent() {
  const handleSubmit = (event: Event) => {
    const detail = (event as PwcSubmitEvent).detail;

    // Process form submission
    if (detail.payload.name && detail.payload.email) {
      detail.success();
    } else {
      detail.failure({
        message: 'Please fill in all required fields'
      });
    }
  };

  return (
    <PwcForm
      heading="User Profile"
      hint="Update your personal information"
      showButtons
      onPwcSubmit={handleSubmit}
    >
      <PwcFormSection heading="Personal Information">
        <PwcInput name="name" label="Full Name" required />
        <PwcInput name="email" label="Email Address" type="email" required />
      </PwcFormSection>
    </PwcForm>
  );
}
import { useEffect, useRef, useState } from 'react';
import '@progress-i360/progress-web-components/checkbox';
import '@progress-i360/progress-web-components/form';
import '@progress-i360/progress-web-components/form-section';
import '@progress-i360/progress-web-components/input';

type FormElement = HTMLElement & {
  disabled?: boolean;
};

type SubmitDetail = {
  formData: FormData;
  success: () => void;
  failure: (payload: { message: string }) => void;
};

function AccountSettingsForm() {
  const formRef = useRef<FormElement | null>(null);
  const [isSubmitting, setIsSubmitting] = useState(false);

  useEffect(() => {
    const formElement = formRef.current;
    if (!formElement) {
      return;
    }

    const handleSubmit = async (event: Event) => {
      const detail = (event as CustomEvent<SubmitDetail>).detail;
      setIsSubmitting(true);

      try {
        await new Promise((resolve) => setTimeout(resolve, 1000));
        detail.success();
      } catch (error) {
        detail.failure({ message: 'Failed to save data. Please try again.' });
      } finally {
        setIsSubmitting(false);
      }
    };

    formElement.addEventListener('pwc-submit', handleSubmit);
    return () => formElement.removeEventListener('pwc-submit', handleSubmit);
  }, []);

  useEffect(() => {
    if (formRef.current) {
      formRef.current.disabled = isSubmitting;
    }
  }, [isSubmitting]);

  return (
    <pwc-form
      ref={formRef}
      heading="Account Settings"
      hint="Manage your profile preferences"
      show-buttons="true"
      size="m"
    >
      <pwc-form-section heading="Account Settings">
        <pwc-input name="username" label="Username" required></pwc-input>
        <pwc-checkbox name="notifications" label="Enable notifications"></pwc-checkbox>
      </pwc-form-section>
    </pwc-form>
  );
}
import { Component, CUSTOM_ELEMENTS_SCHEMA } from "@angular/core";
import "@progress-i360/progress-web-components/body";
import "@progress-i360/progress-web-components/button";
import "@progress-i360/progress-web-components/button-group";
import "@progress-i360/progress-web-components/checkbox";
import "@progress-i360/progress-web-components/flex";
import "@progress-i360/progress-web-components/form";
import "@progress-i360/progress-web-components/form-section";
import "@progress-i360/progress-web-components/input";

@Component({
  selector: 'form-demo',
  template: `
    <pwc-form 
      [heading]="formHeading" 
      [hint]="formHint"
      [showButtons]="true"
      size="m"
      (pwc-submit)="handleSubmit($event)"
      (pwc-cancel)="handleCancel()">

      <pwc-form-section>
        <pwc-input 
          name="name" 
          label="Full Name" 
          [required]="true"
          autoFocus>
        </pwc-input>

        <pwc-input 
          name="email" 
          label="Email Address" 
          type="email"
          [required]="true">
        </pwc-input>

        <pwc-checkbox 
          name="newsletter" 
          label="Subscribe to newsletter">
        </pwc-checkbox>

        <pwc-button-group 
          name="plan" 
          label="Subscription Plan"
          [options]="planOptions"
          [required]="true">
        </pwc-button-group>
      </pwc-form-section>

    </pwc-form>

    <pwc-flex direction="column" gap="s" style="margin-top: 16px;">
      <pwc-button label="Toggle Form State" variant="outline" (pwc-click)="toggleFormState()"></pwc-button>
      <pwc-body [content]="'Submissions: ' + submissionCount + ', Form State: ' + formState" color="subtle" size="xs"></pwc-body>
    </pwc-flex>
  `,
  schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class FormDemo {
  formHeading = 'User Registration';
  formHint = 'Please fill out all required fields to create your account.';
  submissionCount = 0;
  formState = 'Ready';

  planOptions = [
    { label: 'Basic', value: 'basic' },
    { label: 'Pro', value: 'pro' },
    { label: 'Enterprise', value: 'enterprise' }
  ];

  handleSubmit(e: Event) {
    const ce = (e as CustomEvent);
    this.formState = 'Submitting...';

    // Simulate form submission
    setTimeout(() => {
      this.submissionCount++;
      this.formState = 'Success';
      ce.detail.success();

      setTimeout(() => {
        this.formState = 'Ready';
      }, 2000);
    }, 1500);
  }

  handleCancel() {
    this.formState = 'Cancelled';
    setTimeout(() => {
      this.formState = 'Ready';
    }, 1000);
  }

  toggleFormState() {
    if (this.formHeading === 'User Registration') {
      this.formHeading = 'Profile Update';
      this.formHint = 'Update your account information below.';
    } else {
      this.formHeading = 'User Registration';
      this.formHint = 'Please fill out all required fields to create your account.';
    }
  }
}
import '@progress-i360/progress-web-components/checkbox';
import '@progress-i360/progress-web-components/form';
import '@progress-i360/progress-web-components/form-section';
import '@progress-i360/progress-web-components/input';

const form = document.createElement('pwc-form');
form.setAttribute('heading', 'Contact Form');
form.setAttribute('hint', 'We will reach out within 2 business days.');
form.setAttribute('show-buttons', 'true');
form.setAttribute('size', 'm');

const section = document.createElement('pwc-form-section');
section.setAttribute('heading', 'Details');

const nameField = document.createElement('pwc-input');
nameField.setAttribute('name', 'name');
nameField.setAttribute('label', 'Full Name');
nameField.setAttribute('required', 'true');

const contactOptIn = document.createElement('pwc-checkbox');
contactOptIn.setAttribute('name', 'contact-opt-in');
contactOptIn.setAttribute('label', 'Allow follow-up emails');

section.append(nameField, contactOptIn);
form.appendChild(section);

form.addEventListener('pwc-submit', (event) => {
  const { formData, success } = event.detail;
  console.log('Submitted data:', formData.get('name'));
  success();
});

document.body.appendChild(form);

Usage Patterns

  • Single-Page Forms - Complete forms with validation, error handling, and submission for user registration, profile updates, and settings

  • Multi-Section Forms - Complex forms with grouped sections for different categories of information and progressive disclosure

  • Modal Forms - Compact forms within dialogs and overlays for quick data entry and confirmation workflows

  • Wizard-Style Forms - Step-by-step forms with multiple sections and conditional field display based on user selections

Best Practices

Content Strategy Guidelines

  • Clear Form Structure - Use descriptive headings and helpful hints to guide users through the form completion process

  • Logical Field Grouping - Organize related fields into sections with meaningful headings and appropriate visual separation

  • Progressive Disclosure - Show only relevant fields and sections based on user selections to reduce cognitive load

  • Helpful Error Messages - Provide specific, actionable error messages that help users understand and fix validation issues

Performance Optimization

  • Lazy Validation - Validate fields on blur or change events rather than continuously during typing to reduce processing

  • Efficient State Updates - Use context efficiently to minimize re-renders and update only affected form components

  • Debounced Submissions - Prevent double submissions and rapid-fire form processing with appropriate debouncing

  • Memory Management - Properly clean up event listeners and context subscriptions when forms are unmounted

Integration Architecture

  • Context-Driven Design - Leverage form context to coordinate state between form fields and validation logic

  • Error Boundary Integration - Implement proper error boundaries to handle form failures gracefully

  • Loading State Management - Coordinate loading states across all form components for consistent user experience

  • Accessibility Standards - Ensure proper ARIA attributes, keyboard navigation, and screen reader compatibility

Common Use Cases

User Account Management

  • Registration forms with validation for usernames, passwords, and email verification

  • Profile editing interfaces with personal information, preferences, and privacy settings

  • Account security forms for password changes, two-factor authentication setup, and security questions

Business Data Entry

  • Customer information forms with contact details, addresses, and business relationship data

  • Order processing forms with product selection, quantities, pricing, and shipping information

  • Configuration interfaces for system settings, integration parameters, and workflow customization

Content Management

  • Article creation and editing forms with rich text content, metadata, and publishing options

  • Media upload forms with file selection, descriptions, categorization, and access permissions

  • Survey and feedback forms with various question types, conditional logic, and response validation

Troubleshooting

Common Issues

Actions Not Triggering

Symptoms: Form submission or validation events don't fire properly

Solutions:

  • Verify event listeners are attached to correct form events (pwc-submit, pwc-load)

  • Check form context is properly provided and consumed by child components

  • Ensure form fields have correct name attributes for proper data binding

Actions Not Visible

Symptoms: Form buttons, error messages, or loading states don't appear

Solutions:

  • Confirm showButtons property is set when using built-in form buttons

  • Check error handling callbacks are properly implemented for error display

  • Verify form context loading states are properly managed and displayed

Layout Issues

Symptoms: Form sections appear misaligned or with incorrect spacing

Solutions:

  • Use appropriate size property (xs, s, m, l, xl) for form container width

  • Check parent container styling doesn't conflict with form layout

  • Ensure form sections and fields use consistent gap and padding values

Icon Problems

Symptoms: Form validation icons, loading spinners, or error indicators don't display

Solutions:

  • Verify icon system is loaded and available for form field validation states

  • Check design tokens are loaded for proper color and styling of form elements

  • Ensure form context properly communicates validation states to child components

Implementation Support

  • Form Architecture - Pattern guidance for complex form structures with validation, conditional fields, and multi-step workflows

  • State Management - Best practices for efficient form data handling, validation coordination, and submission processing

  • Accessibility Compliance - WCAG implementation strategies for form navigation, error announcement, and screen reader support

Resources

Storybook Documentation

For comprehensive API documentation, interactive examples, and testing tools: 📖 View Complete API Documentation in Storybook →


This guide provides high-level implementation guidance. For detailed API specifications and interactive examples, visit our Storybook documentation.