Skip to content

Pending Review

Pending Review from User Experience (UX)

Label Component

Overview

The PWC Label component provides consistent labeling for form fields with integrated hint support, required field indicators, and proper accessibility attributes. Built as a utility function, it ensures standardized typography, spacing, and semantic structure across all form input components.

Core Capabilities

  • Semantic HTML Structure - Proper label element association with form inputs using labelFor attribute for accessibility compliance
  • Required Field Indicators - Visual asterisk indicators with semantic red color coding to clearly mark mandatory fields
  • Integrated Hint Support - Built-in hint rendering with optional headings for contextual help and user guidance
  • Typography Consistency - Standardized text styling using Body component with subtle color and semi-bold weight for hierarchy
  • Flexible Layout - Responsive flex layout with consistent gap spacing that adapts to various content combinations
  • Conditional Rendering - Smart display logic that only renders when label content is provided to prevent empty elements

When to use Label:

  • Form input fields requiring proper accessibility labeling and semantic HTML structure
  • Required field indication with visual and semantic markers for user guidance
  • Contextual help integration where hints and additional information enhance form completion
  • Consistent form styling where standardized typography and spacing improve user experience

When not to use Label:

  • Standalone text that doesn't relate to form inputs - use Body or Heading components instead
  • Complex help content requiring rich formatting - consider dedicated help components or documentation
  • Navigation or action labels that should use Button or Link components for proper semantics

Basic Implementation

import React from 'react';
import { PwcInput, PwcTextarea } from "@progress-i360/pwc-react";

function MyComponent() {
  return (
    <>
      <PwcInput
        name="email"
        label="Email Address"
        type="email"
        required
        hint="We will never share your email address"
        placeholder="you@example.com"
      />

      <PwcInput
        name="company"
        label="Company Name"
        hint="Enter your registered business name"
        placeholder="Your Company Inc."
      />

      <PwcTextarea
        name="notes"
        label="Notes"
        hint="Optional context that appears below the field"
        rows={3}
      />
    </>
  );
}
import { useEffect, useRef, useState } from 'react';
import '@progress-i360/progress-web-components/input';
import '@progress-i360/progress-web-components/textarea';

type TextFieldElement = HTMLElement & { value?: string };

function ContactFormLabels() {
  const fullNameRef = useRef<TextFieldElement | null>(null);
  const phoneRef = useRef<TextFieldElement | null>(null);
  const notesRef = useRef<TextFieldElement | null>(null);

  const [fields, setFields] = useState({
    fullName: '',
    phone: '',
    notes: ''
  });

  useEffect(() => {
    const fullNameEl = fullNameRef.current;
    const phoneEl = phoneRef.current;
    const notesEl = notesRef.current;

    if (!fullNameEl || !phoneEl || !notesEl) {
      return;
    }

    const handleFullName = (event: Event) => {
      const detail = (event as CustomEvent<string>).detail;
      setFields((prev) => ({ ...prev, fullName: detail }));
    };

    const handlePhone = (event: Event) => {
      const detail = (event as CustomEvent<string>).detail;
      setFields((prev) => ({ ...prev, phone: detail }));
    };

    const handleNotes = (event: Event) => {
      const detail = (event as CustomEvent<string>).detail;
      setFields((prev) => ({ ...prev, notes: detail }));
    };

    fullNameEl.addEventListener('pwc-input', handleFullName);
    phoneEl.addEventListener('pwc-input', handlePhone);
    notesEl.addEventListener('pwc-input', handleNotes);

    return () => {
      fullNameEl.removeEventListener('pwc-input', handleFullName);
      phoneEl.removeEventListener('pwc-input', handlePhone);
      notesEl.removeEventListener('pwc-input', handleNotes);
    };
  }, []);

  useEffect(() => {
    if (fullNameRef.current) {
      fullNameRef.current.value = fields.fullName;
    }
    if (phoneRef.current) {
      phoneRef.current.value = fields.phone;
    }
    if (notesRef.current) {
      notesRef.current.value = fields.notes;
    }
  }, [fields]);

  return (
    <>
      <pwc-input
        ref={fullNameRef}
        name="full-name"
        label="Full Name"
        required
        placeholder="Enter your full name"
        hint="First and last name as they appear on official documents"
      ></pwc-input>

      <pwc-input
        ref={phoneRef}
        name="phone"
        label="Phone Number"
        type="tel"
        placeholder="+1 (555) 123-4567"
        hint="Include country code for international numbers"
      ></pwc-input>

      <pwc-textarea
        ref={notesRef}
        name="notes"
        label="Notes"
        hint="Optional context that appears below the field"
        rows="3"
      ></pwc-textarea>
    </>
  );
}
import { Component, CUSTOM_ELEMENTS_SCHEMA } from "@angular/core";
import "@progress-i360/progress-web-components/input";

@Component({
  selector: 'label-demo',
  template: `
    <div class="form-field">
      <pwc-input 
        label="Username" 
        required
        hint="Must be at least 3 characters long"
        hint-heading="Username Requirements"
        [value]="username"
        (pwc-change)="updateUsername($event)">
      </pwc-input>
    </div>

    <div class="form-field">
      <pwc-input 
        label="Optional Field" 
        hint="This field is not required"
        placeholder="Enter optional information">
      </pwc-input>
    </div>

    <div class="form-status" *ngIf="showStatus">
      <p>Username validation: {{ usernameValid ? 'Valid' : 'Too short' }}</p>
    </div>
  `,
  schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class LabelDemo {
  username = '';
  usernameValid = false;
  showStatus = false;

  updateUsername(event: any) {
    this.username = event.detail;
    this.usernameValid = this.username.length >= 3;
    this.showStatus = this.username.length > 0;
  }
}
import '@progress-i360/progress-web-components/input';
import '@progress-i360/progress-web-components/textarea';

const form = document.createElement('form');
form.style.maxWidth = '400px';
form.style.margin = '0 auto';
form.style.display = 'flex';
form.style.flexDirection = 'column';
form.style.gap = '16px';

const nameField = document.createElement('pwc-input');
nameField.setAttribute('name', 'full-name');
nameField.setAttribute('label', 'Full Name');
nameField.setAttribute('required', 'true');
nameField.setAttribute('hint', 'This name appears on your profile');

const emailField = document.createElement('pwc-input');
emailField.setAttribute('name', 'email');
emailField.setAttribute('label', 'Email Address');
emailField.setAttribute('type', 'email');
emailField.setAttribute('required', 'true');

const notesField = document.createElement('pwc-textarea');
notesField.setAttribute('name', 'notes');
notesField.setAttribute('label', 'Notes');
notesField.setAttribute('hint', 'Optional context for the team');

form.append(nameField, emailField, notesField);
document.body.appendChild(form);

Usage Patterns

  • Required Field Indication - Mark mandatory form fields with red asterisk indicators to guide user attention and prevent submission errors
  • Contextual Help Integration - Provide inline guidance through hint text that explains field requirements, formats, or usage
  • Accessibility Compliance - Ensure proper label-input association for screen readers and keyboard navigation support
  • Consistent Form Styling - Maintain uniform typography, spacing, and visual hierarchy across all form field labels

Best Practices

Content Strategy Guidelines

  • Clear and Descriptive Labels - Use concise, specific text that clearly identifies what information each field requires
  • Meaningful Hint Content - Provide helpful context that reduces user confusion and improves form completion rates
  • Consistent Language Patterns - Use similar phrasing and terminology across related form fields and sections
  • Appropriate Detail Level - Balance informativeness with brevity to avoid overwhelming users with excessive text

Performance Optimization

  • Conditional Rendering - Only render label elements when label content is provided to minimize DOM complexity
  • Efficient Text Rendering - Leverage Body component for consistent typography without custom styling overhead
  • Minimal Re-renders - Structure label props to prevent unnecessary component updates during form interactions
  • Memory Management - Properly handle label component lifecycle in dynamic form scenarios

Integration Architecture

  • Semantic HTML Structure - Use proper label elements with correct for attributes to ensure accessibility compliance
  • Design System Integration - Rely on typography tokens and color system for consistent visual presentation
  • Form Context Coordination - Integrate with form validation and error handling systems for complete user experience
  • Component Composition - Design labels to work seamlessly with all form input types and validation states

Common Use Cases

Form Field Labeling

  • Input field identification with clear, descriptive text for user guidance and accessibility
  • Required field marking with visual indicators and semantic attributes for form validation
  • Multi-language support with consistent labeling patterns across localized interfaces

Contextual Help Integration

  • Field-specific guidance with hints that explain format requirements and data expectations
  • Error prevention through proactive instruction and example content in hint text
  • Progressive disclosure of advanced options with expandable hint headings and detailed explanations

Accessibility Enhancement

  • Screen reader support through proper label-input association and semantic HTML structure
  • Keyboard navigation assistance with focus management and logical tab order support
  • High contrast compatibility with appropriate color tokens and typography hierarchy

Troubleshooting

Common Issues

Actions Not Triggering

Symptoms: Label clicks don't focus associated input fields or form interactions fail

Solutions:

  • Verify labelFor attribute matches the exact ID of the target input element

  • Check that target input element exists in DOM when label is rendered

  • Ensure no conflicting event handlers prevent label click behavior

Actions Not Visible

Symptoms: Labels don't render or appear with missing text or styling

Solutions:

  • Confirm label property contains non-empty string content for rendering

  • Check that Body component and typography tokens are properly loaded

  • Verify hint content renders correctly when hintHeading or hint props are provided

Layout Issues

Symptoms: Labels appear misaligned or with incorrect spacing relative to form inputs

Solutions:

  • Use appropriate gap and padding values that align with design system spacing tokens

  • Check parent container styling doesn't conflict with label flex layout properties

  • Ensure consistent label positioning across different form field types

Icon Problems

Symptoms: Required field asterisks don't appear or display with incorrect colors

Solutions:

  • Verify required property is properly set to boolean true value

  • Check that red-base color token is loaded and available for asterisk styling

  • Ensure hint icons render correctly when hint content includes icon references

Implementation Support

  • Accessibility Integration - Guidance for proper label-input association, ARIA attributes, and screen reader compatibility
  • Form Architecture - Best practices for label integration with validation systems, error handling, and submission workflows
  • Design System Consistency - Token usage patterns for typography, color, and spacing across label implementations

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.