增加一个弹性快速颜色展示组件。
This commit is contained in:
parent
9f603df57a
commit
4effdb0847
23
src/components/FlexColorStand.module.css
Normal file
23
src/components/FlexColorStand.module.css
Normal 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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
59
src/components/FlexColorStand.tsx
Normal file
59
src/components/FlexColorStand.tsx
Normal 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>
|
||||||
|
);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user