From 4effdb0847829f59366bcdbebbacd1d83b49561d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=BE=90=E6=B6=9B?= Date: Mon, 6 Jan 2025 15:30:04 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E4=B8=80=E4=B8=AA=E5=BC=B9?= =?UTF-8?q?=E6=80=A7=E5=BF=AB=E9=80=9F=E9=A2=9C=E8=89=B2=E5=B1=95=E7=A4=BA?= =?UTF-8?q?=E7=BB=84=E4=BB=B6=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/FlexColorStand.module.css | 23 +++++++++ src/components/FlexColorStand.tsx | 59 ++++++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 src/components/FlexColorStand.module.css create mode 100644 src/components/FlexColorStand.tsx diff --git a/src/components/FlexColorStand.module.css b/src/components/FlexColorStand.module.css new file mode 100644 index 0000000..60b0703 --- /dev/null +++ b/src/components/FlexColorStand.module.css @@ -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; + } + } +} diff --git a/src/components/FlexColorStand.tsx b/src/components/FlexColorStand.tsx new file mode 100644 index 0000000..34f6e0f --- /dev/null +++ b/src/components/FlexColorStand.tsx @@ -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 ( +
+
+
copyToClipboard(colorValue)}> + {bgColor} +
+
+ ); +}