diff --git a/src/page-components/harmonies/HarmonyPreview.module.css b/src/page-components/harmonies/HarmonyPreview.module.css index 80b5873..394df47 100644 --- a/src/page-components/harmonies/HarmonyPreview.module.css +++ b/src/page-components/harmonies/HarmonyPreview.module.css @@ -23,7 +23,7 @@ flex-grow: 0; flex-shrink: 1; font-size: var(--font-size-m); - transition: flex-grow 300ms, width 300ms; + transition: flex-grow 300ms, width 300ms, opacity 200ms; > * { overflow: hidden; } @@ -34,6 +34,9 @@ &.zero_width { width: 0; } + &.hide { + opacity: 0; + } .color_ratio { height: 1.5em; padding-inline: var(--spacing-s); @@ -45,6 +48,9 @@ font-size: var(--font-size-s); text-transform: uppercase; text-align: right; + > span { + cursor: pointer; + } } } } diff --git a/src/page-components/harmonies/HarmonyPreview.tsx b/src/page-components/harmonies/HarmonyPreview.tsx index 7540ce8..47ac03d 100644 --- a/src/page-components/harmonies/HarmonyPreview.tsx +++ b/src/page-components/harmonies/HarmonyPreview.tsx @@ -1,6 +1,8 @@ import cx from 'clsx'; -import { constant, flatten, isEqual, take, times } from 'lodash-es'; -import { useMemo } from 'react'; +import { constant, flatten, isEqual, isNil, take, times } from 'lodash-es'; +import { useEffect, useMemo } from 'react'; +import { useCopyToClipboard } from 'react-use'; +import { NotificationType, useNotification } from '../../components/Notifications'; import { HarmonyColor } from '../../models'; import styles from './HarmonyPreview.module.css'; @@ -9,6 +11,8 @@ type HarmonyPreviewProps = { }; export function HarmonyPreview({ colors = [] }: HarmonyPreviewProps) { + const [cpState, copyToClipboard] = useCopyToClipboard(); + const { showToast } = useNotification(); const extendedColors = useMemo(() => { const sortedColors = colors.sort((a, b) => -(a.ratio - b.ratio)); if (sortedColors.length >= 4) { @@ -20,6 +24,19 @@ export function HarmonyPreview({ colors = [] }: HarmonyPreviewProps) { ]); }, [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 (