Timer Plugin
The Timer Plugin provides comprehensive countdown timer functionality for the on-CodeMerge editor, allowing users to create, edit, and manage countdown timers with real-time updates through an intuitive interface.
Features
- Timer Creation: Create multiple countdown timers with custom titles and descriptions
- Real-time Countdown: Live countdown display with automatic updates every second
- Timer Management: Add, edit, and delete timers with full CRUD operations
- Rich Timer Details: Comprehensive timer information including title, description, target date/time, category, and tags
- Visual Timer Widget: Beautiful countdown display with days, hours, minutes, and seconds
- Timer Colors: Custom color coding for different timer categories
- Context Menu: Right-click context menu for quick actions on timers
- Copy & Duplicate: Copy timers with automatic naming
- Export/Import: Export and import timer data in JSON format
- Data Persistence: Automatic saving to localStorage
- Keyboard Shortcuts: Quick access to timer functions
- Toolbar Integration: Easy access via toolbar button
- User Notifications: Built-in notification system for user feedback
- Responsive Design: Works seamlessly on all screen sizes
- Dark Mode Support: Automatic theme adaptation
- Expiration Handling: Automatic display when timer expires
Install and CSS: see Editor API — Getting Started.
Basic Usage
import { Editor, TimerPlugin } from 'on-codemerge';
const editor = new Editor(container, {
plugins: [TimerPlugin()],
});Demo
Public API (v2)
Factory: TimerPlugin().
| Command | |
|---|---|
insertTimer | editor.command('insertTimer') |
Keyboard shortcuts
| Shortcut | Command |
|---|---|
Mod-Alt-d | insertTimer |
Note: No
timer:*editor events — updates live on the atom.
User Interface
Toolbar Button
The plugin adds a timer button to the editor toolbar. Click it to open the timer creation menu.
Context Menu
Right-click on any timer to access the context menu with the following options:
Timer Actions
- Edit Timer: Modify timer details including title, description, target date/time, and category
- Copy Timer: Duplicate the timer with automatic naming
- Export Timer: Download timer data as JSON file
- Import Timer: Import timer data from JSON file
- Delete Timer: Remove the timer
Modal Forms
The plugin uses modal forms for creating and editing timers:
- Timer Form: Comprehensive form with all timer fields including validation
- Real-time Preview: Live preview of countdown display during creation/editing
Examples
Basic Timer Usage
<!-- Simple timer widget -->
<div class="timer-widget" data-timer-id="deadline-1">
<div class="timer-header">
<h3 class="timer-title">Project Deadline</h3>
<div class="timer-category">Work</div>
</div>
<div class="timer-body">
<div class="timer-countdown" id="timer-countdown-deadline-1">
<div class="timer-unit">
<span class="timer-value" id="timer-days-deadline-1">30</span>
<span class="timer-label">days</span>
</div>
<div class="timer-unit">
<span class="timer-value" id="timer-hours-deadline-1">12</span>
<span class="timer-label">hours</span>
</div>
<div class="timer-unit">
<span class="timer-value" id="timer-minutes-deadline-1">45</span>
<span class="timer-label">min</span>
</div>
<div class="timer-unit">
<span class="timer-value" id="timer-seconds-deadline-1">30</span>
<span class="timer-label">sec</span>
</div>
</div>
<div class="timer-target">Until: 31 Dec 2024, 23:59</div>
</div>
</div>Timer with Custom Styling
<div class="timer-widget" data-timer-id="urgent-deadline" style="--timer-color: #dc2626">
<div class="timer-header">
<h3 class="timer-title">Urgent Deadline</h3>
<div class="timer-category">Critical</div>
</div>
<div class="timer-body">
<div class="timer-countdown" id="timer-countdown-urgent-deadline">
<!-- Countdown units -->
</div>
<div class="timer-target">Until: 15 Dec 2024, 18:00</div>
</div>
</div>Working with Timer Manager
// Create a timer with specific target
const timer = timerManager.createTimer({
title: 'Meeting in 2 hours',
description: 'Team sync meeting',
targetDate: new Date('2024-01-15'),
targetTime: '14:00',
category: 'Meeting',
tags: ['team', 'sync'],
color: '#3b82f6',
});
// Copy a timer
const copiedTimer = timerManager.copyTimer(timer.id);
// Result: "Meeting in 2 hours (Copy)"
// Export timer for backup
const exportData = timerManager.exportTimer(timer.id);
// Save exportData to file or send to server
// Import timer from backup
const importedTimer = timerManager.importTimer(exportData);
// Check time remaining
const timeLeft = timerManager.getTimeLeft(timer);
if (timeLeft.isExpired) {
console.log('Timer has expired!');
} else {
console.log(`${timeLeft.days} days, ${timeLeft.hours} hours remaining`);
}Integration Examples
React Integration
import React, { useEffect, useRef } from 'react';
import { Editor, TimerPlugin } from 'on-codemerge';
function MyEditor() {
const editorRef = useRef(null);
const editorInstance = useRef(null);
useEffect(() => {
if (editorRef.current && !editorInstance.current) {
editorInstance.current = new Editor(editorRef.current);
editorInstance.current.use(TimerPlugin());
// Listen to timer events
editorInstance.current.on('timer:created', (timer) => {
console.log('New timer:', timer);
});
editorInstance.current.on('timer:expired', (timer) => {
console.log('Timer expired:', timer);
});
}
return () => {
if (editorInstance.current) {
editorInstance.current.destroy();
}
};
}, []);
return <div ref={editorRef} className="editor-container" />;
}Vue Integration
<template>
<div ref="editorContainer" class="editor-container"></div>
</template>
<script>
import { Editor, TimerPlugin } from 'on-codemerge';
export default {
name: 'MyEditor',
mounted() {
this.editor = new Editor(this.$refs.editorContainer);
this./* use plugins: [TimerPlugin()] in Editor(...) */;
// Listen to timer events
this.editor.on('timer:expired', (timer) => {
this.$notify({
title: 'Timer Expired',
message: `Timer "${timer.title}" has expired!`,
type: 'warning'
});
});
},
beforeDestroy() {
if (this.editor) {
this.editor.destroy();
}
}
};
</script>Timer Widget Structure
HTML Structure
<div class="timer-widget" data-timer-id="timer-123">
<div class="timer-header">
<h3 class="timer-title">Project Deadline</h3>
<div class="timer-category">Work</div>
</div>
<div class="timer-body">
<div class="timer-countdown" id="timer-countdown-timer-123">
<div class="timer-unit">
<span class="timer-value" id="timer-days-timer-123">30</span>
<span class="timer-label">days</span>
</div>
<div class="timer-unit">
<span class="timer-value" id="timer-hours-timer-123">12</span>
<span class="timer-label">hours</span>
</div>
<div class="timer-unit">
<span class="timer-value" id="timer-minutes-timer-123">45</span>
<span class="timer-label">min</span>
</div>
<div class="timer-unit">
<span class="timer-value" id="timer-seconds-timer-123">30</span>
<span class="timer-label">sec</span>
</div>
</div>
<div class="timer-target">Until: 31 Dec 2024, 23:59</div>
<div class="timer-tags">
<span class="timer-tag">deadline</span>
<span class="timer-tag">important</span>
</div>
</div>
</div>CSS Classes
.timer-widget: Main timer container.timer-header: Header with title and category.timer-title: Timer title.timer-category: Timer category display.timer-body: Timer content area.timer-countdown: Countdown display container.timer-unit: Individual time unit (days, hours, minutes, seconds).timer-value: Time value display.timer-label: Time unit label.timer-target: Target date/time display.timer-tags: Tags container.timer-tag: Individual tag.timer-expired: Expired timer display
Styling
Custom Timer Colors
.timer-widget {
--timer-primary-color: #3b82f6;
--timer-secondary-color: #f3f4f6;
--timer-border-color: #e5e7eb;
--timer-color: #3b82f6; /* Default timer color */
}
.timer-widget[style*='--timer-color: #dc2626'] {
--timer-color: #dc2626; /* Red for urgent timers */
}Custom Timer Styles
.timer-widget {
border-left: 4px solid var(--timer-color);
background: linear-gradient(90deg, var(--timer-color, #3b82f6) 0%, transparent 100%);
opacity: 0.1;
}
.timer-countdown {
display: flex;
gap: 1rem;
justify-content: center;
align-items: center;
}
.timer-unit {
text-align: center;
min-width: 60px;
}
.timer-value {
font-size: 1.5rem;
font-weight: bold;
color: var(--timer-color);
}
.timer-label {
font-size: 0.75rem;
color: #6b7280;
text-transform: uppercase;
}Dark Mode Support
The plugin automatically adapts to dark mode when the html.dark class is present:
html.dark .timer-widget {
background: #1f2937;
color: #f9fafb;
border-color: #374151;
}
html.dark .timer-value {
color: var(--timer-color);
}
html.dark .timer-label {
color: #9ca3af;
}Real-time Updates
The timer plugin automatically updates countdown displays every second using embedded JavaScript:
// Automatic timer update script (embedded in each timer)
(function () {
const timerId = 'timer-123';
const targetDate = new Date('2024-12-31T23:59:00');
const expiredText = 'Time expired';
function updateTimer() {
const now = new Date();
const diff = targetDate.getTime() - now.getTime();
if (diff <= 0) {
// Timer expired
const countdownEl = document.getElementById('timer-countdown-' + timerId);
if (countdownEl) {
countdownEl.innerHTML = '<div class="timer-expired">' + expiredText + '</div>';
}
return;
}
// Update countdown values
const days = Math.floor(diff / (1000 * 60 * 60 * 24));
const hours = Math.floor((diff % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
const minutes = Math.floor((diff % (1000 * 60 * 60)) / (1000 * 60));
const seconds = Math.floor((diff % (1000 * 60)) / 1000);
// Update DOM elements
document.getElementById('timer-days-' + timerId).textContent = days;
document.getElementById('timer-hours-' + timerId).textContent = hours
.toString()
.padStart(2, '0');
document.getElementById('timer-minutes-' + timerId).textContent = minutes
.toString()
.padStart(2, '0');
document.getElementById('timer-seconds-' + timerId).textContent = seconds
.toString()
.padStart(2, '0');
}
// Update every second
updateTimer();
setInterval(updateTimer, 1000);
})();Data Persistence
Timers are automatically saved to localStorage and persist between browser sessions:
// Storage key: 'html-editor-timers'
// Data format: JSON array of timer objects
const timers = [
{
id: 'timer-123',
title: 'Project Deadline',
description: 'Final submission deadline',
targetDate: '2024-12-31T23:59:00.000Z',
targetTime: '23:59',
color: '#3b82f6',
category: 'Work',
tags: ['deadline', 'important'],
isActive: true,
createdAt: 1703123456789,
updatedAt: 1703123456789,
},
];Error Handling
The plugin includes comprehensive error handling for common scenarios:
// Validation errors
try {
const timer = timerManager.createTimer({
title: '', // Empty title will throw error
targetDate: new Date('2024-12-31'),
targetTime: '23:59',
});
} catch (error) {
console.error('Timer creation failed:', error.message);
// Shows: "Title is required"
}
// Timer not found
try {
timerManager.updateTimer('non-existent-id', { title: 'New Title' });
} catch (error) {
console.error('Timer update failed:', error.message);
// Shows: "Timer not found"
}