An Angular Material timezone selector component with UTC offset navigation. Browse timezones by offset using arrow buttons, then select a specific timezone from the filtered dropdown.
- UTC Offset Navigation - Browse timezones by offset with
< +00:00 >arrows (infinite loop) - Browser Timezone Detection - Optional button to auto-detect and set browser timezone
- IANA Timezone Names - Uses native
Intl.supportedValuesOf('timeZone')for timezone data - MatFormField Compatible - Implements
MatFormFieldControlfor seamless integration - Signal-first -
valueis amodel()signal:[(value)]two-way binding, and Signal Forms'[formField]drives it natively (FormValueControlcontract) - Material 3 Ready - Uses M3 design tokens for theming
- Standalone Component - Easy to import in any Angular 21+ application
- No Dependencies - Uses native JavaScript
IntlAPI for timezone data
npm install @softwarity/timezone-select| Package | Version |
|---|---|
| @angular/common | >= 21.0.0 |
| @angular/core | >= 21.0.0 |
| @angular/cdk | >= 21.0.0 |
| @angular/forms | >= 21.0.0 |
| @angular/material | >= 21.0.0 |
Import the component in your Angular component:
import { signal } from '@angular/core';
import { TimezoneSelectComponent } from '@softwarity/timezone-select';
import { MatFormFieldModule } from '@angular/material/form-field';
@Component({
selector: 'app-my-component',
imports: [TimezoneSelectComponent, MatFormFieldModule],
template: `
<mat-form-field appearance="outline">
<mat-label>Timezone</mat-label>
<timezone-select [(value)]="timezone" />
<mat-hint>Select your preferred timezone</mat-hint>
</mat-form-field>
`
})
export class MyComponent {
timezone = signal<string | null>('Europe/Paris');
}Migrating from 1.x: the
ControlValueAccessorwas removed (Angular forbids implementing it alongside the Signal FormsFormValueControlcontract), so[formControl]/ngModelno longer bind. Use[(value)](or[value]+(valueChange)), or Signal Forms'[formField].
timezone-select
| Input | Type | Default | Description |
|---|---|---|---|
value |
model<string | null> |
null |
The selected timezone — two-way bindable with [(value)], driven by [formField] in Signal Forms |
placeholder |
string |
'' |
Placeholder text |
required |
boolean |
false |
Whether the field is required |
disabled |
boolean |
false |
Whether the field is disabled |
showDetectButton |
boolean |
false |
Shows a button to detect and set browser timezone |
| Output | Type | Description |
|---|---|---|
valueChange |
string | null |
Emits when the selected timezone changes (implicit output of the value model) |
touch |
void |
Emits when focus leaves the control — enables Signal Forms' debounce('blur') |
The component value is an IANA timezone name string (e.g., 'Europe/Paris', 'America/New_York', 'UTC').
The component provides a SCSS mixin for theming. Import and use it in your styles.scss:
@use '@angular/material' as mat;
@use '@softwarity/timezone-select/timezone-select-theme' as timezone-select;
html {
@include mat.theme((color: (primary: mat.$violet-palette)));
// Apply timezone-select theme
@include timezone-select.theme();
}import { signal } from '@angular/core';
import { TimezoneSelectComponent } from '@softwarity/timezone-select';
@Component({
imports: [TimezoneSelectComponent, MatFormFieldModule],
template: `
<mat-form-field>
<mat-label>Timezone</mat-label>
<timezone-select [(value)]="timezone" />
</mat-form-field>
`
})
export class MyComponent {
timezone = signal<string | null>('UTC');
}@Component({
template: `
<mat-form-field>
<mat-label>Timezone</mat-label>
<timezone-select
[value]="timezone()"
(valueChange)="onTimezoneChange($event)" />
</mat-form-field>
`
})
export class MyComponent {
timezone = signal<string | null>('America/New_York');
onTimezoneChange(timezone: string | null): void {
this.timezone.set(timezone);
console.log('Selected timezone:', timezone);
}
}import { signal } from '@angular/core';
import { form, FormField } from '@angular/forms/signals';
@Component({
imports: [TimezoneSelectComponent, MatFormFieldModule, FormField],
template: `
<mat-form-field>
<mat-label>Timezone</mat-label>
<timezone-select [formField]="settingsForm.timezone" />
</mat-form-field>
`
})
export class MyComponent {
settingsModel = signal({ timezone: 'Europe/London' });
settingsForm = form(this.settingsModel);
}@Component({
template: `
<mat-form-field>
<mat-label>Timezone</mat-label>
<timezone-select [value]="'Europe/London'" [disabled]="true" />
</mat-form-field>
`
})
export class MyComponent {}The component uses the native JavaScript Intl API to:
- Get the list of supported timezones:
Intl.supportedValuesOf('timeZone') - Calculate UTC offsets:
Intl.DateTimeFormatwithtimeZoneName: 'shortOffset'
This ensures the timezone data is always up-to-date with the browser's IANA timezone database.
Apache-2.0