Create custom icons using the Blank component while maintaining consistency with the grommet-icons theming system and styling.
Template component for creating custom icons that integrate seamlessly with the grommet-icons system.
/**
* Blank icon component for creating custom icons
* Provides the base StyledIcon wrapper with theming support
*/
declare const Blank: React.ComponentType<IconProps & JSX.IntrinsicElements['svg']>;
interface IconProps {
/** Accessibility title for screen readers */
a11yTitle?: string;
/** Icon color - theme color name, CSS color value, or 'plain' for original colors */
color?: string;
/** Icon size - predefined size or custom CSS value */
size?: 'small' | 'medium' | 'large' | 'xlarge' | string;
/** Hide from screen readers (default: true for decorative icons) */
'aria-hidden'?: boolean;
}Create simple custom icons using SVG content within the Blank component.
Usage Examples:
import React from 'react';
import { Blank } from 'grommet-icons';
// Decorative custom icon (default aria-hidden=true)
export const MyCustomIcon = (props) => (
<Blank {...props}>
<circle cx="12" cy="12" r="5" />
</Blank>
);
// Semantic custom icon (accessible)
export const MyAccessibleIcon = (props) => (
<Blank
a11yTitle="Custom action"
aria-hidden={undefined}
{...props}
>
<path d="M12 2L2 7V10C2 16 6 21.5 12 23C18 21.5 22 16 22 10V7L12 2Z" />
</Blank>
);
// Usage
function MyComponent() {
return (
<div>
<MyCustomIcon />
<MyCustomIcon color="brand" size="large" />
<MyAccessibleIcon color="accent" />
</div>
);
}Create more complex custom icons with multiple SVG elements and advanced styling.
Complex SVG Icons:
import React from 'react';
import { Blank } from 'grommet-icons';
export const ComplexCustomIcon = (props) => (
<Blank {...props}>
<g>
<rect x="2" y="3" width="20" height="14" rx="2" ry="2" />
<line x1="8" y1="21" x2="16" y2="21" />
<line x1="12" y1="17" x2="12" y2="21" />
</g>
</Blank>
);
export const MultiColorIcon = (props) => (
<Blank {...props}>
<svg viewBox="0 0 24 24">
<circle cx="12" cy="12" r="10" fill="currentColor" />
<path
d="M8 12l2 2 4-4"
stroke="white"
strokeWidth="2"
fill="none"
/>
</svg>
</Blank>
);Create custom icons that fully integrate with the grommet-icons theming system.
Theme-Aware Custom Icons:
import React from 'react';
import { Blank } from 'grommet-icons';
// Custom icon that responds to theme
export const ThemedCustomIcon = (props) => (
<Blank {...props}>
<g>
{/* Main shape - inherits theme color */}
<rect
x="3"
y="3"
width="18"
height="18"
rx="2"
fill="currentColor"
/>
{/* Inner detail - contrasting color */}
<circle
cx="12"
cy="12"
r="6"
fill="none"
stroke="white"
strokeWidth="2"
/>
</g>
</Blank>
);
// Usage with different theme colors
function ThemedExample() {
return (
<div>
<ThemedCustomIcon color="brand" />
<ThemedCustomIcon color="accent" />
<ThemedCustomIcon color="#ff6600" />
</div>
);
}Create collections of related custom icons for consistent usage.
Custom Icon Library:
import React from 'react';
import { Blank } from 'grommet-icons';
// Weather icon collection
export const WeatherSunny = (props) => (
<Blank a11yTitle="Sunny weather" aria-hidden={undefined} {...props}>
<circle cx="12" cy="12" r="5" />
<path d="M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42" />
</Blank>
);
export const WeatherCloudy = (props) => (
<Blank a11yTitle="Cloudy weather" aria-hidden={undefined} {...props}>
<path d="M18 10h-1.26A8 8 0 1 0 9 20h9a5 5 0 0 0 0-10z" />
</Blank>
);
export const WeatherRainy = (props) => (
<Blank a11yTitle="Rainy weather" aria-hidden={undefined} {...props}>
<path d="M16 13v8l-4-4-4 4v-8" />
<path d="M18 7h-1.26A8 8 0 1 0 9 17h9a5 5 0 0 0 0-10z" />
</Blank>
);
// Export as collection
export const WeatherIcons = {
Sunny: WeatherSunny,
Cloudy: WeatherCloudy,
Rainy: WeatherRainy,
};Integrate external SVG files or content into the Blank component system.
External SVG Usage:
import React from 'react';
import { Blank } from 'grommet-icons';
// From external SVG string
const externalSvgContent = `
<path d="M12 2L2 7V10C2 16 6 21.5 12 23C18 21.5 22 16 22 10V7L12 2Z"/>
<path d="M9 12L11 14L15 10"/>
`;
export const ExternalIcon = (props) => (
<Blank {...props}>
<g dangerouslySetInnerHTML={{ __html: externalSvgContent }} />
</Blank>
);
// From imported SVG component
import CustomSvg from './custom-icon.svg';
export const ImportedIcon = (props) => (
<Blank {...props}>
<CustomSvg />
</Blank>
);Create custom icons that adapt to different sizes and contexts.
Size-Responsive Icons:
import React from 'react';
import { Blank } from 'grommet-icons';
export const ResponsiveIcon = ({ size, ...props }) => {
// Adjust detail based on size
const isSmall = size === 'small' || (typeof size === 'string' && parseInt(size) < 16);
return (
<Blank size={size} {...props}>
<rect x="2" y="2" width="20" height="20" rx="2" />
{!isSmall && (
<>
{/* Additional detail for larger sizes */}
<circle cx="8" cy="8" r="2" />
<circle cx="16" cy="8" r="2" />
<path d="M8 16s2-2 4-2 4 2 4 2" />
</>
)}
</Blank>
);
};Accessibility Guidelines:
import React from 'react';
import { Blank } from 'grommet-icons';
// Decorative icon - hidden from screen readers
export const DecorativeIcon = (props) => (
<Blank {...props}>
{/* Decorative SVG content */}
<circle cx="12" cy="12" r="10" />
</Blank>
);
// Semantic icon - accessible with title
export const SemanticIcon = (props) => (
<Blank
a11yTitle="Semantic meaning"
aria-hidden={undefined}
{...props}
>
{/* Meaningful SVG content */}
<path d="M12 2L2 7V10C2 16 6 21.5 12 23C18 21.5 22 16 22 10V7L12 2Z" />
</Blank>
);
// Interactive icon - with proper ARIA labels
export const InteractiveIcon = ({ onClick, ...props }) => (
<Blank
a11yTitle="Perform action"
aria-hidden={undefined}
role="button"
tabIndex={0}
onClick={onClick}
onKeyDown={(e) => e.key === 'Enter' && onClick?.(e)}
{...props}
>
<path d="M12 2L2 7V10C2 16 6 21.5 12 23C18 21.5 22 16 22 10V7L12 2Z" />
</Blank>
);Custom icons created with Blank inherit all standard icon properties and theming capabilities:
interface CustomIconProps extends IconProps {
/** All standard SVG props are supported */
className?: string;
style?: React.CSSProperties;
onClick?: (event: React.MouseEvent) => void;
onKeyDown?: (event: React.KeyboardEvent) => void;
role?: string;
tabIndex?: number;
/** Custom props for your specific icon */
[customProp: string]: any;
}Custom icons maintain full compatibility with the grommet-icons theming system, sizing options, and accessibility features while allowing complete creative control over the SVG content.