Pending Review
Pending Review from User Experience (UX)
Body Component
Overview
The PWC Body is a fundamental typography component in the Progress Web Components design system. It provides consistent body text styling with flexible size, color, and weight options for readable content display across React and Angular applications.
Core Capabilities
- Typography Hierarchy - XS and S sizes following design system text scale
- Weight Variations - Regular, semi-bold, and bold font weights for content emphasis
- Color System - 26 color variants including base, subtle, accent, and semantic colors
- Content Integration - Flexible content property with slot support for complex markup
- Design Token Integration - Uses system font family and consistent line height values
- Accessibility Support - Optimal line length with 100ch max-width and proper contrast ratios
When to use Body:
- Display paragraph text, descriptions, and content blocks
- Show form labels, help text, and instructional content
- Present data values and informational text in tables and lists
- Create consistent text hierarchy within interface components
When not to use Body:
- Page or section headings (use Heading component instead)
- Interactive text elements (use Link component for clickable text)
- Large blocks of content requiring advanced formatting
Basic Implementation
import React, { useState, useCallback, useMemo } from 'react';
import { PwcBody, PwcFlex, PwcButton } from '@progress-i360/pwc-react';
function ContentDisplay() {
const [messageType, setMessageType] = useState('info');
const [isHighlighted, setIsHighlighted] = useState(false);
// React 18: Manual memoization with useMemo
const messageConfig = useMemo(() => {
const configs = {
info: { color: 'blue-base', content: 'Information: Process completed successfully' },
warning: { color: 'orange-base', content: 'Warning: Please review your settings' },
error: { color: 'red-base', content: 'Error: Something went wrong' },
success: { color: 'green-base', content: 'Success: Changes saved successfully' }
};
return configs[messageType] || configs.info;
}, [messageType]);
// React 18: useCallback for event handlers
const cycleMessageType = useCallback(() => {
const types = ['info', 'warning', 'error', 'success'];
const currentIndex = types.indexOf(messageType);
setMessageType(types[(currentIndex + 1) % types.length]);
}, [messageType]);
const toggleHighlight = useCallback(() => {
setIsHighlighted(prev => !prev);
}, []);
return (
<PwcFlex direction="column" gap="m">
<PwcBody
content={messageConfig.content}
color={messageConfig.color}
weight={isHighlighted ? 'semi-bold' : 'regular'}
/>
<PwcFlex gap="s">
<PwcButton
label="Change Message"
variant="primary"
onPwcClick={cycleMessageType}
/>
<PwcButton
label={`${isHighlighted ? 'Remove' : 'Add'} Emphasis`}
variant="outline"
onPwcClick={toggleHighlight}
/>
</PwcFlex>
<PwcBody
content={`Current: ${messageType} message`}
size="xs"
color="subtle"
/>
</PwcFlex>
);
}
import { useState, useDeferredValue, useOptimistic, useActionState } from 'react';
import '@progress-i360/progress-web-components/body';
import '@progress-i360/progress-web-components/flex';
import '@progress-i360/progress-web-components/button';
function DynamicContentDisplay() {
const [notifications, setNotifications] = useState([
{ id: 1, text: 'Welcome to the application', priority: 'low' },
{ id: 2, text: 'New message received', priority: 'medium' }
]);
// React 19+: Defer expensive notification rendering
const deferredNotifications = useDeferredValue(notifications);
// React 19+: Optimistic updates for instant feedback
const [optimisticNotifications, addOptimisticNotification] = useOptimistic(
deferredNotifications,
(state, newNotification) => [newNotification, ...state]
);
// React 19+: useActionState for form-like interactions
const [actionState, submitAction, isPending] = useActionState(
async (prevState, formData) => {
const text = formData.get('notification');
const priority = Math.random() > 0.5 ? 'high' : 'medium';
const newNotification = {
id: Date.now(),
text: text || `Auto-generated notification ${Date.now()}`,
priority
};
addOptimisticNotification(newNotification);
// Simulate API call
await new Promise((resolve) => setTimeout(resolve, 1000));
setNotifications((prev) => [newNotification, ...prev]);
return { success: true, count: prevState.count + 1 };
},
{ success: false, count: 0 }
);
const getColorByPriority = (priority: string) => {
switch (priority) {
case 'high':
return 'red-base';
case 'medium':
return 'orange-base';
case 'low':
return 'blue-base';
default:
return 'base';
}
};
return (
<pwc-flex direction="column" gap="m">
<pwc-body content="Notification Center" weight="bold"></pwc-body>
<pwc-flex direction="column" gap="s">
{optimisticNotifications.map((notification) => (
<pwc-body
key={notification.id}
content={notification.text}
color={getColorByPriority(notification.priority)}
size="s"
></pwc-body>
))}
</pwc-flex>
<form action={submitAction}>
<pwc-flex gap="s" align-items="center">
<pwc-button
type="submit"
label={isPending ? 'Adding...' : 'Add Notification'}
variant="primary"
disabled={isPending}
></pwc-button>
<pwc-body
content={`Total notifications: ${actionState.count + optimisticNotifications.length}`}
size="xs"
color="subtle"
></pwc-body>
</pwc-flex>
</form>
</pwc-flex>
);
}
import { Component, CUSTOM_ELEMENTS_SCHEMA } from "@angular/core";
import "@progress-i360/progress-web-components/body";
import "@progress-i360/progress-web-components/flex";
import "@progress-i360/progress-web-components/button";
import "@progress-i360/progress-web-components/heading";
@Component({
selector: 'body-demo',
template: `
<pwc-flex direction="column" gap="m" padding="m">
<pwc-heading content="Body Text Styles" size="l"></pwc-heading>
<pwc-body [content]="bodyText" [size]="textSize" [weight]="textWeight"></pwc-body>
<pwc-flex gap="s">
<pwc-button label="Toggle Size" variant="outline" (pwc-click)="toggleSize()"></pwc-button>
<pwc-button label="Toggle Weight" variant="outline" (pwc-click)="toggleWeight()"></pwc-button>
<pwc-button label="Update Text" variant="primary" (pwc-click)="updateText()"></pwc-button>
</pwc-flex>
<pwc-body [content]="'Current: Size ' + textSize + ', Weight ' + textWeight" color="subtle" size="xs"></pwc-body>
</pwc-flex>
`,
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class BodyDemo {
bodyText = 'This is sample body text that demonstrates different styling options.';
textSize = 's';
textWeight = 'regular';
textCount = 0;
toggleSize() {
this.textSize = this.textSize === 's' ? 'xs' : 's';
}
toggleWeight() {
const weights = ['regular', 'semi-bold', 'bold'];
const currentIndex = weights.indexOf(this.textWeight);
this.textWeight = weights[(currentIndex + 1) % weights.length];
}
updateText() {
this.textCount++;
this.bodyText = `Updated body text example #${this.textCount}. This demonstrates dynamic content changes.`;
}
}
// Import the component
import '@progress-i360/progress-web-components/body';
// Create body text elements
const bodyText = document.createElement('pwc-body');
bodyText.setAttribute('content', 'Main content text');
bodyText.setAttribute('size', 's');
bodyText.setAttribute('color', 'base');
const secondaryText = document.createElement('pwc-body');
secondaryText.setAttribute('content', 'Secondary information');
secondaryText.setAttribute('size', 'xs');
secondaryText.setAttribute('color', 'subtle');
secondaryText.setAttribute('weight', 'semi-bold');
// Append to DOM
document.querySelector('#content-area').appendChild(bodyText);
document.querySelector('#content-area').appendChild(secondaryText);
Usage Patterns
Body components adapt to different content and styling scenarios:
- Standard Content - Default size and base color for primary text content
- Secondary Information - XS size with subtle color for metadata and helper text
- Emphasis Text - Semi-bold or bold weight for important information highlighting
- Semantic Colors - Accent colors for status messages, warnings, and categorized content
Best Practices
Content Strategy Guidelines
- Clear Hierarchy - Use size and weight combinations to establish clear content hierarchy
- Consistent Coloring - Apply semantic colors consistently across similar content types
- Readable Line Length - Leverage 100ch max-width for optimal reading experience
- Content Appropriateness - Match text styling to content purpose and importance level
Performance Optimization
- Efficient Rendering - Minimize unnecessary re-renders for static text content
- Token Usage - Leverage design system tokens for consistent performance
- Bundle Optimization - Import only required typography components
- Font Loading - Ensure proper Source Sans Pro font loading strategies
Integration Architecture
- Component Composition - Integrate seamlessly with other typography components
- Slot Support - Use content property for simple text, slots for complex markup
- Responsive Behavior - Maintain readability across all screen sizes and devices
- Theme Compatibility - Work effectively with light and dark theme variations
Common Use Cases
Data Table Headers
- Column Headers - Use semi-bold weight body text for table column labels
- Cell Content - Standard body text for data values and descriptive content
- Table Metadata - XS size with subtle color for row counts and table information
Search Result Sections
- Result Descriptions - Standard body text for search result snippets and descriptions
- Metadata Display - XS size body text for dates, categories, and result context
- Status Information - Semantic colors for result status and relevance indicators
Dashboard Widget Headers
- Widget Content - Body text for data values, descriptions, and informational content
- Help Text - Subtle colored body text for widget explanations and guidance
- Dynamic Content - Various color variants for real-time data and status updates
Troubleshooting
Common Issues
Text Not Displaying
Problem: Body component appears empty or doesn't show content
Solution:
- Verify content property is set correctly and contains valid string data
Font Not Loading
Problem: Text displays with fallback fonts instead of Source Sans Pro
Solution:
- Check font loading configuration and ensure design system fonts are available
Color Not Applying
Problem: Text color doesn't match expected color variant
Solution:
- Verify color property matches available color options and theme is properly configured
Layout Issues
Problem: Text doesn't align properly with other components
Solution:
- Check CSS integration and ensure proper flexbox properties are applied
Implementation Support
For detailed implementation guidance:
- Typography Integration - Works seamlessly with other PWC typography components
- Design System Tokens - Uses standardized font, color, and spacing tokens
- Framework Compatibility - Tested across React, Angular, and vanilla JavaScript 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.