Pending Review
Pending Review from User Experience (UX)
Expander Component
Overview
The PWC Expander is an interactive toggle button component in the Progress Web Components design system that provides visual expand/collapse controls for expandable content sections. It works seamlessly with expand context providers to create intuitive user interfaces with collapsible sections across React and Angular applications.
Core Capabilities
- Context-Aware Toggle - Automatically updates icon state based on expand context to show current expansion state
- Chevron Icon Integration - Built-in chevron-up and chevron-down icons that provide clear visual feedback
- Button Component Foundation - Leverages the PWC button component for consistent styling and interaction patterns
- State Synchronization - Seamlessly syncs with expand context state changes without manual event handling
- Accessibility Support - Proper button semantics and ARIA attributes for screen reader compatibility
- Lightweight Implementation - Minimal footprint with efficient context-based state management
When to use Expander:
- Create toggle controls for collapsible content sections in cards, panels, or accordion interfaces
- Provide clear visual indicators for expandable/collapsible states in complex layouts
- Build intuitive controls for progressive disclosure patterns and nested content structures
- Implement consistent expand/collapse interactions across different application sections
When not to use Expander:
- Simple show/hide functionality that doesn't require expand context integration
- Cases where custom toggle controls or different visual indicators are more appropriate
- Modal dialogs or overlays that need different interaction patterns than expand/collapse
Basic Implementation
import React, { useState } from 'react';
import { PwcExpandContainer, PwcExpandContext, PwcExpander } from "@progress-i360/pwc-react";
function FAQItem() {
const [isExpanded, setIsExpanded] = useState(false);
return (
<div style={{ maxWidth: '400px', border: '1px solid #ddd', borderRadius: '8px' }}>
<PwcExpandContext expanded={isExpanded}>
<div
style={{ padding: '16px', display: 'flex', justifyContent: 'space-between', alignItems: 'center', cursor: 'pointer' }}
onClick={() => setIsExpanded(!isExpanded)}
>
<h4>System Requirements</h4>
<PwcExpander />
</div>
<PwcExpandContainer>
<div style={{ padding: '16px', borderTop: '1px solid #ddd' }}>
<ul>
<li>Windows 10+ or macOS 10.15+</li>
<li>4GB RAM minimum</li>
<li>Internet connection required</li>
</ul>
</div>
</PwcExpandContainer>
</PwcExpandContext>
</div>
);
}
import { useState } from 'react';
import '@progress-i360/progress-web-components/expand-context';
import '@progress-i360/progress-web-components/expand-container';
import '@progress-i360/progress-web-components/expander';
function NavigationSidebar() {
const [activeSection, setActiveSection] = useState<string | null>(null);
const sections = ['Getting Started', 'Components', 'Advanced'];
return (
<div style={{ width: '250px', border: '1px solid #ddd', borderRadius: '8px' }}>
<h3 style={{ padding: '16px', margin: 0, borderBottom: '1px solid #ddd' }}>Documentation</h3>
{sections.map((section) => (
<pwc-expand-context key={section} expanded={activeSection === section}>
<div
style={{ padding: '12px 16px', display: 'flex', justifyContent: 'space-between', alignItems: 'center', cursor: 'pointer' }}
onClick={() => setActiveSection(activeSection === section ? null : section)}
>
<span>{section}</span>
<pwc-expander></pwc-expander>
</div>
<pwc-expand-container>
<div style={{ paddingLeft: '32px', paddingBottom: '8px' }}>
<div style={{ padding: '4px 0', color: '#666' }}>Installation</div>
<div style={{ padding: '4px 0', color: '#666' }}>Quick Start</div>
<div style={{ padding: '4px 0', color: '#666' }}>Examples</div>
</div>
</pwc-expand-container>
</pwc-expand-context>
))}
</div>
);
}
import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import '@progress-i360/progress-web-components/expand-context';
import '@progress-i360/progress-web-components/expand-container';
import '@progress-i360/progress-web-components/expander';
import '@progress-i360/progress-web-components/button';
@Component({
selector: 'expander-demo',
template: `
<pwc-expand-context [expanded]="isExpanded">
<div class="header">
<h3>{{ headerTitle }}</h3>
<pwc-expander (click)="toggle()"></pwc-expander>
</div>
<pwc-expand-container>
<p>{{ expandedContent }}</p>
<pwc-button label="Update Info" (pwc-click)="updateInfo()"></pwc-button>
</pwc-expand-container>
</pwc-expand-context>
`,
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class ExpanderDemo {
isExpanded = false;
headerTitle = 'Project Details';
expandedContent = 'This section contains detailed project information.';
toggle() {
this.isExpanded = !this.isExpanded;
}
updateInfo() {
const updates = [
'Updated project timeline and milestones.',
'New team member assignments added.',
'Resource allocation has been optimized.',
'Latest progress report is now available.'
];
this.expandedContent = updates[Math.floor(Math.random() * updates.length)];
this.headerTitle = 'Updated Details';
}
}
// Create expand context with header and expander
const expandContext = document.createElement('pwc-expand-context');
expandContext.setAttribute('expanded', 'false');
// Create header with expander button
const header = document.createElement('div');
header.textContent = 'Click to expand section';
header.style.padding = '10px';
header.style.cursor = 'pointer';
header.style.borderBottom = '1px solid #ddd';
// Create expander (toggle button)
const expander = document.createElement('pwc-expander');
header.appendChild(expander);
// Create expandable content
const expandContainer = document.createElement('pwc-expand-container');
expandContainer.innerHTML = '<div style="padding: 10px;">This is the expanded content!</div>';
// Add components to context
expandContext.appendChild(header);
expandContext.appendChild(expandContainer);
// Add to page
document.body.appendChild(expandContext);
Usage Patterns
- Card Header Controls - Place expanders in card headers to provide clear toggle controls for expandable content sections
- Sidebar Navigation - Use in collapsible navigation menus where sections can be expanded to show sub-items or detailed options
- Settings Panels - Implement in configuration interfaces where different setting categories can be expanded independently
- Data Table Rows - Apply to table rows that contain expandable detail sections or nested information
Best Practices
Content Strategy Guidelines
- Consistent Placement - Position expanders consistently within headers or control areas to establish predictable user interaction patterns
- Clear Visual Hierarchy - Ensure expander buttons don't compete with primary content but remain easily discoverable
- Meaningful Context - Place expanders adjacent to content that clearly indicates what will be expanded or collapsed
- Loading States - Consider loading states for expanders that trigger content fetching when expanded
Performance Optimization
- Button Component Reuse - Leverage the underlying button component architecture for consistent performance and styling
- Context Efficiency - Use expand context providers efficiently to minimize unnecessary re-renders and state updates
- Icon Optimization - Take advantage of built-in chevron icons rather than loading custom icon assets
- Event Handler Management - Ensure proper cleanup of event handlers when expander components are unmounted
Integration Architecture
- Context Boundaries - Establish clear expand context boundaries to prevent unintended state sharing between unrelated components
- State Management - Coordinate expander state with application-level state management when persistence is required
- Accessibility Integration - Ensure expanders work properly with keyboard navigation and screen reader technologies
- Theme Consistency - Utilize design system tokens to maintain consistent expander styling across different themes
Common Use Cases
Accordion and FAQ Interfaces
- Create expandable question/answer sections with clear toggle controls that indicate expansion state
- Build multi-section accordions where users can expand multiple sections simultaneously
- Implement progressive disclosure patterns that reveal detailed information on demand
Dashboard and Widget Controls
- Provide expand/collapse controls for dashboard widgets that can show summary or detailed views
- Create collapsible sidebar sections that users can customize based on their workflow needs
- Build expandable chart legends or data filters that don't overwhelm the primary visualization
Form and Settings Organization
- Organize complex forms into expandable sections that reduce cognitive load and improve completion rates
- Create settings panels where advanced options are hidden by default but easily accessible
- Implement wizard-style interfaces where completed sections can be collapsed to focus on current steps
Troubleshooting
Common Issues
Expander Not Responding
Problem: Expander button doesn't trigger expand/collapse functionality or appears inactive.
Solution:
- Verify that the expander is properly nested within an expand context provider. Check that the expand context is correctly managing state and that the
setExpandedfunction is available. Ensure no parent elements are preventing click event propagation.
Icon Not Updating
Problem: Chevron icon doesn't change between up and down states when content expands or collapses.
Solution:
- Confirm that the expand context state is properly updating and being consumed by the expander component. Check that the context subscription is working correctly and that the component is re-rendering when state changes occur.
Multiple Expanders Conflicting
Problem: Multiple expanders in the same context don't work independently or interfere with each other.
Solution:
- Ensure each expandable section has its own expand context provider. Avoid nesting expand contexts inappropriately and verify that each expander is associated with the correct context scope.
Styling Issues
Problem: Expander button styling doesn't match the design system or appears inconsistent with other buttons.
Solution:
- Verify that the underlying button component is properly configured and that design system tokens are being applied correctly. Check for CSS conflicts that might override the default button styling.
Implementation Support
- Button Integration - Comprehensive examples showing how the expander leverages the PWC button component for consistent styling and behavior
- Context Coordination - Best practices for coordinating expander components with expand context providers in complex layouts
- Accessibility Guidelines - Implementation patterns that ensure expanders work effectively with assistive technologies and keyboard navigation
Resources
Storybook Documentation
For comprehensive API documentation, interactive examples, and testing tools: 📖 View Complete API Documentation in Storybook →
For additional implementation guidance or framework-specific questions, consult the PWC Design System documentation or reach out to the component library team.