mirror of
https://github.com/remvze/moodist.git
synced 2025-09-29 15:30:49 -04:00
feat: add hidden selection indicator
This commit is contained in:
parent
13cd72a065
commit
e2cd75a332
@ -12,9 +12,18 @@ interface SoundProps {
|
|||||||
src: string;
|
src: string;
|
||||||
icon: React.ReactNode;
|
icon: React.ReactNode;
|
||||||
hidden: boolean;
|
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 { isPlaying, play } = usePlay();
|
||||||
const [isSelected, setIsSelected] = useLocalStorage(
|
const [isSelected, setIsSelected] = useLocalStorage(
|
||||||
`${label}-is-selected`,
|
`${label}-is-selected`,
|
||||||
@ -32,6 +41,11 @@ export function Sound({ hidden, icon, label, src }: SoundProps) {
|
|||||||
}
|
}
|
||||||
}, [isSelected, sound, isPlaying]);
|
}, [isSelected, sound, isPlaying]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (hidden && isSelected) selectHidden(label);
|
||||||
|
else if (hidden && !isSelected) unselectHidden(label);
|
||||||
|
}, [label, isSelected, hidden, selectHidden, unselectHidden]);
|
||||||
|
|
||||||
const select = useCallback(() => {
|
const select = useCallback(() => {
|
||||||
setIsSelected(true);
|
setIsSelected(true);
|
||||||
play();
|
play();
|
||||||
|
@ -36,4 +36,15 @@
|
|||||||
content: '';
|
content: '';
|
||||||
transform: translateX(-50%);
|
transform: translateX(-50%);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.active::after {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: #818cf8;
|
||||||
|
content: '';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
|
import { useState, useMemo, useCallback } from 'react';
|
||||||
|
|
||||||
import { Sound } from '@/components/sound';
|
import { Sound } from '@/components/sound';
|
||||||
import { useLocalStorage } from '@/hooks/use-local-storage';
|
import { useLocalStorage } from '@/hooks/use-local-storage';
|
||||||
|
import { cn } from '@/helpers/styles';
|
||||||
|
|
||||||
import styles from './sounds.module.css';
|
import styles from './sounds.module.css';
|
||||||
|
|
||||||
@ -11,17 +14,50 @@ interface SoundsProps {
|
|||||||
export function Sounds({ id, sounds }: SoundsProps) {
|
export function Sounds({ id, sounds }: SoundsProps) {
|
||||||
const [showAll, setShowAll] = useLocalStorage(`${id}-show-more`, false);
|
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 (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<div className={styles.sounds}>
|
<div className={styles.sounds}>
|
||||||
{sounds.map((sound, index) => (
|
{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>
|
</div>
|
||||||
|
|
||||||
{sounds.length > 4 && (
|
{sounds.length > 4 && (
|
||||||
<button
|
<button
|
||||||
className={styles.button}
|
className={cn(
|
||||||
|
styles.button,
|
||||||
|
hasHiddenSelection && !showAll && styles.active,
|
||||||
|
)}
|
||||||
onClick={() => setShowAll(prev => !prev)}
|
onClick={() => setShowAll(prev => !prev)}
|
||||||
>
|
>
|
||||||
{showAll ? 'Show Less' : 'Show More'}
|
{showAll ? 'Show Less' : 'Show More'}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user