PatternFly 4 Icons as React Components providing tree-shakable icon imports with TypeScript support
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
The icon factory system provides the createIcon function for generating custom icon components that match the library's patterns and behavior. This enables creation of custom icons with the same accessibility features, styling, and component structure as built-in icons.
Factory function that creates React class components from icon definitions.
/**
* Factory function to create Icon class components
* @param iconDefinition - Configuration object defining the icon's properties
* @returns React class component that renders an SVG icon
*/
function createIcon(iconDefinition: IconDefinition): React.ComponentClass<SVGIconProps>;
interface IconDefinition {
/** Display name for the icon component (used for React DevTools) */
name?: string;
/** Icon width in pixels */
width: number;
/** Icon height in pixels */
height: number;
/** SVG path data or array of path objects for multi-path icons */
svgPath: string | SVGPathObject[];
/** X-axis offset for viewBox (default: 0) */
xOffset?: number;
/** Y-axis offset for viewBox (default: 0) */
yOffset?: number;
/** CSS class to apply to the SVG element */
svgClassName?: string;
}
interface SVGPathObject {
/** SVG path data string */
path: string;
/** CSS class for this specific path element */
className?: string;
}Create simple icons using a single SVG path string.
Usage Example:
import { createIcon, IconDefinition, SVGIconProps } from "@patternfly/react-icons/dist/esm/createIcon";
// Define a simple star icon
const starIconDef: IconDefinition = {
name: 'StarIcon',
width: 24,
height: 24,
svgPath: 'M12 2l3.09 6.26L22 9.27l-5 4.87 1.18 6.88L12 17.77l-6.18 3.25L7 14.14 2 9.27l6.91-1.01L12 2z'
};
// Create the icon component
const StarIcon = createIcon(starIconDef);
// Use the icon
function MyComponent() {
return (
<div>
<StarIcon title="Favorite item" />
<StarIcon className="text-yellow-500" />
</div>
);
}Create complex icons with multiple path elements, each with optional individual styling.
/**
* Multi-path icon definition using SVGPathObject array
*/
interface MultiPathIconDefinition extends IconDefinition {
svgPath: SVGPathObject[];
}Usage Example:
import { createIcon, SVGPathObject } from "@patternfly/react-icons/dist/esm/createIcon";
// Define a complex shield icon with multiple paths
const shieldIconDef = {
name: 'ShieldIcon',
width: 24,
height: 24,
svgPath: [
{
path: 'M12 2L2 7v10c0 5.55 3.84 9.71 9 9.71s9-4.16 9-9.71V7l-10-5z',
className: 'shield-background'
},
{
path: 'M12 7L8.5 10.5L12 14l7-7-2.5-2.5L12 7z',
className: 'shield-check'
}
],
svgClassName: 'complex-shield'
};
const ShieldIcon = createIcon(shieldIconDef);Create icons that require viewport adjustments using offset parameters.
Usage Example:
const customIconDef = {
name: 'CustomIcon',
width: 100,
height: 100,
xOffset: 20, // Shifts viewBox 20 units right
yOffset: 10, // Shifts viewBox 10 units down
svgPath: 'M50 10 L90 90 L10 90 Z', // Triangle
svgClassName: 'custom-triangle'
};
const CustomIcon = createIcon(customIconDef);
// Results in viewBox="20 10 100 100"The createIcon function generates React class components with consistent structure and behavior.
/**
* Structure of components created by createIcon
*/
interface CreatedIconComponent extends React.ComponentClass<SVGIconProps> {
/** Static display name from IconDefinition.name */
displayName: string;
/** Component renders SVG with these features */
render(): React.ReactElement<{
className: string; // 'pf-v6-svg' + svgClassName + props.className
viewBox: string; // Calculated from xOffset, yOffset, width, height
fill: 'currentColor'; // Inherits text color
'aria-labelledby': string | null; // Links to title element if title provided
'aria-hidden': boolean | null; // true when no title provided
role: 'img'; // Semantic role
width: '1em'; // Scales with font size
height: '1em'; // Scales with font size
}>;
}Created icon components behave identically to built-in icons with full feature parity.
Accessibility Features:
Styling Integration:
pf-v6-svg base classsvgClassName if providedclassName prop1em dimensionsEvent Handling:
Usage Examples:
// Created icons work exactly like built-in icons
const MyIcon = createIcon({
name: 'MyIcon',
width: 16,
height: 16,
svgPath: 'M8 0L16 8L8 16L0 8Z'
});
// All standard usage patterns work
<MyIcon />
<MyIcon title="My custom icon" />
<MyIcon className="custom-style" onClick={handleClick} />
<MyIcon style={{ color: 'red', fontSize: '24px' }} />Full TypeScript support with proper type inference and safety.
/**
* Type definitions for createIcon usage
*/
declare function createIcon<T extends IconDefinition>(
iconDefinition: T
): React.ComponentClass<SVGIconProps>;
// Type-safe icon definition
const typedIconDef: IconDefinition = {
name: 'TypedIcon',
width: 24,
height: 24,
svgPath: 'M12 2L22 12L12 22L2 12Z'
};
// Resulting component has full type safety
const TypedIcon: React.ComponentClass<SVGIconProps> = createIcon(typedIconDef);Naming Conventions:
EmailIcon, CalendarIconSendIcon over ArrowIconSVG Path Optimization:
Accessibility:
name values1em size (typically 16px)Performance:
// Good: Create once, reuse
const IconComponent = createIcon(iconDef);
function MyComponent() {
return <IconComponent />;
}
// Avoid: Creating in render
function MyComponent() {
return <>{createIcon(iconDef)}</>; // Creates new component on every render
}Install with Tessl CLI
npx tessl i tessl/npm-patternfly--react-icons