feat: scroll the new timer into view

This commit is contained in:
MAZE 2024-06-16 22:22:32 +03:30
parent 28abc16b9c
commit f4c66e3092
4 changed files with 36 additions and 5 deletions

View File

@ -3,6 +3,7 @@ import { useState, useMemo } from 'react';
import { Field } from './field';
import { useCountdownTimers } from '@/stores/countdown-timers';
import { waitUntil } from '@/helpers/wait';
import styles from './form.module.css';
@ -19,17 +20,23 @@ export function Form() {
const add = useCountdownTimers(state => state.add);
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
const handleSubmit = async (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
if (totalSeconds === 0) return;
add({
const id = add({
name,
total: totalSeconds,
});
setName('');
await waitUntil(() => !!document.getElementById(`timer-${id}`), 50);
document
.getElementById(`timer-${id}`)
?.scrollIntoView({ behavior: 'smooth' });
};
return (

View File

@ -139,7 +139,7 @@ export function Timer({ id }: TimerProps) {
}, [isRunning, tick, id, spent, total, left]);
return (
<div className={styles.timer}>
<div className={styles.timer} id={`timer-${id}`}>
<header className={styles.header}>
<div className={styles.bar}>
<div

20
src/helpers/wait.ts Normal file
View File

@ -0,0 +1,20 @@
export function waitUntil(
func: () => boolean,
interval: number,
): Promise<void> {
return new Promise((resolve, reject) => {
const intervalId = setInterval(() => {
try {
const result = func();
if (result) {
clearInterval(intervalId);
resolve();
}
} catch (error) {
clearInterval(intervalId);
reject(error);
}
}, interval);
});
}

View File

@ -16,7 +16,7 @@ interface State {
}
interface Actions {
add: (timer: { name: string; total: number }) => void;
add: (timer: { name: string; total: number }) => string;
delete: (id: string) => void;
getTimer: (id: string) => Timer;
rename: (id: string, newName: string) => void;
@ -28,10 +28,12 @@ export const useCountdownTimers = create<State & Actions>()(
persist(
(set, get) => ({
add({ name, total }) {
const id = uuid();
set(state => ({
timers: [
{
id: uuid(),
id,
name,
spent: 0,
total,
@ -39,6 +41,8 @@ export const useCountdownTimers = create<State & Actions>()(
...state.timers,
],
}));
return id;
},
delete(id) {