color-q/src/page-components/harmonies/HarmonyPreview.tsx

45 lines
1.5 KiB
TypeScript

import cx from 'clsx';
import { constant, flatten, isEqual, take, times } from 'lodash-es';
import { useMemo } from 'react';
import { useCopyColor } from '../../hooks/useCopyColor';
import { HarmonyColor } from '../../models';
import styles from './HarmonyPreview.module.css';
type HarmonyPreviewProps = {
colors?: HarmonyColor[];
};
export function HarmonyPreview({ colors = [] }: HarmonyPreviewProps) {
const copyColor = useCopyColor();
const extendedColors = useMemo(() => {
const sortedColors = colors.sort((a, b) => -(a.ratio - b.ratio));
if (sortedColors.length >= 4) {
return take(sortedColors, 4);
}
return flatten([
...sortedColors,
times(4 - sortedColors.length, constant({ color: '', ratio: 0 })),
]);
}, [colors]);
return (
<div className={styles.preview}>
<h5>Harmony Preview</h5>
<div className={styles.color_blocks}>
{extendedColors.map(({ color, ratio }, index) => (
<div
key={index}
className={cx(styles.color_block, isEqual(ratio, 0) && styles.hide)}
style={{ flexGrow: ratio }}>
<div className={styles.color_ratio}>{ratio > 0 && `Ratio: ${ratio}`}</div>
<div className={styles.color_square} style={{ backgroundColor: `#${color}` }}></div>
<div className={styles.color_code}>
{ratio > 0 && <span onClick={() => copyColor(color)}>#{color}</span>}
</div>
</div>
))}
</div>
</div>
);
}