feat: add more and less button for sounds

This commit is contained in:
MAZE 2023-10-08 18:30:12 +03:30
parent 41c5ae5db8
commit 13cd72a065
5 changed files with 66 additions and 9 deletions

View File

@ -9,7 +9,7 @@ interface CategoryProps {
sounds: Array<{ label: string; src: string; icon: React.ReactNode }>; sounds: Array<{ label: string; src: string; icon: React.ReactNode }>;
} }
export function Category({ icon, sounds, title }: CategoryProps) { export function Category({ icon, id, sounds, title }: CategoryProps) {
return ( return (
<div className={styles.category}> <div className={styles.category}>
<div className={styles.iconContainer}> <div className={styles.iconContainer}>
@ -19,7 +19,7 @@ export function Category({ icon, sounds, title }: CategoryProps) {
<h2 className={styles.title}>{title}</h2> <h2 className={styles.title}>{title}</h2>
<Sounds sounds={sounds} /> <Sounds id={id} sounds={sounds} />
</div> </div>
); );
} }

View File

@ -10,6 +10,10 @@
background: linear-gradient(var(--color-neutral-100), transparent); background: linear-gradient(var(--color-neutral-100), transparent);
text-align: center; text-align: center;
&.hidden {
display: none;
}
&:not(.selected)::before { &:not(.selected)::before {
position: absolute; position: absolute;
top: -1px; top: -1px;

View File

@ -11,9 +11,10 @@ interface SoundProps {
label: string; label: string;
src: string; src: string;
icon: React.ReactNode; icon: React.ReactNode;
hidden: boolean;
} }
export function Sound({ icon, label, src }: SoundProps) { export function Sound({ hidden, icon, label, src }: SoundProps) {
const { isPlaying, play } = usePlay(); const { isPlaying, play } = usePlay();
const [isSelected, setIsSelected] = useLocalStorage( const [isSelected, setIsSelected] = useLocalStorage(
`${label}-is-selected`, `${label}-is-selected`,
@ -49,7 +50,11 @@ export function Sound({ icon, label, src }: SoundProps) {
return ( return (
<div <div
className={cn(styles.sound, isSelected && styles.selected)} className={cn(
styles.sound,
isSelected && styles.selected,
hidden && styles.hidden,
)}
onClick={toggle} onClick={toggle}
onKeyDown={toggle} onKeyDown={toggle}
> >

View File

@ -4,3 +4,36 @@
gap: 20px; gap: 20px;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
} }
.button {
position: relative;
display: flex;
width: max-content;
height: 35px;
align-items: center;
justify-content: center;
padding: 0 15px;
border: 1px solid var(--color-neutral-200);
border-radius: 50px;
margin: 25px auto 0;
background-color: var(--color-neutral-50);
color: var(--color-neutral-subtle);
cursor: pointer;
font-size: var(--font-xsm);
&::before {
position: absolute;
top: -1px;
left: 50%;
width: 70%;
height: 1px;
background: linear-gradient(
90deg,
transparent,
var(--color-neutral-300),
transparent
);
content: '';
transform: translateX(-50%);
}
}

View File

@ -1,17 +1,32 @@
import { Sound } from '@/components/sound'; import { Sound } from '@/components/sound';
import { useLocalStorage } from '@/hooks/use-local-storage';
import styles from './sounds.module.css'; import styles from './sounds.module.css';
interface SoundsProps { interface SoundsProps {
id: string;
sounds: Array<{ label: string; src: string; icon: React.ReactNode }>; sounds: Array<{ label: string; src: string; icon: React.ReactNode }>;
} }
export function Sounds({ sounds }: SoundsProps) { export function Sounds({ id, sounds }: SoundsProps) {
const [showAll, setShowAll] = useLocalStorage(`${id}-show-more`, false);
return ( return (
<div className={styles.sounds}> <div>
{sounds.map(sound => ( <div className={styles.sounds}>
<Sound key={sound.label} {...sound} /> {sounds.map((sound, index) => (
))} <Sound key={sound.label} {...sound} hidden={!showAll && index > 3} />
))}
</div>
{sounds.length > 4 && (
<button
className={styles.button}
onClick={() => setShowAll(prev => !prev)}
>
{showAll ? 'Show Less' : 'Show More'}
</button>
)}
</div> </div>
); );
} }