|
| 1 | +// Function to calculate relative luminance |
| 2 | +const getLuminance = (r: number, g: number, b: number) => { |
| 3 | + const [rs, gs, bs] = [r, g, b].map((c) => { |
| 4 | + c = c / 255; |
| 5 | + return c <= 0.03928 ? c / 12.92 : Math.pow((c + 0.055) / 1.055, 2.4); |
| 6 | + }); |
| 7 | + return 0.2126 * rs + 0.7152 * gs + 0.0722 * bs; |
| 8 | +}; |
| 9 | + |
| 10 | +// Function to calculate contrast ratio |
| 11 | +const getContrastRatio = (color1: string, color2: string) => { |
| 12 | + const hexToRgb = (hex: string) => { |
| 13 | + const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex); |
| 14 | + return result |
| 15 | + ? { |
| 16 | + r: parseInt(result[1], 16), |
| 17 | + g: parseInt(result[2], 16), |
| 18 | + b: parseInt(result[3], 16), |
| 19 | + } |
| 20 | + : { r: 0, g: 0, b: 0 }; |
| 21 | + }; |
| 22 | + |
| 23 | + const color1rgb = hexToRgb(color1); |
| 24 | + const color2rgb = hexToRgb(color2); |
| 25 | + |
| 26 | + const l1 = getLuminance(color1rgb.r, color1rgb.g, color1rgb.b); |
| 27 | + const l2 = getLuminance(color2rgb.r, color2rgb.g, color2rgb.b); |
| 28 | + |
| 29 | + const lighter = Math.max(l1, l2); |
| 30 | + const darker = Math.min(l1, l2); |
| 31 | + |
| 32 | + return ((lighter + 0.05) / (darker + 0.05)).toFixed(2); |
| 33 | +}; |
| 34 | + |
| 35 | +interface ColorContrastDemoProps { |
| 36 | + textColor: string; |
| 37 | + backgroundColor: string; |
| 38 | +} |
| 39 | + |
| 40 | +export const ColorContrastDemo = ({ |
| 41 | + textColor = '#000000', |
| 42 | + backgroundColor = '#ffffff', |
| 43 | +}: ColorContrastDemoProps) => { |
| 44 | + const containerStyle = { |
| 45 | + backgroundColor, |
| 46 | + padding: '20px', |
| 47 | + margin: '20px', |
| 48 | + }; |
| 49 | + |
| 50 | + const headingStyle = { |
| 51 | + color: textColor, |
| 52 | + }; |
| 53 | + |
| 54 | + const contrastRatio = getContrastRatio(textColor, backgroundColor); |
| 55 | + |
| 56 | + return ( |
| 57 | + <div style={containerStyle}> |
| 58 | + <h1 style={headingStyle}>Heading Level 1</h1> |
| 59 | + <p style={headingStyle}>Contrast ratio: {contrastRatio}</p> |
| 60 | + |
| 61 | + <h2 style={headingStyle}>Heading Level 2</h2> |
| 62 | + <p style={headingStyle}>Contrast ratio: {contrastRatio}</p> |
| 63 | + |
| 64 | + <h3 style={headingStyle}>Heading Level 3</h3> |
| 65 | + <p style={headingStyle}>Contrast ratio: {contrastRatio}</p> |
| 66 | + |
| 67 | + <h4 style={headingStyle}>Heading Level 4</h4> |
| 68 | + <p style={headingStyle}>Contrast ratio: {contrastRatio}</p> |
| 69 | + </div> |
| 70 | + ); |
| 71 | +}; |
0 commit comments