refactor(player): simplify popover input focus logic

Removed `isPopoverOpen` state and associated `useEffect` hook.
Auto-focus and select logic for the input are now directly handled
within `handlePopoverOpen`, reducing state management complexity.
This commit is contained in:
Richard Roberson 2025-11-22 02:06:28 -07:00
parent 7046666b3f
commit e39a5b8bcf

View file

@ -9,25 +9,12 @@ export const Navigator = ({ currentPage, numPages, skipToLocation }: {
skipToLocation: (location: string | number, shouldPause?: boolean) => void; skipToLocation: (location: string | number, shouldPause?: boolean) => void;
}) => { }) => {
const [inputValue, setInputValue] = useState(''); const [inputValue, setInputValue] = useState('');
const [isPopoverOpen, setIsPopoverOpen] = useState(false);
const inputRef = useRef<HTMLInputElement>(null); const inputRef = useRef<HTMLInputElement>(null);
useEffect(() => { useEffect(() => {
setInputValue(currentPage.toString()); setInputValue(currentPage.toString());
}, [currentPage]); }, [currentPage]);
// Auto-focus and select input when popover opens
useEffect(() => {
if (isPopoverOpen && inputRef.current) {
// Small delay to ensure the popover is fully rendered
const timer = setTimeout(() => {
inputRef.current?.focus();
inputRef.current?.select();
}, 50);
return () => clearTimeout(timer);
}
}, [isPopoverOpen]);
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => { const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
// Only allow numbers // Only allow numbers
const value = e.target.value.replace(/[^0-9]/g, ''); const value = e.target.value.replace(/[^0-9]/g, '');
@ -56,6 +43,11 @@ export const Navigator = ({ currentPage, numPages, skipToLocation }: {
const handlePopoverOpen = () => { const handlePopoverOpen = () => {
setInputValue(''); // Clear input when popup opens setInputValue(''); // Clear input when popup opens
// Auto-focus and select input shortly after opening
setTimeout(() => {
inputRef.current?.focus();
inputRef.current?.select();
}, 50);
}; };
return ( return (
@ -73,44 +65,34 @@ export const Navigator = ({ currentPage, numPages, skipToLocation }: {
</Button> </Button>
{/* Page number popup */} {/* Page number popup */}
<Popover className="relative"> <Popover className="relative mb-1">
{({ open }) => { <PopoverButton
if (open !== isPopoverOpen) { className="bg-offbase px-2 py-0.5 rounded-full focus:outline-none cursor-pointer hover:bg-offbase transform transition-transform duration-200 ease-in-out hover:scale-[1.04] hover:text-accent"
setIsPopoverOpen(open); onClick={handlePopoverOpen}
} >
<p className="text-xs whitespace-nowrap">
return ( {currentPage} / {numPages || 1}
<> </p>
<PopoverButton </PopoverButton>
className="bg-offbase px-2 py-0.5 rounded-full focus:outline-none cursor-pointer hover:bg-offbase transform transition-transform duration-200 ease-in-out hover:scale-[1.04] hover:text-accent" <PopoverPanel anchor="top" className="absolute z-50 bg-base p-3 rounded-md shadow-lg border border-offbase">
onClick={handlePopoverOpen} <div className="flex flex-col space-y-2">
> <div className="text-xs font-medium text-foreground">Go to page</div>
<p className="text-xs whitespace-nowrap"> <input
{currentPage} / {numPages || 1} ref={inputRef}
</p> type="text"
</PopoverButton> inputMode="numeric"
<PopoverPanel anchor="top" className="absolute z-50 bg-base p-3 rounded-md shadow-lg border border-offbase"> pattern="[0-9]*"
<div className="flex flex-col space-y-2"> className="w-20 px-2 py-1 text-xs text-accent bg-offbase rounded border-none outline-none appearance-none text-center"
<div className="text-xs font-medium text-foreground">Go to page</div> value={inputValue}
<input onChange={handleInputChange}
ref={inputRef} onBlur={handleInputConfirm}
type="text" onKeyDown={handleInputKeyDown}
inputMode="numeric" placeholder={currentPage.toString()}
pattern="[0-9]*" aria-label="Page number"
className="w-20 px-2 py-1 text-xs text-accent bg-offbase rounded border-none outline-none appearance-none text-center" />
value={inputValue} <div className="text-xs text-muted text-center">of {numPages || 1}</div>
onChange={handleInputChange} </div>
onBlur={handleInputConfirm} </PopoverPanel>
onKeyDown={handleInputKeyDown}
placeholder={currentPage.toString()}
aria-label="Page number"
/>
<div className="text-xs text-muted text-center">of {numPages || 1}</div>
</div>
</PopoverPanel>
</>
);
}}
</Popover> </Popover>
{/* Page forward */} {/* Page forward */}
@ -126,4 +108,4 @@ export const Navigator = ({ currentPage, numPages, skipToLocation }: {
</Button> </Button>
</div> </div>
); );
} }