ngxsmk-datepicker 2.2.0 → 2.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,1344 +1,1313 @@
1
- <!--
2
- SEO Keywords: Angular DatePicker, Angular Date Range Picker, Lightweight Calendar Component, Angular Signals DatePicker, SSR Ready DatePicker, Zoneless Angular, A11y DatePicker, Mobile-Friendly DatePicker, Ionic DatePicker
3
- Meta Description: The most powerful, lightweight, and accessible date and range picker for modern Angular (17-21+). Built with Signals, Zoneless-ready, and zero dependencies.
4
- -->
5
-
6
- <div align="center">
7
- <img src="projects/ngxsmk-datepicker/docs/header-banner.png" alt="ngxsmk-datepicker - Lightweight Angular Date Range Picker" width="100%" />
8
-
9
- # **ngxsmk-datepicker** – Modern Angular Date Picker & Range Picker
10
-
11
- ### _The Gold Standard for Premium Angular Calendar Selection_
12
-
13
- [![npm version](https://img.shields.io/npm/v/ngxsmk-datepicker.svg?style=flat-square&color=6d28d9)](https://www.npmjs.com/package/ngxsmk-datepicker)
14
- [![Angular](https://img.shields.io/badge/Angular-17%2B-DD0031.svg?style=flat-square&logo=angular)](https://angular.io/)
15
- [![License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](https://github.com/NGXSMK/ngxsmk-datepicker/blob/main/LICENSE)
16
- [![Bundle Size](https://img.shields.io/badge/bundle-~127KB-success.svg?style=flat-square)](https://bundlephobia.com/package/ngxsmk-datepicker)
17
- [![Zoneless](https://img.shields.io/badge/Zoneless-Ready-blueviolet.svg?style=flat-square)](https://angular.dev/guide/zoneless)
18
-
19
- **`npm i ngxsmk-datepicker`**
20
-
21
- [Explore Live Demo](https://ngxsmk.github.io/ngxsmk-datepicker/) • [API Documentation](https://github.com/NGXSMK/ngxsmk-datepicker/blob/main/projects/ngxsmk-datepicker/docs/API.md) • [Submit Issue](https://github.com/NGXSMK/ngxsmk-datepicker/issues)
22
-
23
- </div>
24
-
25
- ---
26
-
27
- **Last updated:** February 25, 2026 · **Current stable:** v2.2.0
28
-
29
- ### **Overview**
30
-
31
- **ngxsmk-datepicker** is a high-performance, enterprise-ready date and range picker engineered for the modern Angular ecosystem (v17+). Built from the ground up with **Angular Signals**, it delivers a seamless, zoneless-ready experience for both desktop and mobile (Ionic) applications.
32
-
33
- > **Stable Release**: `v2.2.0` is live! This release brings a **TypeScript Strictness Overhaul** (eliminating `any` types and ensuring `exactOptionalPropertyTypes` compatibility), fixes **appendToBody** popover positioning, datepicker-in-modal first-open behavior, and popover width matching the input; it also reduces loading time and cleans up CSS. No breaking changes.
34
- >
35
- > ⚠️ **Important**: Versions 2.0.10 and 2.0.11 are broken and have been unpublished. Please use v2.2.0 or later.
36
-
37
- ---
38
-
39
- ### **📌 Table of Contents**
40
-
41
- 1. [📷 Screenshots](#-screenshots)
42
- 2. [✨ Features](#-features)
43
- 3. [📋 Compatibility](#-compatibility)
44
- 4. [🌍 Localization (i18n)](#-localization-i18n)
45
- 5. [📦 Installation](#-installation)
46
- 6. [🚀 Quick Start](#-quick-start)
47
- 7. [🔌 Framework Integration](#-framework-integration)
48
- 8. [⚙️ API Reference](#-api-reference)
49
- 9. [🎨 Theming](#-theming)
50
- 10. [⌨️ Keyboard Navigation](#-keyboard-navigation)
51
-
52
- ---
53
-
54
- ## 📷 Screenshots
55
-
56
- <p align="center">
57
- <img src="https://github.com/NGXSMK/ngxsmk-datepicker/raw/main/projects/ngxsmk-datepicker/docs/1.png" alt="Angular Standalone DatePicker Single Selection Mode" width="30%" />
58
- <img src="https://github.com/NGXSMK/ngxsmk-datepicker/raw/main/projects/ngxsmk-datepicker/docs/2.png" alt="Angular Date Range Picker Selection Mode" width="30%" />
59
- <img src="https://github.com/NGXSMK/ngxsmk-datepicker/raw/main/projects/ngxsmk-datepicker/docs/3.png" alt="Mobile Angular DatePicker Ionic Compatibility" width="30%" />
60
- </p>
61
-
62
- ## **✨ Features**
63
-
64
- ### **Core Capabilities**
65
-
66
- - 💎 **Signal-Driven Engine**: Hyper-reactive state management using Angular Signals.
67
- - 🌓 **Native Dark Mode**: Beautifully crafted themes for light and dark environments.
68
- - 📱 **Mobile-First UX**: Native mobile picker integration with touch gestures and haptic feedback.
69
- - 🧩 **Zero Dependencies**: Lightweight standalone component with no external bloat.
70
- - ⚡ **Performance++**: Lazy-loaded calendar months, memoized calculations, and tree-shakable architecture.
71
-
72
- ### **Advanced Functionality**
73
-
74
- - 📅 **Google Calendar Sync**: Built-in support for seamlessly syncing and displaying events natively from Google Calendar.
75
- - 🌐 **8-Language i18n**: Full localization for `en`, `de`, `es`, `sv`, `ko`, `zh`, `ja`, and `fr`.
76
- - 🛠️ **Plugin Architecture**: Extend functionality via hooks for rendering, validation, and shortcuts.
77
- - 🧪 **Signal Forms Native**: Direct integration with Angular 21's new Signal Forms API.
78
- - 🚀 **Zoneless Ready**: Optimized for the future of Angular—works perfectly without zone.js.
79
- - ♿ **Full Accessibility**: WAI-ARIA compliant with extensive keyboard navigation support.
80
-
81
- ## **📋 Compatibility**
82
-
83
- For detailed compatibility information, see [COMPATIBILITY.md](https://github.com/NGXSMK/ngxsmk-datepicker/blob/main/projects/ngxsmk-datepicker/docs/COMPATIBILITY.md).
84
-
85
- ### Quick Reference
86
-
87
- | Angular Version | Status | Core Features | Signal Forms | SSR | Zoneless |
88
- | --------------- | ------------------ | ------------- | ------------ | --- | -------- |
89
- | Angular 17 | ✅ Fully Supported | ✅ All | ❌ | ✅ | ✅ |
90
- | Angular 18 | ✅ Fully Supported | ✅ All | ❌ | ✅ | ✅ |
91
- | Angular 19 | ✅ Fully Supported | ✅ All | ❌ | ✅ | ✅ |
92
- | Angular 20 | ✅ Fully Supported | ✅ All | ❌ | ✅ | ✅ |
93
- | Angular 21 | ✅ Fully Supported | ✅ All | ✅ | ✅ | ✅ |
94
- | Angular 22+ | 🔄 Future Support | ✅ All | ✅ | ✅ | ✅ |
95
-
96
- **Zone.js**: Optional - The library works with or without Zone.js (zoneless apps supported)
97
-
98
- **SSR**: ✅ Fully compatible with Angular Universal and server-side rendering
99
-
100
- **Peer Dependencies**: `@angular/core >=17.0.0 <24.0.0`
101
-
102
- ## **🔒 API Stability & Deprecation Policy**
103
-
104
- ### API Stability Guarantees
105
-
106
- - **Public API**: All public APIs (inputs, outputs, methods) are stable within a major version
107
- - **Experimental Features**: Features marked as `experimental` may change in minor versions
108
- - **Internal APIs**: Private methods and internal services are not part of the public API and may change without notice
109
-
110
- ### Deprecation Policy
111
-
112
- - **Deprecation Period**: Features are deprecated for at least **2 major versions** before removal
113
- - **Deprecation Warnings**:
114
- - `@deprecated` JSDoc tags in code
115
- - Console warnings in development mode
116
- - Clear documentation in CHANGELOG.md
117
- - **Migration Guides**: Provided in `MIGRATION.md` for all breaking changes
118
- - **Breaking Changes**: Only occur in major version releases (semver)
119
-
120
- ### Stable APIs
121
-
122
- The following are considered stable public APIs:
123
-
124
- - Component inputs and outputs (`@Input()`, `@Output()`)
125
- - Public methods documented in API docs
126
- - Exported types and interfaces
127
- - Service APIs (when marked as public)
128
-
129
- ### Experimental Features
130
-
131
- Features marked as experimental may change:
132
-
133
- - Signal Forms support (`[field]` input) - Experimental in v1.9.x, stable in v2.0.0+
134
- - Some advanced selection modes
135
- - Plugin architecture hooks (subject to refinement)
136
-
137
- For details, see [CONTRIBUTING.md](https://github.com/NGXSMK/ngxsmk-datepicker/blob/main/CONTRIBUTING.md#deprecation-policy).
138
-
139
- ## **📦 Installation**
140
-
141
- ```bash
142
- npm install ngxsmk-datepicker@2.2.0
143
- ```
144
-
145
- ### Alternative installation
146
-
147
- You can install without npm using any of these methods (peer dependencies must still be installed in your app):
148
-
149
- | Method | Command |
150
- |--------|--------|
151
- | **Yarn** | `yarn add ngxsmk-datepicker@2.2.0` |
152
- | **pnpm** | `pnpm add ngxsmk-datepicker@2.2.0` |
153
- | **Bun** | `bun add ngxsmk-datepicker@2.2.0` |
154
- | **From Git** | `npm install github:NGXSMK/ngxsmk-datepicker#v2.2.0` (requires the repo to have built output or you build from source) |
155
- | **Local path** | Build the library in the repo (`npx ng build ngxsmk-datepicker`), then `npm install /path/to/ngxsmk-datepicker/dist/ngxsmk-datepicker` |
156
- | **CDN (ESM)** | Use [unpkg](https://unpkg.com/ngxsmk-datepicker@2.2.0/) or [jsDelivr](https://cdn.jsdelivr.net/npm/ngxsmk-datepicker@2.2.0/) in your bundler or import map; peer dependencies (Angular, etc.) must be installed in your app. |
157
-
158
- For all options and caveats, see [docs/INSTALLATION.md](docs/INSTALLATION.md).
159
-
160
- ## **Usage**
161
-
162
- ngxsmk-datepicker is a standalone component, so you can import it directly into your component or module.
163
-
164
- ### Signal Forms (Angular 21)
165
-
166
- You can bind directly to a writable Signal using standard two-way binding. This works seamlessly alongside traditional Reactive Forms.
167
-
168
- ```ts
169
- import { signal } from "@angular/core";
170
- import { DatepickerValue } from "ngxsmk-datepicker";
171
-
172
- export class MyComponent {
173
- dateSig = signal<DatepickerValue>(null);
174
- }
175
- ```
176
-
177
- ```html
178
- <ngxsmk-datepicker mode="single" [value]="dateSig()" (valueChange)="dateSig.set($event)"> </ngxsmk-datepicker>
179
-
180
- <p>Signal value: {{ dateSig() | json }}</p>
181
- ```
182
-
183
- This pattern is also compatible with computed/linked signals produced by `httpResource`, enabling powerful data flows with Angular 21.
184
-
185
- ### Signal Forms with `[field]` Input (Angular 21+)
186
-
187
- For direct integration with Angular Signal Forms, use the `[field]` input. The datepicker automatically tracks dirty state when using this binding:
188
-
189
- ```typescript
190
- import { Component, signal, form, objectSchema } from "@angular/core";
191
- import { NgxsmkDatepickerComponent } from "ngxsmk-datepicker";
192
-
193
- @Component({
194
- selector: "app-form",
195
- standalone: true,
196
- imports: [NgxsmkDatepickerComponent],
197
- template: `
198
- <form>
199
- <ngxsmk-datepicker [field]="myForm.dateInQuestion" mode="single" placeholder="Select a date"> </ngxsmk-datepicker>
200
- </form>
201
- `,
202
- })
203
- export class FormComponent {
204
- localObject = signal({ dateInQuestion: new Date() });
205
-
206
- myForm = form(
207
- this.localObject,
208
- objectSchema({
209
- dateInQuestion: objectSchema<Date>(),
210
- }),
211
- );
212
- }
213
- ```
214
-
215
- The `[field]` input provides automatic two-way binding with signal forms - no manual event handling needed! It also automatically tracks the form's dirty state, so `form().dirty()` will return `true` after a user selects a date.
216
-
217
- For detailed Signal Forms integration including dirty state tracking, see the [Signal Forms Integration Guide](https://github.com/NGXSMK/ngxsmk-datepicker/blob/main/projects/ngxsmk-datepicker/docs/signal-forms.md).
218
-
219
- ### Documentation
220
-
221
- - **[Plugin Architecture](https://github.com/NGXSMK/ngxsmk-datepicker/blob/main/projects/ngxsmk-datepicker/docs/PLUGIN-ARCHITECTURE.md)** - Complete guide to the plugin architecture and hook system
222
- - **[Signals Integration Guide](https://github.com/NGXSMK/ngxsmk-datepicker/blob/main/projects/ngxsmk-datepicker/docs/signals.md)** - Complete guide to using signals with the datepicker
223
- - **[Signal Forms Guide](https://github.com/NGXSMK/ngxsmk-datepicker/blob/main/projects/ngxsmk-datepicker/docs/signal-forms.md)** - Deep dive into Signal Forms integration
224
- - **[SSR Guide](https://github.com/NGXSMK/ngxsmk-datepicker/blob/main/projects/ngxsmk-datepicker/docs/ssr.md)** - Server-side rendering setup and best practices
225
- - **[SSR Example](https://github.com/NGXSMK/ngxsmk-datepicker/blob/main/projects/ngxsmk-datepicker/docs/SSR-EXAMPLE.md)** - Complete Angular Universal example with hydration notes
226
- - **[Extension Points Guide](https://github.com/NGXSMK/ngxsmk-datepicker/blob/main/projects/ngxsmk-datepicker/docs/extension-points.md)** - Customization hooks and extension points
227
- - **[Theme Tokens Reference](https://github.com/NGXSMK/ngxsmk-datepicker/blob/main/projects/ngxsmk-datepicker/docs/THEME-TOKENS.md)** - Complete CSS custom properties reference with examples
228
- - **[API Documentation](https://github.com/NGXSMK/ngxsmk-datepicker/blob/main/projects/ngxsmk-datepicker/docs/API.md)** - Complete public API reference
229
-
230
- #### **1. Import the Component**
231
-
232
- In your component file (e.g., app.component.ts), import the component (or the module—see troubleshooting below).
233
-
234
- import { Component } from '@angular/core';
235
- import { NgxsmkDatepickerComponent, DateRange, HolidayProvider } from 'ngxsmk-datepicker';
236
-
237
- @Component({
238
- selector: 'app-root',
239
- standalone: true,
240
- imports: [NgxsmkDatepickerComponent],
241
- templateUrl: './app.component.html',
242
- })
243
- export class AppComponent {
244
- // Example for predefined ranges
245
- public myRanges: DateRange = {
246
- 'Today': [new Date(), new Date()],
247
- 'Last 7 Days': [new Date(new Date().setDate(new Date().getDate() - 6)), new Date()],
248
- 'This Month': [new Date(new Date().getFullYear(), new Date().getMonth(), 1), new Date(new Date().getFullYear(), new Date().getMonth() + 1, 0)],
249
- };
250
-
251
- // Example for disabling weekends
252
- isWeekend = (date: Date): boolean => {
253
- const day = date.getDay();
254
- return day === 0 || day === 6; // Sunday or Saturday
255
- };
256
-
257
- onDateChange(value: Date | { start: Date; end: Date } | Date[]) {
258
- console.log('Date changed:', value);
259
- }
260
- }
261
-
262
- **If you see NG1010** (`'imports' must be an array... Value could not be determined statically`) when using the Angular compiler plugin or in strict AOT builds, use the wrapper module instead: `import { NgxsmkDatepickerModule } from 'ngxsmk-datepicker'` and set `imports: [NgxsmkDatepickerModule]`. The template stays the same (`<ngxsmk-datepicker>`).
263
-
264
- #### **2. Add it to Your Template**
265
-
266
- Use the `<ngxsmk-datepicker>` selector in your HTML template.
267
-
268
- ````html
269
- <h2>Advanced Date Range Picker</h2>
270
-
271
- <ngxsmk-datepicker [mode]="'range'" [ranges]="myRanges" [showTime]="true" [minuteInterval]="15" [minDate]="today" [isInvalidDate]="isWeekend" [locale]="'en-US'" [theme]="'light'" [inline]="'auto'" (valueChange)="onDateChange($event)"></ngxsmk-datepicker>
272
-
273
- #### **3. Disabled Dates Example** Disable specific dates by passing an array of date strings or Date objects: ```typescript // In your component disabledDates = ['10/21/2025', '08/21/2025', '10/15/2025', '10/8/2025', '10/3/2025']; // In your template
274
- <ngxsmk-datepicker [mode]="'single'" [disabledDates]="disabledDates" placeholder="Select a date"> </ngxsmk-datepicker>
275
- ````
276
-
277
- #### **4. Holiday Tooltips Example**
278
-
279
- Holiday dates automatically show tooltips when you hover over them:
280
-
281
- ```typescript
282
- // Holiday provider with tooltips
283
- class MyHolidayProvider implements HolidayProvider {
284
- private holidays: { [key: string]: string } = {
285
- '2025-01-01': 'New Year\'s Day',
286
- '2025-07-04': 'Independence Day',
287
- '2025-12-25': 'Christmas Day',
288
- };
289
-
290
- isHoliday(date: Date): boolean {
291
- const key = this.formatDateKey(date);
292
- return !!this.holidays[key];
293
- }
294
-
295
- getHolidayLabel(date: Date): string | null {
296
- const key = this.formatDateKey(date);
297
- return this.holidays[key] || null;
298
- }
299
- }
300
-
301
- // In your template
302
- <ngxsmk-datepicker
303
- [holidayProvider]="holidayProvider"
304
- [disableHolidays]="false"
305
- placeholder="Hover over holidays to see tooltips">
306
- </ngxsmk-datepicker>
307
- ```
308
-
309
- ## **🔌 Framework Integration**
310
-
311
- ### **Angular Material Form Fields**
312
-
313
- Integrate with Angular Material's form field components for a seamless Material Design experience. Works with both standalone and non-standalone components:
314
-
315
- **Standalone Components:**
316
-
317
- ```typescript
318
- import { Component } from "@angular/core";
319
- import { FormControl, FormGroup, ReactiveFormsModule } from "@angular/forms";
320
- import { MatFormFieldModule } from "@angular/material/form-field";
321
- import { MatInputModule } from "@angular/material/input";
322
- import { NgxsmkDatepickerComponent } from "ngxsmk-datepicker";
323
-
324
- @Component({
325
- selector: "app-material-form",
326
- standalone: true,
327
- imports: [ReactiveFormsModule, MatFormFieldModule, MatInputModule, NgxsmkDatepickerComponent],
328
- template: `
329
- <form [formGroup]="myForm">
330
- <mat-form-field appearance="outline">
331
- <mat-label>Select Date</mat-label>
332
- <ngxsmk-datepicker mode="single" formControlName="date" placeholder="Choose a date"> </ngxsmk-datepicker>
333
- </mat-form-field>
334
- </form>
335
- `,
336
- })
337
- export class MaterialFormComponent {
338
- myForm = new FormGroup({
339
- date: new FormControl<Date | null>(null),
340
- });
341
- }
342
- ```
343
-
344
- **Non-Standalone Components (NgModules):**
345
-
346
- ```typescript
347
- import { NgModule } from "@angular/core";
348
- import { MAT_FORM_FIELD_CONTROL } from "@angular/material/form-field";
349
- import { NgxsmkDatepickerComponent, provideMaterialFormFieldControl } from "ngxsmk-datepicker";
350
- import { MatFormFieldModule } from "@angular/material/form-field";
351
- import { MatInputModule } from "@angular/material/input";
352
- import { ReactiveFormsModule } from "@angular/forms";
353
-
354
- @NgModule({
355
- imports: [NgxsmkDatepickerComponent, MatFormFieldModule, MatInputModule, ReactiveFormsModule],
356
- providers: [provideMaterialFormFieldControl(MAT_FORM_FIELD_CONTROL)],
357
- })
358
- export class MyModule {}
359
- ```
360
-
361
- **With Date Range:**
362
-
363
- ```html
364
- <mat-form-field appearance="fill">
365
- <mat-label>Date Range</mat-label>
366
- <ngxsmk-datepicker mode="range" [showTime]="true" formControlName="dateRange"> </ngxsmk-datepicker>
367
- </mat-form-field>
368
- ```
369
-
370
- ### **Ionic Components**
371
-
372
- For best integration with Ionic, import the integration styles in your global CSS/SCSS file:
373
-
374
- ```css
375
- @import "ngxsmk-datepicker/styles/ionic-integration.css";
376
- ```
377
-
378
- **Automatic Theming:**
379
- The datepicker automatically detects and uses Ionic CSS variables (e.g., `--ion-color-primary`, `--ion-background-color`) so it matches your app's theme out of the box without extra configuration.
380
-
381
- Works seamlessly with Ionic form components and follows Ionic design patterns:
382
-
383
- ```typescript
384
- import { Component } from "@angular/core";
385
- import { FormControl, FormGroup, ReactiveFormsModule } from "@angular/forms";
386
- import { IonItem, IonLabel, IonInput } from "@ionic/angular/standalone";
387
- import { NgxsmkDatepickerComponent } from "ngxsmk-datepicker";
388
-
389
- @Component({
390
- selector: "app-ionic-form",
391
- standalone: true,
392
- imports: [ReactiveFormsModule, IonItem, IonLabel, IonInput, NgxsmkDatepickerComponent],
393
- template: `
394
- <form [formGroup]="myForm">
395
- <ion-item>
396
- <ion-label position="stacked">Appointment Date</ion-label>
397
- <ngxsmk-datepicker mode="single" formControlName="appointmentDate" placeholder="Select date"> </ngxsmk-datepicker>
398
- </ion-item>
399
- </form>
400
- `,
401
- })
402
- export class IonicFormComponent {
403
- myForm = new FormGroup({
404
- appointmentDate: new FormControl<Date | null>(null),
405
- });
406
- }
407
- ```
408
-
409
- **With Ionic Datetime Styling:**
410
-
411
- ```html
412
- <ion-item>
413
- <ion-label>Check-in / Check-out</ion-label>
414
- <ngxsmk-datepicker mode="range" [theme]="'light'" formControlName="bookingDates"> </ngxsmk-datepicker>
415
- </ion-item>
416
- ```
417
-
418
- ### **React, Vue, & Vanilla JS (Web Components)**
419
-
420
- Because `ngxsmk-datepicker` is highly decoupled from heavy external dependencies, it can be exported as a standard Custom Web Component using Angular Elements. This allows you to use exactly the same datepicker in React, Vue, Svelte, or Vanilla JavaScript projects seamlessly!
421
-
422
- **1. Create a Custom Element Wrapper**
423
- ```typescript
424
- import { createApplication } from '@angular/platform-browser';
425
- import { createCustomElement } from '@angular/elements';
426
- import { NgxsmkDatepickerComponent } from 'ngxsmk-datepicker';
427
-
428
- (async () => {
429
- const app = await createApplication();
430
- const DatepickerElement = createCustomElement(NgxsmkDatepickerComponent, { injector: app.injector });
431
- customElements.define('ngxsmk-datepicker', DatepickerElement);
432
- })().catch(console.error);
433
- ```
434
-
435
- **2. Use It Natively Anywhere**
436
- ```html
437
- <!-- In any HTML, React, Vue, or Svelte file -->
438
- <ngxsmk-datepicker id="myPicker" mode="range" theme="light"></ngxsmk-datepicker>
439
-
440
- <script>
441
- // Add native DOM event listeners
442
- document.getElementById('myPicker').addEventListener('dateSelect', (e) => {
443
- console.log('Selected date:', e.detail);
444
- });
445
- </script>
446
- ```
447
-
448
- For full working examples (including React & Vue bindings), check out the `/examples` directory in our GitHub repository!
449
-
450
- ### **Plain HTML Inputs**
451
-
452
- Use with standard HTML form inputs for maximum flexibility:
453
-
454
- ```typescript
455
- import { Component } from "@angular/core";
456
- import { FormControl, FormGroup, ReactiveFormsModule } from "@angular/forms";
457
- import { NgxsmkDatepickerComponent } from "ngxsmk-datepicker";
458
-
459
- @Component({
460
- selector: "app-plain-form",
461
- standalone: true,
462
- imports: [ReactiveFormsModule, NgxsmkDatepickerComponent],
463
- template: `
464
- <form [formGroup]="myForm">
465
- <label for="birthdate">Birth Date</label>
466
- <ngxsmk-datepicker id="birthdate" mode="single" formControlName="birthdate" placeholder="MM/DD/YYYY"> </ngxsmk-datepicker>
467
-
468
- <button type="submit">Submit</button>
469
- </form>
470
- `,
471
- })
472
- export class PlainFormComponent {
473
- myForm = new FormGroup({
474
- birthdate: new FormControl<Date | null>(null),
475
- });
476
- }
477
- ```
478
-
479
- **With Native HTML5 Validation:**
480
-
481
- ```html
482
- <form [formGroup]="myForm">
483
- <div class="form-group">
484
- <label for="event-date">Event Date *</label>
485
- <ngxsmk-datepicker id="event-date" mode="single" formControlName="eventDate" [minDate]="today" required> </ngxsmk-datepicker>
486
- </div>
487
- </form>
488
- ```
489
-
490
- ### **Form Validation**
491
-
492
- By default, the datepicker input is `readonly` to prevent invalid date strings and force selection via the calendar. However, **browsers do not validate `readonly` fields** during native form submission.
493
-
494
- **Behavior:**
495
-
496
- - Native browser validation (e.g., blocking submit on `required` fields) will **NOT** trigger on the datepicker by default.
497
- - Custom validation (e.g., Angular validators) works normally but often only shows errors after the control is "touched".
498
-
499
- **Solutions:**
500
-
501
- 1. **Enable Typing (Recommended for Native Validation):**
502
- Set `[allowTyping]="true"` to make the input standard editable field. This enables native browser validation tooltips and submit-blocking.
503
-
504
- ```html
505
- <ngxsmk-datepicker [allowTyping]="true" required ...></ngxsmk-datepicker>
506
- ```
507
-
508
- 2. **Custom Validation Logic:**
509
- If you prefer the readonly behavior, ensure your form submission handler explicitly checks `form.invalid` before proceeding, as the browser won't stop the submit button click.
510
-
511
- ## **⚙️ API Reference**
512
-
513
- ### **Inputs**
514
-
515
- | Property | Type | Default | Description |
516
- | :----------------- | :--- | :------ | :---------- |
517
- | mode | 'single' \| 'range' \| 'multiple' | 'single' | The selection mode. |
518
- | inline | boolean \| 'always' \| 'auto' | false | Controls the display mode. `true` or `'always'` for inline, `'auto'` for responsive. |
519
- | locale | string | navigator.language | Sets the locale for language and regional formatting (e.g., 'en-US', 'de-DE'). |
520
- | theme | 'light' \| 'dark' | 'light' | The color theme. |
521
- | showRanges | boolean | true | If true, displays the predefined ranges panel when in 'range' mode. |
522
- | minDate | DateInput | null | The earliest selectable date. |
523
- | maxDate | DateInput | null | The latest selectable date. |
524
- | isInvalidDate | (date: Date) => boolean | () => false | A function to programmatically disable specific dates. |
525
- | ranges | DateRange | null | An object of predefined date ranges. |
526
- | minuteInterval | number | 1 | Interval for minute dropdown options. |
527
- | showTime | boolean | false | Enables the hour/minute/AM/PM selection section. |
528
- | timeOnly | boolean | false | Display time picker only (no calendar). Automatically enables `showTime`. |
529
- | use24Hour | boolean | false | Enable 24-hour time format (00-23) and hide AM/PM selector. |
530
- | allowTyping | boolean | false | Enable manual typing in the input field. Required for native validation. |
531
- | displayFormat | string | null | Custom date format string (e.g., 'MM/DD/YYYY'). |
532
- | showCalendarButton | boolean | false | Show/hide the calendar icon button. |
533
- | value | DatepickerValue | null | Programmatic value setting from code. |
534
- | startAt | DateInput | null | The date to initially center the calendar view on. |
535
- | holidayProvider | HolidayProvider | null | An object that provides holiday information. |
536
- | disableHolidays | boolean | false | If true, disables holiday dates from being selected. |
537
- | disabledDates | (string \| Date)[] | [] | Array of dates to disable. |
538
- | weekStart | number \| null | null | Override week start day (0=Sunday, 1=Monday, etc.). |
539
- | yearRange | number | 10 | Number of years before/after current year to show in year dropdown. |
540
- | clearLabel | string | 'Clear' | Custom label for the clear button. |
541
- | closeLabel | string | 'Close' | Custom label for the close button. |
542
- | prevMonthAriaLabel | string | 'Previous month' | Aria label for previous month navigation button. |
543
- | nextMonthAriaLabel | string | 'Next month' | Aria label for next month navigation button. |
544
- | clearAriaLabel | string | 'Clear selection' | Aria label for clear button. |
545
- | closeAriaLabel | string | 'Close calendar' | Aria label for close button. |
546
- | classes | object | undefined | Tailwind-friendly class overrides (wrapper, input, popover, etc.). |
547
- | enableGoogleCalendar| boolean | false | Enable seamless Google Calendar integration and sync. |
548
- | googleClientId | string \| null | null | Google API OAuth 2.0 Web Client ID for authentication. |
549
-
550
- ### **Outputs**
551
-
552
- | Event | Payload | Description |
553
- | :---------- | :------------------------------ | :------------------------------------------------------------ |
554
- | valueChange | DatepickerValue | Emits the newly selected date, range, or array of dates. |
555
- | action | { type: string; payload?: any } | Emits various events like `dateSelected`, `timeChanged`, etc. |
556
- | googleSyncClick | void | Emitted when the user clicks the Google Calendar sync button. |
557
-
558
- ## **🎨 Theming**
559
-
560
- ### CSS Variables
561
-
562
- You can easily customize the colors of the datepicker by overriding the CSS custom properties in your own stylesheet.
563
-
564
- ```css
565
- ngxsmk-datepicker {
566
- --datepicker-primary-color: #d9267d;
567
- --datepicker-primary-contrast: #ffffff;
568
- --datepicker-range-background: #fce7f3;
569
- }
570
- ```
571
-
572
- ### Tailwind/ngClass Support
573
-
574
- For Tailwind CSS or custom class-based theming, use the `classes` input:
575
-
576
- ```html
577
- <ngxsmk-datepicker
578
- mode="single"
579
- [classes]="{
580
- inputGroup: 'rounded-lg border',
581
- input: 'px-3 py-2 text-sm',
582
- popover: 'shadow-2xl',
583
- dayCell: 'hover:bg-indigo-50',
584
- footer: 'flex justify-end gap-2',
585
- clearBtn: 'btn btn-ghost',
586
- calendarBtn: 'btn btn-icon',
587
- closeBtn: 'btn btn-primary'
588
- }"
589
- >
590
- </ngxsmk-datepicker>
591
- ```
592
-
593
- ### Dark Theme
594
-
595
- To enable the dark theme, simply bind the theme input:
596
-
597
- ```html
598
- <ngxsmk-datepicker [theme]="'dark'"></ngxsmk-datepicker>
599
- ```
600
-
601
- ### Calendar Button Visibility
602
-
603
- Control the visibility of the calendar icon button:
604
-
605
- ```html
606
- <!-- Hide calendar button (default - users can still click input to open calendar) -->
607
- <ngxsmk-datepicker mode="single"> </ngxsmk-datepicker>
608
-
609
- <!-- Show calendar button -->
610
- <ngxsmk-datepicker [showCalendarButton]="true" mode="single"> </ngxsmk-datepicker>
611
-
612
- <!-- Useful with allowTyping for custom UI -->
613
- <ngxsmk-datepicker [allowTyping]="true" [showCalendarButton]="false" mode="single"> </ngxsmk-datepicker>
614
- ```
615
-
616
- ## **🌍 Localization (i18n)**
617
-
618
- The `locale` input controls all internationalization. It automatically formats month names, weekday names, and sets the first day of the week based on BCP 47 language tags.
619
-
620
- ### **Global Language Support**
621
-
622
- ngxsmk-datepicker v2.2.0 now features **full localization synchronization** for:
623
-
624
- - �� English (`en`)
625
- - �� German (`de`)
626
- - �� French (`fr`)
627
- - �� Spanish (`es`)
628
- - 🇸🇪 Swedish (`sv`)
629
- - �� Korean (`ko`)
630
- - �� Chinese (`zh`)
631
- - �� Japanese (`ja`)
632
-
633
- ### **Usage Example**
634
-
635
- ```html
636
- <!-- Force German Locale -->
637
- <ngxsmk-datepicker [locale]="'de-DE'"></ngxsmk-datepicker>
638
-
639
- <!-- Swedish with YYYY-MM-DD format and Monday week start -->
640
- <ngxsmk-datepicker [locale]="'sv-SE'"></ngxsmk-datepicker>
641
- ```
642
-
643
- The component automatically uses ISO 8601 standards (Monday start) for European locales and appropriate regional date formats.
644
-
645
- ## **🖥️ Server-Side Rendering (SSR)**
646
-
647
- The datepicker is fully compatible with Angular Universal and server-side rendering:
648
-
649
- - ✅ All browser APIs are platform-checked
650
- - No `window` or `document` access during initialization
651
- - ✅ Works with partial hydration
652
- - Compatible with zoneless applications
653
-
654
- See the [SSR Guide](./projects/ngxsmk-datepicker/docs/ssr.md) for detailed setup instructions.
655
-
656
- ## **⌨️ Keyboard Navigation**
657
-
658
- The datepicker supports full keyboard navigation for accessibility:
659
-
660
- ### Built-in Shortcuts
661
-
662
- - **Arrow Keys** (← → ↑ ↓): Navigate between dates
663
- - **Page Up/Down**: Navigate months (Shift + Page Up/Down for years)
664
- - **Home/End**: Jump to first/last day of month
665
- - **Enter/Space**: Select focused date
666
- - **Escape**: Close calendar (popover mode)
667
- - **T**: Select today's date
668
- - **Y**: Select yesterday
669
- - **N**: Select tomorrow
670
- - **W**: Select next week (7 days from today)
671
- - **Tab**: Navigate between interactive elements
672
- - **?** (Shift + /): Toggle keyboard shortcuts help dialog
673
-
674
- ### Custom Keyboard Shortcuts
675
-
676
- You can add custom keyboard shortcuts using the `hooks` input or `customShortcuts` input:
677
-
678
- ```typescript
679
- import { DatepickerHooks, KeyboardShortcutContext } from "ngxsmk-datepicker";
680
-
681
- const myHooks: DatepickerHooks = {
682
- handleShortcut: (event, context) => {
683
- if (event.ctrlKey && event.key === "1") {
684
- // Custom action
685
- return true; // Handled
686
- }
687
- return false; // Use default
688
- },
689
- };
690
- ```
691
-
692
- ```html
693
- <ngxsmk-datepicker [hooks]="myHooks" [customShortcuts]="shortcuts" mode="single"> </ngxsmk-datepicker>
694
- ```
695
-
696
- All date cells are keyboard accessible with proper ARIA attributes for screen readers.
697
-
698
- See [Extension Points Guide](./projects/ngxsmk-datepicker/docs/extension-points.md) for detailed customization options.
699
-
700
- ## **🚀 Performance Optimizations**
701
-
702
- This library has been optimized for maximum performance:
703
-
704
- - **30% Smaller Bundle**: Optimized build configuration and tree-shaking
705
- - **40% Faster Rendering**: OnPush change detection strategy with proper triggers
706
- - **60% Faster Selection**: Memoized date comparisons and debounced operations
707
- - **Zero Dependencies**: Standalone component with no external dependencies
708
- - **Tree-shakable**: Only import what you need
709
- - **Memory Efficient**: Cache size limits prevent memory leaks
710
- - **Hardware Accelerated**: CSS optimizations for smooth animations
711
- - **Mobile Optimized**: Touch-friendly interactions and responsive design
712
-
713
- ## **🐛 Bug Fixes & Improvements**
714
-
715
- ### **Critical Bug Fixes in v1.4.15:**
716
-
717
- - **Change Detection**: Fixed OnPush change detection issues with proper `markForCheck()` triggers
718
- - ✅ **Date Comparison**: Fixed null safety issues in date range comparisons
719
- - ✅ **Memory Leaks**: Added cache size limits to prevent memory leaks
720
- - ✅ **Type Safety**: Improved TypeScript types and null safety checks
721
- - **Mobile UX**: Enhanced mobile interactions and touch feedback
722
- - ✅ **Performance**: Optimized template bindings with memoized functions
723
- - **Accessibility**: Better focus states and keyboard navigation
724
- - **Build System**: Improved build configuration and optimization
725
-
726
- ### **Performance Enhancements:**
727
-
728
- - 🚀 **Optimized Bundle Size**: Main bundle ~127KB (source maps excluded from published package)
729
- - 🚀 **40% Faster Rendering**: Enhanced OnPush change detection
730
- - 🚀 **60% Faster Selection**: Memoized date comparisons
731
- - 🚀 **Memory Efficient**: Cache size limits prevent memory leaks
732
- - 🚀 **Hardware Accelerated**: CSS optimizations for smooth animations
733
- - 🚀 **Better Tree-Shaking**: Optimized TypeScript compiler settings for smaller output
734
- - 🚀 **Production Optimized**: Source maps automatically removed from production builds
735
-
736
- ## **📱 Demo Application**
737
-
738
- A comprehensive demo application is included to showcase all features with a modern, polished UI:
739
-
740
- ```bash
741
- # Clone the repository
742
- git clone https://github.com/NGXSMK/ngxsmk-datepicker.git
743
- cd ngxsmk-datepicker
744
-
745
- # Install dependencies
746
- npm install
747
-
748
- # Run the demo app
749
- npm start
750
- ```
751
-
752
- The demo includes:
753
-
754
- - **Modern UI Design**: Beautiful glassmorphism effects, gradient themes, and polished visual hierarchy
755
- - **Responsive Navigation**: Modern navbar with search, theme toggle, and mobile-friendly menu
756
- - **Enhanced Sidebar**: Redesigned documentation sidebar with smooth animations and visual indicators
757
- - **Signal Forms (Angular 21)** with writable signal binding examples
758
- - **Theming** with CSS variables and Tailwind classes examples
759
- - **Customization & A11y** with weekStart, yearRange, labels, and aria examples
760
- - **Holiday Provider Integration** with US holidays
761
- - **Single Date Selection** with weekend restrictions
762
- - **Inline Range Picker** with toggle controls
763
- - **Date Range with Time** selection
764
- - **Multiple Date Selection** with action tracking
765
- - **Programmatic Value Setting** for all selection modes
766
- - **Theme Toggle** (Light/Dark mode) with automatic system preference detection
767
- - **Customizable Calendar Views**: Year-picker, decade-picker, timeline view, and time-slider view
768
-
769
- ## **🔧 Development**
770
-
771
- ### **GitHub Actions**
772
-
773
- The project uses GitHub Actions for automated deployment:
774
-
775
- - **Deploy Demo App**: Automatically deploys the demo application to GitHub Pages on pushes to `main`/`master` branches
776
- - Workflow: `.github/workflows/deploy-demo.yml`
777
- - Triggers: Push to main/master or manual workflow dispatch
778
- - Builds and deploys the demo app to GitHub Pages
779
-
780
- ### **Building the Library**
781
-
782
- ```bash
783
- # Build the library (development)
784
- npm run build
785
-
786
- # Build optimized production version
787
- # - Removes source maps automatically
788
- # - Optimized TypeScript compilation
789
- # - Enhanced tree-shaking
790
- npm run build:optimized
791
-
792
- # Analyze bundle size (excludes source maps)
793
- npm run build:analyze
794
- ```
795
-
796
- **Build Output:**
797
-
798
- - Main bundle: `dist/ngxsmk-datepicker/fesm2022/ngxsmk-datepicker.mjs` (~127KB)
799
- - Type definitions: `dist/ngxsmk-datepicker/index.d.ts`
800
- - Source maps: Automatically removed from production builds
801
-
802
- ### **Running Tests**
803
-
804
- ```bash
805
- # Run all tests (library + demo app)
806
- npm test
807
-
808
- # Run library tests only
809
- npx ng test ngxsmk-datepicker --no-watch --browsers=ChromeHeadless
810
-
811
- # Run specific test file
812
- npx ng test ngxsmk-datepicker --include="**/issue-13.spec.ts"
813
-
814
- # Run tests in watch mode
815
- npm test -- --watch
816
- ```
817
-
818
- ### **Code Quality Improvements**
819
-
820
- The library now includes:
821
-
822
- - ✅ **TypeScript Strict Mode**: Enhanced type safety
823
- - **ESLint Configuration**: Code quality enforcement
824
- - ✅ **Performance Monitoring**: Built-in performance metrics
825
- - **Memory Leak Prevention**: Cache size limits and cleanup
826
- - ✅ **Accessibility Testing**: WCAG compliance checks
827
- - **Mobile Testing**: Touch interaction validation
828
-
829
- ## **📦 Package Structure**
830
-
831
- ```
832
- ngxsmk-datepicker/
833
- ├── projects/
834
- │ ├── ngxsmk-datepicker/ # Main library
835
- │ └── demo-app/ # Demo application
836
- ├── dist/ # Built packages
837
- ├── docs/ # Documentation
838
- └── scripts/ # Build scripts
839
- ```
840
-
841
- ## **🎯 Browser Support**
842
-
843
- - **Chrome** 90+
844
- - **Firefox** 88+
845
- - **Safari** 14+
846
- - **Edge** 90+
847
- - **Mobile Safari** 14+
848
- - **Chrome Mobile** 90+
849
-
850
- ## **🗺️ Roadmap**
851
-
852
- Check out our [Roadmap](https://github.com/NGXSMK/ngxsmk-datepicker/blob/main/ROADMAP.md) to see planned features, improvements, and how you can contribute. We're always looking for contributors, especially for issues labeled `good-first-issue` and `help-wanted`!
853
-
854
- ## **🤝 Contributions**
855
-
856
- We welcome and appreciate contributions from the community! Whether it's reporting a bug, suggesting a new feature, or submitting code, your help is valuable.
857
-
858
- ### **Development Setup**
859
-
860
- 1. **Fork the repository** on GitHub
861
- 2. **Clone your fork** to your local machine
862
- 3. **Install dependencies**: `npm install`
863
- 4. **Run the demo app**: `npm start`
864
- 5. **Create a feature branch** for your changes
865
- 6. **Commit your changes** following conventional commits
866
- 7. **Submit a Pull Request** to the main branch
867
-
868
- ### **Contribution Guidelines**
869
-
870
- - Follow the existing code style
871
- - Add tests for new features
872
- - Update documentation as needed
873
- - Ensure all tests pass
874
- - Follow conventional commit messages
875
-
876
- ## **📄 Changelog**
877
-
878
- For a full list of changes, please refer to the [CHANGELOG.md](https://github.com/NGXSMK/ngxsmk-datepicker/blob/main/CHANGELOG.md) file.
879
-
880
- ### **v2.2.0** (Current Stable)
881
-
882
- - 🎉 **Version Update**: Updated to version 2.2.0.
883
- - **Key Updates**: Optimized loading times, refined mobile header layout, and improved dropdown accessibility.
884
- - **Stable Release**: Full synchronization of header components with `ViewEncapsulation.None`.
885
-
886
- ### **v1.9.24**
887
-
888
- - 🎉 **Version Update**: Updated to version 1.9.24
889
- - **Stable Release**: Version 1.9.24 is the current stable version
890
-
891
- ### **v1.9.23**
892
-
893
- - 🐛 **Fixed**: CSS Variables Theming (Issue #84) - CSS variables theming now works when variables are defined in global `:root` selector
894
- - Enhanced CSS selector from `:root` to `:root, :root > body` for higher specificity
895
- - Added `!important` flags to inline styles to ensure they override existing styles
896
- - ThemeBuilderService now properly overrides global stylesheet variables
897
- - Updated documentation to explain the fix and provide guidance
898
- - Resolves issue where theme variables defined in global stylesheets were not being applied
899
-
900
- ### **v1.9.22**
901
-
902
- - 🎉 **Version Update**: Updated to version 1.9.22
903
- - 🐛 **Fixed**: Form control value initialization issue - datepicker now correctly displays month from form control values
904
- - Fixed calendar month display when using Reactive Forms with initial values
905
- - Added proper signal updates and change detection in `writeValue()` method
906
- - 🐛 **Fixed**: Locale week start detection for en-GB and other European locales
907
- - Added fallback logic for locales where `Intl.Locale.weekInfo` is not available
908
- - Now correctly returns Monday (1) for en-GB and other European locales
909
-
910
- ### **v1.9.21**
911
-
912
- - 🎉 **Version Update**: Updated to version 1.9.21
913
- - 📱 **Mobile-Specific Features**: Comprehensive mobile optimization
914
- - Native date picker integration with automatic mobile detection
915
- - Bottom sheet modal with swipe-to-dismiss gestures
916
- - Enhanced touch gestures (double-tap, swipe navigation)
917
- - Haptic feedback support for better mobile UX
918
- - Mobile-optimized animations and keyboard handling
919
- - 🎯 **Advanced Selection Modes**: Extended selection capabilities
920
- - Week selection mode for selecting entire weeks
921
- - Month selection mode for selecting full months
922
- - Quarter selection mode for quarterly selections
923
- - Year selection mode for annual date ranges
924
- - ⏱️ **Enhanced Time Selection**: Improved time picker
925
- - Seconds selection with configurable intervals
926
- - Better time picker UX and controls
927
- - 🏗️ **Code Refactoring**: Improved architecture
928
- - New services: CalendarGenerationService, DisplayFormattingService, DateValidationService
929
- - Better code organization and maintainability
930
- - Reduced component complexity
931
- - **Accessibility Enhancements**: Better screen reader support
932
- - Improved ARIA live regions
933
- - Enhanced focus management
934
- - Better keyboard navigation
935
- - **Performance Optimizations**: Infrastructure improvements
936
- - Lazy loading calendar months with intelligent caching
937
- - Virtual scrolling infrastructure
938
- - Preloading adjacent months
939
- - 🧪 **Test Coverage**: Comprehensive test suite
940
- - 414 tests passing
941
- - New service tests
942
- - Updated component and utility tests
943
- - 🔄 **Backward Compatible**: Full backward compatibility with v1.9.20
944
-
945
- ### **v1.9.20**
946
-
947
- - 🎉 **Version Update**: Updated to version 1.9.20
948
- - 🐛 **Bug Fix (Issue #71)**: Fixed `TypeError: window.matchMedia is not a function` error in test environments (jsdom/Vitest)
949
- - Added error handling for `window.matchMedia` in `applyAnimationConfig()` method
950
- - Component now gracefully handles missing `matchMedia` API in test environments
951
- - Prevents test failures when running with Vitest and jsdom
952
- - **Test Coverage**: Added comprehensive test coverage for `matchMedia` compatibility scenarios
953
- - 🔄 **Backward Compatible**: Full backward compatibility with v1.9.19
954
-
955
- ### **v1.9.19**
956
-
957
- - 🎉 **Version Update**: Updated to version 1.9.19
958
- - 🎨 **Responsive Layout Redesign**: Complete redesign of demo project layout for all screen sizes (320px to desktop)
959
- - 📱 **Mobile Optimization**: Enhanced mobile experience with improved navbar, sidebar, hero section, and feature grid
960
- - 🧹 **Code Cleanup**: Removed unnecessary comments for cleaner codebase
961
- - 🔧 **Meta Tag Update**: Replaced deprecated `apple-mobile-web-app-capable` with `mobile-web-app-capable`
962
- - 🔄 **Backward Compatible**: Full backward compatibility with v1.9.18
963
-
964
- ### **v1.9.18**
965
-
966
- - 🐛 **Mobile Touch Event Handling**: Fixed touch listener attachment when calendar opens on mobile devices
967
- - Touch listeners now properly attach when calendar first opens, eliminating the need to navigate months first
968
- - Added retry mechanism with multiple attempts to ensure listeners are attached even on slower mobile devices
969
- - Improved timing with double `requestAnimationFrame` calls and multiple retry strategies
970
- - 🎉 **Version Update**: Updated to version 1.9.18
971
- - 🔄 **Backward Compatible**: Full backward compatibility with v1.9.17
972
-
973
- ### **v1.9.17**
974
-
975
- - 🎉 **Calendar Button Visibility Control**: Added `showCalendarButton` input property to show/hide the calendar icon button
976
- - Defaults to `false` for a cleaner, more minimal UI
977
- - When set to `true`, displays the calendar icon button next to the input field
978
- - When set to `false`, users can still open the calendar by clicking the input field
979
- - Perfect for custom UI designs or when using `allowTyping` with custom calendar triggers
980
- - 🎨 **Calendar Button Styling**: Added `calendarBtn` to `DatepickerClasses` for custom styling of the calendar button
981
- - 🔧 **Type Compatibility**: Updated `SignalFormField` type to be fully compatible with Angular 21's `FieldTree<Date, string>` types
982
- - Resolves TypeScript compilation issues when using `[field]` input with Angular 21 Signal Forms
983
- - Maintains full backward compatibility with Angular 17-20
984
- - 🎉 **Version Update**: Updated to version 1.9.17
985
- - 🔄 **Backward Compatible**: Full backward compatibility with v1.9.16
986
- - ✅ **Angular 17-22 Compatible**: Verified compatibility with Angular 17-22 (including Angular 21)
987
-
988
- ### **v1.9.16**
989
-
990
- - 🐛 **Range Mode Previous Month Selection**: Fixed issue where users could not select dates from previous months in range mode when starting with `{ start: null, end: null }`
991
- - 🎉 **Version Update**: Updated to version 1.9.16
992
- - 🔄 **Backward Compatible**: Full backward compatibility with v1.9.15
993
- - **Angular 17+ Compatible**: Verified compatibility with Angular 17 and up versions
994
-
995
- ### **v1.9.15**
996
-
997
- - 🐛 **Moment Object Binding Fix**: Fixed Moment.js objects not binding correctly with ngModel
998
- - 🐛 **Date Clicks After Navigation**: Fixed dates becoming unclickable after month navigation
999
- - 🎉 **Version Update**: Updated to version 1.9.15
1000
- - 🔄 **Backward Compatible**: Full backward compatibility with v1.9.14
1001
- - **Angular 17+ Compatible**: Verified compatibility with Angular 17 and up versions
1002
-
1003
- ### **v1.9.14**
1004
-
1005
- - 🐛 **Date Picker Selection Fix**: Fixed date picker selection issues, especially in range mode
1006
- - 🐛 **Moment.js Timezone Support**: Fixed timezone offset preservation for Moment.js objects
1007
- - 🎉 **Version Update**: Updated to version 1.9.14
1008
- - 🔄 **Backward Compatible**: Full backward compatibility with v1.9.13
1009
-
1010
- ### **v1.9.13**
1011
-
1012
- - 🐛 **Bug Fixes**: Fixed `valueChange` event emitting null for range mode with ngModel
1013
- - 🐛 **Bug Fixes**: Fixed date selection becoming disabled after month navigation in range mode
1014
- - 🐛 **Bug Fixes**: Fixed Moment.js object handling in range values and arrays
1015
- - 🎉 **Version Update**: Updated to version 1.9.13
1016
- - 🔄 **Backward Compatible**: Full backward compatibility with v1.9.12
1017
-
1018
- ### **v1.9.12**
1019
-
1020
- - 🎉 **Version Update**: Updated to version 1.9.12
1021
- - 🔄 **Backward Compatible**: Full backward compatibility with v1.9.11
1022
- - 📚 **Migration Guide**: See [MIGRATION.md](MIGRATION.md) for detailed migration instructions
1023
-
1024
- ### **v1.9.11**
1025
-
1026
- - 🐛 **Moment.js Integration**: Fixed critical issue where Moment.js objects with custom date formats would not populate correctly
1027
- - Added `isMomentObject()` helper method to safely detect Moment.js instances
1028
- - Enhanced `_normalizeValue()` method to handle Moment.js objects directly
1029
- - Improved `parseCustomDateString()` method for TypeScript compatibility
1030
- - Added comprehensive support for format tokens: YYYY, YY, MM, M, DD, D, hh, h, HH, H, mm, m, ss, s, a, A
1031
- - Maintains full backward compatibility with Date objects, strings, and all other supported formats
1032
- - 🎨 **Custom Format Parser**: Enhanced format token parsing with better TypeScript compatibility
1033
- - 🔍 **Moment.js Detection**: More robust detection of Moment.js objects across different versions
1034
- - 🎮 **Demo Application**: Added working Moment.js integration example with interactive controls
1035
-
1036
- ### **v1.9.10**
1037
-
1038
- - 🐛 **Async Database Value Loading**: Enhanced datepicker to properly handle database values that load asynchronously
1039
- - Added fallback sync mechanism in `ngAfterViewInit` to catch async database loads
1040
- - Added delayed sync checks in `ngOnInit`, `ngOnChanges`, and `ngAfterViewInit`
1041
- - Added sync on calendar open, focus events, and touch events
1042
- - Extended interval sync duration to 30 seconds with 100ms check intervals
1043
- - 🔧 **TypeScript Compilation Error**: Fixed `EffectRef` type error when using Angular 17+ `effect()` API
1044
- - Changed `_fieldEffectDestroy: (() => void) | null` to `_fieldEffectRef: EffectRef | null`
1045
- - Updated effect cleanup to use `effectRef.destroy()` instead of function call
1046
- - Added proper `EffectRef` import from `@angular/core`
1047
- - 🧪 **Test Configuration**: Fixed test configuration for Angular 17+ compatibility
1048
- - Updated karma configuration to work with `@angular/build:karma` builder
1049
- - Simplified karma.conf.js to remove deprecated plugins
1050
- - Updated test script to target correct project
1051
-
1052
- ### **v1.9.9**
1053
-
1054
- - 🐛 **Database Value Population**: Fixed critical issue where datepicker would not populate with values from database when using `[field]` input binding
1055
- - Added `_normalizeValue()` helper method to properly handle all value types
1056
- - Updated field effect and related methods to use `_normalizeValue()` instead of `_normalizeDate()`
1057
- - Fixed issue where string dates from database were not being parsed and displayed correctly
1058
- - Now properly handles Date objects, string dates, range objects, and arrays of dates
1059
-
1060
- ### **v1.9.8**
1061
-
1062
- - 🐛 **Date Selection Reset Issue**: Fixed critical bug where selected dates would reset to today's date when using `[field]` input binding
1063
- - Fixed `applyCurrentTime` to create a new Date object instead of mutating the original
1064
- - Added `_isUpdatingFromInternal` flag to prevent field effect from resetting the value
1065
- - This ensures selected dates are properly stored in the form field
1066
-
1067
- ### **v1.9.7**
1068
-
1069
- - 🐛 **Calendar Population**: Fixed critical issue where datepicker calendar would not populate with dates when opened
1070
- - Fixed issue when multiple datepickers were present in the same form
1071
- - Ensured `generateCalendar()` is called when opening the datepicker via click, touch, or programmatic methods
1072
-
1073
- ### **v1.9.6**
1074
-
1075
- - 🐛 **Multiple Datepicker Management**: Fixed issue where multiple datepickers in the same form would open in the same centered location
1076
- - 🖱️ **Outside Click Detection**: Improved click detection to properly close datepicker when clicking outside
1077
- - 🔄 **Auto-close Other Datepickers**: When opening a datepicker, all other open datepickers in the same form are now automatically closed
1078
- - 📱 **Mobile Datepicker Opening**: Fixed issue where datepicker modal would not open on mobile screens
1079
- - 📱 **Datepicker Closing on Mobile**: Fixed issue where datepicker would open and immediately disappear on mobile devices
1080
- - 👆 **Select Box Cursor**: Added pointer cursor to all select boxes (month, year, hour, minute, AM/PM) in the datepicker
1081
-
1082
- ### **v1.9.5**
1083
-
1084
- - 🔧 **Angular 21+ Signal Forms Type Compatibility**: Fixed TypeScript compilation error with Angular 21+ Signal Forms
1085
- - Fixed `Type '() => string' is not assignable to type 'never'` error when using `[field]` input
1086
- - Updated `SignalFormField` type definition to be compatible with Angular 21's `FieldTree<Date, string>` types
1087
- - Maintains backward compatibility with Angular 17-20 where field input is optional
1088
- - Resolves [#33](https://github.com/NGXSMK/ngxsmk-datepicker/issues/33)
1089
-
1090
- ### **v1.9.4**
1091
-
1092
- - **Custom Date Format**: New `[displayFormat]` input property to display dates in custom formats
1093
- - Supports format strings like "MM/DD/YYYY hh:mm A"
1094
- - Works with date adapters (date-fns, dayjs, luxon) or built-in simple formatter
1095
- - Supports common format tokens: YYYY, MM, DD, hh, mm, A, etc.
1096
- - Resolves [#31](https://github.com/NGXSMK/ngxsmk-datepicker/issues/31)
1097
- - 🐛 **Time Selection Dropdowns**: Fixed visibility issues with time selection dropdowns
1098
- - Dropdowns now properly display and are not clipped by parent containers
1099
- - Improved z-index handling for time selection dropdowns
1100
- - Removed unnecessary scrollbars from datepicker wrapper
1101
- - Resolves [#32](https://github.com/NGXSMK/ngxsmk-datepicker/issues/32)
1102
-
1103
- ### **v1.9.3**
1104
-
1105
- - **Time-Only Picker**: New `[timeOnly]` input property to display only time selection without calendar
1106
- - Hides calendar grid and shows only time controls (hour, minute, AM/PM)
1107
- - Automatically enables `showTime` when `timeOnly` is true
1108
- - Perfect for time selection scenarios where date is not needed
1109
- - Value is still a Date object using today's date with selected time
1110
- - Placeholder automatically changes to "Select Time" in time-only mode
1111
- - Resolves [#29](https://github.com/NGXSMK/ngxsmk-datepicker/issues/29)
1112
- - 🎨 **Modern Demo App UI**: Complete redesign of the demo application
1113
- - Modern navbar with glassmorphism effects, search functionality, and improved theme toggle
1114
- - Redesigned sidebar with gradient backgrounds, smooth animations, and visual indicators
1115
- - Enhanced icon sizes and better visual hierarchy
1116
- - Improved responsive design with better mobile experience
1117
- - Automatic system theme detection (dark/light mode preference)
1118
- - Gradient accents, shadows, and modern design patterns throughout
1119
- - 🧪 **Test Suite**: Fixed 25+ failing tests across multiple test files
1120
- - Fixed date utils tests, calendar utils tests, timezone utils tests, edge cases tests
1121
- - Fixed adapters tests, performance utils tests, RTL tests, touch gestures tests
1122
- - Fixed calendar views tests, recurring dates utils tests
1123
- - All 353 tests now pass successfully
1124
-
1125
- ### **v1.9.2**
1126
-
1127
- - 📦 **Bundle Optimization**: Optimized bundle size with improved TypeScript compiler settings
1128
- - Main bundle: ~127KB (source maps excluded from published package)
1129
- - Enhanced tree-shaking with optimized imports and compiler options
1130
- - Added `importsNotUsedAsValues: "remove"` for smaller output
1131
- - Disabled `preserveConstEnums` for better inlining
1132
- - 🔧 **Build Process**:
1133
- - Source maps automatically removed from production builds (saves ~127KB)
1134
- - Improved build scripts with better error handling
1135
- - Enhanced bundle analysis that excludes source maps
1136
- - 📦 **Package Configuration**:
1137
- - Fixed package.json exports to eliminate build warnings
1138
- - Optimized `files` array to exclude unnecessary files
1139
- - Updated exports field for better module resolution
1140
- - 🧪 **Test Configuration**:
1141
- - Added Zone.js polyfills to library test configuration
1142
- - Updated test commands to explicitly target library project
1143
- - Improved test reliability across Angular versions
1144
- - 🐛 **Bug Fixes**:
1145
- - Test suite configuration - added missing Zone.js polyfills for library tests
1146
- - Bundle analysis now correctly excludes source maps from size calculations
1147
- - Build warnings from conflicting export conditions resolved
1148
- - Source map removal script made more resilient for build environments
1149
-
1150
- ### **v1.9.1**
1151
-
1152
- - 🐛 Minor bug fixes and improvements
1153
-
1154
- ### **v1.9.0**
1155
-
1156
- - **Extension Points & Hooks**: system for customization
1157
- - ⌨️ **Enhanced Keyboard Shortcuts**: Y, N, W keys with custom shortcut support
1158
- - 🎨 **Modern UI/UX**: Improved animations and responsiveness
1159
- - 📚 **API Documentation**: TypeDoc integration
1160
- - 🤖 **Semantic Release**: Automated versioning and publishing
1161
- - 🚀 **Animation Performance**: Optimizations with GPU acceleration
1162
- - 🔍 **Global Search**: Functionality in documentation
1163
- - 📱 **Mobile Playground**: For responsive testing
1164
-
1165
- ### **v1.7.0**
1166
-
1167
- - 🎯 **Signal Forms Support**: Full Angular 21 signal forms integration with writable signals
1168
- - 🎨 **Tailwind Theming**: Added `classes` input for Tailwind CSS and custom class-based theming
1169
- - 🌍 **Localization Improvements**: Added `weekStart` input to override locale-based week start day
1170
- - 📅 **Year Range Configuration**: Added `yearRange` input to customize year dropdown range
1171
- - **Accessibility Enhancements**: Added customizable aria labels for all interactive elements
1172
- - 🏷️ **Custom Labels**: Added `clearLabel` and `closeLabel` inputs for button customization
1173
- - 🧪 **Comprehensive Test Suite**: Added 56 tests covering all features and edge cases
1174
- - 🐛 **Bug Fixes**: Fixed programmatic value setting and Angular 21 compatibility tests
1175
- - 🧹 **Code Cleanup**: Removed unnecessary files, folders, and comments from codebase
1176
- - 📝 **Test Improvements**: Enhanced test coverage with comprehensive feature tests
1177
- - 🔧 **Test Fixes**: Fixed disabled date tests and integration test issues
1178
- - 🎯 **Code Quality**: Improved code maintainability by removing redundant comments
1179
-
1180
- ### **v1.6.0**
1181
-
1182
- - 🎯 **Programmatic Value Setting**: Added `value` input property to set datepicker value programmatically, perfect for server-side API data integration
1183
- - 🎨 **Enhanced Demo App**: Completely redesigned demo application with TokiForge-inspired modern UI and API documentation style
1184
- - 🚀 **GitHub Pages Deployment**: Added automated GitHub Pages deployment with GitHub Actions workflow
1185
- - 📚 **Improved Documentation**: Enhanced demo app with comprehensive examples, code snippets, and interactive documentation
1186
- - 🔧 **Build Optimizations**: Updated CSS budget limits and improved build configuration
1187
- - 🎨 **Modern UI Design**: Beautiful gradient themes, glass-morphism effects, and improved visual hierarchy
1188
- - 📱 **Better UX**: Enhanced navigation, code copying functionality, and responsive design
1189
- - 🛠️ **Developer Experience**: Improved build scripts and deployment automation
1190
-
1191
- ### **v1.5.0**
1192
-
1193
- - 🚀 **Angular 21 Support**: Full compatibility with Angular 21 RC versions
1194
- - **Zone-less Support**: Works without zone.js for improved performance
1195
- - 🧪 **Comprehensive Tests**: Added extensive test suite covering all features
1196
- - 🔧 **Angular 17-21 Compatibility**: Supports Angular versions 17, 18, 19, 20, and 21
1197
- - 📦 **Dependency Updates**: Updated to Angular 21 RC and latest build tools
1198
- - 🧹 **Code Cleanup**: Removed unnecessary documentation files and comments
1199
- - 📝 **Improved Keywords**: Added version-specific keywords for better discoverability
1200
- - 🎯 **Peer Dependencies**: Updated to support Angular 17-21 range
1201
-
1202
- ### **v1.4.16**
1203
-
1204
- - 📚 **Documentation**: Comprehensive README updates with latest features and improvements
1205
- - 🎯 **Version Management**: Updated version references across all package files
1206
- - 📖 **User Experience**: Enhanced documentation with better examples and API references
1207
- - 🔧 **Maintenance**: Improved project structure and documentation consistency
1208
- - 📦 **Package Updates**: Synchronized version numbers across all package.json files
1209
- - 🎨 **Documentation**: Added detailed bug fixes and performance metrics
1210
- - 🚀 **Developer Experience**: Better setup instructions and contribution guidelines
1211
-
1212
- ### **v1.4.15**
1213
-
1214
- - 🐛 **Bug Fixes**: Fixed 10 critical bugs including change detection issues and date comparison errors
1215
- - ⚡ **Performance**: Enhanced OnPush change detection with proper triggers
1216
- - 🎯 **Memory Management**: Added cache size limits to prevent memory leaks
1217
- - 🔧 **Type Safety**: Improved TypeScript types and null safety
1218
- - 📱 **Mobile Optimization**: Enhanced mobile responsive design with touch-friendly interactions
1219
- - 🎨 **UI Improvements**: Better visual feedback and accessibility
1220
- - 🚀 **Build Optimization**: Improved build configuration and tree-shaking
1221
- - 🧹 **Code Quality**: Enhanced code maintainability and performance
1222
-
1223
- ### **v1.4.13**
1224
-
1225
- - 🚫 **Disabled Dates**: New `disabledDates` input property to disable specific dates
1226
- - 🎯 **Date String Support**: Supports both string dates (MM/DD/YYYY) and Date objects
1227
- - 💡 **Holiday Tooltips**: Hover over holiday dates to see holiday names as tooltips
1228
- - 🎨 **Enhanced UX**: Better visual feedback for disabled dates
1229
- - 📦 **Improved API**: More flexible date disabling options
1230
-
1231
- ### **v1.4.12**
1232
-
1233
- - **Instant Navigation**: Removed all animations for lightning-fast arrow navigation
1234
- - 🚫 **Smart Back Arrow**: Automatically disables back arrow when minDate is set
1235
- - 🎯 **Better UX**: Prevents navigation to invalid date ranges
1236
- - 🗓️ **Previous Month Days**: Now shows last few days of previous month for better context
1237
- - 🎨 **Enhanced Styling**: Improved visual hierarchy with better day cell sizing
1238
- - 🖱️ **Interactive Previous Days**: Previous month days are now selectable and interactive
1239
- - 🧹 **Code Optimization**: Cleaner, more maintainable codebase
1240
- - 📦 **Smaller Bundle**: Reduced CSS and JavaScript footprint
1241
-
1242
- ### **v1.4.11**
1243
-
1244
- - 🎨 **UI Improvements**: Enhanced day cell sizing and visual hierarchy
1245
- - 🖱️ **Better Interactions**: Improved click and hover states for previous month days
1246
-
1247
- ### **v1.4.10**
1248
-
1249
- - 🗓️ **Previous Month Display**: Added last few days of previous month for better context
1250
- - 🎯 **Smart Selection**: Previous month days are now selectable and interactive
1251
-
1252
- ### **v1.4.9**
1253
-
1254
- - 🚫 **Range Fix**: Fixed range highlighting on empty/previous month days
1255
- - 🎨 **Styling Updates**: Improved visual consistency across all day types
1256
-
1257
- ### **v1.4.8**
1258
-
1259
- - **Performance**: Optimized calendar generation and rendering
1260
- - 🧹 **Code Cleanup**: Removed unused animation code and improved maintainability
1261
-
1262
- ### **v1.4.6**
1263
-
1264
- - 🔧 **Fixed Import Paths**: Corrected package exports for proper module resolution
1265
- - 📦 **Better Package Structure**: Improved npm package configuration
1266
-
1267
- ### **v1.4.5**
1268
-
1269
- - 🐛 Bug fixes and stability improvements
1270
- - 🔧 Enhanced error handling
1271
- - 📱 Improved mobile responsiveness
1272
- - 🎨 Minor UI/UX improvements
1273
-
1274
- ### **v1.4.0**
1275
-
1276
- - ✅ Performance optimizations (30% smaller bundle)
1277
- - ✅ OnPush change detection strategy
1278
- - Memoized date comparisons
1279
- - ✅ Tree-shakable architecture
1280
- - Enhanced TypeScript support
1281
- - ✅ Improved accessibility
1282
- - Better mobile responsiveness
1283
-
1284
- ### **Previous Versions**
1285
-
1286
- - v1.3.5: Initial release with core features
1287
- - v1.3.4: Bug fixes and improvements
1288
- - v1.3.3: Holiday provider integration
1289
-
1290
- ## **🎨 Theming with TokiForge**
1291
-
1292
- Looking for a powerful theming solution for your Angular application? Check out **[TokiForge](https://tokiforge.github.io/tokiforge/)** an open-source modern design token & theme engine that provides runtime theme switching for React, Vue, Svelte, Angular, and any framework.
1293
-
1294
- ### Why TokiForge?
1295
-
1296
- - **Framework-agnostic** — Works with Angular, React, Vue, Svelte, and vanilla JS
1297
- - ✅ **Runtime theme switching** — Change themes dynamically without rebuilds
1298
- - **Type-safe** — Full TypeScript support for design tokens
1299
- - ✅ **Lightweight** — <3 KB gzipped runtime footprint
1300
- - **CSS custom properties** — Zero JS overhead in static mode
1301
- - **SSR compatible** — Works seamlessly with Angular Universal
1302
-
1303
- Perfect for managing design tokens, creating theme systems, and implementing dark mode in your Angular applications!
1304
-
1305
- **👉 [Learn more about TokiForge →](https://tokiforge.github.io/tokiforge/)**
1306
-
1307
- ---
1308
-
1309
- ## **📜 License**
1310
-
1311
- MIT License - see [LICENSE](https://github.com/NGXSMK/ngxsmk-datepicker/blob/main/LICENSE) file for details.
1312
-
1313
- ## **🔍 SEO & Discoverability**
1314
-
1315
- This library is optimized for search engine visibility, especially for European markets:
1316
-
1317
- - **Keywords**: Angular datepicker, date range picker, calendar component, Angular 17-21, TypeScript, Signal Forms, SSR compatible
1318
- - **European SEO**: Optimized for Germany, France, Spain, Italy, Netherlands, Poland, Portugal, Sweden, Norway, Finland, Denmark, Belgium, Switzerland, Austria, and United Kingdom
1319
- - **Multi-language Support**: hreflang tags for 15+ European languages and locales
1320
- - **European Geo-targeting**: Geo tags and structured data optimized for European Union countries
1321
- - **Meta Tags**: Comprehensive Open Graph and Twitter Card support with European locale alternates
1322
- - **Structured Data**: JSON-LD schema markup with European audience targeting and area served information
1323
- - **Documentation**: Complete API documentation with examples
1324
- - **Performance**: Optimized bundle size (~127KB) for fast loading
1325
- - **European Localization**: Full i18n support for European date formats, week start days, and regional preferences
1326
-
1327
- ## **👨‍💻 Author**
1328
-
1329
- **Sachin Dilshan**
1330
-
1331
- - 📧 Email: [sachindilshan040@gmail.com](mailto:sachindilshan040@gmail.com)
1332
- - 🐙 GitHub: [@toozuuu](https://github.com/toozuuu)
1333
- - 📦 NPM: [ngxsmk-datepicker](https://www.npmjs.com/package/ngxsmk-datepicker)
1334
- - 💼 LinkedIn: [sachindilshan](https://www.linkedin.com/in/sachindilshan/)
1335
-
1336
- ## **⭐ Support**
1337
-
1338
- If you find this library helpful, please consider:
1339
-
1340
- - ⭐ **Starring** the repository
1341
- - 🐛 **Reporting** bugs and issues
1342
- - 💡 **Suggesting** new features
1343
- - 🤝 **Contributing** code improvements
1344
- - 📢 **Sharing** with the community
1
+ <!--
2
+ SEO Keywords: Angular DatePicker, Angular Date Range Picker, Lightweight Calendar Component, Angular Signals DatePicker, SSR Ready DatePicker, Zoneless Angular, A11y DatePicker, Mobile-Friendly DatePicker, Ionic DatePicker
3
+ Meta Description: The most powerful, lightweight, and accessible date and range picker for modern Angular (17-21+). Built with Signals, Zoneless-ready, and zero dependencies.
4
+ -->
5
+
6
+ <div align="center">
7
+ <img src="projects/ngxsmk-datepicker/docs/header-banner.png" alt="ngxsmk-datepicker - Lightweight Angular Date Range Picker" width="100%" />
8
+
9
+ # **ngxsmk-datepicker** – Modern Angular Date Picker & Range Picker
10
+
11
+ ### _The Gold Standard for Premium Angular Calendar Selection_
12
+
13
+ [![npm version](https://img.shields.io/npm/v/ngxsmk-datepicker.svg?style=flat-square&color=6d28d9)](https://www.npmjs.com/package/ngxsmk-datepicker)
14
+ [![Angular](https://img.shields.io/badge/Angular-17%2B-DD0031.svg?style=flat-square&logo=angular)](https://angular.io/)
15
+ [![License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square)](https://github.com/NGXSMK/ngxsmk-datepicker/blob/main/LICENSE)
16
+ [![Bundle Size](https://img.shields.io/badge/bundle-~127KB-success.svg?style=flat-square)](https://bundlephobia.com/package/ngxsmk-datepicker)
17
+ [![Zoneless](https://img.shields.io/badge/Zoneless-Ready-blueviolet.svg?style=flat-square)](https://angular.dev/guide/zoneless)
18
+
19
+ **`npm i ngxsmk-datepicker`**
20
+
21
+ [Explore Live Demo](https://ngxsmk.github.io/ngxsmk-datepicker/) • [API Documentation](https://github.com/NGXSMK/ngxsmk-datepicker/blob/main/projects/ngxsmk-datepicker/docs/API.md) • [Submit Issue](https://github.com/NGXSMK/ngxsmk-datepicker/issues)
22
+
23
+ </div>
24
+
25
+ ---
26
+
27
+ **Last updated:** March 3, 2026 · **Current stable:** v2.2.2
28
+
29
+ ### **Overview**
30
+
31
+ **ngxsmk-datepicker** is a high-performance, enterprise-ready date and range picker engineered for the modern Angular ecosystem (v17+). Built from the ground up with **Angular Signals**, it delivers a seamless, zoneless-ready experience for both desktop and mobile (Ionic) applications.
32
+
33
+ > **Stable Release**: `v2.2.2` is live! This release brings a **TypeScript Strictness Overhaul** (eliminating `any` types and ensuring `exactOptionalPropertyTypes` compatibility), fixes **appendToBody** popover positioning, datepicker-in-modal first-open, and popover width matching the input; reduces loading time; and cleans up CSS. No breaking changes.
34
+ >
35
+ > ⚠️ **Important**: Versions 2.0.10 and 2.0.11 are broken and have been unpublished. Please use v2.2.2 or later.
36
+
37
+ ---
38
+
39
+ ### **📌 Table of Contents**
40
+
41
+ 1. [📷 Screenshots](#-screenshots)
42
+ 2. [✨ Features](#-features)
43
+ 3. [📋 Compatibility](#-compatibility)
44
+ 4. [🌍 Localization (i18n)](#-localization-i18n)
45
+ 5. [📦 Installation](#-installation)
46
+ 6. [🚀 Quick Start](#-quick-start)
47
+ 7. [🔌 Framework Integration](#-framework-integration)
48
+ 8. [⚙️ API Reference](#-api-reference)
49
+ 9. [🎨 Theming](#-theming)
50
+ 10. [⌨️ Keyboard Navigation](#-keyboard-navigation)
51
+
52
+ ---
53
+
54
+ ## 📷 Screenshots
55
+
56
+ <p align="center">
57
+ <img src="https://github.com/NGXSMK/ngxsmk-datepicker/raw/main/projects/ngxsmk-datepicker/docs/1.png" alt="Angular Standalone DatePicker Single Selection Mode" width="30%" />
58
+ <img src="https://github.com/NGXSMK/ngxsmk-datepicker/raw/main/projects/ngxsmk-datepicker/docs/2.png" alt="Angular Date Range Picker Selection Mode" width="30%" />
59
+ <img src="https://github.com/NGXSMK/ngxsmk-datepicker/raw/main/projects/ngxsmk-datepicker/docs/3.png" alt="Mobile Angular DatePicker Ionic Compatibility" width="30%" />
60
+ </p>
61
+
62
+ ## **✨ Features**
63
+
64
+ ### **Core Capabilities**
65
+
66
+ - 💎 **Signal-Driven Engine**: Hyper-reactive state management using Angular Signals.
67
+ - 🌓 **Native Dark Mode**: Beautifully crafted themes for light and dark environments.
68
+ - 📱 **Mobile-First UX**: Native mobile picker integration with touch gestures and haptic feedback.
69
+ - 🧩 **Zero Dependencies**: Lightweight standalone component with no external bloat.
70
+ - ⚡ **Performance++**: Lazy-loaded calendar months, memoized calculations, and tree-shakable architecture.
71
+
72
+ ### **Advanced Functionality**
73
+
74
+ - 📅 **Google Calendar Sync**: Built-in support for seamlessly syncing and displaying events natively from Google Calendar.
75
+ - 🌐 **8-Language i18n**: Full localization for `en`, `de`, `es`, `sv`, `ko`, `zh`, `ja`, and `fr`.
76
+ - 🛠️ **Plugin Architecture**: Extend functionality via hooks for rendering, validation, and shortcuts.
77
+ - 🧪 **Signal Forms Native**: Direct integration with Angular 21's new Signal Forms API.
78
+ - 🚀 **Zoneless Ready**: Optimized for the future of Angular—works perfectly without zone.js.
79
+ - ♿ **Full Accessibility**: WAI-ARIA compliant with extensive keyboard navigation support.
80
+
81
+ ## **📋 Compatibility**
82
+
83
+ For detailed compatibility information, see [COMPATIBILITY.md](https://github.com/NGXSMK/ngxsmk-datepicker/blob/main/projects/ngxsmk-datepicker/docs/COMPATIBILITY.md).
84
+
85
+ ### Quick Reference
86
+
87
+ | Angular Version | Status | Core Features | Signal Forms | SSR | Zoneless |
88
+ | --------------- | ------------------ | ------------- | ------------ | --- | -------- |
89
+ | Angular 17 | ✅ Fully Supported | ✅ All | ❌ | ✅ | ✅ |
90
+ | Angular 18 | ✅ Fully Supported | ✅ All | ❌ | ✅ | ✅ |
91
+ | Angular 19 | ✅ Fully Supported | ✅ All | ❌ | ✅ | ✅ |
92
+ | Angular 20 | ✅ Fully Supported | ✅ All | ❌ | ✅ | ✅ |
93
+ | Angular 21 | ✅ Fully Supported | ✅ All | ✅ | ✅ | ✅ |
94
+ | Angular 22+ | 🔄 Future Support | ✅ All | ✅ | ✅ | ✅ |
95
+
96
+ **Zone.js**: Optional - The library works with or without Zone.js (zoneless apps supported)
97
+
98
+ **SSR**: ✅ Fully compatible with Angular Universal and server-side rendering
99
+
100
+ **Peer Dependencies**: `@angular/core >=17.0.0 <24.0.0`
101
+
102
+ ## **🔒 API Stability & Deprecation Policy**
103
+
104
+ ### API Stability Guarantees
105
+
106
+ - **Public API**: All public APIs (inputs, outputs, methods) are stable within a major version
107
+ - **Experimental Features**: Features marked as `experimental` may change in minor versions
108
+ - **Internal APIs**: Private methods and internal services are not part of the public API and may change without notice
109
+
110
+ ### Deprecation Policy
111
+
112
+ - **Deprecation Period**: Features are deprecated for at least **2 major versions** before removal
113
+ - **Deprecation Warnings**:
114
+ - `@deprecated` JSDoc tags in code
115
+ - Console warnings in development mode
116
+ - Clear documentation in CHANGELOG.md
117
+ - **Migration Guides**: Provided in `MIGRATION.md` for all breaking changes
118
+ - **Breaking Changes**: Only occur in major version releases (semver)
119
+
120
+ ### Stable APIs
121
+
122
+ The following are considered stable public APIs:
123
+
124
+ - Component inputs and outputs (`@Input()`, `@Output()`)
125
+ - Public methods documented in API docs
126
+ - Exported types and interfaces
127
+ - Service APIs (when marked as public)
128
+
129
+ ### Experimental Features
130
+
131
+ Features marked as experimental may change:
132
+
133
+ - Signal Forms support (`[field]` input) - Experimental in v1.9.x, stable in v2.0.0+
134
+ - Some advanced selection modes
135
+ - Plugin architecture hooks (subject to refinement)
136
+
137
+ For details, see [CONTRIBUTING.md](https://github.com/NGXSMK/ngxsmk-datepicker/blob/main/CONTRIBUTING.md#deprecation-policy).
138
+
139
+ ## **🚀 Installation**
140
+
141
+ Install the package using npm:
142
+
143
+ ```bash
144
+ npm install ngxsmk-datepicker@latest
145
+ ```
146
+
147
+ ### Alternative installation
148
+
149
+ You can install without npm using Yarn, pnpm, Bun, from Git, a local path, or via CDN (ESM). Peer dependencies must still be installed in your app. For all options and caveats, see [INSTALLATION.md](../../docs/INSTALLATION.md) in the repo root.
150
+
151
+ ## **Usage**
152
+
153
+ ngxsmk-datepicker is a standalone component, so you can import it directly into your component or module. If you see **NG1010** (`'imports' must be an array... Value could not be determined statically`) when using the Angular compiler plugin or in strict AOT builds, use `NgxsmkDatepickerModule` in your `imports` array instead of `NgxsmkDatepickerComponent` (same template: `<ngxsmk-datepicker>`).
154
+
155
+ ### Signal Forms (Angular 21)
156
+
157
+ You can bind directly to a writable Signal using standard two-way binding. This works seamlessly alongside traditional Reactive Forms.
158
+
159
+ ```ts
160
+ import { signal } from "@angular/core";
161
+ import { DatepickerValue } from "ngxsmk-datepicker";
162
+
163
+ export class MyComponent {
164
+ dateSig = signal<DatepickerValue>(null);
165
+ }
166
+ ```
167
+
168
+ ```html
169
+ <ngxsmk-datepicker mode="single" [value]="dateSig()" (valueChange)="dateSig.set($event)"> </ngxsmk-datepicker>
170
+
171
+ <p>Signal value: {{ dateSig() | json }}</p>
172
+ ```
173
+
174
+ This pattern is also compatible with computed/linked signals produced by `httpResource`, enabling powerful data flows with Angular 21.
175
+
176
+ ### Signal Forms with `[field]` Input (Angular 21+)
177
+
178
+ For direct integration with Angular Signal Forms, use the `[field]` input. The datepicker automatically tracks dirty state when using this binding:
179
+
180
+ ```typescript
181
+ import { Component, signal, form, objectSchema } from "@angular/core";
182
+ import { NgxsmkDatepickerComponent } from "ngxsmk-datepicker";
183
+
184
+ @Component({
185
+ selector: "app-form",
186
+ standalone: true,
187
+ imports: [NgxsmkDatepickerComponent],
188
+ template: `
189
+ <form>
190
+ <ngxsmk-datepicker [field]="myForm.dateInQuestion" mode="single" placeholder="Select a date"> </ngxsmk-datepicker>
191
+ </form>
192
+ `,
193
+ })
194
+ export class FormComponent {
195
+ localObject = signal({ dateInQuestion: new Date() });
196
+
197
+ myForm = form(
198
+ this.localObject,
199
+ objectSchema({
200
+ dateInQuestion: objectSchema<Date>(),
201
+ }),
202
+ );
203
+ }
204
+ ```
205
+
206
+ The `[field]` input provides automatic two-way binding with signal forms - no manual event handling needed! It also automatically tracks the form's dirty state, so `form().dirty()` will return `true` after a user selects a date.
207
+
208
+ For detailed Signal Forms integration including dirty state tracking, see the [Signal Forms Integration Guide](https://github.com/NGXSMK/ngxsmk-datepicker/blob/main/projects/ngxsmk-datepicker/docs/signal-forms.md).
209
+
210
+ ### Documentation
211
+
212
+ - **[Plugin Architecture](https://github.com/NGXSMK/ngxsmk-datepicker/blob/main/projects/ngxsmk-datepicker/docs/PLUGIN-ARCHITECTURE.md)** - Complete guide to the plugin architecture and hook system
213
+ - **[Signals Integration Guide](https://github.com/NGXSMK/ngxsmk-datepicker/blob/main/projects/ngxsmk-datepicker/docs/signals.md)** - Complete guide to using signals with the datepicker
214
+ - **[Signal Forms Guide](https://github.com/NGXSMK/ngxsmk-datepicker/blob/main/projects/ngxsmk-datepicker/docs/signal-forms.md)** - Deep dive into Signal Forms integration
215
+ - **[SSR Guide](https://github.com/NGXSMK/ngxsmk-datepicker/blob/main/projects/ngxsmk-datepicker/docs/ssr.md)** - Server-side rendering setup and best practices
216
+ - **[SSR Example](https://github.com/NGXSMK/ngxsmk-datepicker/blob/main/projects/ngxsmk-datepicker/docs/SSR-EXAMPLE.md)** - Complete Angular Universal example with hydration notes
217
+ - **[Extension Points Guide](https://github.com/NGXSMK/ngxsmk-datepicker/blob/main/projects/ngxsmk-datepicker/docs/extension-points.md)** - Customization hooks and extension points
218
+ - **[Theme Tokens Reference](https://github.com/NGXSMK/ngxsmk-datepicker/blob/main/projects/ngxsmk-datepicker/docs/THEME-TOKENS.md)** - Complete CSS custom properties reference with examples
219
+ - **[API Documentation](https://github.com/NGXSMK/ngxsmk-datepicker/blob/main/projects/ngxsmk-datepicker/docs/API.md)** - Complete public API reference
220
+
221
+ #### **1. Import the Component**
222
+
223
+ In your component file (e.g., app.component.ts), import NgxsmkDatepickerComponent.
224
+
225
+ import { Component } from '@angular/core';
226
+ import { NgxsmkDatepickerComponent, DateRange, HolidayProvider } from 'ngxsmk-datepicker';
227
+
228
+ @Component({
229
+ selector: 'app-root',
230
+ standalone: true,
231
+ imports: [NgxsmkDatepickerComponent],
232
+ templateUrl: './app.component.html',
233
+ })
234
+ export class AppComponent {
235
+ // Example for predefined ranges
236
+ public myRanges: DateRange = {
237
+ 'Today': [new Date(), new Date()],
238
+ 'Last 7 Days': [new Date(new Date().setDate(new Date().getDate() - 6)), new Date()],
239
+ 'This Month': [new Date(new Date().getFullYear(), new Date().getMonth(), 1), new Date(new Date().getFullYear(), new Date().getMonth() + 1, 0)],
240
+ };
241
+
242
+ // Example for disabling weekends
243
+ isWeekend = (date: Date): boolean => {
244
+ const day = date.getDay();
245
+ return day === 0 || day === 6; // Sunday or Saturday
246
+ };
247
+
248
+ onDateChange(value: Date | { start: Date; end: Date } | Date[]) {
249
+ console.log('Date changed:', value);
250
+ }
251
+ }
252
+
253
+ #### **2. Add it to Your Template**
254
+
255
+ Use the `<ngxsmk-datepicker>` selector in your HTML template.
256
+
257
+ ````html
258
+ <h2>Advanced Date Range Picker</h2>
259
+
260
+ <ngxsmk-datepicker [mode]="'range'" [ranges]="myRanges" [showTime]="true" [minuteInterval]="15" [minDate]="today" [isInvalidDate]="isWeekend" [locale]="'en-US'" [theme]="'light'" [inline]="'auto'" (valueChange)="onDateChange($event)"></ngxsmk-datepicker>
261
+
262
+ #### **3. Disabled Dates Example** Disable specific dates by passing an array of date strings or Date objects: ```typescript // In your component disabledDates = ['10/21/2025', '08/21/2025', '10/15/2025', '10/8/2025', '10/3/2025']; // In your template
263
+ <ngxsmk-datepicker [mode]="'single'" [disabledDates]="disabledDates" placeholder="Select a date"> </ngxsmk-datepicker>
264
+ ````
265
+
266
+ #### **4. Holiday Tooltips Example**
267
+
268
+ Holiday dates automatically show tooltips when you hover over them:
269
+
270
+ ```typescript
271
+ // Holiday provider with tooltips
272
+ class MyHolidayProvider implements HolidayProvider {
273
+ private holidays: { [key: string]: string } = {
274
+ '2025-01-01': 'New Year\'s Day',
275
+ '2025-07-04': 'Independence Day',
276
+ '2025-12-25': 'Christmas Day',
277
+ };
278
+
279
+ isHoliday(date: Date): boolean {
280
+ const key = this.formatDateKey(date);
281
+ return !!this.holidays[key];
282
+ }
283
+
284
+ getHolidayLabel(date: Date): string | null {
285
+ const key = this.formatDateKey(date);
286
+ return this.holidays[key] || null;
287
+ }
288
+ }
289
+
290
+ // In your template
291
+ <ngxsmk-datepicker
292
+ [holidayProvider]="holidayProvider"
293
+ [disableHolidays]="false"
294
+ placeholder="Hover over holidays to see tooltips">
295
+ </ngxsmk-datepicker>
296
+ ```
297
+
298
+ ## **🔌 Framework Integration**
299
+
300
+ ### **Angular Material Form Fields**
301
+
302
+ Integrate with Angular Material's form field components for a seamless Material Design experience. Works with both standalone and non-standalone components:
303
+
304
+ **Standalone Components:**
305
+
306
+ ```typescript
307
+ import { Component } from "@angular/core";
308
+ import { FormControl, FormGroup, ReactiveFormsModule } from "@angular/forms";
309
+ import { MatFormFieldModule } from "@angular/material/form-field";
310
+ import { MatInputModule } from "@angular/material/input";
311
+ import { NgxsmkDatepickerComponent } from "ngxsmk-datepicker";
312
+
313
+ @Component({
314
+ selector: "app-material-form",
315
+ standalone: true,
316
+ imports: [ReactiveFormsModule, MatFormFieldModule, MatInputModule, NgxsmkDatepickerComponent],
317
+ template: `
318
+ <form [formGroup]="myForm">
319
+ <mat-form-field appearance="outline">
320
+ <mat-label>Select Date</mat-label>
321
+ <ngxsmk-datepicker mode="single" formControlName="date" placeholder="Choose a date"> </ngxsmk-datepicker>
322
+ </mat-form-field>
323
+ </form>
324
+ `,
325
+ })
326
+ export class MaterialFormComponent {
327
+ myForm = new FormGroup({
328
+ date: new FormControl<Date | null>(null),
329
+ });
330
+ }
331
+ ```
332
+
333
+ **Non-Standalone (NgModules):** Add the directive file from [INTEGRATION.md § Angular Material](docs/INTEGRATION.md#angular-material), then add it to your module `imports` (with `NgxsmkDatepickerComponent`, `MatFormFieldModule`, etc.) and use `ngxsmkMatFormFieldControl` on the datepicker in templates.
334
+
335
+ **With Date Range:**
336
+
337
+ ```html
338
+ <mat-form-field appearance="fill">
339
+ <mat-label>Date Range</mat-label>
340
+ <ngxsmk-datepicker mode="range" [showTime]="true" formControlName="dateRange"> </ngxsmk-datepicker>
341
+ </mat-form-field>
342
+ ```
343
+
344
+ ### **Ionic Components**
345
+
346
+ For best integration with Ionic, import the integration styles in your global CSS/SCSS file:
347
+
348
+ ```css
349
+ @import "ngxsmk-datepicker/styles/ionic-integration.css";
350
+ ```
351
+
352
+ Works seamlessly with Ionic form components and follows Ionic design patterns:
353
+
354
+ ```typescript
355
+ import { Component } from "@angular/core";
356
+ import { FormControl, FormGroup, ReactiveFormsModule } from "@angular/forms";
357
+ import { IonItem, IonLabel, IonInput } from "@ionic/angular/standalone";
358
+ import { NgxsmkDatepickerComponent } from "ngxsmk-datepicker";
359
+
360
+ @Component({
361
+ selector: "app-ionic-form",
362
+ standalone: true,
363
+ imports: [ReactiveFormsModule, IonItem, IonLabel, IonInput, NgxsmkDatepickerComponent],
364
+ template: `
365
+ <form [formGroup]="myForm">
366
+ <ion-item>
367
+ <ion-label position="stacked">Appointment Date</ion-label>
368
+ <ngxsmk-datepicker mode="single" formControlName="appointmentDate" placeholder="Select date"> </ngxsmk-datepicker>
369
+ </ion-item>
370
+ </form>
371
+ `,
372
+ })
373
+ export class IonicFormComponent {
374
+ myForm = new FormGroup({
375
+ appointmentDate: new FormControl<Date | null>(null),
376
+ });
377
+ }
378
+ ```
379
+
380
+ **With Ionic Datetime Styling:**
381
+
382
+ ```html
383
+ <ion-item>
384
+ <ion-label>Check-in / Check-out</ion-label>
385
+ <ngxsmk-datepicker mode="range" [theme]="'light'" formControlName="bookingDates"> </ngxsmk-datepicker>
386
+ </ion-item>
387
+ ```
388
+
389
+ ### **React, Vue, & Vanilla JS (Web Components)**
390
+
391
+ Because `ngxsmk-datepicker` is highly decoupled from heavy external dependencies, it can be exported as a standard Custom Web Component using Angular Elements. This allows you to use exactly the same datepicker in React, Vue, Svelte, or Vanilla JavaScript projects seamlessly!
392
+
393
+ **1. Create a Custom Element Wrapper**
394
+ ```typescript
395
+ import { createApplication } from '@angular/platform-browser';
396
+ import { createCustomElement } from '@angular/elements';
397
+ import { NgxsmkDatepickerComponent } from 'ngxsmk-datepicker';
398
+
399
+ (async () => {
400
+ const app = await createApplication();
401
+ const DatepickerElement = createCustomElement(NgxsmkDatepickerComponent, { injector: app.injector });
402
+ customElements.define('ngxsmk-datepicker', DatepickerElement);
403
+ })().catch(console.error);
404
+ ```
405
+
406
+ **2. Use It Natively Anywhere**
407
+ ```html
408
+ <!-- In any HTML, React, Vue, or Svelte file -->
409
+ <ngxsmk-datepicker id="myPicker" mode="range" theme="light"></ngxsmk-datepicker>
410
+
411
+ <script>
412
+ // Add native DOM event listeners
413
+ document.getElementById('myPicker').addEventListener('dateSelect', (e) => {
414
+ console.log('Selected date:', e.detail);
415
+ });
416
+ </script>
417
+ ```
418
+
419
+ For full working examples (including React & Vue bindings), check out the `/examples` directory in our GitHub repository!
420
+
421
+ ### **Plain HTML Inputs**
422
+
423
+ Use with standard HTML form inputs for maximum flexibility:
424
+
425
+ ```typescript
426
+ import { Component } from "@angular/core";
427
+ import { FormControl, FormGroup, ReactiveFormsModule } from "@angular/forms";
428
+ import { NgxsmkDatepickerComponent } from "ngxsmk-datepicker";
429
+
430
+ @Component({
431
+ selector: "app-plain-form",
432
+ standalone: true,
433
+ imports: [ReactiveFormsModule, NgxsmkDatepickerComponent],
434
+ template: `
435
+ <form [formGroup]="myForm">
436
+ <label for="birthdate">Birth Date</label>
437
+ <ngxsmk-datepicker id="birthdate" mode="single" formControlName="birthdate" placeholder="MM/DD/YYYY"> </ngxsmk-datepicker>
438
+
439
+ <button type="submit">Submit</button>
440
+ </form>
441
+ `,
442
+ })
443
+ export class PlainFormComponent {
444
+ myForm = new FormGroup({
445
+ birthdate: new FormControl<Date | null>(null),
446
+ });
447
+ }
448
+ ```
449
+
450
+ **With Native HTML5 Validation:**
451
+
452
+ ```html
453
+ <form [formGroup]="myForm">
454
+ <div class="form-group">
455
+ <label for="event-date">Event Date *</label>
456
+ <ngxsmk-datepicker id="event-date" mode="single" formControlName="eventDate" [minDate]="today" required> </ngxsmk-datepicker>
457
+ </div>
458
+ </form>
459
+ ```
460
+
461
+ ### **Form Validation**
462
+
463
+ By default, the datepicker input is `readonly` to prevent invalid date strings and force selection via the calendar. However, **browsers do not validate `readonly` fields** during native form submission.
464
+
465
+ **Behavior:**
466
+
467
+ - Native browser validation (e.g., blocking submit on `required` fields) will **NOT** trigger on the datepicker by default.
468
+ - Custom validation (e.g., Angular validators) works normally but often only shows errors after the control is "touched".
469
+
470
+ **Solutions:**
471
+
472
+ 1. **Enable Typing (Recommended for Native Validation):**
473
+ Set `[allowTyping]="true"` to make the input standard editable field. This enables native browser validation tooltips and submit-blocking.
474
+
475
+ ```html
476
+ <ngxsmk-datepicker [allowTyping]="true" required ...></ngxsmk-datepicker>
477
+ ```
478
+
479
+ 2. **Custom Validation Logic:**
480
+ If you prefer the readonly behavior, ensure your form submission handler explicitly checks `form.invalid` before proceeding, as the browser won't stop the submit button click.
481
+
482
+ ## **⚙️ API Reference**
483
+
484
+ ### **Inputs**
485
+
486
+ | Property | Type | Default | Description |
487
+ | :----------------- | :--- | :------ | :---------- |
488
+ | mode | 'single' \| 'range' \| 'multiple' | 'single' | The selection mode. |
489
+ | inline | boolean \| 'always' \| 'auto' | false | Controls the display mode. `true` or `'always'` for inline, `'auto'` for responsive. |
490
+ | locale | string | navigator.language | Sets the locale for language and regional formatting (e.g., 'en-US', 'de-DE'). |
491
+ | theme | 'light' \| 'dark' | 'light' | The color theme. |
492
+ | showRanges | boolean | true | If true, displays the predefined ranges panel when in 'range' mode. |
493
+ | minDate | DateInput | null | The earliest selectable date. |
494
+ | maxDate | DateInput | null | The latest selectable date. |
495
+ | isInvalidDate | (date: Date) => boolean | () => false | A function to programmatically disable specific dates. |
496
+ | ranges | DateRange | null | An object of predefined date ranges. |
497
+ | minuteInterval | number | 1 | Interval for minute dropdown options. |
498
+ | showTime | boolean | false | Enables the hour/minute/AM/PM selection section. |
499
+ | timeOnly | boolean | false | Display time picker only (no calendar). Automatically enables `showTime`. |
500
+ | use24Hour | boolean | false | Enable 24-hour time format (00-23) and hide AM/PM selector. |
501
+ | allowTyping | boolean | false | Enable manual typing in the input field. Required for native validation. |
502
+ | displayFormat | string | null | Custom date format string (e.g., 'MM/DD/YYYY'). |
503
+ | showCalendarButton | boolean | false | Show/hide the calendar icon button. |
504
+ | value | DatepickerValue | null | Programmatic value setting from code. |
505
+ | startAt | DateInput | null | The date to initially center the calendar view on. |
506
+ | holidayProvider | HolidayProvider | null | An object that provides holiday information. |
507
+ | disableHolidays | boolean | false | If true, disables holiday dates from being selected. |
508
+ | disabledDates | (string \| Date)[] | [] | Array of dates to disable. |
509
+ | weekStart | number \| null | null | Override week start day (0=Sunday, 1=Monday, etc.). |
510
+ | yearRange | number | 10 | Number of years before/after current year to show in year dropdown. |
511
+ | clearLabel | string | 'Clear' | Custom label for the clear button. |
512
+ | closeLabel | string | 'Close' | Custom label for the close button. |
513
+ | prevMonthAriaLabel | string | 'Previous month' | Aria label for previous month navigation button. |
514
+ | nextMonthAriaLabel | string | 'Next month' | Aria label for next month navigation button. |
515
+ | clearAriaLabel | string | 'Clear selection' | Aria label for clear button. |
516
+ | closeAriaLabel | string | 'Close calendar' | Aria label for close button. |
517
+ | classes | object | undefined | Tailwind-friendly class overrides (wrapper, input, popover, etc.). |
518
+ | enableGoogleCalendar| boolean | false | Enable seamless Google Calendar integration and sync. |
519
+ | googleClientId | string \| null | null | Google API OAuth 2.0 Web Client ID for authentication. |
520
+
521
+ ### **Outputs**
522
+
523
+ | Event | Payload | Description |
524
+ | :---------- | :------------------------------ | :------------------------------------------------------------ |
525
+ | valueChange | DatepickerValue | Emits the newly selected date, range, or array of dates. |
526
+ | action | { type: string; payload?: any } | Emits various events like `dateSelected`, `timeChanged`, etc. |
527
+ | googleSyncClick | void | Emitted when the user clicks the Google Calendar sync button. |
528
+
529
+ ## **🎨 Theming**
530
+
531
+ ### CSS Variables
532
+
533
+ You can easily customize the colors of the datepicker by overriding the CSS custom properties in your own stylesheet.
534
+
535
+ ```css
536
+ ngxsmk-datepicker {
537
+ --datepicker-primary-color: #d9267d;
538
+ --datepicker-primary-contrast: #ffffff;
539
+ --datepicker-range-background: #fce7f3;
540
+ }
541
+ ```
542
+
543
+ ### Tailwind/ngClass Support
544
+
545
+ For Tailwind CSS or custom class-based theming, use the `classes` input:
546
+
547
+ ```html
548
+ <ngxsmk-datepicker
549
+ mode="single"
550
+ [classes]="{
551
+ inputGroup: 'rounded-lg border',
552
+ input: 'px-3 py-2 text-sm',
553
+ popover: 'shadow-2xl',
554
+ dayCell: 'hover:bg-indigo-50',
555
+ footer: 'flex justify-end gap-2',
556
+ clearBtn: 'btn btn-ghost',
557
+ calendarBtn: 'btn btn-icon',
558
+ closeBtn: 'btn btn-primary'
559
+ }"
560
+ >
561
+ </ngxsmk-datepicker>
562
+ ```
563
+
564
+ ### Dark Theme
565
+
566
+ To enable the dark theme, simply bind the theme input:
567
+
568
+ ```html
569
+ <ngxsmk-datepicker [theme]="'dark'"></ngxsmk-datepicker>
570
+ ```
571
+
572
+ ### Calendar Button Visibility
573
+
574
+ Control the visibility of the calendar icon button:
575
+
576
+ ```html
577
+ <!-- Hide calendar button (default - users can still click input to open calendar) -->
578
+ <ngxsmk-datepicker mode="single"> </ngxsmk-datepicker>
579
+
580
+ <!-- Show calendar button -->
581
+ <ngxsmk-datepicker [showCalendarButton]="true" mode="single"> </ngxsmk-datepicker>
582
+
583
+ <!-- Useful with allowTyping for custom UI -->
584
+ <ngxsmk-datepicker [allowTyping]="true" [showCalendarButton]="false" mode="single"> </ngxsmk-datepicker>
585
+ ```
586
+
587
+ ## **🌍 Localization (i18n)**
588
+
589
+ The `locale` input controls all internationalization. It automatically formats month names, weekday names, and sets the first day of the week based on BCP 47 language tags.
590
+
591
+ ### **Global Language Support**
592
+
593
+ ngxsmk-datepicker v2.2.2 now features **full localization synchronization** for:
594
+
595
+ - 🇺🇸 English (`en`)
596
+ - 🇩🇪 German (`de`)
597
+ - 🇫🇷 French (`fr`)
598
+ - 🇪🇸 Spanish (`es`)
599
+ - 🇸🇪 Swedish (`sv`)
600
+ - 🇰🇷 Korean (`ko`)
601
+ - 🇨🇳 Chinese (`zh`)
602
+ - 🇯🇵 Japanese (`ja`)
603
+
604
+ ### **Usage Example**
605
+
606
+ ```html
607
+ <!-- Force German Locale -->
608
+ <ngxsmk-datepicker [locale]="'de-DE'"></ngxsmk-datepicker>
609
+
610
+ <!-- Swedish with YYYY-MM-DD format and Monday week start -->
611
+ <ngxsmk-datepicker [locale]="'sv-SE'"></ngxsmk-datepicker>
612
+ ```
613
+
614
+ The component automatically uses ISO 8601 standards (Monday start) for European locales and appropriate regional date formats.
615
+
616
+ ## **🖥️ Server-Side Rendering (SSR)**
617
+
618
+ The datepicker is fully compatible with Angular Universal and server-side rendering:
619
+
620
+ - All browser APIs are platform-checked
621
+ - ✅ No `window` or `document` access during initialization
622
+ - Works with partial hydration
623
+ - ✅ Compatible with zoneless applications
624
+
625
+ See the [SSR Guide](./projects/ngxsmk-datepicker/docs/ssr.md) for detailed setup instructions.
626
+
627
+ ## **⌨️ Keyboard Navigation**
628
+
629
+ The datepicker supports full keyboard navigation for accessibility:
630
+
631
+ ### Built-in Shortcuts
632
+
633
+ - **Arrow Keys** (← → ↑ ↓): Navigate between dates
634
+ - **Page Up/Down**: Navigate months (Shift + Page Up/Down for years)
635
+ - **Home/End**: Jump to first/last day of month
636
+ - **Enter/Space**: Select focused date
637
+ - **Escape**: Close calendar (popover mode)
638
+ - **T**: Select today's date
639
+ - **Y**: Select yesterday
640
+ - **N**: Select tomorrow
641
+ - **W**: Select next week (7 days from today)
642
+ - **Tab**: Navigate between interactive elements
643
+ - **?** (Shift + /): Toggle keyboard shortcuts help dialog
644
+
645
+ ### Custom Keyboard Shortcuts
646
+
647
+ You can add custom keyboard shortcuts using the `hooks` input or `customShortcuts` input:
648
+
649
+ ```typescript
650
+ import { DatepickerHooks, KeyboardShortcutContext } from "ngxsmk-datepicker";
651
+
652
+ const myHooks: DatepickerHooks = {
653
+ handleShortcut: (event, context) => {
654
+ if (event.ctrlKey && event.key === "1") {
655
+ // Custom action
656
+ return true; // Handled
657
+ }
658
+ return false; // Use default
659
+ },
660
+ };
661
+ ```
662
+
663
+ ```html
664
+ <ngxsmk-datepicker [hooks]="myHooks" [customShortcuts]="shortcuts" mode="single"> </ngxsmk-datepicker>
665
+ ```
666
+
667
+ All date cells are keyboard accessible with proper ARIA attributes for screen readers.
668
+
669
+ See [Extension Points Guide](./projects/ngxsmk-datepicker/docs/extension-points.md) for detailed customization options.
670
+
671
+ ## **🚀 Performance Optimizations**
672
+
673
+ This library has been optimized for maximum performance:
674
+
675
+ - **30% Smaller Bundle**: Optimized build configuration and tree-shaking
676
+ - **40% Faster Rendering**: OnPush change detection strategy with proper triggers
677
+ - **60% Faster Selection**: Memoized date comparisons and debounced operations
678
+ - **Zero Dependencies**: Standalone component with no external dependencies
679
+ - **Tree-shakable**: Only import what you need
680
+ - **Memory Efficient**: Cache size limits prevent memory leaks
681
+ - **Hardware Accelerated**: CSS optimizations for smooth animations
682
+ - **Mobile Optimized**: Touch-friendly interactions and responsive design
683
+
684
+ ## **🐛 Bug Fixes & Improvements**
685
+
686
+ ### **Critical Updates in v2.2.2:**
687
+
688
+ - ✅ **Validation messages**: User-facing i18n strings for invalid date, min/max; `validationError` output and on-screen error display
689
+ - ✅ **Calendar loading state**: Visual spinner + text and screen-reader announcement while calendar opens/generates
690
+ - ✅ **Demo theme**: Light/dark theme toggle and system preference now correctly switch the demo UI
691
+ - ✅ **Installation options**: Full install guide (npm, Yarn, pnpm, Bun, Git, CDN, etc.) and demo page updates
692
+ - ✅ **Accessibility**: Loading state announced via live region; validation errors exposed for a11y
693
+ - **Type Safety**: New translation keys and strictly typed inputs/outputs
694
+
695
+ ### **Performance Enhancements:**
696
+
697
+ - 🚀 **Optimized Bundle Size**: Main bundle ~127KB (source maps excluded from published package)
698
+ - 🚀 **40% Faster Rendering**: Enhanced OnPush change detection
699
+ - 🚀 **60% Faster Selection**: Memoized date comparisons
700
+ - 🚀 **Memory Efficient**: Cache size limits prevent memory leaks
701
+ - 🚀 **Hardware Accelerated**: CSS optimizations for smooth animations
702
+ - 🚀 **Better Tree-Shaking**: Optimized TypeScript compiler settings for smaller output
703
+ - 🚀 **Production Optimized**: Source maps automatically removed from production builds
704
+
705
+ ## **📱 Demo Application**
706
+
707
+ A comprehensive demo application is included to showcase all features with a modern, polished UI:
708
+
709
+ ```bash
710
+ # Clone the repository
711
+ git clone https://github.com/NGXSMK/ngxsmk-datepicker.git
712
+ cd ngxsmk-datepicker
713
+
714
+ # Install dependencies
715
+ npm install
716
+
717
+ # Run the demo app
718
+ npm start
719
+ ```
720
+
721
+ The demo includes:
722
+
723
+ - **Modern UI Design**: Beautiful glassmorphism effects, gradient themes, and polished visual hierarchy
724
+ - **Responsive Navigation**: Modern navbar with search, theme toggle, and mobile-friendly menu
725
+ - **Enhanced Sidebar**: Redesigned documentation sidebar with smooth animations and visual indicators
726
+ - **Signal Forms (Angular 21)** with writable signal binding examples
727
+ - **Theming** with CSS variables and Tailwind classes examples
728
+ - **Customization & A11y** with weekStart, yearRange, labels, and aria examples
729
+ - **Holiday Provider Integration** with US holidays
730
+ - **Single Date Selection** with weekend restrictions
731
+ - **Inline Range Picker** with toggle controls
732
+ - **Date Range with Time** selection
733
+ - **Multiple Date Selection** with action tracking
734
+ - **Programmatic Value Setting** for all selection modes
735
+ - **Theme Toggle** (Light/Dark mode) with automatic system preference detection
736
+ - **Customizable Calendar Views**: Year-picker, decade-picker, timeline view, and time-slider view
737
+
738
+ ## **🔧 Development**
739
+
740
+ ### **GitHub Actions**
741
+
742
+ The project uses GitHub Actions for automated deployment:
743
+
744
+ - **Deploy Demo App**: Automatically deploys the demo application to GitHub Pages on pushes to `main`/`master` branches
745
+ - Workflow: `.github/workflows/deploy-demo.yml`
746
+ - Triggers: Push to main/master or manual workflow dispatch
747
+ - Builds and deploys the demo app to GitHub Pages
748
+
749
+ ### **Building the Library**
750
+
751
+ ```bash
752
+ # Build the library (development)
753
+ npm run build
754
+
755
+ # Build optimized production version
756
+ # - Removes source maps automatically
757
+ # - Optimized TypeScript compilation
758
+ # - Enhanced tree-shaking
759
+ npm run build:optimized
760
+
761
+ # Analyze bundle size (excludes source maps)
762
+ npm run build:analyze
763
+ ```
764
+
765
+ **Build Output:**
766
+
767
+ - Main bundle: `dist/ngxsmk-datepicker/fesm2022/ngxsmk-datepicker.mjs` (~127KB)
768
+ - Type definitions: `dist/ngxsmk-datepicker/index.d.ts`
769
+ - Source maps: Automatically removed from production builds
770
+
771
+ ### **Running Tests**
772
+
773
+ ```bash
774
+ # Run all tests (library + demo app)
775
+ npm test
776
+
777
+ # Run library tests only
778
+ npx ng test ngxsmk-datepicker --no-watch --browsers=ChromeHeadless
779
+
780
+ # Run specific test file
781
+ npx ng test ngxsmk-datepicker --include="**/issue-13.spec.ts"
782
+
783
+ # Run tests in watch mode
784
+ npm test -- --watch
785
+ ```
786
+
787
+ ### **Code Quality Improvements**
788
+
789
+ The library now includes:
790
+
791
+ - ✅ **TypeScript Strict Mode**: Enhanced type safety
792
+ - **ESLint Configuration**: Code quality enforcement
793
+ - **Performance Monitoring**: Built-in performance metrics
794
+ - ✅ **Memory Leak Prevention**: Cache size limits and cleanup
795
+ - ✅ **Accessibility Testing**: WCAG compliance checks
796
+ - ✅ **Mobile Testing**: Touch interaction validation
797
+
798
+ ## **📦 Package Structure**
799
+
800
+ ```
801
+ ngxsmk-datepicker/
802
+ ├── projects/
803
+ │ ├── ngxsmk-datepicker/ # Main library
804
+ │ └── demo-app/ # Demo application
805
+ ├── dist/ # Built packages
806
+ ├── docs/ # Documentation
807
+ └── scripts/ # Build scripts
808
+ ```
809
+
810
+ ## **🎯 Browser Support**
811
+
812
+ - **Chrome** 90+
813
+ - **Firefox** 88+
814
+ - **Safari** 14+
815
+ - **Edge** 90+
816
+ - **Mobile Safari** 14+
817
+ - **Chrome Mobile** 90+
818
+
819
+ ## **🗺️ Roadmap**
820
+
821
+ Check out our [Roadmap](https://github.com/NGXSMK/ngxsmk-datepicker/blob/main/ROADMAP.md) to see planned features, improvements, and how you can contribute. We're always looking for contributors, especially for issues labeled `good-first-issue` and `help-wanted`!
822
+
823
+ ## **🤝 Contributions**
824
+
825
+ We welcome and appreciate contributions from the community! Whether it's reporting a bug, suggesting a new feature, or submitting code, your help is valuable.
826
+
827
+ ### **Development Setup**
828
+
829
+ 1. **Fork the repository** on GitHub
830
+ 2. **Clone your fork** to your local machine
831
+ 3. **Install dependencies**: `npm install`
832
+ 4. **Run the demo app**: `npm start`
833
+ 5. **Create a feature branch** for your changes
834
+ 6. **Commit your changes** following conventional commits
835
+ 7. **Submit a Pull Request** to the main branch
836
+
837
+ ### **Contribution Guidelines**
838
+
839
+ - Follow the existing code style
840
+ - Add tests for new features
841
+ - Update documentation as needed
842
+ - Ensure all tests pass
843
+ - Follow conventional commit messages
844
+
845
+ ## **📄 Changelog**
846
+
847
+ For a full list of changes, please refer to the [CHANGELOG.md](https://github.com/NGXSMK/ngxsmk-datepicker/blob/main/CHANGELOG.md) file.
848
+
849
+ ### **v2.2.2** (Current Stable)
850
+
851
+ - 🎉 **Version Update**: Updated to version 2.2.2.
852
+ - **Key Updates**: Optimized loading times, refined mobile header layout, and improved dropdown accessibility.
853
+ - ✅ **Stable Release**: Full synchronization of header components with `ViewEncapsulation.None`.
854
+
855
+ ### **v1.9.24**
856
+
857
+ - 🎉 **Version Update**: Updated to version 1.9.24
858
+ - **Stable Release**: Version 2.2.2 is the current stable version
859
+
860
+ ### **v1.9.23**
861
+
862
+ - 🐛 **Fixed**: CSS Variables Theming (Issue #84) - CSS variables theming now works when variables are defined in global `:root` selector
863
+ - Enhanced CSS selector from `:root` to `:root, :root > body` for higher specificity
864
+ - Added `!important` flags to inline styles to ensure they override existing styles
865
+ - ThemeBuilderService now properly overrides global stylesheet variables
866
+ - Updated documentation to explain the fix and provide guidance
867
+ - Resolves issue where theme variables defined in global stylesheets were not being applied
868
+
869
+ ### **v1.9.22**
870
+
871
+ - 🎉 **Version Update**: Updated to version 1.9.22
872
+ - 🐛 **Fixed**: Form control value initialization issue - datepicker now correctly displays month from form control values
873
+ - Fixed calendar month display when using Reactive Forms with initial values
874
+ - Added proper signal updates and change detection in `writeValue()` method
875
+ - 🐛 **Fixed**: Locale week start detection for en-GB and other European locales
876
+ - Added fallback logic for locales where `Intl.Locale.weekInfo` is not available
877
+ - Now correctly returns Monday (1) for en-GB and other European locales
878
+
879
+ ### **v1.9.21**
880
+
881
+ - 🎉 **Version Update**: Updated to version 1.9.21
882
+ - 📱 **Mobile-Specific Features**: Comprehensive mobile optimization
883
+ - Native date picker integration with automatic mobile detection
884
+ - Bottom sheet modal with swipe-to-dismiss gestures
885
+ - Enhanced touch gestures (double-tap, swipe navigation)
886
+ - Haptic feedback support for better mobile UX
887
+ - Mobile-optimized animations and keyboard handling
888
+ - 🎯 **Advanced Selection Modes**: Extended selection capabilities
889
+ - Week selection mode for selecting entire weeks
890
+ - Month selection mode for selecting full months
891
+ - Quarter selection mode for quarterly selections
892
+ - Year selection mode for annual date ranges
893
+ - ⏱️ **Enhanced Time Selection**: Improved time picker
894
+ - Seconds selection with configurable intervals
895
+ - Better time picker UX and controls
896
+ - 🏗️ **Code Refactoring**: Improved architecture
897
+ - New services: CalendarGenerationService, DisplayFormattingService, DateValidationService
898
+ - Better code organization and maintainability
899
+ - Reduced component complexity
900
+ - **Accessibility Enhancements**: Better screen reader support
901
+ - Improved ARIA live regions
902
+ - Enhanced focus management
903
+ - Better keyboard navigation
904
+ - **Performance Optimizations**: Infrastructure improvements
905
+ - Lazy loading calendar months with intelligent caching
906
+ - Virtual scrolling infrastructure
907
+ - Preloading adjacent months
908
+ - 🧪 **Test Coverage**: Comprehensive test suite
909
+ - 414 tests passing
910
+ - New service tests
911
+ - Updated component and utility tests
912
+ - 🔄 **Backward Compatible**: Full backward compatibility with v1.9.20
913
+
914
+ ### **v1.9.20**
915
+
916
+ - 🎉 **Version Update**: Updated to version 1.9.20
917
+ - 🐛 **Bug Fix (Issue #71)**: Fixed `TypeError: window.matchMedia is not a function` error in test environments (jsdom/Vitest)
918
+ - Added error handling for `window.matchMedia` in `applyAnimationConfig()` method
919
+ - Component now gracefully handles missing `matchMedia` API in test environments
920
+ - Prevents test failures when running with Vitest and jsdom
921
+ - **Test Coverage**: Added comprehensive test coverage for `matchMedia` compatibility scenarios
922
+ - 🔄 **Backward Compatible**: Full backward compatibility with v1.9.19
923
+
924
+ ### **v1.9.19**
925
+
926
+ - 🎉 **Version Update**: Updated to version 1.9.19
927
+ - 🎨 **Responsive Layout Redesign**: Complete redesign of demo project layout for all screen sizes (320px to desktop)
928
+ - 📱 **Mobile Optimization**: Enhanced mobile experience with improved navbar, sidebar, hero section, and feature grid
929
+ - 🧹 **Code Cleanup**: Removed unnecessary comments for cleaner codebase
930
+ - 🔧 **Meta Tag Update**: Replaced deprecated `apple-mobile-web-app-capable` with `mobile-web-app-capable`
931
+ - 🔄 **Backward Compatible**: Full backward compatibility with v1.9.18
932
+
933
+ ### **v1.9.18**
934
+
935
+ - 🐛 **Mobile Touch Event Handling**: Fixed touch listener attachment when calendar opens on mobile devices
936
+ - Touch listeners now properly attach when calendar first opens, eliminating the need to navigate months first
937
+ - Added retry mechanism with multiple attempts to ensure listeners are attached even on slower mobile devices
938
+ - Improved timing with double `requestAnimationFrame` calls and multiple retry strategies
939
+ - 🎉 **Version Update**: Updated to version 1.9.18
940
+ - 🔄 **Backward Compatible**: Full backward compatibility with v1.9.17
941
+
942
+ ### **v1.9.17**
943
+
944
+ - 🎉 **Calendar Button Visibility Control**: Added `showCalendarButton` input property to show/hide the calendar icon button
945
+ - Defaults to `false` for a cleaner, more minimal UI
946
+ - When set to `true`, displays the calendar icon button next to the input field
947
+ - When set to `false`, users can still open the calendar by clicking the input field
948
+ - Perfect for custom UI designs or when using `allowTyping` with custom calendar triggers
949
+ - 🎨 **Calendar Button Styling**: Added `calendarBtn` to `DatepickerClasses` for custom styling of the calendar button
950
+ - 🔧 **Type Compatibility**: Updated `SignalFormField` type to be fully compatible with Angular 21's `FieldTree<Date, string>` types
951
+ - Resolves TypeScript compilation issues when using `[field]` input with Angular 21 Signal Forms
952
+ - Maintains full backward compatibility with Angular 17-20
953
+ - 🎉 **Version Update**: Updated to version 1.9.17
954
+ - 🔄 **Backward Compatible**: Full backward compatibility with v1.9.16
955
+ - **Angular 17-22 Compatible**: Verified compatibility with Angular 17-22 (including Angular 21)
956
+
957
+ ### **v1.9.16**
958
+
959
+ - 🐛 **Range Mode Previous Month Selection**: Fixed issue where users could not select dates from previous months in range mode when starting with `{ start: null, end: null }`
960
+ - 🎉 **Version Update**: Updated to version 1.9.16
961
+ - 🔄 **Backward Compatible**: Full backward compatibility with v1.9.15
962
+ - **Angular 17+ Compatible**: Verified compatibility with Angular 17 and up versions
963
+
964
+ ### **v1.9.15**
965
+
966
+ - 🐛 **Moment Object Binding Fix**: Fixed Moment.js objects not binding correctly with ngModel
967
+ - 🐛 **Date Clicks After Navigation**: Fixed dates becoming unclickable after month navigation
968
+ - 🎉 **Version Update**: Updated to version 1.9.15
969
+ - 🔄 **Backward Compatible**: Full backward compatibility with v1.9.14
970
+ - **Angular 17+ Compatible**: Verified compatibility with Angular 17 and up versions
971
+
972
+ ### **v1.9.14**
973
+
974
+ - 🐛 **Date Picker Selection Fix**: Fixed date picker selection issues, especially in range mode
975
+ - 🐛 **Moment.js Timezone Support**: Fixed timezone offset preservation for Moment.js objects
976
+ - 🎉 **Version Update**: Updated to version 1.9.14
977
+ - 🔄 **Backward Compatible**: Full backward compatibility with v1.9.13
978
+
979
+ ### **v1.9.13**
980
+
981
+ - 🐛 **Bug Fixes**: Fixed `valueChange` event emitting null for range mode with ngModel
982
+ - 🐛 **Bug Fixes**: Fixed date selection becoming disabled after month navigation in range mode
983
+ - 🐛 **Bug Fixes**: Fixed Moment.js object handling in range values and arrays
984
+ - 🎉 **Version Update**: Updated to version 1.9.13
985
+ - 🔄 **Backward Compatible**: Full backward compatibility with v1.9.12
986
+
987
+ ### **v1.9.12**
988
+
989
+ - 🎉 **Version Update**: Updated to version 1.9.12
990
+ - 🔄 **Backward Compatible**: Full backward compatibility with v1.9.11
991
+ - 📚 **Migration Guide**: See [MIGRATION.md](MIGRATION.md) for detailed migration instructions
992
+
993
+ ### **v1.9.11**
994
+
995
+ - 🐛 **Moment.js Integration**: Fixed critical issue where Moment.js objects with custom date formats would not populate correctly
996
+ - Added `isMomentObject()` helper method to safely detect Moment.js instances
997
+ - Enhanced `_normalizeValue()` method to handle Moment.js objects directly
998
+ - Improved `parseCustomDateString()` method for TypeScript compatibility
999
+ - Added comprehensive support for format tokens: YYYY, YY, MM, M, DD, D, hh, h, HH, H, mm, m, ss, s, a, A
1000
+ - Maintains full backward compatibility with Date objects, strings, and all other supported formats
1001
+ - 🎨 **Custom Format Parser**: Enhanced format token parsing with better TypeScript compatibility
1002
+ - 🔍 **Moment.js Detection**: More robust detection of Moment.js objects across different versions
1003
+ - 🎮 **Demo Application**: Added working Moment.js integration example with interactive controls
1004
+
1005
+ ### **v1.9.10**
1006
+
1007
+ - 🐛 **Async Database Value Loading**: Enhanced datepicker to properly handle database values that load asynchronously
1008
+ - Added fallback sync mechanism in `ngAfterViewInit` to catch async database loads
1009
+ - Added delayed sync checks in `ngOnInit`, `ngOnChanges`, and `ngAfterViewInit`
1010
+ - Added sync on calendar open, focus events, and touch events
1011
+ - Extended interval sync duration to 30 seconds with 100ms check intervals
1012
+ - 🔧 **TypeScript Compilation Error**: Fixed `EffectRef` type error when using Angular 17+ `effect()` API
1013
+ - Changed `_fieldEffectDestroy: (() => void) | null` to `_fieldEffectRef: EffectRef | null`
1014
+ - Updated effect cleanup to use `effectRef.destroy()` instead of function call
1015
+ - Added proper `EffectRef` import from `@angular/core`
1016
+ - 🧪 **Test Configuration**: Fixed test configuration for Angular 17+ compatibility
1017
+ - Updated karma configuration to work with `@angular/build:karma` builder
1018
+ - Simplified karma.conf.js to remove deprecated plugins
1019
+ - Updated test script to target correct project
1020
+
1021
+ ### **v1.9.9**
1022
+
1023
+ - 🐛 **Database Value Population**: Fixed critical issue where datepicker would not populate with values from database when using `[field]` input binding
1024
+ - Added `_normalizeValue()` helper method to properly handle all value types
1025
+ - Updated field effect and related methods to use `_normalizeValue()` instead of `_normalizeDate()`
1026
+ - Fixed issue where string dates from database were not being parsed and displayed correctly
1027
+ - Now properly handles Date objects, string dates, range objects, and arrays of dates
1028
+
1029
+ ### **v1.9.8**
1030
+
1031
+ - 🐛 **Date Selection Reset Issue**: Fixed critical bug where selected dates would reset to today's date when using `[field]` input binding
1032
+ - Fixed `applyCurrentTime` to create a new Date object instead of mutating the original
1033
+ - Added `_isUpdatingFromInternal` flag to prevent field effect from resetting the value
1034
+ - This ensures selected dates are properly stored in the form field
1035
+
1036
+ ### **v1.9.7**
1037
+
1038
+ - 🐛 **Calendar Population**: Fixed critical issue where datepicker calendar would not populate with dates when opened
1039
+ - Fixed issue when multiple datepickers were present in the same form
1040
+ - Ensured `generateCalendar()` is called when opening the datepicker via click, touch, or programmatic methods
1041
+
1042
+ ### **v1.9.6**
1043
+
1044
+ - 🐛 **Multiple Datepicker Management**: Fixed issue where multiple datepickers in the same form would open in the same centered location
1045
+ - 🖱️ **Outside Click Detection**: Improved click detection to properly close datepicker when clicking outside
1046
+ - 🔄 **Auto-close Other Datepickers**: When opening a datepicker, all other open datepickers in the same form are now automatically closed
1047
+ - 📱 **Mobile Datepicker Opening**: Fixed issue where datepicker modal would not open on mobile screens
1048
+ - 📱 **Datepicker Closing on Mobile**: Fixed issue where datepicker would open and immediately disappear on mobile devices
1049
+ - 👆 **Select Box Cursor**: Added pointer cursor to all select boxes (month, year, hour, minute, AM/PM) in the datepicker
1050
+
1051
+ ### **v1.9.5**
1052
+
1053
+ - 🔧 **Angular 21+ Signal Forms Type Compatibility**: Fixed TypeScript compilation error with Angular 21+ Signal Forms
1054
+ - Fixed `Type '() => string' is not assignable to type 'never'` error when using `[field]` input
1055
+ - Updated `SignalFormField` type definition to be compatible with Angular 21's `FieldTree<Date, string>` types
1056
+ - Maintains backward compatibility with Angular 17-20 where field input is optional
1057
+ - Resolves [#33](https://github.com/NGXSMK/ngxsmk-datepicker/issues/33)
1058
+
1059
+ ### **v1.9.4**
1060
+
1061
+ - ✨ **Custom Date Format**: New `[displayFormat]` input property to display dates in custom formats
1062
+ - Supports format strings like "MM/DD/YYYY hh:mm A"
1063
+ - Works with date adapters (date-fns, dayjs, luxon) or built-in simple formatter
1064
+ - Supports common format tokens: YYYY, MM, DD, hh, mm, A, etc.
1065
+ - Resolves [#31](https://github.com/NGXSMK/ngxsmk-datepicker/issues/31)
1066
+ - 🐛 **Time Selection Dropdowns**: Fixed visibility issues with time selection dropdowns
1067
+ - Dropdowns now properly display and are not clipped by parent containers
1068
+ - Improved z-index handling for time selection dropdowns
1069
+ - Removed unnecessary scrollbars from datepicker wrapper
1070
+ - Resolves [#32](https://github.com/NGXSMK/ngxsmk-datepicker/issues/32)
1071
+
1072
+ ### **v1.9.3**
1073
+
1074
+ - ✨ **Time-Only Picker**: New `[timeOnly]` input property to display only time selection without calendar
1075
+ - Hides calendar grid and shows only time controls (hour, minute, AM/PM)
1076
+ - Automatically enables `showTime` when `timeOnly` is true
1077
+ - Perfect for time selection scenarios where date is not needed
1078
+ - Value is still a Date object using today's date with selected time
1079
+ - Placeholder automatically changes to "Select Time" in time-only mode
1080
+ - Resolves [#29](https://github.com/NGXSMK/ngxsmk-datepicker/issues/29)
1081
+ - 🎨 **Modern Demo App UI**: Complete redesign of the demo application
1082
+ - Modern navbar with glassmorphism effects, search functionality, and improved theme toggle
1083
+ - Redesigned sidebar with gradient backgrounds, smooth animations, and visual indicators
1084
+ - Enhanced icon sizes and better visual hierarchy
1085
+ - Improved responsive design with better mobile experience
1086
+ - Automatic system theme detection (dark/light mode preference)
1087
+ - Gradient accents, shadows, and modern design patterns throughout
1088
+ - 🧪 **Test Suite**: Fixed 25+ failing tests across multiple test files
1089
+ - Fixed date utils tests, calendar utils tests, timezone utils tests, edge cases tests
1090
+ - Fixed adapters tests, performance utils tests, RTL tests, touch gestures tests
1091
+ - Fixed calendar views tests, recurring dates utils tests
1092
+ - All 353 tests now pass successfully
1093
+
1094
+ ### **v1.9.2**
1095
+
1096
+ - 📦 **Bundle Optimization**: Optimized bundle size with improved TypeScript compiler settings
1097
+ - Main bundle: ~127KB (source maps excluded from published package)
1098
+ - Enhanced tree-shaking with optimized imports and compiler options
1099
+ - Added `importsNotUsedAsValues: "remove"` for smaller output
1100
+ - Disabled `preserveConstEnums` for better inlining
1101
+ - 🔧 **Build Process**:
1102
+ - Source maps automatically removed from production builds (saves ~127KB)
1103
+ - Improved build scripts with better error handling
1104
+ - Enhanced bundle analysis that excludes source maps
1105
+ - 📦 **Package Configuration**:
1106
+ - Fixed package.json exports to eliminate build warnings
1107
+ - Optimized `files` array to exclude unnecessary files
1108
+ - Updated exports field for better module resolution
1109
+ - 🧪 **Test Configuration**:
1110
+ - Added Zone.js polyfills to library test configuration
1111
+ - Updated test commands to explicitly target library project
1112
+ - Improved test reliability across Angular versions
1113
+ - 🐛 **Bug Fixes**:
1114
+ - Test suite configuration - added missing Zone.js polyfills for library tests
1115
+ - Bundle analysis now correctly excludes source maps from size calculations
1116
+ - Build warnings from conflicting export conditions resolved
1117
+ - Source map removal script made more resilient for build environments
1118
+
1119
+ ### **v1.9.1**
1120
+
1121
+ - 🐛 Minor bug fixes and improvements
1122
+
1123
+ ### **v1.9.0**
1124
+
1125
+ - **Extension Points & Hooks**: system for customization
1126
+ - ⌨️ **Enhanced Keyboard Shortcuts**: Y, N, W keys with custom shortcut support
1127
+ - 🎨 **Modern UI/UX**: Improved animations and responsiveness
1128
+ - 📚 **API Documentation**: TypeDoc integration
1129
+ - 🤖 **Semantic Release**: Automated versioning and publishing
1130
+ - 🚀 **Animation Performance**: Optimizations with GPU acceleration
1131
+ - 🔍 **Global Search**: Functionality in documentation
1132
+ - 📱 **Mobile Playground**: For responsive testing
1133
+
1134
+ ### **v1.7.0**
1135
+
1136
+ - 🎯 **Signal Forms Support**: Full Angular 21 signal forms integration with writable signals
1137
+ - 🎨 **Tailwind Theming**: Added `classes` input for Tailwind CSS and custom class-based theming
1138
+ - 🌍 **Localization Improvements**: Added `weekStart` input to override locale-based week start day
1139
+ - 📅 **Year Range Configuration**: Added `yearRange` input to customize year dropdown range
1140
+ - **Accessibility Enhancements**: Added customizable aria labels for all interactive elements
1141
+ - 🏷️ **Custom Labels**: Added `clearLabel` and `closeLabel` inputs for button customization
1142
+ - 🧪 **Comprehensive Test Suite**: Added 56 tests covering all features and edge cases
1143
+ - 🐛 **Bug Fixes**: Fixed programmatic value setting and Angular 21 compatibility tests
1144
+ - 🧹 **Code Cleanup**: Removed unnecessary files, folders, and comments from codebase
1145
+ - 📝 **Test Improvements**: Enhanced test coverage with comprehensive feature tests
1146
+ - 🔧 **Test Fixes**: Fixed disabled date tests and integration test issues
1147
+ - 🎯 **Code Quality**: Improved code maintainability by removing redundant comments
1148
+
1149
+ ### **v1.6.0**
1150
+
1151
+ - 🎯 **Programmatic Value Setting**: Added `value` input property to set datepicker value programmatically, perfect for server-side API data integration
1152
+ - 🎨 **Enhanced Demo App**: Completely redesigned demo application with TokiForge-inspired modern UI and API documentation style
1153
+ - 🚀 **GitHub Pages Deployment**: Added automated GitHub Pages deployment with GitHub Actions workflow
1154
+ - 📚 **Improved Documentation**: Enhanced demo app with comprehensive examples, code snippets, and interactive documentation
1155
+ - 🔧 **Build Optimizations**: Updated CSS budget limits and improved build configuration
1156
+ - 🎨 **Modern UI Design**: Beautiful gradient themes, glass-morphism effects, and improved visual hierarchy
1157
+ - 📱 **Better UX**: Enhanced navigation, code copying functionality, and responsive design
1158
+ - 🛠️ **Developer Experience**: Improved build scripts and deployment automation
1159
+
1160
+ ### **v1.5.0**
1161
+
1162
+ - 🚀 **Angular 21 Support**: Full compatibility with Angular 21 RC versions
1163
+ - **Zone-less Support**: Works without zone.js for improved performance
1164
+ - 🧪 **Comprehensive Tests**: Added extensive test suite covering all features
1165
+ - 🔧 **Angular 17-21 Compatibility**: Supports Angular versions 17, 18, 19, 20, and 21
1166
+ - 📦 **Dependency Updates**: Updated to Angular 21 RC and latest build tools
1167
+ - 🧹 **Code Cleanup**: Removed unnecessary documentation files and comments
1168
+ - 📝 **Improved Keywords**: Added version-specific keywords for better discoverability
1169
+ - 🎯 **Peer Dependencies**: Updated to support Angular 17-21 range
1170
+
1171
+ ### **v1.4.16**
1172
+
1173
+ - 📚 **Documentation**: Comprehensive README updates with latest features and improvements
1174
+ - 🎯 **Version Management**: Updated version references across all package files
1175
+ - 📖 **User Experience**: Enhanced documentation with better examples and API references
1176
+ - 🔧 **Maintenance**: Improved project structure and documentation consistency
1177
+ - 📦 **Package Updates**: Synchronized version numbers across all package.json files
1178
+ - 🎨 **Documentation**: Added detailed bug fixes and performance metrics
1179
+ - 🚀 **Developer Experience**: Better setup instructions and contribution guidelines
1180
+
1181
+ ### **v1.4.15**
1182
+
1183
+ - 🐛 **Bug Fixes**: Fixed 10 critical bugs including change detection issues and date comparison errors
1184
+ - **Performance**: Enhanced OnPush change detection with proper triggers
1185
+ - 🎯 **Memory Management**: Added cache size limits to prevent memory leaks
1186
+ - 🔧 **Type Safety**: Improved TypeScript types and null safety
1187
+ - 📱 **Mobile Optimization**: Enhanced mobile responsive design with touch-friendly interactions
1188
+ - 🎨 **UI Improvements**: Better visual feedback and accessibility
1189
+ - 🚀 **Build Optimization**: Improved build configuration and tree-shaking
1190
+ - 🧹 **Code Quality**: Enhanced code maintainability and performance
1191
+
1192
+ ### **v1.4.13**
1193
+
1194
+ - 🚫 **Disabled Dates**: New `disabledDates` input property to disable specific dates
1195
+ - 🎯 **Date String Support**: Supports both string dates (MM/DD/YYYY) and Date objects
1196
+ - 💡 **Holiday Tooltips**: Hover over holiday dates to see holiday names as tooltips
1197
+ - 🎨 **Enhanced UX**: Better visual feedback for disabled dates
1198
+ - 📦 **Improved API**: More flexible date disabling options
1199
+
1200
+ ### **v1.4.12**
1201
+
1202
+ - **Instant Navigation**: Removed all animations for lightning-fast arrow navigation
1203
+ - 🚫 **Smart Back Arrow**: Automatically disables back arrow when minDate is set
1204
+ - 🎯 **Better UX**: Prevents navigation to invalid date ranges
1205
+ - 🗓️ **Previous Month Days**: Now shows last few days of previous month for better context
1206
+ - 🎨 **Enhanced Styling**: Improved visual hierarchy with better day cell sizing
1207
+ - 🖱️ **Interactive Previous Days**: Previous month days are now selectable and interactive
1208
+ - 🧹 **Code Optimization**: Cleaner, more maintainable codebase
1209
+ - 📦 **Smaller Bundle**: Reduced CSS and JavaScript footprint
1210
+
1211
+ ### **v1.4.11**
1212
+
1213
+ - 🎨 **UI Improvements**: Enhanced day cell sizing and visual hierarchy
1214
+ - 🖱️ **Better Interactions**: Improved click and hover states for previous month days
1215
+
1216
+ ### **v1.4.10**
1217
+
1218
+ - 🗓️ **Previous Month Display**: Added last few days of previous month for better context
1219
+ - 🎯 **Smart Selection**: Previous month days are now selectable and interactive
1220
+
1221
+ ### **v1.4.9**
1222
+
1223
+ - 🚫 **Range Fix**: Fixed range highlighting on empty/previous month days
1224
+ - 🎨 **Styling Updates**: Improved visual consistency across all day types
1225
+
1226
+ ### **v1.4.8**
1227
+
1228
+ - **Performance**: Optimized calendar generation and rendering
1229
+ - 🧹 **Code Cleanup**: Removed unused animation code and improved maintainability
1230
+
1231
+ ### **v1.4.6**
1232
+
1233
+ - 🔧 **Fixed Import Paths**: Corrected package exports for proper module resolution
1234
+ - 📦 **Better Package Structure**: Improved npm package configuration
1235
+
1236
+ ### **v1.4.5**
1237
+
1238
+ - 🐛 Bug fixes and stability improvements
1239
+ - 🔧 Enhanced error handling
1240
+ - 📱 Improved mobile responsiveness
1241
+ - 🎨 Minor UI/UX improvements
1242
+
1243
+ ### **v1.4.0**
1244
+
1245
+ - Performance optimizations (30% smaller bundle)
1246
+ - ✅ OnPush change detection strategy
1247
+ - ✅ Memoized date comparisons
1248
+ - ✅ Tree-shakable architecture
1249
+ - Enhanced TypeScript support
1250
+ - Improved accessibility
1251
+ - ✅ Better mobile responsiveness
1252
+
1253
+ ### **Previous Versions**
1254
+
1255
+ - v1.3.5: Initial release with core features
1256
+ - v1.3.4: Bug fixes and improvements
1257
+ - v1.3.3: Holiday provider integration
1258
+
1259
+ ## **🎨 Theming with TokiForge**
1260
+
1261
+ Looking for a powerful theming solution for your Angular application? Check out **[TokiForge](https://tokiforge.github.io/tokiforge/)** — an open-source modern design token & theme engine that provides runtime theme switching for React, Vue, Svelte, Angular, and any framework.
1262
+
1263
+ ### Why TokiForge?
1264
+
1265
+ - **Framework-agnostic** Works with Angular, React, Vue, Svelte, and vanilla JS
1266
+ - ✅ **Runtime theme switching** — Change themes dynamically without rebuilds
1267
+ - **Type-safe** — Full TypeScript support for design tokens
1268
+ - ✅ **Lightweight** — <3 KB gzipped runtime footprint
1269
+ - **CSS custom properties** Zero JS overhead in static mode
1270
+ - **SSR compatible** — Works seamlessly with Angular Universal
1271
+
1272
+ Perfect for managing design tokens, creating theme systems, and implementing dark mode in your Angular applications!
1273
+
1274
+ **👉 [Learn more about TokiForge →](https://tokiforge.github.io/tokiforge/)**
1275
+
1276
+ ---
1277
+
1278
+ ## **📜 License**
1279
+
1280
+ MIT License - see [LICENSE](https://github.com/NGXSMK/ngxsmk-datepicker/blob/main/LICENSE) file for details.
1281
+
1282
+ ## **🔍 SEO & Discoverability**
1283
+
1284
+ This library is optimized for search engine visibility, especially for European markets:
1285
+
1286
+ - **Keywords**: Angular datepicker, date range picker, calendar component, Angular 17-21, TypeScript, Signal Forms, SSR compatible
1287
+ - **European SEO**: Optimized for Germany, France, Spain, Italy, Netherlands, Poland, Portugal, Sweden, Norway, Finland, Denmark, Belgium, Switzerland, Austria, and United Kingdom
1288
+ - **Multi-language Support**: hreflang tags for 15+ European languages and locales
1289
+ - **European Geo-targeting**: Geo tags and structured data optimized for European Union countries
1290
+ - **Meta Tags**: Comprehensive Open Graph and Twitter Card support with European locale alternates
1291
+ - **Structured Data**: JSON-LD schema markup with European audience targeting and area served information
1292
+ - **Documentation**: Complete API documentation with examples
1293
+ - **Performance**: Optimized bundle size (~127KB) for fast loading
1294
+ - **European Localization**: Full i18n support for European date formats, week start days, and regional preferences
1295
+
1296
+ ## **👨‍💻 Author**
1297
+
1298
+ **Sachin Dilshan**
1299
+
1300
+ - 📧 Email: [sachindilshan040@gmail.com](mailto:sachindilshan040@gmail.com)
1301
+ - 🐙 GitHub: [@toozuuu](https://github.com/toozuuu)
1302
+ - 📦 NPM: [ngxsmk-datepicker](https://www.npmjs.com/package/ngxsmk-datepicker)
1303
+ - 💼 LinkedIn: [sachindilshan](https://www.linkedin.com/in/sachindilshan/)
1304
+
1305
+ ## **⭐ Support**
1306
+
1307
+ If you find this library helpful, please consider:
1308
+
1309
+ - **Starring** the repository
1310
+ - 🐛 **Reporting** bugs and issues
1311
+ - 💡 **Suggesting** new features
1312
+ - 🤝 **Contributing** code improvements
1313
+ - 📢 **Sharing** with the community