feat: add hidden selection indicator

This commit is contained in:
MAZE 2023-10-08 18:52:08 +03:30
parent 13cd72a065
commit e2cd75a332
3 changed files with 64 additions and 3 deletions

View File

@ -12,9 +12,18 @@ interface SoundProps {
src: string;
icon: React.ReactNode;
hidden: boolean;
selectHidden: (key: string) => void;
unselectHidden: (key: string) => void;
}
export function Sound({ hidden, icon, label, src }: SoundProps) {
export function Sound({
hidden,
icon,
label,
selectHidden,
src,
unselectHidden,
}: SoundProps) {
const { isPlaying, play } = usePlay();
const [isSelected, setIsSelected] = useLocalStorage(
`${label}-is-selected`,
@ -32,6 +41,11 @@ export function Sound({ hidden, icon, label, src }: SoundProps) {
}
}, [isSelected, sound, isPlaying]);
useEffect(() => {
if (hidden && isSelected) selectHidden(label);
else if (hidden && !isSelected) unselectHidden(label);
}, [label, isSelected, hidden, selectHidden, unselectHidden]);
const select = useCallback(() => {
setIsSelected(true);
play();

View File

@ -36,4 +36,15 @@
content: '';
transform: translateX(-50%);
}
&.active::after {
position: absolute;
top: 0;
right: 0;
width: 8px;
height: 8px;
border-radius: 50%;
background-color: #818cf8;
content: '';
}
}

View File

@ -1,5 +1,8 @@
import { useState, useMemo, useCallback } from 'react';
import { Sound } from '@/components/sound';
import { useLocalStorage } from '@/hooks/use-local-storage';
import { cn } from '@/helpers/styles';
import styles from './sounds.module.css';
@ -11,17 +14,50 @@ interface SoundsProps {
export function Sounds({ id, sounds }: SoundsProps) {
const [showAll, setShowAll] = useLocalStorage(`${id}-show-more`, false);
const [hiddenSelections, setHiddenSelections] = useState<{
[key: string]: boolean;
}>({});
const hasHiddenSelection = useMemo(() => {
const keys = Object.keys(hiddenSelections);
return keys.some(key => hiddenSelections[key]);
}, [hiddenSelections]);
const selectHidden = useCallback((key: string) => {
setHiddenSelections(prev => ({
...prev,
[key]: true,
}));
}, []);
const unselectHidden = useCallback((key: string) => {
setHiddenSelections(prev => ({
...prev,
[key]: false,
}));
}, []);
return (
<div>
<div className={styles.sounds}>
{sounds.map((sound, index) => (
<Sound key={sound.label} {...sound} hidden={!showAll && index > 3} />
<Sound
key={sound.label}
{...sound}
hidden={!showAll && index > 3}
selectHidden={selectHidden}
unselectHidden={unselectHidden}
/>
))}
</div>
{sounds.length > 4 && (
<button
className={styles.button}
className={cn(
styles.button,
hasHiddenSelection && !showAll && styles.active,
)}
onClick={() => setShowAll(prev => !prev)}
>
{showAll ? 'Show Less' : 'Show More'}