Skip to content

Pending Review

Pending Review from User Experience (UX)

Number Component

Overview

The PWC Number component provides a specialized numeric input field with integrated stepper controls, validation, and form integration. Built on the InputBase foundation, it offers precise numeric data entry with configurable constraints, accessibility features, and seamless integration with the PWC form system.

Core Capabilities

  • Integrated Stepper Controls - Optional increment/decrement buttons with configurable visibility and precise value manipulation
  • Numeric Validation - Built-in browser validation with min/max constraints and real-time feedback
  • Form System Integration - Seamless connection with PWC forms, validation contexts, and data management
  • Loading State Support - Skeleton rendering during form loading with consistent visual feedback
  • Accessibility Compliance - Full keyboard navigation, screen reader support, and semantic HTML structure
  • Value Type Safety - Strong typing for numeric values with automatic parsing and validation

When to use Number:

  • Numeric data entry requiring precise integer values with clear boundaries and constraints
  • Forms needing stepper controls for quantity selection, rating inputs, or incremental value adjustment
  • Data collection interfaces where numeric validation and user guidance are essential for accuracy
  • Settings panels with numeric configuration options requiring immediate feedback and validation

When not to use Number:

  • Decimal or floating-point numbers requiring precision beyond integer values
  • Large numeric ranges where stepper controls become impractical for efficient data entry
  • Simple numeric display content that doesn't require user input or interaction capabilities

Basic Implementation

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

function QuantitySelector() {
  const [values, setValues] = useState({
    quantity: 1,
    rating: 3
  });

  const handleValueChange = (name, value) => {
    setValues(prev => ({ ...prev, [name]: value }));
  };

  return (
    <>
      <PwcNumber
        name="quantity"
        label="Quantity"
        hint="Select number of items"
        min={1}
        max={10}
        required
        value={values.quantity}
        onChange={(e) => handleValueChange('quantity', e.detail)}
      />

      <PwcNumber
        name="rating"
        label="Rating"
        hint="Rate from 1 to 5 stars"
        min={1}
        max={5}
        value={values.rating}
        onChange={(e) => handleValueChange('rating', e.detail)}
      />
    </>
  );
}
import { useEffect, useRef, useState } from 'react';
import '@progress-i360/progress-web-components/number';

type NumberElement = HTMLElement & { value?: number };

function ProductConfiguration() {
  const quantityRef = useRef<NumberElement | null>(null);
  const priorityRef = useRef<NumberElement | null>(null);

  const [config, setConfig] = useState({
    quantity: 1,
    priority: 3
  });

  useEffect(() => {
    const quantityEl = quantityRef.current;
    const priorityEl = priorityRef.current;

    if (!quantityEl || !priorityEl) {
      return;
    }

    const handleQuantity = (event: Event) => {
      const detail = (event as CustomEvent<number>).detail;
      setConfig((prev) => ({ ...prev, quantity: detail }));
    };

    const handlePriority = (event: Event) => {
      const detail = (event as CustomEvent<number>).detail;
      setConfig((prev) => ({ ...prev, priority: detail }));
    };

    quantityEl.addEventListener('pwc-change', handleQuantity);
    priorityEl.addEventListener('pwc-change', handlePriority);

    return () => {
      quantityEl.removeEventListener('pwc-change', handleQuantity);
      priorityEl.removeEventListener('pwc-change', handlePriority);
    };
  }, []);

  useEffect(() => {
    if (quantityRef.current) {
      quantityRef.current.value = config.quantity;
    }
    if (priorityRef.current) {
      priorityRef.current.value = config.priority;
    }
  }, [config]);

  return (
    <>
      <pwc-number
        ref={quantityRef}
        name="quantity"
        label="Item Quantity"
        hint="Number of items to process"
        min="1"
        max="100"
        required
      ></pwc-number>

      <pwc-number
        ref={priorityRef}
        name="priority"
        label="Processing Priority"
        hint="Higher numbers = higher priority"
        min="1"
        max="10"
      ></pwc-number>
    </>
  );
}
import { Component, CUSTOM_ELEMENTS_SCHEMA } from "@angular/core";
import "@progress-i360/progress-web-components/number";

@Component({
  selector: 'number-demo',
  template: `
    <pwc-number 
      label="Items per Page" 
      [min]="5" 
      [max]="50" 
      [value]="itemsPerPage"
      hint="Number of items to display"
      required
      (pwc-change)="updateItemsPerPage($event)">
    </pwc-number>

    <pwc-number 
      label="Cache Size (MB)" 
      [min]="10" 
      [max]="1000" 
      [value]="cacheSize"
      [hideSteppers]="true"
      hint="Memory allocated for caching"
      (pwc-change)="updateCacheSize($event)">
    </pwc-number>

    <pwc-number 
      label="Priority Level" 
      [min]="1" 
      [max]="10" 
      [value]="priority"
      [disabled]="!canChangePriority"
      (pwc-change)="updatePriority($event)">
    </pwc-number>

    <div class="settings-summary" *ngIf="showSummary">
      <p>Current settings: {{ itemsPerPage }} items, {{ cacheSize }}MB cache, Priority: {{ priority }}</p>
    </div>
  `,
  schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class NumberDemo {
  itemsPerPage = 25;
  cacheSize = 100;
  priority = 5;
  canChangePriority = true;

  get showSummary() {
    return this.itemsPerPage > 0 || this.cacheSize > 0;
  }

  updateItemsPerPage(event: any) {
    this.itemsPerPage = event.detail || 25;
    this.canChangePriority = this.itemsPerPage >= 20;
  }

  updateCacheSize(event: any) {
    this.cacheSize = event.detail || 100;
  }

  updatePriority(event: any) {
    this.priority = event.detail || 5;
  }
}
import '@progress-i360/progress-web-components/number';

const numberInput = document.createElement('pwc-number');
numberInput.setAttribute('label', 'Quantity');
numberInput.setAttribute('name', 'quantity');
numberInput.setAttribute('min', '1');
numberInput.setAttribute('max', '100');
numberInput.setAttribute('value', '5');

numberInput.addEventListener('pwc-change', (event) => {
  console.log('Quantity changed:', event.detail);
});

document.body.appendChild(numberInput);

Usage Patterns

  • Quantity Selection - E-commerce cart quantities, inventory counts, and item selection with clear boundaries
  • Configuration Settings - System parameters, user preferences, and application settings requiring numeric input
  • Rating and Scoring - User ratings, priority levels, and numeric feedback collection with defined ranges
  • Time and Duration Inputs - Timeout values, interval settings, and time-based configuration parameters

Best Practices

Content Strategy Guidelines

  • Clear Value Ranges - Always define meaningful min and max values that reflect real-world constraints and business rules
  • Descriptive Labels - Use specific, actionable labels that clearly explain what the numeric value represents and affects
  • Helpful Hints - Provide context about acceptable ranges, units, and the impact of different values on system behavior
  • Appropriate Stepper Usage - Show steppers for small ranges (1-20) and hide them for large ranges where typing is more efficient

Performance Optimization

  • Debounced Input Handling - Use built-in debouncing for onChange events to prevent excessive API calls or state updates
  • Efficient Validation - Leverage browser native validation combined with component validation for optimal performance
  • Minimal Re-renders - Structure parent components to minimize unnecessary re-renders when numeric values change
  • Loading State Integration - Properly handle loading states during form submission to provide user feedback

Integration Architecture

  • Form Context Coordination - Integrate with PWC form systems for validation, submission, and error handling workflows
  • Type Safety - Use TypeScript interfaces and proper typing to ensure numeric data integrity throughout the application
  • Accessibility Standards - Ensure proper ARIA labels, keyboard navigation, and screen reader compatibility for all users
  • Design Token Usage - Leverage PWC design tokens for consistent styling, spacing, and color usage across number inputs

Common Use Cases

Data Table Headers

  • Pagination controls with items-per-page selection and page size configuration options
  • Column width adjustments with pixel-based numeric inputs and responsive design considerations
  • Sorting priority settings with numeric rank assignment and visual hierarchy management

Search Result Sections

  • Results-per-page configuration with user preference storage and performance optimization
  • Price range filters with min/max numeric inputs and real-time search integration
  • Date range selection with numeric day, month, and year inputs for precise temporal filtering

Dashboard Widget Headers

  • Refresh interval settings with time-based numeric inputs and automatic update scheduling
  • Data point limits with performance-conscious numeric constraints and real-time visualization
  • Chart configuration with axis ranges, data sampling rates, and display parameter controls

Troubleshooting

Common Issues

Actions Not Triggering

Symptoms: Stepper buttons don't increment/decrement values or onChange events don't fire properly

Solutions:

  • Verify min and max constraints allow the intended value changes and aren't blocking operations

  • Check that disabled or readOnly states aren't preventing user interactions or event propagation

  • Ensure onChange and onInput handlers are properly bound and contain valid function references

Actions Not Visible

Symptoms: Stepper buttons don't appear or number input field doesn't render with expected styling

Solutions:

  • Confirm hideSteppers property is set correctly based on your use case and design requirements

  • Check that form loading states aren't replacing the input with skeleton components inappropriately

  • Verify CSS styling doesn't hide stepper buttons or interfere with component layout structure

Layout Issues

Symptoms: Number input appears misaligned, too wide, or with incorrect spacing in form layouts

Solutions:

  • Use appropriate parent container styling to control max-width (default 7.5rem) and alignment behavior

  • Check that flex layout properties work correctly with your specific form layout and responsive design

  • Ensure gap and padding values from design system tokens provide consistent spacing

Icon Problems

Symptoms: Stepper icons don't display correctly or validation icons don't appear for invalid states

Solutions:

  • Verify add and subtract icons are loaded and available in your icon system configuration

  • Check that invalid state styling applies correctly when validation fails and error messages appear

  • Ensure focus indicators and border color changes work properly for different input states

Implementation Support

  • Form Integration Guidance - Best practices for connecting number inputs with form validation, submission, and error handling systems
  • Accessibility Compliance - WCAG guidelines implementation, keyboard navigation patterns, and screen reader optimization techniques
  • Performance Optimization - Debouncing strategies, validation efficiency, and loading state management for optimal user experience

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.