重构目前所有的复制颜色代码功能使用统一的Hook。
This commit is contained in:
parent
10f885526e
commit
69afcc369e
|
@ -1,11 +1,10 @@
|
||||||
import { isEqual, isNil } from 'lodash-es';
|
import { isEqual } from 'lodash-es';
|
||||||
import { useCallback, useEffect, useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { useCopyToClipboard } from 'react-use';
|
import { useCopyColor } from '../hooks/useCopyColor';
|
||||||
import { ColorComponentInput } from './ColorComponentInput';
|
import { ColorComponentInput } from './ColorComponentInput';
|
||||||
import styles from './ColorPicker.module.css';
|
import styles from './ColorPicker.module.css';
|
||||||
import { HSegmentedControl } from './HSegmentedControl';
|
import { HSegmentedControl } from './HSegmentedControl';
|
||||||
import { HslAssemble } from './HslAsssemble';
|
import { HslAssemble } from './HslAsssemble';
|
||||||
import { NotificationType, useNotification } from './Notifications';
|
|
||||||
import { RGBAssemble } from './RGBAssemble';
|
import { RGBAssemble } from './RGBAssemble';
|
||||||
|
|
||||||
type ColorPickerProps = {
|
type ColorPickerProps = {
|
||||||
|
@ -14,35 +13,18 @@ type ColorPickerProps = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export function ColorPicker({ color, onSelect }: ColorPickerProps) {
|
export function ColorPicker({ color, onSelect }: ColorPickerProps) {
|
||||||
const [cpState, copyToClipboard] = useCopyToClipboard();
|
|
||||||
const { showToast } = useNotification();
|
|
||||||
const [pickMode, setMode] = useState<'rgb' | 'hsl' | 'input'>('rgb');
|
const [pickMode, setMode] = useState<'rgb' | 'hsl' | 'input'>('rgb');
|
||||||
const [selectedColor, setSelectedColor] = useState<string>(color ?? '000000');
|
const [selectedColor, setSelectedColor] = useState<string>(color ?? '000000');
|
||||||
const handleColorSelect = (color: string) => {
|
const handleColorSelect = (color: string) => {
|
||||||
setSelectedColor(color);
|
setSelectedColor(color);
|
||||||
onSelect?.(color);
|
onSelect?.(color);
|
||||||
};
|
};
|
||||||
const handleCopyAction = useCallback(() => {
|
const copyColor = useCopyColor();
|
||||||
copyToClipboard(`#${selectedColor}`);
|
|
||||||
}, [selectedColor]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!isNil(cpState.error)) {
|
|
||||||
showToast(NotificationType.ERROR, 'Failed to copy to clipboard', 'tabler:alert-circle', 3000);
|
|
||||||
} else if (!isNil(cpState.value)) {
|
|
||||||
showToast(
|
|
||||||
NotificationType.SUCCESS,
|
|
||||||
`${cpState.value} has been copied to clipboard.`,
|
|
||||||
'tabler:circle-check',
|
|
||||||
3000,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}, [cpState]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.color_picker}>
|
<div className={styles.color_picker}>
|
||||||
<div className={styles.color_preview} style={{ backgroundColor: `#${selectedColor}` }} />
|
<div className={styles.color_preview} style={{ backgroundColor: `#${selectedColor}` }} />
|
||||||
<div className={styles.color_code} onClick={handleCopyAction}>
|
<div className={styles.color_code} onClick={() => copyColor(selectedColor)}>
|
||||||
#{selectedColor}
|
#{selectedColor}
|
||||||
</div>
|
</div>
|
||||||
<HSegmentedControl
|
<HSegmentedControl
|
||||||
|
|
|
@ -1,38 +1,18 @@
|
||||||
import { Icon } from '@iconify/react/dist/iconify.js';
|
import { Icon } from '@iconify/react/dist/iconify.js';
|
||||||
import { isNil } from 'lodash-es';
|
import { isNil } from 'lodash-es';
|
||||||
import { useCallback, useEffect, useMemo, useState } from 'react';
|
import { useMemo, useState } from 'react';
|
||||||
import { useCopyToClipboard } from 'react-use';
|
|
||||||
import NoColor from '../assets/NoColor.svg';
|
import NoColor from '../assets/NoColor.svg';
|
||||||
import { useColorFunction } from '../ColorFunctionContext';
|
import { useColorFunction } from '../ColorFunctionContext';
|
||||||
|
import { useCopyColor } from '../hooks/useCopyColor';
|
||||||
import styles from './ColorStand.module.css';
|
import styles from './ColorStand.module.css';
|
||||||
import { HSegmentedControl } from './HSegmentedControl';
|
import { HSegmentedControl } from './HSegmentedControl';
|
||||||
import { NotificationType, useNotification } from './Notifications';
|
|
||||||
|
|
||||||
type ColorValueProps = {
|
type ColorValueProps = {
|
||||||
value: string | null;
|
value: string | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
function ColorValue({ value }: ColorValueProps) {
|
function ColorValue({ value }: ColorValueProps) {
|
||||||
const [cpState, copyToClipboard] = useCopyToClipboard();
|
const copyColor = useCopyColor();
|
||||||
const { showToast } = useNotification();
|
|
||||||
const handleCopy = useCallback(() => {
|
|
||||||
if (!isNil(value)) {
|
|
||||||
copyToClipboard(value);
|
|
||||||
}
|
|
||||||
}, [value]);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!isNil(cpState.error)) {
|
|
||||||
showToast(NotificationType.ERROR, 'Failed to copy to clipboard', 'tabler:alert-circle', 3000);
|
|
||||||
} else if (!isNil(cpState.value)) {
|
|
||||||
showToast(
|
|
||||||
NotificationType.SUCCESS,
|
|
||||||
`${cpState.value} has been copied to clipboard.`,
|
|
||||||
'tabler:circle-check',
|
|
||||||
3000,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}, [cpState]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.color_value}>
|
<div className={styles.color_value}>
|
||||||
|
@ -42,7 +22,7 @@ function ColorValue({ value }: ColorValueProps) {
|
||||||
<span>Not Available</span>
|
<span>Not Available</span>
|
||||||
</div>
|
</div>
|
||||||
) : (
|
) : (
|
||||||
<div className={styles.value} onClick={handleCopy}>
|
<div className={styles.value} onClick={() => copyColor(value)}>
|
||||||
{value}
|
{value}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -7,6 +7,7 @@ export function useCopyColor() {
|
||||||
const { showToast } = useNotification();
|
const { showToast } = useNotification();
|
||||||
const [cpState, copyToClipboard] = useCopyToClipboard();
|
const [cpState, copyToClipboard] = useCopyToClipboard();
|
||||||
const copyAction = useCallback((color: string) => {
|
const copyAction = useCallback((color: string) => {
|
||||||
|
if (isNil(color)) return;
|
||||||
if (color.startsWith('#')) {
|
if (color.startsWith('#')) {
|
||||||
copyToClipboard(color);
|
copyToClipboard(color);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
import cx from 'clsx';
|
import cx from 'clsx';
|
||||||
import { constant, flatten, isEqual, isNil, take, times } from 'lodash-es';
|
import { constant, flatten, isEqual, take, times } from 'lodash-es';
|
||||||
import { useEffect, useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import { useCopyToClipboard } from 'react-use';
|
import { useCopyColor } from '../../hooks/useCopyColor';
|
||||||
import { NotificationType, useNotification } from '../../components/Notifications';
|
|
||||||
import { HarmonyColor } from '../../models';
|
import { HarmonyColor } from '../../models';
|
||||||
import styles from './HarmonyPreview.module.css';
|
import styles from './HarmonyPreview.module.css';
|
||||||
|
|
||||||
|
@ -11,8 +10,7 @@ type HarmonyPreviewProps = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export function HarmonyPreview({ colors = [] }: HarmonyPreviewProps) {
|
export function HarmonyPreview({ colors = [] }: HarmonyPreviewProps) {
|
||||||
const [cpState, copyToClipboard] = useCopyToClipboard();
|
const copyColor = useCopyColor();
|
||||||
const { showToast } = useNotification();
|
|
||||||
const extendedColors = useMemo(() => {
|
const extendedColors = useMemo(() => {
|
||||||
const sortedColors = colors.sort((a, b) => -(a.ratio - b.ratio));
|
const sortedColors = colors.sort((a, b) => -(a.ratio - b.ratio));
|
||||||
if (sortedColors.length >= 4) {
|
if (sortedColors.length >= 4) {
|
||||||
|
@ -24,19 +22,6 @@ export function HarmonyPreview({ colors = [] }: HarmonyPreviewProps) {
|
||||||
]);
|
]);
|
||||||
}, [colors]);
|
}, [colors]);
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!isNil(cpState.error)) {
|
|
||||||
showToast(NotificationType.ERROR, 'Failed to copy to clipboard', 'tabler:alert-circle', 3000);
|
|
||||||
} else if (!isNil(cpState.value)) {
|
|
||||||
showToast(
|
|
||||||
NotificationType.SUCCESS,
|
|
||||||
`${cpState.value} has been copied to clipboard.`,
|
|
||||||
'tabler:circle-check',
|
|
||||||
3000,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}, [cpState]);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.preview}>
|
<div className={styles.preview}>
|
||||||
<h5>Harmony Preview</h5>
|
<h5>Harmony Preview</h5>
|
||||||
|
@ -49,7 +34,7 @@ export function HarmonyPreview({ colors = [] }: HarmonyPreviewProps) {
|
||||||
<div className={styles.color_ratio}>{ratio > 0 && `Ratio: ${ratio}`}</div>
|
<div className={styles.color_ratio}>{ratio > 0 && `Ratio: ${ratio}`}</div>
|
||||||
<div className={styles.color_square} style={{ backgroundColor: `#${color}` }}></div>
|
<div className={styles.color_square} style={{ backgroundColor: `#${color}` }}></div>
|
||||||
<div className={styles.color_code}>
|
<div className={styles.color_code}>
|
||||||
{ratio > 0 && <span onClick={() => copyToClipboard(`#${color}`)}>#{color}</span>}
|
{ratio > 0 && <span onClick={() => copyColor(color)}>#{color}</span>}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user