增加一个弹性快速颜色展示组件。

This commit is contained in:
徐涛 2025-01-06 15:30:04 +08:00
parent 9f603df57a
commit 4effdb0847
2 changed files with 82 additions and 0 deletions

View File

@ -0,0 +1,23 @@
@layer components {
.color_stand {
max-width: 10em;
height: 100%;
flex: 1 1 2em;
display: flex;
flex-direction: column;
align-items: stretch;
gap: var(--spacing-n);
border-radius: var(--border-radius-xs);
border: 1px solid var(--color-border);
.color_block {
flex: 1 0;
}
.color_value {
padding: var(--spacing-xxs) var(--spacing-xs);
font-size: var(--font-size-xs);
text-align: right;
text-transform: uppercase;
cursor: pointer;
}
}
}

View File

@ -0,0 +1,59 @@
import { useMemo } from 'react';
import { useColorFunction } from '../ColorFunctionContext';
import { useCopyColor } from '../hooks/useCopyColor';
import styles from './FlexColorStand.module.css';
type FlexColorStandProps = {
color: string;
valueMode?: 'hex' | 'rgb' | 'hsl' | 'lab' | 'oklch';
};
export function FlexColorStand({ color, valueMode = 'hex' }: FlexColorStandProps) {
const { colorFn } = useColorFunction();
const bgColor = useMemo(() => (color.startsWith('#') ? color : `#${color}`), [color]);
const colorValue = useMemo(() => {
if (!colorFn) return color;
try {
switch (valueMode) {
case 'rgb':
{
const [r, g, b] = colorFn!.represent_rgb(color);
return `rgb(${r}, ${g}, ${b})`;
}
break;
case 'hsl':
{
const [h, s, l] = colorFn!.represent_hsl(color);
return `hsl(${h.toFixed(2)}, ${(s * 100).toFixed(2)}%, ${(l * 100).toFixed(2)}%)`;
}
break;
case 'lab':
{
const [l, a, b] = colorFn!.represent_lab(color);
return `lab(${l.toFixed(2)}, ${a.toFixed(2)}, ${b.toFixed(2)})`;
}
break;
case 'oklch': {
const [l, c, h] = colorFn!.represent_oklch(color);
return `oklch(${l.toFixed(2)}, ${c.toFixed(2)}, ${h.toFixed(2)})`;
}
case 'hex':
default:
return color.startsWith('#') ? color : `#${color}`;
}
} catch (e) {
console.error('[Convert color]', e);
return color;
}
}, [color, valueMode]);
const copyToClipboard = useCopyColor();
return (
<div className={styles.color_stand}>
<div className={styles.color_block} style={{ backgroundColor: bgColor }} />
<div className={styles.color_value} onClick={() => copyToClipboard(colorValue)}>
{bgColor}
</div>
</div>
);
}