Pending Review
Pending Review from User Experience (UX)
Heading Component
Overview
The PWC Heading is a typography hierarchy component in the Progress Web Components design system. It provides consistent heading structure with four size variations and proper semantic formatting for content organization across React and Angular applications.
Core Capabilities
- Size Hierarchy - XXL, XL, L, and M sizes following design system typography scale
- Color Variants - Base and disabled color options for different content contexts
- Text Overflow Control - NoWrap option with ellipsis for constrained layouts
- Source Sans Pro Typography - Consistent font family with proper line height ratios
- Content Flexibility - Content property with slot support for complex markup
- Semantic Structure - Proper heading markup for accessibility and SEO optimization
When to use Heading:
- Create page titles, section headings, and content hierarchy structure
- Establish visual importance and information architecture in interfaces
- Display prominent text that introduces content sections and page areas
- Provide semantic headings for screen readers and search engine optimization
When not to use Heading:
- Body text or paragraph content (use Body component for regular text)
- Interactive elements requiring click handlers (use Button or Link components)
- Small labels or metadata that don't represent content hierarchy
Basic Implementation
import React, { useState, useCallback, useMemo } from 'react';
import { PwcHeading, PwcFlex, PwcButton, PwcBody } from '@progress-i360/pwc-react';
function PageTitle() {
const [currentSection, setCurrentSection] = useState('dashboard');
const [isCompactMode, setIsCompactMode] = useState(false);
// React 18: Manual memoization for heading configuration
const headingConfig = useMemo(() => {
const configs = {
dashboard: { content: 'Analytics Dashboard', size: 'xxl' },
reports: { content: 'Quarterly Reports', size: 'xl' },
settings: { content: 'System Configuration', size: 'l' },
profile: { content: 'User Profile Settings', size: 'm' }
};
return configs[currentSection] || configs.dashboard;
}, [currentSection]);
// React 18: useCallback for performance optimization
const cycleSections = useCallback(() => {
const sections = ['dashboard', 'reports', 'settings', 'profile'];
const currentIndex = sections.indexOf(currentSection);
setCurrentSection(sections[(currentIndex + 1) % sections.length]);
}, [currentSection]);
const toggleCompactMode = useCallback(() => {
setIsCompactMode(prev => !prev);
}, []);
// React 18: Computed values using useMemo
const displaySize = useMemo(() => {
if (isCompactMode) {
const sizeMap = { xxl: 'xl', xl: 'l', l: 'm', m: 'm' };
return sizeMap[headingConfig.size];
}
return headingConfig.size;
}, [headingConfig.size, isCompactMode]);
return (
<PwcFlex direction="column" gap="m" alignItems="center">
<PwcHeading
content={headingConfig.content}
size={displaySize}
noWrap={isCompactMode}
/>
<PwcFlex gap="s">
<PwcButton
label="Next Section"
variant="primary"
onPwcClick={cycleSections}
/>
<PwcButton
label={`${isCompactMode ? 'Expand' : 'Compact'} Mode`}
variant="outline"
onPwcClick={toggleCompactMode}
/>
</PwcFlex>
<PwcBody
content={`Current: ${currentSection} (${displaySize} size)`}
size="xs"
color="subtle"
/>
</PwcFlex>
);
}
import { Suspense, use, useCallback, useDeferredValue, useOptimistic, useState } from 'react';
import '@progress-i360/progress-web-components/heading';
import '@progress-i360/progress-web-components/body';
import '@progress-i360/progress-web-components/flex';
import '@progress-i360/progress-web-components/button';
// React 19+: Async resource for dynamic content
const fetchPageContext = async (pageId) => {
await new Promise(resolve => setTimeout(resolve, 800));
const contexts = {
home: { title: 'Welcome to Progress Platform', subtitle: 'Your unified development environment' },
projects: { title: 'Active Projects Overview', subtitle: 'Managing 12 development initiatives' },
analytics: { title: 'Performance Analytics Hub', subtitle: 'Real-time insights and metrics' },
team: { title: 'Team Collaboration Center', subtitle: 'Connect with 45+ team members' }
};
return contexts[pageId] || contexts.home;
};
type PageState = {
id: 'home' | 'projects' | 'analytics' | 'team';
active: boolean;
loading: boolean;
};
function DynamicPageHeader() {
const [pageStates, setPageStates] = useState<PageState[]>([
{ id: 'home', active: true, loading: false },
{ id: 'projects', active: false, loading: false },
{ id: 'analytics', active: false, loading: false },
{ id: 'team', active: false, loading: false }
]);
// React 19+: Defer expensive page state calculations
const deferredPageStates = useDeferredValue(pageStates);
// React 19+: Optimistic page switching for instant feedback
const [optimisticStates, setOptimisticState] = useOptimistic(
deferredPageStates,
(state, update) => state.map(page =>
page.id === update.id ? { ...page, ...update } : { ...page, active: false }
)
);
const activePage = optimisticStates.find(page => page.active) || optimisticStates[0];
// React 19+: Use hook for async data fetching
const pageContext = use(fetchPageContext(activePage.id));
const switchPage = useCallback(
async (targetPageId: PageState['id']) => {
// React 19+: Optimistic update for instant UI feedback
setOptimisticState({ id: targetPageId, active: true, loading: true });
// Simulate page context loading
await new Promise(resolve => setTimeout(resolve, 300));
setPageStates(prev =>
prev.map(page => ({
...page,
active: page.id === targetPageId,
loading: false
}))
);
},
[setOptimisticState, setPageStates]
);
const refreshContext = useCallback(() => {
setPageStates(prev =>
prev.map(page => (page.active ? { ...page, loading: true } : page))
);
// Force refresh by re-triggering context fetch
setTimeout(() => {
setPageStates(prev =>
prev.map(page => (page.active ? { ...page, loading: false } : page))
);
}, 1000);
}, [setPageStates]);
return (
<pwc-flex direction="column" gap="l" align-items="center">
<Suspense fallback={<pwc-heading content="Loading..." size="xl" color="disabled"></pwc-heading>}>
<pwc-flex direction="column" gap="s" align-items="center">
<pwc-heading
content={pageContext.title}
size="xxl"
></pwc-heading>
<pwc-body
content={pageContext.subtitle}
size="s"
color="subtle"
></pwc-body>
</pwc-flex>
</Suspense>
<pwc-flex gap="xs" wrap="wrap" justify-content="center">
{optimisticStates.map(page => (
<pwc-button
key={page.id}
label={page.id.charAt(0).toUpperCase() + page.id.slice(1)}
variant={page.active ? 'primary' : 'outline'}
onPwcClick={() => switchPage(page.id)}
disabled={page.loading}
></pwc-button>
))}
</pwc-flex>
<pwc-button
label="Refresh Context"
variant="outline"
onPwcClick={refreshContext}
></pwc-button>
<pwc-body
content={`Active: ${activePage.id} page ${activePage.loading ? '(loading...)' : ''}`}
size="xs"
color="subtler"
></pwc-body>
</pwc-flex>
);
}
import { Component, CUSTOM_ELEMENTS_SCHEMA } from "@angular/core";
import "@progress-i360/progress-web-components/heading";
import "@progress-i360/progress-web-components/flex";
import "@progress-i360/progress-web-components/button";
import "@progress-i360/progress-web-components/body";
@Component({
selector: 'heading-demo',
template: `
<pwc-flex direction="column" gap="m" padding="m">
<pwc-heading [content]="headingText" [size]="headingSize"></pwc-heading>
<pwc-flex gap="s" wrap="wrap">
<pwc-button label="XXL Size" variant="outline" (pwc-click)="setSize('xxl')"></pwc-button>
<pwc-button label="XL Size" variant="outline" (pwc-click)="setSize('xl')"></pwc-button>
<pwc-button label="L Size" variant="outline" (pwc-click)="setSize('l')"></pwc-button>
<pwc-button label="M Size" variant="outline" (pwc-click)="setSize('m')"></pwc-button>
</pwc-flex>
<pwc-button label="Update Heading" variant="primary" (pwc-click)="updateHeading()"></pwc-button>
<pwc-body [content]="'Current Size: ' + headingSize" color="subtle" size="xs"></pwc-body>
</pwc-flex>
`,
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class HeadingDemo {
headingText = 'Dynamic Heading Example';
headingSize = 'xl';
headingCount = 0;
setSize(size: string) {
this.headingSize = size;
}
updateHeading() {
this.headingCount++;
this.headingText = `Updated Heading #${this.headingCount}`;
}
}
import '@progress-i360/progress-web-components/heading';
const mainHeading = document.createElement('pwc-heading');
mainHeading.setAttribute('content', 'Dashboard');
mainHeading.setAttribute('size', 'xxl');
const sectionHeading = document.createElement('pwc-heading');
sectionHeading.setAttribute('content', 'Recent Activity');
sectionHeading.setAttribute('size', 'l');
sectionHeading.setAttribute('color', 'disabled');
document.querySelector('#page-header')?.appendChild(mainHeading);
document.querySelector('#section-header')?.appendChild(sectionHeading);
Usage Patterns
Heading components adapt to different content hierarchy scenarios:
- Size Hierarchy - XXL for main titles, XL for major sections, L for subsections, M for minor headings
- Color Variations - Base color for standard headings, disabled color for secondary or inactive headings
- Text Overflow - NoWrap option with ellipsis for constrained layout areas
- Content Flexibility - Content property for simple text, slot support for complex markup
Best Practices
Content Strategy Guidelines
- Clear Hierarchy - Use size progression (XXL → XL → L → M) to establish content importance
- Meaningful Titles - Write descriptive headings that accurately represent section content
- Consistent Terminology - Apply uniform language patterns across similar content areas
- Scannable Structure - Create heading hierarchy that supports quick content navigation
Performance Optimization
- Efficient Rendering - Leverage component reusability for consistent heading performance
- Font Loading - Ensure Source Sans Pro font loads properly for typography consistency
- Memory Management - Avoid unnecessary re-renders for static heading content
- Layout Optimization - Use noWrap option judiciously to prevent layout performance issues
Integration Architecture
- Typography System - Integrate seamlessly with other PWC typography components
- Design Token Usage - Leverage design system tokens for consistent sizing and colors
- Semantic Structure - Maintain proper heading hierarchy for accessibility and SEO
- Responsive Behavior - Ensure headings scale appropriately across screen sizes
Common Use Cases
Data Table Headers
- Table Section Titles - Use L or M size headings for table section labels and categories
- Column Group Headers - Apply M size headings for grouped column headers and classifications
- Data Summary Headers - Implement XL or L headings for data summary sections and analytics
Search Result Sections
- Search Category Headers - Use XL headings for major search result categories and filters
- Result Group Titles - Apply L headings for search result groupings and classifications
- Filter Section Headers - Implement M headings for search filter categories and options
Dashboard Widget Headers
- Widget Main Titles - Use L or XL headings for primary dashboard widget titles
- Section Labels - Apply M headings for dashboard section labels and widget groups
- Chart Titles - Implement L headings for chart and visualization titles within widgets
Troubleshooting
Common Issues
Size Not Applying
Problem: Heading size doesn't change or displays incorrectly
Solution:
- Verify size property matches available options (xxl, xl, l, m) and CSS tokens are loaded
Color Not Displaying
Problem: Heading color doesn't apply or shows incorrect color
Solution:
- Check color property matches available options (base, disabled) and theme is configured
Text Overflow Issues
Problem: Long headings don't handle overflow properly
Solution:
- Use noWrap property for ellipsis behavior or adjust container width constraints
Content Not Rendering
Problem: Heading content doesn't display or shows empty
Solution:
- Verify content property is set correctly or use slot content for complex markup
Implementation Support
For detailed implementation guidance:
- Typography Integration - Works seamlessly with PWC Body and other text components
- Design System Tokens - Uses standardized sizing, color, and font tokens
- Accessibility Support - Maintains proper semantic structure for screen readers and SEO
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.