Pending Review
Pending Review from User Experience (UX)
Focus Component
Overview
The PWC Focus component provides visual focus indication and styling wrapper for form elements and interactive components. Built as a utility component, it enhances accessibility by providing consistent focus outlines and semantic color variants for different states and contexts.
Core Capabilities
- Focus Visualization - Consistent focus ring styling with brand colors and accessibility-compliant contrast ratios
-
Semantic Variants - Six color variants (default, critical, invalid, success, tip, warning) for contextual state indication
-
Flexible Layout - Support for flex properties and alignment options to integrate with various layout patterns
-
Blur Border Option - Additional border styling for enhanced visual separation when elements lose focus
-
CSS Modern Features - Uses :has() selector for advanced styling based on child element focus states
- Accessibility Standards - WCAG-compliant focus indicators that work with keyboard navigation and screen readers
When to use Focus:
- Form elements requiring enhanced focus visibility beyond browser defaults
- Interactive components needing contextual color coding for different states
- Complex form layouts where consistent focus styling improves user experience
- Accessibility-critical interfaces where clear focus indication is essential for navigation
When not to use Focus:
- Simple text links or buttons where browser default focus styling is sufficient
- Non-interactive elements that don't receive keyboard focus
- Components that already include their own focus management and styling
Basic Implementation
import React from 'react';
import { PwcFocus, PwcInput } from "@progress-i360/pwc-react";
function MyComponent() {
return (
<>
<PwcFocus variant="default">
<input
type="text"
placeholder="Enter your name"
style={{ border: 'none', outline: 'none', padding: '8px' }}
/>
</PwcFocus>
<PwcFocus variant="invalid">
<input
type="email"
placeholder="Invalid email format"
style={{ border: 'none', outline: 'none', padding: '8px' }}
/>
</PwcFocus>
<PwcFocus variant="success" flex>
<PwcInput
type="text"
placeholder="Valid input"
name="validInput"
/>
</PwcFocus>
</>
);
}
import '@progress-i360/progress-web-components/focus';
import '@progress-i360/progress-web-components/input';
function FocusStates() {
return (
<>
<pwc-focus variant="success" flex>
<pwc-input
type="text"
name="validated-input"
value="Valid input"
></pwc-input>
</pwc-focus>
<pwc-focus variant="warning" blur-border>
<select style={{ border: 'none', outline: 'none', padding: '8px' }}>
<option value="">Choose option</option>
<option value="high">High priority</option>
<option value="low">Low priority</option>
</select>
</pwc-focus>
</>
);
}
import { Component, CUSTOM_ELEMENTS_SCHEMA } from "@angular/core";
import "@progress-i360/progress-web-components/body";
import "@progress-i360/progress-web-components/button";
import "@progress-i360/progress-web-components/flex";
import "@progress-i360/progress-web-components/focus";
import "@progress-i360/progress-web-components/heading";
@Component({
selector: 'focus-demo',
template: `
<pwc-flex direction="column" gap="m" padding="m">
<pwc-heading content="Focus State Demonstration" size="l"></pwc-heading>
<pwc-flex direction="column" gap="s">
<pwc-body content="Click on the inputs below to see focus styling:"></pwc-body>
<pwc-focus variant="default">
<input type="text" placeholder="Default focus style" (focus)="setFocusType('default')" (blur)="clearFocus()">
</pwc-focus>
<pwc-focus [variant]="currentFocusVariant">
<input type="email" placeholder="Validation focus (try invalid email)"
[value]="emailValue"
(input)="updateEmail($event)"
(focus)="setFocusType('validation')"
(blur)="validateEmail()">
</pwc-focus>
<pwc-focus variant="success" *ngIf="showSuccess">
<input type="text" placeholder="Success state" readonly value="Valid input!">
</pwc-focus>
</pwc-flex>
<pwc-flex gap="s">
<pwc-button label="Trigger Success" variant="success" (pwc-click)="showSuccessState()"></pwc-button>
<pwc-button label="Trigger Warning" variant="warning" (pwc-click)="showWarningState()"></pwc-button>
<pwc-button label="Trigger Error" variant="critical" (pwc-click)="showErrorState()"></pwc-button>
</pwc-flex>
<pwc-body [content]="'Current focus: ' + (currentFocus || 'None') + ', Validations: ' + validationCount" color="subtle" size="xs"></pwc-body>
</pwc-flex>
`,
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})
export class FocusDemo {
currentFocus = '';
currentFocusVariant = 'default';
emailValue = '';
showSuccess = false;
validationCount = 0;
setFocusType(type: string) {
this.currentFocus = type;
}
clearFocus() {
this.currentFocus = '';
}
updateEmail(event: any) {
this.emailValue = event.target.value;
}
validateEmail() {
const isValid = this.emailValue.includes('@') && this.emailValue.includes('.');
this.currentFocusVariant = isValid ? 'success' : 'invalid';
this.validationCount++;
}
showSuccessState() {
this.currentFocusVariant = 'success';
this.showSuccess = true;
this.validationCount++;
}
showWarningState() {
this.currentFocusVariant = 'warning';
this.validationCount++;
}
showErrorState() {
this.currentFocusVariant = 'invalid';
this.validationCount++;
}
}
import '@progress-i360/progress-web-components/focus';
const focusWrapper = document.createElement('pwc-focus');
focusWrapper.setAttribute('variant', 'invalid');
const input = document.createElement('input');
input.type = 'email';
input.placeholder = 'Enter email address';
focusWrapper.appendChild(input);
document.body.appendChild(focusWrapper);
Usage Patterns
- Form Validation - Use semantic variants (invalid, success, warning) to provide visual feedback for field validation states
- Interactive Elements - Wrap buttons, inputs, and custom controls with focus styling for consistent keyboard navigation experience
- State Communication - Apply contextual colors (critical, tip) to communicate urgency, importance, or informational context
- Layout Integration - Use flex and alignment properties to integrate focused elements seamlessly with form layouts
Best Practices
Content Strategy Guidelines
- Semantic Color Usage - Choose focus variants that match the semantic meaning of the content and validation state
- Consistent Application - Apply focus styling consistently across similar interactive elements in the same interface
- Clear Visual Hierarchy - Use focus variants to support, not compete with, other visual hierarchy elements
- Accessibility Priority - Ensure focus indicators meet WCAG contrast requirements and are visible to all users
Performance Optimization
- CSS Modern Features - Leverage :has() selector for efficient styling without JavaScript event handlers
- Minimal DOM Impact - Use focus wrapper only when enhanced styling is needed beyond browser defaults
- State-based Rendering - Conditionally apply focus variants based on actual validation or interaction states
- Layout Efficiency - Use flex and alignment properties to reduce layout recalculations
Integration Architecture
- Form System Integration - Coordinate focus variants with form validation states and error handling
- Design Token Usage - Rely on design system color tokens for consistent focus styling across applications
- Accessibility Standards - Ensure focus management works with screen readers and keyboard navigation patterns
- Component Composition - Combine with other form components while maintaining focus behavior
Common Use Cases
Form Validation
- Input field error states with red focus rings for validation failures
- Success confirmation with green focus styling for completed valid fields
- Warning states with orange focus for fields requiring attention but not blocking submission
Interactive Controls
- Button focus enhancement for primary actions and critical operations
- Custom control focus styling for complex widgets like date pickers and dropdown menus
- Navigation element focus for keyboard accessibility in menus and tab interfaces
Status Indication
- Critical alerts with red focus styling for urgent attention requirements
- Informational tips with purple focus for helpful guidance and contextual information
- Progress indicators with semantic focus colors to show completion states
Troubleshooting
Common Issues
Actions Not Triggering
Symptoms: Focus styles don't appear when elements receive keyboard focus
Solutions:
-
Verify child elements can receive focus (tabindex, focusable elements)
-
Check that :has() selector is supported in target browsers
-
Ensure focus styles aren't overridden by other CSS rules with higher specificity
Actions Not Visible
Symptoms: Focus component doesn't render or appears with default styling
Solutions:
-
Confirm renderSlot function returns valid Lit template result
-
Check CSS imports and focus styles are properly loaded
-
Verify variant names match expected FocusVariant types
Layout Issues
Symptoms: Focus wrapper disrupts intended layout or element positioning
Solutions:
-
Use alignSelf property to control focus wrapper alignment within flex containers
-
Apply flex property when focus wrapper should expand to fill available space
-
Check parent container styling doesn't conflict with focus wrapper display properties
Icon Problems
Symptoms: Focus colors don't match design system or appear incorrect
Solutions:
-
Verify design token CSS variables are loaded and available
-
Check color variant mapping matches intended semantic meaning
-
Ensure focus ring contrast meets accessibility requirements for background colors
Implementation Support
- Accessibility Compliance - Focus indicator implementation strategies meeting WCAG guidelines and screen reader compatibility
- Browser Compatibility - Fallback strategies for browsers that don't support modern CSS features like :has() selector
- Design System Integration - Guidance for consistent focus styling patterns across complex application interfaces
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.