Timer

Timer is a flexible countdown component that works in both visual mode (with DOM display) and headless mode (pure logic). Perfect for Pomodoro timers, cooking timers, workout intervals, and any countdown scenario.

Key Features

  • Visual mode with customisable display and controls
  • Headless mode for background timers without UI
  • Multiple time formats (HH:MM:SS, MM:SS, SS)
  • Start, pause, reset, and stop controls
  • Dynamic time manipulation (add/subtract time)
  • Desktop notification integration on completion
  • Optional sound playback when timer finishes
  • Event callbacks for all lifecycle events
  • High-precision timing with configurable update intervals

When to Use Timers

  • Productivity: Pomodoro technique, work/break intervals, time blocking
  • Cooking & Recipes: Step timing, cooking duration, multi-stage recipes
  • Fitness: Workout intervals, rest periods, HIIT training
  • Education: Quiz time limits, study sessions, presentation timing
  • Gaming: Turn timers, challenge countdowns, cooldown periods
  • Meetings: Speaking time, agenda items, total meeting duration

Basic Usage

// Visual timer with controls
const timer = Domma.elements.timer('#timer', {
    duration: 60000,  // 1 minute in milliseconds
    format: 'mm:ss',
    showControls: true,
    onComplete: () => {
        console.log('Timer finished!');
    }
});

// Headless timer (no UI)
const backgroundTimer = Domma.elements.timer(null, {
    duration: 300000,  // 5 minutes
    onTick: (remaining) => {
        console.log(`${remaining}ms remaining`);
    }
});

backgroundTimer.start();

Quick Start

Create your first timer in seconds with automatic UI and controls.

Simplest Visual Timer

// HTML: Just an empty div
<div id="my-timer"></div>

// JavaScript: Timer with controls
const timer = Domma.elements.timer('#my-timer', {
    duration: 30000,  // 30 seconds
    showControls: true,
    autoStart: true   // Starts immediately
});

Simplest Headless Timer

// No HTML needed - pure JavaScript
const timer = Domma.elements.timer(null, {
    duration: 10000,  // 10 seconds
    onComplete: () => Domma.elements.alert('Done!')
});

timer.start();  // Go!

Step-by-Step Tutorial

Build a Pomodoro timer with work/break intervals and notifications.

Step 1: Create Work Timer

const workTimer = Domma.elements.timer('#work-timer', {
    duration: 1500000,  // 25 minutes (Pomodoro work period)
    format: 'mm:ss',
    showControls: true,
    notification: true,  // Desktop notification on complete
    notificationOptions: {
        title: 'Work Session Complete!',
        body: 'Time for a 5-minute break',
        requireInteraction: true
    },
    onComplete: () => {
        console.log('Work session finished');
        // Start break timer automatically
        breakTimer.start();
    }
});

Step 2: Create Break Timer

const breakTimer = Domma.elements.timer('#break-timer', {
    duration: 300000,  // 5 minutes
    format: 'mm:ss',
    showControls: true,
    notification: true,
    notificationOptions: {
        title: 'Break Complete!',
        body: 'Ready to start another work session?'
    },
    onComplete: () => {
        console.log('Break finished');
        // Optionally auto-start work timer again
    }
});

Step 3: Add Controls

// Manual control buttons
document.getElementById('start-work').addEventListener('click', () => {
    workTimer.start();
});

// Add time during work session
document.getElementById('add-5min').addEventListener('click', () => {
    workTimer.add(300000);  // Add 5 minutes
});

// Pause for interruption
document.getElementById('pause').addEventListener('click', () => {
    workTimer.pause();
});
Work Timer (25 min)
Break Timer (5 min)

Real-World Examples

1. Cooking Timer

const cookingTimer = Domma.elements.timer('#cooking-timer', {
    duration: 600000,  // 10 minutes
    format: 'mm:ss',
    showControls: true,
    sound: true,
    soundUrl: '/sounds/kitchen-bell.mp3',
    notification: true,
    notificationOptions: {
        title: 'Cooking Timer',
        body: 'Your food is ready!',
        requireInteraction: true
    }
});

2. HIIT Workout Timer

let currentRound = 1;
const totalRounds = 8;

const workoutTimer = Domma.elements.timer('#workout', {
    duration: 30000,  // 30 seconds work
    format: 'ss',
    onComplete: () => {
        if (currentRound < totalRounds) {
            // Start rest period
            restTimer.start();
        } else {
            Domma.elements.alert('Workout complete!', { title: 'HIIT Complete' });
        }
    }
});

const restTimer = Domma.elements.timer(null, {
    duration: 10000,  // 10 seconds rest
    onComplete: () => {
        currentRound++;
        workoutTimer.reset();
        workoutTimer.start();
    }
});

Round: 1/8

3. Presentation Timer

const presentationTimer = Domma.elements.timer('#presentation', {
    duration: 600000,  // 10 minutes
    format: 'mm:ss',
    showControls: true,
    onTick: (remaining) => {
        // Visual warnings at certain thresholds
        if (remaining === 120000) {  // 2 minutes
            Domma.elements.alert('2 minutes remaining!', { title: 'Time Warning' });
        } else if (remaining === 60000) {  // 1 minute
            Domma.elements.alert('1 minute remaining!', { title: 'Time Warning' });
        }
    }
});

4. Multiple Timers

// Manage multiple cooking tasks
const timers = {
    pasta: Domma.elements.timer('#pasta-timer', {
        duration: 480000,  // 8 minutes
        format: 'mm:ss',
        showControls: true
    }),
    sauce: Domma.elements.timer('#sauce-timer', {
        duration: 900000,  // 15 minutes
        format: 'mm:ss',
        showControls: true
    }),
    garlic: Domma.elements.timer('#garlic-timer', {
        duration: 120000,  // 2 minutes
        format: 'mm:ss',
        showControls: true
    })
};

// Start all at once
Object.values(timers).forEach(timer => timer.start());
Pasta (8 min)
Sauce (15 min)
Garlic (2 min)

Best Practices

✅ Do's

  • Use headless mode for background timers - No DOM overhead when UI not needed
  • Set appropriate update intervals - 100ms for smooth UI, 1000ms for efficiency
  • Add notifications for long timers - Users may switch tabs or minimize window
  • Provide controls for user timers - showControls: true for user-facing timers
  • Choose correct time format - HH:MM:SS for hours, MM:SS for minutes, SS for seconds
  • Clean up with destroy() - Stop timers and remove listeners when done
  • Use onTick for progress bars - Update UI elements based on remaining time

❌ Don'ts

  • Don't use very short update intervals - 10ms updates waste CPU, 100ms is sufficient
  • Don't forget to stop timers - Running timers continue even if element removed from DOM
  • Don't rely solely on client-side timing - For critical timings, validate server-side
  • Don't create excessive timer instances - Reuse timers with reset() and setDuration()
  • Don't use timers for real-time clocks - Use Date objects for wall-clock time

Performance Pattern

// Good: Reuse timer for repeated countdowns
const reusableTimer = Domma.elements.timer('#timer', {
    duration: 60000,
    showControls: true,
    onComplete: () => {
        console.log('Cycle complete');
        // Reset and restart for next cycle
        setTimeout(() => {
            reusableTimer.reset();
            reusableTimer.start();
        }, 1000);
    }
});

// Bad: Creating new timer each time (memory leak)
function startNewTimer() {
    const timer = Domma.elements.timer('#timer', {
        duration: 60000,
        onComplete: () => startNewTimer()  // Creates infinite timers!
    });
    timer.start();
}

Cleanup Pattern

// Store reference for cleanup
let currentTimer = null;

function setupTimer() {
    // Clean up old timer
    if (currentTimer) {
        currentTimer.destroy();
    }

    // Create new timer
    currentTimer = Domma.elements.timer('#timer', {
        duration: 60000,
        showControls: true
    });
}

// Clean up when page unloads
window.addEventListener('beforeunload', () => {
    if (currentTimer) {
        currentTimer.destroy();
    }
});

API Reference

Factory Method

// Visual mode (with DOM element)
elements.timer(selector, options)

// Headless mode (no DOM element)
elements.timer(null, options)

Options

Option Type Default Description
duration number 60000 Timer duration in milliseconds
autoStart boolean false Start timer automatically on creation
format string 'mm:ss' Display format: 'hh:mm:ss', 'mm:ss', 'ss'
showControls boolean false Show start/pause/reset buttons
updateInterval number 100 Update frequency in milliseconds
notification boolean false Show desktop notification on complete
notificationOptions object {} Options passed to notification
sound boolean false Play sound on completion
soundUrl string null URL to sound file
onTick function null Callback on each update (remaining)
onComplete function null Callback when timer reaches 0
onStart function null Callback when timer starts
onPause function null Callback when timer pauses
onReset function null Callback when timer resets

Instance Methods

// Control methods
timer.start()          // Start or resume timer
timer.pause()          // Pause timer
timer.reset()          // Reset to initial duration
timer.stop()           // Stop timer completely

// Time manipulation
timer.add(ms)          // Add milliseconds
timer.subtract(ms)     // Subtract milliseconds
timer.setDuration(ms)  // Change total duration

// State methods
timer.isRunning()      // Returns boolean
timer.getRemaining()   // Returns milliseconds remaining
timer.getElapsed()     // Returns milliseconds elapsed

// Cleanup
timer.destroy()        // Stop timer and clean up

Declarative Configuration

Set up timers declaratively using the config engine.

Basic Timer Setup

$.setup({
    '#my-timer': {
        component: 'timer',
        options: {
            duration: 300000,  // 5 minutes
            format: 'mm:ss',
            showControls: true,
            notification: true
        }
    }
});

Multiple Timers

$.setup({
    '#quick-timer': {
        component: 'timer',
        options: {
            duration: 60000,
            format: 'ss',
            showControls: true
        }
    },
    '#long-timer': {
        component: 'timer',
        options: {
            duration: 3600000,  // 1 hour
            format: 'hh:mm:ss',
            showControls: true
        }
    }
});

Related Components

Timer integrates seamlessly with other Domma components for complete timing solutions.