diff --git a/src/components/FloatColorPicker.module.css b/src/components/FloatColorPicker.module.css new file mode 100644 index 0000000..42f35f6 --- /dev/null +++ b/src/components/FloatColorPicker.module.css @@ -0,0 +1,38 @@ +@layer components { + .float_color_picker { + position: relative; + height: 32px; + .preview { + height: 100%; + display: flex; + flex-direction: row; + align-items: center; + gap: var(--spacing-xs); + .preview_block { + height: 100%; + aspect-ratio: 16 / 9; + border-radius: var(--border-radius-xxs); + border: 1px solid var(--color-border); + cursor: pointer; + } + } + .picker { + position: absolute; + top: calc(100% + 4px); + padding: var(--spacing-s) var(--spacing-s); + border-radius: var(--border-radius-xxs); + border: 1px solid var(--color-border); + background-color: var(--color-bg); + box-shadow: 2px 0 8px oklch(from var(--color-black) l c h / 65%); + display: flex; + flex-direction: column; + align-items: stretch; + gap: var(--spacing-s); + .btns { + display: flex; + flex-direction: row-reverse; + gap: var(--spacing-xs); + } + } + } +} diff --git a/src/components/FloatColorPicker.tsx b/src/components/FloatColorPicker.tsx new file mode 100644 index 0000000..056ccb2 --- /dev/null +++ b/src/components/FloatColorPicker.tsx @@ -0,0 +1,54 @@ +import { isEqual, isNil } from 'lodash-es'; +import { useCallback, useEffect, useState } from 'react'; +import { ActionIcon } from './ActionIcon'; +import { ColorPicker } from './ColorPicker'; +import styles from './FloatColorPicker.module.css'; + +type FloatColorPickerProps = { + name?: string; + color?: string; + onPick?: (color: string) => void; +}; + +export function FloatColorPicker({ name, color, onPick }: FloatColorPickerProps) { + const [pickedColor, setPicked] = useState(color ?? null); + const [showPicker, setPickerShow] = useState(false); + const handlePickAction = useCallback( + (value: string | null) => { + setPicked(value); + onPick?.(value); + }, + [onPick], + ); + + useEffect(() => { + if (!isEqual(pickedColor, color)) { + setPicked(color); + } + }, [color]); + + return ( +
+
+
setPickerShow(true)} + style={{ + backgroundColor: isNil(pickedColor) ? 'rgba(0, 0, 0, 0)' : `#${pickedColor}`, + }}>
+ handlePickAction(null)} /> +
+ {showPicker && ( +
+ +
+ +
+
+ )} + {!isNil(name) && } +
+ ); +}