Merge branch 'develop'

This commit is contained in:
MAZE 2024-04-25 20:00:22 +03:30
commit a46a4cdc96
2 changed files with 34 additions and 16 deletions

View File

@ -1,4 +1,4 @@
import { useCallback, useEffect } from 'react'; import { useCallback, useEffect, forwardRef } from 'react';
import { ImSpinner9 } from 'react-icons/im/index'; import { ImSpinner9 } from 'react-icons/im/index';
import { Range } from './range'; import { Range } from './range';
@ -10,27 +10,21 @@ import { cn } from '@/helpers/styles';
import styles from './sound.module.css'; import styles from './sound.module.css';
import type { Sound } from '@/data/types'; import type { Sound as SoundType } from '@/data/types';
import { useKeyboardButton } from '@/hooks/use-keyboard-button'; import { useKeyboardButton } from '@/hooks/use-keyboard-button';
interface SoundProps extends Sound { interface SoundProps extends SoundType {
functional: boolean; functional: boolean;
hidden: boolean; hidden: boolean;
selectHidden: (key: string) => void; selectHidden: (key: string) => void;
unselectHidden: (key: string) => void; unselectHidden: (key: string) => void;
} }
export function Sound({ export const Sound = forwardRef<HTMLDivElement, SoundProps>(function Sound(
functional, { functional, hidden, icon, id, label, selectHidden, src, unselectHidden },
hidden, ref,
icon, ) {
id,
label,
selectHidden,
src,
unselectHidden,
}: SoundProps) {
const isPlaying = useSoundStore(state => state.isPlaying); const isPlaying = useSoundStore(state => state.isPlaying);
const play = useSoundStore(state => state.play); const play = useSoundStore(state => state.play);
const select = useSoundStore(state => state.select); const select = useSoundStore(state => state.select);
@ -82,6 +76,7 @@ export function Sound({
return ( return (
<div <div
aria-label={`${label} sound`} aria-label={`${label} sound`}
ref={ref}
role="button" role="button"
tabIndex={0} tabIndex={0}
className={cn( className={cn(
@ -108,4 +103,4 @@ export function Sound({
<Range id={id} label={label} /> <Range id={id} label={label} />
</div> </div>
); );
} });

View File

@ -1,4 +1,4 @@
import { useState, useMemo, useCallback } from 'react'; import { useState, useMemo, useCallback, useRef, useEffect } from 'react';
import { AnimatePresence, motion } from 'framer-motion'; import { AnimatePresence, motion } from 'framer-motion';
import { Sound } from '@/components/sound'; import { Sound } from '@/components/sound';
@ -19,6 +19,17 @@ interface SoundsProps {
export function Sounds({ functional, id, sounds }: SoundsProps) { export function Sounds({ functional, id, sounds }: SoundsProps) {
const [showAll, setShowAll] = useLocalStorage(`${id}-show-more`, false); const [showAll, setShowAll] = useLocalStorage(`${id}-show-more`, false);
const firstNewSound = useRef<HTMLDivElement>(null);
const showMoreButton = useRef<HTMLButtonElement>(null);
const [exitComplete, setExitComplete] = useState(false);
useEffect(() => {
if (showAll) {
firstNewSound.current?.focus();
}
}, [showAll]);
const [hiddenSelections, setHiddenSelections] = useState<{ const [hiddenSelections, setHiddenSelections] = useState<{
[key: string]: boolean; [key: string]: boolean;
}>({}); }>({});
@ -54,6 +65,7 @@ export function Sounds({ functional, id, sounds }: SoundsProps) {
{...sound} {...sound}
functional={functional} functional={functional}
hidden={!showAll && index > 5} hidden={!showAll && index > 5}
ref={index === 6 ? firstNewSound : undefined}
selectHidden={selectHidden} selectHidden={selectHidden}
unselectHidden={unselectHidden} unselectHidden={unselectHidden}
/> />
@ -66,12 +78,17 @@ export function Sounds({ functional, id, sounds }: SoundsProps) {
</div> </div>
{sounds.length > 6 && ( {sounds.length > 6 && (
<AnimatePresence initial={false} mode="wait"> <AnimatePresence
initial={false}
mode="wait"
onExitComplete={() => setExitComplete(true)}
>
<motion.button <motion.button
animate="show" animate="show"
exit="hidden" exit="hidden"
initial="hidden" initial="hidden"
key={showAll ? `${id}-show-less` : `${id}-show-more`} key={showAll ? `${id}-show-less` : `${id}-show-more`}
ref={showMoreButton}
transition={{ duration: 0.2 }} transition={{ duration: 0.2 }}
variants={variants} variants={variants}
className={cn( className={cn(
@ -79,6 +96,12 @@ export function Sounds({ functional, id, sounds }: SoundsProps) {
hasHiddenSelection && !showAll && styles.active, hasHiddenSelection && !showAll && styles.active,
)} )}
onClick={() => setShowAll(prev => !prev)} onClick={() => setShowAll(prev => !prev)}
onAnimationComplete={() => {
if (!showAll && exitComplete) {
setExitComplete(false);
showMoreButton.current?.focus();
}
}}
> >
{showAll ? 'Show Less' : 'Show More'} {showAll ? 'Show Less' : 'Show More'}
</motion.button> </motion.button>