Skip to content

Commit 2b3594c

Browse files
committed
contrast
1 parent d59b688 commit 2b3594c

File tree

2 files changed

+102
-0
lines changed

2 files changed

+102
-0
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import type { Meta, StoryObj } from '@storybook/react';
2+
import { ColorContrastDemo } from './ColorContrastDemo';
3+
4+
const meta = {
5+
title: 'Example/Color Contrast',
6+
component: ColorContrastDemo,
7+
parameters: {
8+
layout: 'centered',
9+
},
10+
tags: ['autodocs'],
11+
argTypes: {
12+
textColor: {
13+
control: { type: 'color' },
14+
description: 'Color of the headings',
15+
},
16+
backgroundColor: {
17+
control: { type: 'color' },
18+
description: 'Background color of the container',
19+
},
20+
},
21+
} satisfies Meta<typeof ColorContrastDemo>;
22+
23+
export default meta;
24+
type Story = StoryObj<typeof meta>;
25+
26+
export const Default: Story = {
27+
args: {
28+
textColor: '#000000',
29+
backgroundColor: '#ffffff',
30+
},
31+
};
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
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

Comments
 (0)