Generates accessible color combinations that meet WCAG contrast requirements.
Usage
import { useAccessibleColor } from "@servicetitan/anvil2";
function ColorfulBadge({ color }) {
const colors = useAccessibleColor(color, "light");
return (
<span
style={{
color: colors.foreground,
backgroundColor: colors.background,
borderColor: colors.border,
}}
>
Badge Text
</span>
);
}
Parameters
| Parameter | Type | Description |
|---|
hex | string | The hex color to generate accessible colors for (e.g., "#FF0000") |
mode | "light" | "dark" | The color mode for context-aware generation |
Return Value
| Property | Type | Description |
|---|
foreground | string | undefined | Accessible text color (4.5:1 contrast ratio) |
background | string | undefined | The background color |
border | string | undefined | Accessible border color (3:1 contrast ratio) |
Contrast Requirements
The hook ensures colors meet WCAG accessibility standards:
- Text (foreground): 4.5:1 contrast ratio against background
- Border: 3:1 contrast ratio against page background
- Colors are iteratively adjusted up to 16 times to meet requirements
Examples
Dynamic Badge Colors
function CategoryBadge({ category }) {
const categoryColors = {
urgent: "#FF0000",
warning: "#FFA500",
info: "#0066CC",
success: "#00AA00",
};
const colors = useAccessibleColor(categoryColors[category], "light");
return (
<span
style={{
color: colors.foreground,
backgroundColor: colors.background,
border: `1px solid ${colors.border}`,
padding: "4px 8px",
borderRadius: "4px",
}}
>
{category}
</span>
);
}
Theme-Aware Colors
function ThemedTag({ color }) {
const { mode } = usePrefersColorScheme();
const colors = useAccessibleColor(color, mode);
return (
<span
style={{
color: colors.foreground,
backgroundColor: colors.background,
}}
>
Tag
</span>
);
}
User-Selected Colors
function CustomColorPicker({ userColor }) {
const colors = useAccessibleColor(userColor, "light");
return (
<div>
<div
style={{
backgroundColor: colors.background,
color: colors.foreground,
padding: "16px",
}}
>
Preview with accessible text
</div>
<Text size="small" subdued>
Text color adjusted for {">"}4.5:1 contrast ratio
</Text>
</div>
);
}
Algorithm Details
Light Mode
- Determines if the background is light or dark using contrast comparison
- Selects white or dark text based on background
- Ensures 4.5:1 contrast ratio for text readability
- Falls back to black text if contrast is insufficient
- Generates border color with 3:1 contrast against page background
Dark Mode
- Starts with the provided color for both foreground and background
- Ensures background meets darkness threshold for dark themes
- Iteratively adjusts foreground and background for 4.5:1 contrast
- Prioritizes background darkening to maintain theme consistency
- Generates border color with 3:1 contrast against page background
Last modified on January 23, 2026