ng-timezone-tooltip
v1.1.0
Published
Lightweight Angular 20+ standalone directive that attaches a hover tooltip to any element, displaying a UTC timestamp converted to UTC, local time, and any number of IANA timezones. Built with Angular CDK Overlay and Luxon.
Maintainers
Readme
ng-timezone-tooltip
A lightweight, standalone Angular directive that attaches an interactive hover tooltip to any element — displaying a UTC timestamp converted to local time, UTC, and any number of labeled IANA timezones.
Features
- ✅ Zero-config — one directive, no module setup
- ✅ Always shows Local time first, then UTC — both always present
- ✅ Custom zone labels — pass
{ zone, label }to show "Merchant Time" instead of "Europe/Stockholm" - ✅ IANA zone id shown as a small subtitle under custom labels
- ✅ Light / dark / auto theming —
autofollowsprefers-color-scheme - ✅ Full CSS custom property override support (
--tz-bg,--tz-accent-utc, etc.) - ✅ Hide UTC or Local rows individually with
[tzShowUtc]/[tzShowLocal] - ✅ 4 positions with automatic viewport-aware flip
- ✅ SSR-safe — all DOM access guarded with
isPlatformBrowser() - ✅ Signal-based inputs,
OnPushchange detection, fully standalone - ✅ Luxon bundled — DST-safe IANA conversions, zero extra install
Requirements
| Dependency | Type | Version |
|----------------|------------|----------------|
| Angular | peer | ^20.0.0 |
| @angular/cdk | peer | ^20.0.0 |
| luxon | bundled | auto-installed |
Installation
npm install ng-timezone-tooltip @angular/cdkIf your project already uses @angular/cdk (e.g. via Angular Material):
npm install ng-timezone-tooltipSetup
Add provideAnimations() to your app.config.ts (required by CDK Overlay):
// app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideAnimations } from '@angular/platform-browser/animations';
export const appConfig: ApplicationConfig = {
providers: [provideAnimations()],
};Basic Usage
import { TimezoneTooltipDirective } from 'ng-timezone-tooltip';
@Component({
standalone: true,
imports: [TimezoneTooltipDirective],
template: `
<span
[tzTooltip]="'2026-01-16T12:00:00Z'"
[tzTooltipZones]="['Asia/Kolkata', 'America/New_York']"
tzPosition="bottom">
Hover me
</span>
`,
})
export class MyComponent {}Hovering shows:
Local 13:00 CET+01:00
UTC 12:00 UTC+00:00
Asia/Kolkata 17:30 IST+05:30
America/New_York 07:00 EST-05:00Directive API
| Input | Type | Default | Description |
|---|---|---|---|
| [tzTooltip] | string \| Date | required | UTC timestamp (ISO 8601 or Date) |
| [tzTooltipZones] | TooltipZoneInput[] | [] | Extra zone rows — plain strings or { zone, label } objects |
| tzPosition | 'top' \| 'bottom' \| 'left' \| 'right' | 'bottom' | Preferred tooltip position, auto-flips at viewport edge |
| tzTheme | 'dark' \| 'light' \| 'auto' | 'auto' | Card color theme |
| [tzShowUtc] | boolean | true | Show / hide the UTC row |
| [tzShowLocal] | boolean | true | Show / hide the Local row |
[tzTooltipZones]
Accepts plain IANA strings, labeled objects, or a mix of both:
<!-- Plain strings -->
[tzTooltipZones]="['Asia/Kolkata', 'America/New_York']"
<!-- Labeled objects — shows custom title + IANA id as small subtitle -->
[tzTooltipZones]="[
{ zone: 'Europe/Stockholm', label: 'Merchant Time' },
{ zone: 'America/New_York', label: 'Customer Time' }
]"Labeled tooltip output:
Local 14:00 CET+01:00
UTC 13:00 UTC+00:00
Merchant Time 14:00 CET+01:00
Europe/Stockholm
Customer Time 08:00 EST-05:00
America/New_YorkTypeScript type: type TooltipZoneInput = string | { zone: string; label: string }
tzTheme
| Value | Behaviour |
|---|---|
| 'auto' (default) | Follows prefers-color-scheme |
| 'dark' | Always dark |
| 'light' | Always light |
tzTheme="light"CSS Custom Properties
Fine-tune the card appearance by overriding any token on :root or a parent element:
:root {
--tz-bg: #1e293b; /* card background */
--tz-border: #334155; /* row separator */
--tz-text: #f1f5f9; /* value text */
--tz-label: #94a3b8; /* label text */
--tz-zone-id: #64748b; /* zone id subtitle (labeled zones) */
--tz-accent-utc: #60a5fa; /* UTC row label colour */
--tz-accent-local: #34d399; /* Local row label colour */
--tz-shadow: /* box-shadow */;
--tz-radius: 8px;
--tz-min-width: 240px;
}Examples
Dashboard — merchant & customer timezones
readonly zones: TooltipZoneInput[] = [
{ zone: 'Europe/Stockholm', label: 'Merchant Time' },
{ zone: 'America/New_York', label: 'Customer Time' },
];<span [tzTooltip]="order.createdAt" [tzTooltipZones]="zones">
{{ order.createdAt }}
</span>Hide UTC row
<span [tzTooltip]="ts" [tzTooltipZones]="zones" [tzShowUtc]="false">
Hover me
</span>Light theme, tooltip on top
<span [tzTooltip]="ts" tzTheme="light" tzPosition="top">Hover me</span>Custom accent colour via CSS
:root { --tz-accent-utc: #f59e0b; }Changelog
1.1.0
- Labeled zones —
[tzTooltipZones]now accepts{ zone, label }objects for custom row headings with IANA id subtitle - Theming — new
tzThemeinput:'dark' | 'light' | 'auto'(autofollowsprefers-color-scheme) - Row visibility — new
[tzShowUtc]and[tzShowLocal]boolean inputs to hide built-in rows - Row order — Local time is now shown first, UTC second
- CSS custom properties — 9 tokens for fine-grained card styling
1.0.0
- Initial release
License
MIT © askinjohn
