Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions components/WcagComplianceBadge.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { CheckCircle2, XCircle } from "lucide-react";
import { cn } from "@/lib/utils";

interface ComplianceBadgeProps {
passed: boolean;
level: string;
}

export function ComplianceBadge({ passed, level }: ComplianceBadgeProps) {
const Icon = passed ? CheckCircle2 : XCircle;
const statusClasses = passed
? "bg-green-100 dark:bg-green-900/30 text-green-800 dark:text-green-300"
: "bg-red-100 dark:bg-red-900/30 text-red-800 dark:text-red-300";

return (
<div
className={cn(
"flex items-center gap-2 px-3 py-2 rounded-md text-sm",
statusClasses
)}
>
<Icon className="w-4 h-4" />
<span className="font-medium">{level}</span>
</div>
);
}
67 changes: 67 additions & 0 deletions components/ds/ColorPickerComponent.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
import React, { useState } from "react";
import {
Popover,
PopoverTrigger,
PopoverContent,
} from "@/components/ds/PopoverComponent";
import { SketchPicker } from "react-color";
import { cn } from "@/lib/utils";
import {
normalizeHexForDisplay,
isValidHex,
} from "@/components/utils/wcag-color-contrast.utils";
import { X } from "lucide-react";

const DEFAULT_COLOR = "#000000" as const;

export interface ColorPickerProps {
value: string;
onChange: (color: string) => void;
className?: string;
disabled?: boolean;
}

export const ColorPicker = React.forwardRef<HTMLDivElement, ColorPickerProps>(
({ value, onChange, className, disabled = false }, ref) => {
const [open, setOpen] = useState(false);

const isValid = value ? isValidHex(value) : false;
const displayValue = normalizeHexForDisplay(value) ?? DEFAULT_COLOR;

return (
<Popover open={open} onOpenChange={setOpen}>
<PopoverTrigger asChild>
<button
type="button"
disabled={disabled}
className={cn(
"w-12 h-12 border-2 rounded-md flex-none cursor-pointer transition-all hover:scale-105 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 relative flex items-center justify-center",
className
)}
style={{
backgroundColor: isValid ? displayValue : "transparent",
}}
aria-label="Pick a color"
>
{!isValid && value && (
<X
className="w-6 h-6 text-red-500 dark:text-red-400"
strokeWidth={2.5}
/>
)}
</button>
</PopoverTrigger>
<PopoverContent className="w-auto p-0" align="start" ref={ref}>
<SketchPicker
color={displayValue}
onChange={(color) => onChange(color.hex.toUpperCase())}
disableAlpha
presetColors={[]}
/>
</PopoverContent>
</Popover>
);
}
);

ColorPicker.displayName = "ColorPicker";
96 changes: 96 additions & 0 deletions components/seo/WcagColorContrastCheckerSEO.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
export default function WcagColorContrastCheckerSEO() {
return (
<div className="content-wrapper">
<section>
<h2>Check Color Contrast for WCAG Compliance</h2>
<p>
Ensure your designs meet accessibility standards with our free WCAG
color contrast checker. This tool helps you verify that your color
combinations meet WCAG 2.1 AA and AAA compliance requirements for both
normal and large text.
</p>
</section>

<section>
<h2>How to Use Jam's WCAG Color Contrast Checker</h2>
<p>
Quickly verify color contrast ratios and ensure your designs meet
accessibility standards. Perfect for designers, developers, and anyone
working on accessible web content.
</p>
<ul>
<li>
<b>Enter your foreground color:</b> Input your text color in hex
format (e.g., #000000)
</li>
<li>
<b>Enter your background color:</b> Input your background color in
hex format (e.g., #FFFFFF)
</li>
<li>
<b>Review the results:</b> Instantly see the contrast ratio and WCAG
compliance status for both AA and AAA standards
</li>
</ul>
</section>

<section>
<h2>Understanding WCAG Color Contrast Requirements</h2>
<p>
The Web Content Accessibility Guidelines (WCAG) 2.1 define minimum
contrast ratios to ensure text is readable for people with visual
impairments. The contrast ratio measures the difference in luminance
between text and background colors.
</p>
<ul>
<li>
<b>WCAG AA Normal text:</b> Requires 4.5:1 contrast ratio (text
smaller than 18pt or 14pt bold)
</li>
<li>
<b>WCAG AA Large text:</b> Requires 3:1 contrast ratio (text 18pt+
or 14pt+ bold)
</li>
<li>
<b>WCAG AA Graphical objects and UI components:</b> Requires 3:1
contrast ratio for essential visual information like icons, buttons,
form controls, and other interactive elements
</li>
<li>
<b>WCAG AAA Normal text:</b> Requires 7:1 contrast ratio (text
smaller than 18pt or 14pt bold)
</li>
<li>
<b>WCAG AAA Large text:</b> Requires 4.5:1 contrast ratio (text
18pt+ or 14pt+ bold)
</li>
</ul>
</section>

<section>
<h2>Graphical Objects and User Interface Components</h2>
<p>
WCAG 2.1 also requires a minimum 3:1 contrast ratio for graphical
objects and user interface components. This includes icons, buttons,
form controls, charts, graphs, and other essential visual elements
that convey information or require user interaction. Our tool checks
compliance for these elements, helping you ensure that all parts of
your interface are accessible to users with visual impairments.
</p>
</section>

<section>
<h2>Why Color Contrast Matters for Accessibility</h2>
<p>
Proper color contrast is essential for accessibility. It ensures that
people with visual impairments, color blindness, or those viewing
content in bright sunlight can read your text and interact with your
interface. Meeting WCAG standards not only improves accessibility but
also helps you comply with legal requirements in many jurisdictions.
Our tool calculates the contrast ratio using the WCAG 2.1 formula,
which considers the relative luminance of colors.
</p>
</section>
</div>
);
}
6 changes: 6 additions & 0 deletions components/utils/tools-list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -161,4 +161,10 @@ export const tools = [
"Generate cryptographically secure random strings with configurable character sets. Perfect for API keys, tokens, passwords, and secure identifiers.",
link: "/utilities/random-string-generator",
},
{
title: "WCAG Color Contrast Checker",
description:
"Check color contrast ratios for WCAG AA and AAA compliance. Ensure your designs meet accessibility standards with our free color contrast checker tool.",
link: "/utilities/wcag-color-contrast-checker",
},
];
Loading