ngxsmk-datepicker 2.3.1 β†’ 2.4.0

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.
@@ -1,471 +1,471 @@
1
- # Version Compatibility Matrix
2
-
3
- **Last updated:** June 3, 2026 - **Current stable:** v2.3.1
4
-
5
- This document provides comprehensive compatibility information for `ngxsmk-datepicker` across different Angular versions, Zone.js configurations, and SSR/CSR setups.
6
-
7
- ## πŸ“‹ Angular Version Compatibility
8
-
9
- ### Compatibility Matrix
10
-
11
- | Angular Version | Status | Core Features | Signal Features | Signal Forms | SSR Support | Notes |
12
- |----------------|--------|--------------|----------------|--------------|-------------|-------|
13
- | **Angular 17** | βœ… Fully Supported | βœ… All | βœ… Signals, Computed | ❌ Not Available | βœ… Full | Minimum supported version |
14
- | **Angular 18** | βœ… Fully Supported | βœ… All | βœ… Signals, Computed, Effects | ❌ Not Available | βœ… Full | Enhanced signal support |
15
- | **Angular 19** | βœ… Fully Supported | βœ… All | βœ… Signals, Computed, Effects | ❌ Not Available | βœ… Full | Optimized performance |
16
- | **Angular 20** | βœ… Fully Supported | βœ… All | βœ… Signals, Computed, Effects | ❌ Not Available | βœ… Full | Fully supported |
17
- | **Angular 21** | βœ… Fully Supported | βœ… All | βœ… Signals, Computed, Effects | βœ… Signal Forms `[field]` | βœ… Full | **Officially released - Current development target**<br/>βœ… Signal Forms (experimental)<br/>βœ… Zoneless by default<br/>βœ… Compatible with Vitest-based apps<br/>βœ… Angular Aria compatible |
18
- | **Angular 22+** | πŸ”„ Future Support | βœ… All | βœ… Signals, Computed, Effects | βœ… Signal Forms `[field]` | βœ… Full | Peer dependency: `<24.0.0` |
19
-
20
- ### Feature Availability by Angular Version
21
-
22
- #### Core Features (Available in all versions)
23
- - βœ… Date selection (single, range, multiple)
24
- - βœ… Time selection
25
- - βœ… Calendar views (month, year, decade, timeline, time-slider)
26
- - βœ… Keyboard navigation
27
- - βœ… Touch gestures
28
- - βœ… RTL support
29
- - βœ… Timezone support
30
- - βœ… Custom formatting
31
- - βœ… Holiday provider integration
32
- - βœ… Custom hooks and extensions
33
- - βœ… Accessibility (ARIA, keyboard)
34
- - βœ… Theming (light/dark)
35
- - βœ… Translations/i18n
36
-
37
- #### Signal Features (Angular 17+)
38
- - βœ… `signal()` - Reactive state management
39
- - βœ… `computed()` - Derived reactive values
40
- - βœ… `effect()` - Side effects (Angular 18+)
41
- - βœ… `inject()` - Dependency injection
42
-
43
- #### Signal Forms (Angular 21+)
44
- - βœ… `[field]` input binding (experimental Angular 21 feature)
45
- - βœ… Automatic field synchronization
46
- - βœ… Reactive form field updates
47
- - βœ… Signal-based value management
48
- - βœ… Works with `form()`, `objectSchema()`, and `validators`
49
- - βœ… Compatible with `httpResource` and `linkedSignal` patterns
50
-
51
- #### Angular 21 New Features Compatibility
52
- - βœ… **Zoneless by Default**: Fully compatible with Angular 21 apps that don't include Zone.js
53
- - βœ… **Vitest Test Runner**: Library works in apps using Vitest-based setups
54
- - βœ… **Angular Aria**: Compatible with Angular Aria components; uses custom ARIA implementation for screen reader support
55
-
56
- ### Peer Dependencies
57
-
58
- ```json
59
- {
60
- "@angular/common": ">=17.0.0 <24.0.0",
61
- "@angular/core": ">=17.0.0 <24.0.0",
62
- "@angular/forms": ">=17.0.0 <24.0.0"
63
- }
64
- ```
65
-
66
- **Zone.js**: Optional (declared in `peerDependenciesMeta`)
67
-
68
- ## πŸ”„ Zone.js vs Zoneless Compatibility
69
-
70
- ### Overview
71
-
72
- `ngxsmk-datepicker` is designed to work **with or without Zone.js**, making it compatible with both traditional Angular applications and modern zoneless applications.
73
-
74
- ### Zone.js Required Features
75
-
76
- | Feature | With Zone.js | Without Zone.js | Notes |
77
- |---------|--------------|-----------------|-------|
78
- | **Change Detection** | βœ… Automatic | βœ… Manual (OnPush) | Component uses `OnPush` strategy |
79
- | **Form Integration** | βœ… Works | βœ… Works | Uses `ControlValueAccessor` |
80
- | **Event Handling** | βœ… Works | βœ… Works | Native event listeners |
81
- | **Signal Updates** | βœ… Works | βœ… Works | Signals trigger change detection |
82
- | **Reactive Forms** | βœ… Works | βœ… Works | FormControl integration |
83
- | **Signal Forms** | βœ… Works | βœ… Works | Angular 21+ signal forms |
84
-
85
- ### Zoneless Setup
86
-
87
- The component uses **OnPush change detection strategy** and **signals** for reactive updates, making it fully compatible with zoneless applications:
88
-
89
- ```typescript
90
- @Component({
91
- selector: 'ngxsmk-datepicker',
92
- changeDetection: ChangeDetectionStrategy.OnPush, // βœ… Zoneless compatible
93
- // ...
94
- })
95
- ```
96
-
97
- #### Manual Change Detection
98
-
99
- When using without Zone.js, the component handles change detection internally:
100
-
101
- ```typescript
102
- // Component automatically calls markForCheck() when needed
103
- private scheduleChangeDetection(): void {
104
- if (!this._changeDetectionScheduled) {
105
- this._changeDetectionScheduled = true;
106
- Promise.resolve().then(() => {
107
- this._changeDetectionScheduled = false;
108
- this.cdr.markForCheck();
109
- });
110
- }
111
- }
112
- ```
113
-
114
- #### Signal-Based Reactivity
115
-
116
- The component uses Angular signals for reactive state:
117
-
118
- ```typescript
119
- // Reactive calendar open state
120
- private _isCalendarOpen = signal<boolean>(false);
121
-
122
- // Computed dependencies for memoization
123
- private _memoDependencies = computed(() => ({
124
- month: this._currentMonthSignal(),
125
- year: this._currentYearSignal(),
126
- // ...
127
- }));
128
- ```
129
-
130
- ### Zone.js Configuration
131
-
132
- #### With Zone.js (Default)
133
-
134
- ```typescript
135
- // main.ts
136
- import { bootstrapApplication } from '@angular/platform-browser';
137
- import { AppComponent } from './app/app.component';
138
-
139
- bootstrapApplication(AppComponent);
140
- // Zone.js is automatically included
141
- ```
142
-
143
- #### Without Zone.js (Zoneless)
144
-
145
- ```typescript
146
- // main.ts
147
- import { bootstrapApplication } from '@angular/platform-browser';
148
- import { AppComponent } from './app/app.component';
149
-
150
- bootstrapApplication(AppComponent, {
151
- providers: [
152
- // No Zone.js provider needed
153
- // Component works with OnPush + signals
154
- ]
155
- });
156
- ```
157
-
158
- ### Migration Guide: Zone.js β†’ Zoneless
159
-
160
- 1. **Remove Zone.js dependency** (if desired)
161
- 2. **Ensure OnPush strategy** (already used by component)
162
- 3. **Use signals for state** (component already uses signals)
163
- 4. **No code changes needed** - component is zoneless-ready
164
-
165
- ## 🌐 SSR vs CSR Compatibility
166
-
167
- ### Server-Side Rendering (SSR)
168
-
169
- The component is **fully compatible** with Angular Universal and SSR.
170
-
171
- #### SSR-Safe Features
172
-
173
- | Feature | SSR Support | Implementation |
174
- |---------|-------------|----------------|
175
- | **Platform Detection** | βœ… Safe | Uses `isPlatformBrowser()` and `PLATFORM_ID` |
176
- | **DOM Access** | βœ… Safe | Guarded with `isBrowser` checks |
177
- | **Event Listeners** | βœ… Safe | Only attached in browser |
178
- | **Date Formatting** | βœ… Safe | Uses `Intl` API (available in Node.js) |
179
- | **Local Storage** | βœ… Safe | Not used |
180
- | **Window/Document** | βœ… Safe | Guarded with platform checks |
181
-
182
- #### SSR Implementation Details
183
-
184
- ```typescript
185
- // Platform detection
186
- private readonly platformId = inject(PLATFORM_ID);
187
- private readonly isBrowser = isPlatformBrowser(this.platformId);
188
-
189
- // Safe DOM access
190
- if (this.isBrowser && typeof document !== 'undefined') {
191
- // Browser-only code
192
- document.documentElement.dir === 'rtl';
193
- }
194
-
195
- // Safe event listeners
196
- if (this.isBrowser) {
197
- // Attach event listeners
198
- }
199
- ```
200
-
201
- #### SSR-Specific Considerations
202
-
203
- 1. **Initial Render**: Component renders safely on server
204
- 2. **Hydration**: Client-side hydration works correctly
205
- 3. **Date Formatting**: Uses `Intl.DateTimeFormat` (available in Node.js 13+)
206
- 4. **Locale Detection**: Falls back to 'en-US' on server if `navigator` is unavailable
207
-
208
- ### Client-Side Rendering (CSR)
209
-
210
- All features work identically in CSR mode. No special configuration needed.
211
-
212
- ### SSR vs CSR Differences
213
-
214
- | Aspect | SSR | CSR | Notes |
215
- |--------|-----|-----|-------|
216
- | **Initial Render** | Server | Browser | Component renders on both |
217
- | **DOM Access** | ❌ Not Available | βœ… Available | Guarded with `isPlatformBrowser()` |
218
- | **Event Listeners** | ❌ Not Attached | βœ… Attached | Only in browser |
219
- | **Date Formatting** | βœ… Works | βœ… Works | Uses `Intl` API |
220
- | **Locale Detection** | ⚠️ Limited | βœ… Full | Server uses default, browser detects |
221
- | **Performance** | βœ… Fast Initial Load | βœ… Interactive | SSR improves SEO and initial load |
222
-
223
- ### SSR Setup Example
224
-
225
- ```typescript
226
- // app.config.ts
227
- import { ApplicationConfig } from '@angular/core';
228
- import { provideClientHydration } from '@angular/platform-browser';
229
-
230
- export const appConfig: ApplicationConfig = {
231
- providers: [
232
- provideClientHydration(), // Enable SSR hydration
233
- // ... other providers
234
- ]
235
- };
236
- ```
237
-
238
- ```typescript
239
- // Component usage (works in both SSR and CSR)
240
- @Component({
241
- template: `
242
- <ngxsmk-datepicker
243
- [locale]="'en-US'"
244
- mode="single">
245
- </ngxsmk-datepicker>
246
- `
247
- })
248
- export class MyComponent {
249
- // Component automatically handles SSR/CSR differences
250
- }
251
- ```
252
-
253
- ## 🧩 Shadow DOM & Web Components Compatibility
254
-
255
- `ngxsmk-datepicker` is fully compatible with **Shadow DOM encapsulation** (`ViewEncapsulation.ShadowDom`) and deployment as an **Angular Element (Custom Web Component)** inside other frameworks (React, Vue, etc.).
256
-
257
- ### Composed Path Event Retargeting
258
- When components are loaded inside a Shadow root, the browser retargets event targets when they bubble outside of the Shadow boundary. Standard `.contains()` checks on the host node will fail when checking external interaction listeners (e.g. document close listeners).
259
-
260
- `ngxsmk-datepicker` natively handles this by tracking event composed paths:
261
- * Inspects `event.composedPath()` when available to accurately check event origins inside Shadow DOM trees.
262
- * Falls back to standard light DOM `.contains(target)` when composed paths are not supported by the environment.
263
- * Supported across both the primary Datepicker component and Custom Select dropdown components.
264
-
265
- ## πŸ”§ Feature Compatibility Matrix
266
-
267
- ### By Angular Version
268
-
269
- | Feature | Angular 17 | Angular 18 | Angular 19 | Angular 20 | Angular 21+ |
270
- |---------|------------|-----------|------------|------------|-------------|
271
- | **Standalone Component** | βœ… | βœ… | βœ… | βœ… | βœ… |
272
- | **Signals** | βœ… | βœ… | βœ… | βœ… | βœ… |
273
- | **Shadow DOM Support** | βœ… | βœ… | βœ… | βœ… | βœ… |
274
- | **Computed Signals** | βœ… | βœ… | βœ… | βœ… | βœ… |
275
- | **Effects** | ⚠️ Limited | βœ… | βœ… | βœ… | βœ… |
276
- | **Signal Forms** | ❌ | ❌ | ❌ | ❌ | βœ… |
277
- | **ControlValueAccessor** | βœ… | βœ… | βœ… | βœ… | βœ… |
278
- | **Reactive Forms** | βœ… | βœ… | βœ… | βœ… | βœ… |
279
- | **OnPush Strategy** | βœ… | βœ… | βœ… | βœ… | βœ… |
280
- | **SSR Support** | βœ… | βœ… | βœ… | βœ… | βœ… |
281
- | **Zoneless Support** | βœ… | βœ… | βœ… | βœ… | βœ… |
282
- | **Translations/i18n** | βœ… | βœ… | βœ… | βœ… | βœ… |
283
- | **Locale Registry** | βœ… | βœ… | βœ… | βœ… | βœ… |
284
-
285
- ### By Configuration
286
-
287
- | Configuration | Zone.js | Zoneless | SSR | CSR |
288
- |---------------|---------|----------|-----|-----|
289
- | **Change Detection** | βœ… Auto | βœ… Manual | βœ… Works | βœ… Works |
290
- | **Form Integration** | βœ… Works | βœ… Works | βœ… Works | βœ… Works |
291
- | **Event Handling** | βœ… Works | βœ… Works | ⚠️ Browser Only | βœ… Works |
292
- | **Signal Updates** | βœ… Works | βœ… Works | βœ… Works | βœ… Works |
293
- | **Date Formatting** | βœ… Works | βœ… Works | βœ… Works | βœ… Works |
294
- | **Keyboard Navigation** | βœ… Works | βœ… Works | ⚠️ Browser Only | βœ… Works |
295
- | **Touch Gestures** | βœ… Works | βœ… Works | ⚠️ Browser Only | βœ… Works |
296
-
297
- ## πŸ“ Migration Guides
298
-
299
- ### Upgrading from Angular 17 to 21
300
-
301
- 1. **Update Angular dependencies**:
302
- ```bash
303
- ng update @angular/core @angular/cli
304
- ```
305
-
306
- 2. **Enable Signal Forms** (Angular 21+):
307
- ```typescript
308
- // Before (Angular 17-20)
309
- <ngxsmk-datepicker
310
- [value]="dateValue"
311
- (valueChange)="dateValue = $event">
312
- </ngxsmk-datepicker>
313
-
314
- // After (Angular 21+)
315
- <ngxsmk-datepicker
316
- [field]="myForm.myDate">
317
- </ngxsmk-datepicker>
318
- ```
319
-
320
- 3. **No breaking changes** - all existing code continues to work
321
-
322
- ### Migrating to Zoneless
323
-
324
- 1. **Remove Zone.js** (optional):
325
- ```bash
326
- npm uninstall zone.js
327
- ```
328
-
329
- 2. **Update bootstrap** (if needed):
330
- ```typescript
331
- // No changes needed - component is already zoneless-ready
332
- ```
333
-
334
- 3. **Verify OnPush strategy** (already used):
335
- ```typescript
336
- // Component already uses OnPush
337
- changeDetection: ChangeDetectionStrategy.OnPush
338
- ```
339
-
340
- ### Enabling SSR
341
-
342
- 1. **Install Angular Universal**:
343
- ```bash
344
- ng add @angular/ssr
345
- ```
346
-
347
- 2. **Configure SSR**:
348
- ```typescript
349
- // app.config.ts
350
- import { provideClientHydration } from '@angular/platform-browser';
351
-
352
- export const appConfig: ApplicationConfig = {
353
- providers: [provideClientHydration()]
354
- };
355
- ```
356
-
357
- 3. **No component changes needed** - component is SSR-safe
358
-
359
- ## ⚠️ Known Limitations
360
-
361
- ### Angular 17
362
- - Effects support is limited (use signals/computed instead)
363
- - Signal Forms not available (use `[value]` binding)
364
-
365
- ### SSR
366
- - DOM-dependent features only work in browser (keyboard navigation, touch gestures)
367
- - Locale auto-detection falls back to 'en-US' on server
368
-
369
- ### Zoneless
370
- - Requires manual change detection (handled automatically by component)
371
- - Form integration works the same as with Zone.js
372
-
373
- ## πŸ§ͺ Testing Compatibility
374
-
375
- The component is tested against:
376
- - βœ… Angular 17, 18, 19, 20, 21
377
- - βœ… With and without Zone.js
378
- - βœ… SSR and CSR modes
379
- - βœ… Various browser environments
380
- - βœ… **Vitest Compatible**: Works in Angular 21 applications using Vitest-based test setups
381
- - Library tests use Karma/Jasmine, but the library itself is fully compatible with Vitest-based apps
382
- - No changes needed when using Vitest in your Angular 21 application
383
-
384
- ## πŸ†• Angular 21 New Features Support
385
-
386
- ### Signal Forms (Experimental)
387
- - βœ… **Full Support**: `[field]` input binding for direct Signal Forms integration
388
- - βœ… **Automatic Sync**: Two-way binding with signal form fields
389
- - βœ… **Validation**: Respects field validation and disabled state
390
- - βœ… **Server Integration**: Works with `httpResource` and `linkedSignal` patterns
391
-
392
- ### Zoneless by Default
393
- - βœ… **Fully Compatible**: Works in Angular 21 apps without Zone.js
394
- - βœ… **OnPush Strategy**: Uses OnPush change detection for optimal performance
395
- - βœ… **Signal-Based**: Leverages signals for reactive updates
396
- - βœ… **No Changes Needed**: Existing code works without modification
397
-
398
- ### Vitest Test Runner
399
- - βœ… **Compatible**: Library works in apps using Vitest-based setups
400
- - βœ… **No Migration Required**: Use the library as-is in Vitest-based projects
401
- - βœ… **Test Suite**: Library tests use Karma/Jasmine but library is Vitest-compatible
402
-
403
- ### Angular Aria Compatibility
404
- - βœ… **ARIA Support**: Built-in ARIA attributes and screen reader support
405
- - βœ… **AriaLiveService**: Custom service for live region announcements
406
- - βœ… **Compatible**: Works alongside Angular Aria components
407
- - βœ… **Accessibility First**: All interactive elements have proper ARIA labels
408
-
409
- ## πŸ“š Additional Resources
410
-
411
- - [Angular Signals Documentation](https://angular.dev/guide/signals)
412
- - [Angular SSR Guide](https://angular.dev/guide/ssr)
413
- - [Zoneless Angular Guide](https://angular.dev/guide/zoneless)
414
- - [Signal Forms Documentation](https://angular.dev/guide/forms/signal-forms)
415
- - [Vitest Documentation](https://vitest.dev/)
416
- - [Angular Aria Documentation](https://angular.dev/guide/accessibility/angular-aria)
417
-
418
- ## πŸ” Version Detection
419
-
420
- To check your Angular version:
421
-
422
- ```bash
423
- ng version
424
- ```
425
-
426
- To verify compatibility:
427
-
428
- ```bash
429
- npm list @angular/core @angular/common @angular/forms
430
- ```
431
-
432
- ## πŸ’‘ Best Practices
433
-
434
- 1. **Use Signal Forms** (Angular 21+): Prefer `[field]` input for better integration
435
- 2. **Enable SSR**: Improves SEO and initial load performance
436
- 3. **Consider Zoneless**: Better performance, component is ready
437
- 4. **Use OnPush**: Already enabled, ensures optimal change detection
438
- 5. **Platform Checks**: Component handles SSR/CSR automatically
439
-
440
- ## πŸ†˜ Troubleshooting
441
-
442
- ### Issue: Component not updating in zoneless app
443
- **Solution**: Component uses `markForCheck()` internally. Ensure you're using signals for reactive updates.
444
-
445
- ### Issue: SSR errors with DOM access
446
- **Solution**: Component guards all DOM access. Check if you're using any custom code that accesses DOM directly.
447
-
448
- ### Issue: Signal Forms not working (Angular 21+)
449
- **Solution**: Ensure you're using Angular 21+ and the `[field]` input with a signal form field.
450
-
451
- ### Issue: Translations not working in SSR
452
- **Solution**: Translations work in SSR. Ensure locale is explicitly set if auto-detection fails on server.
453
-
454
- ## CI and Angular peer matrix (maintainers)
455
-
456
- Recommended validation before tagging a release:
457
-
458
- | Step | Command | Notes |
459
- |------|---------|--------|
460
- | Library build | `npx ng build ngxsmk-datepicker --configuration production` | Ensures `dist/ngxsmk-datepicker` artifacts |
461
- | Unit tests | `npm run test:coverage` | Karma/Jasmine for `ngxsmk-datepicker` project |
462
- | Demo build | `npx ng build demo-app --configuration production` | Catches app integration issues |
463
- | Lint | `npm run lint` | ESLint across workspace |
464
- | E2E (optional CI) | `npm run e2e` with `BASE_URL` pointing at served demo | Playwright; set `CI=1` and start demo separately in pipelines |
465
-
466
- **Angular minors**: Keep `@angular/*` on the same minor within the workspace (`package.json`). Bump peers in library `projects/ngxsmk-datepicker/package.json` when raising supported ceiling; update this doc’s matrix table and peer JSON block together.
467
-
468
- **Ionic/Capacitor sample**: The `examples/ionic-test-app` project may require `npm install --legacy-peer-deps` when Ionic’s peers lag Angularβ€”see [examples/ionic-test-app/README.md](../../../examples/ionic-test-app/README.md).
469
-
470
-
471
-
1
+ # Version Compatibility Matrix
2
+
3
+ **Last updated:** July 2, 2026 - **Current stable:** v2.4.0
4
+
5
+ This document provides comprehensive compatibility information for `ngxsmk-datepicker` across different Angular versions, Zone.js configurations, and SSR/CSR setups.
6
+
7
+ ## πŸ“‹ Angular Version Compatibility
8
+
9
+ ### Compatibility Matrix
10
+
11
+ | Angular Version | Status | Core Features | Signal Features | Signal Forms | SSR Support | Notes |
12
+ |----------------|--------|--------------|----------------|--------------|-------------|-------|
13
+ | **Angular 17** | βœ… Fully Supported | βœ… All | βœ… Signals, Computed | ❌ Not Available | βœ… Full | Minimum supported version |
14
+ | **Angular 18** | βœ… Fully Supported | βœ… All | βœ… Signals, Computed, Effects | ❌ Not Available | βœ… Full | Enhanced signal support |
15
+ | **Angular 19** | βœ… Fully Supported | βœ… All | βœ… Signals, Computed, Effects | ❌ Not Available | βœ… Full | Optimized performance |
16
+ | **Angular 20** | βœ… Fully Supported | βœ… All | βœ… Signals, Computed, Effects | ❌ Not Available | βœ… Full | Fully supported |
17
+ | **Angular 21** | βœ… Fully Supported | βœ… All | βœ… Signals, Computed, Effects | βœ… Signal Forms `[field]` | βœ… Full | **Officially released - Current development target**<br/>βœ… Signal Forms (experimental)<br/>βœ… Zoneless by default<br/>βœ… Compatible with Vitest-based apps<br/>βœ… Angular Aria compatible |
18
+ | **Angular 22+** | πŸ”„ Future Support | βœ… All | βœ… Signals, Computed, Effects | βœ… Signal Forms `[field]` | βœ… Full | Peer dependency: `<24.0.0` |
19
+
20
+ ### Feature Availability by Angular Version
21
+
22
+ #### Core Features (Available in all versions)
23
+ - βœ… Date selection (single, range, multiple)
24
+ - βœ… Time selection
25
+ - βœ… Calendar views (month, year, decade, timeline, time-slider)
26
+ - βœ… Keyboard navigation
27
+ - βœ… Touch gestures
28
+ - βœ… RTL support
29
+ - βœ… Timezone support
30
+ - βœ… Custom formatting
31
+ - βœ… Holiday provider integration
32
+ - βœ… Custom hooks and extensions
33
+ - βœ… Accessibility (ARIA, keyboard)
34
+ - βœ… Theming (light/dark)
35
+ - βœ… Translations/i18n
36
+
37
+ #### Signal Features (Angular 17+)
38
+ - βœ… `signal()` - Reactive state management
39
+ - βœ… `computed()` - Derived reactive values
40
+ - βœ… `effect()` - Side effects (Angular 18+)
41
+ - βœ… `inject()` - Dependency injection
42
+
43
+ #### Signal Forms (Angular 21+)
44
+ - βœ… `[field]` input binding (experimental Angular 21 feature)
45
+ - βœ… Automatic field synchronization
46
+ - βœ… Reactive form field updates
47
+ - βœ… Signal-based value management
48
+ - βœ… Works with `form()`, `objectSchema()`, and `validators`
49
+ - βœ… Compatible with `httpResource` and `linkedSignal` patterns
50
+
51
+ #### Angular 21 New Features Compatibility
52
+ - βœ… **Zoneless by Default**: Fully compatible with Angular 21 apps that don't include Zone.js
53
+ - βœ… **Vitest Test Runner**: Library works in apps using Vitest-based setups
54
+ - βœ… **Angular Aria**: Compatible with Angular Aria components; uses custom ARIA implementation for screen reader support
55
+
56
+ ### Peer Dependencies
57
+
58
+ ```json
59
+ {
60
+ "@angular/common": ">=17.0.0 <24.0.0",
61
+ "@angular/core": ">=17.0.0 <24.0.0",
62
+ "@angular/forms": ">=17.0.0 <24.0.0"
63
+ }
64
+ ```
65
+
66
+ **Zone.js**: Optional (declared in `peerDependenciesMeta`)
67
+
68
+ ## πŸ”„ Zone.js vs Zoneless Compatibility
69
+
70
+ ### Overview
71
+
72
+ `ngxsmk-datepicker` is designed to work **with or without Zone.js**, making it compatible with both traditional Angular applications and modern zoneless applications.
73
+
74
+ ### Zone.js Required Features
75
+
76
+ | Feature | With Zone.js | Without Zone.js | Notes |
77
+ |---------|--------------|-----------------|-------|
78
+ | **Change Detection** | βœ… Automatic | βœ… Manual (OnPush) | Component uses `OnPush` strategy |
79
+ | **Form Integration** | βœ… Works | βœ… Works | Uses `ControlValueAccessor` |
80
+ | **Event Handling** | βœ… Works | βœ… Works | Native event listeners |
81
+ | **Signal Updates** | βœ… Works | βœ… Works | Signals trigger change detection |
82
+ | **Reactive Forms** | βœ… Works | βœ… Works | FormControl integration |
83
+ | **Signal Forms** | βœ… Works | βœ… Works | Angular 21+ signal forms |
84
+
85
+ ### Zoneless Setup
86
+
87
+ The component uses **OnPush change detection strategy** and **signals** for reactive updates, making it fully compatible with zoneless applications:
88
+
89
+ ```typescript
90
+ @Component({
91
+ selector: 'ngxsmk-datepicker',
92
+ changeDetection: ChangeDetectionStrategy.OnPush, // βœ… Zoneless compatible
93
+ // ...
94
+ })
95
+ ```
96
+
97
+ #### Manual Change Detection
98
+
99
+ When using without Zone.js, the component handles change detection internally:
100
+
101
+ ```typescript
102
+ // Component automatically calls markForCheck() when needed
103
+ private scheduleChangeDetection(): void {
104
+ if (!this._changeDetectionScheduled) {
105
+ this._changeDetectionScheduled = true;
106
+ Promise.resolve().then(() => {
107
+ this._changeDetectionScheduled = false;
108
+ this.cdr.markForCheck();
109
+ });
110
+ }
111
+ }
112
+ ```
113
+
114
+ #### Signal-Based Reactivity
115
+
116
+ The component uses Angular signals for reactive state:
117
+
118
+ ```typescript
119
+ // Reactive calendar open state
120
+ private _isCalendarOpen = signal<boolean>(false);
121
+
122
+ // Computed dependencies for memoization
123
+ private _memoDependencies = computed(() => ({
124
+ month: this._currentMonthSignal(),
125
+ year: this._currentYearSignal(),
126
+ // ...
127
+ }));
128
+ ```
129
+
130
+ ### Zone.js Configuration
131
+
132
+ #### With Zone.js (Default)
133
+
134
+ ```typescript
135
+ // main.ts
136
+ import { bootstrapApplication } from '@angular/platform-browser';
137
+ import { AppComponent } from './app/app.component';
138
+
139
+ bootstrapApplication(AppComponent);
140
+ // Zone.js is automatically included
141
+ ```
142
+
143
+ #### Without Zone.js (Zoneless)
144
+
145
+ ```typescript
146
+ // main.ts
147
+ import { bootstrapApplication } from '@angular/platform-browser';
148
+ import { AppComponent } from './app/app.component';
149
+
150
+ bootstrapApplication(AppComponent, {
151
+ providers: [
152
+ // No Zone.js provider needed
153
+ // Component works with OnPush + signals
154
+ ]
155
+ });
156
+ ```
157
+
158
+ ### Migration Guide: Zone.js β†’ Zoneless
159
+
160
+ 1. **Remove Zone.js dependency** (if desired)
161
+ 2. **Ensure OnPush strategy** (already used by component)
162
+ 3. **Use signals for state** (component already uses signals)
163
+ 4. **No code changes needed** - component is zoneless-ready
164
+
165
+ ## 🌐 SSR vs CSR Compatibility
166
+
167
+ ### Server-Side Rendering (SSR)
168
+
169
+ The component is **fully compatible** with Angular Universal and SSR.
170
+
171
+ #### SSR-Safe Features
172
+
173
+ | Feature | SSR Support | Implementation |
174
+ |---------|-------------|----------------|
175
+ | **Platform Detection** | βœ… Safe | Uses `isPlatformBrowser()` and `PLATFORM_ID` |
176
+ | **DOM Access** | βœ… Safe | Guarded with `isBrowser` checks |
177
+ | **Event Listeners** | βœ… Safe | Only attached in browser |
178
+ | **Date Formatting** | βœ… Safe | Uses `Intl` API (available in Node.js) |
179
+ | **Local Storage** | βœ… Safe | Not used |
180
+ | **Window/Document** | βœ… Safe | Guarded with platform checks |
181
+
182
+ #### SSR Implementation Details
183
+
184
+ ```typescript
185
+ // Platform detection
186
+ private readonly platformId = inject(PLATFORM_ID);
187
+ private readonly isBrowser = isPlatformBrowser(this.platformId);
188
+
189
+ // Safe DOM access
190
+ if (this.isBrowser && typeof document !== 'undefined') {
191
+ // Browser-only code
192
+ document.documentElement.dir === 'rtl';
193
+ }
194
+
195
+ // Safe event listeners
196
+ if (this.isBrowser) {
197
+ // Attach event listeners
198
+ }
199
+ ```
200
+
201
+ #### SSR-Specific Considerations
202
+
203
+ 1. **Initial Render**: Component renders safely on server
204
+ 2. **Hydration**: Client-side hydration works correctly
205
+ 3. **Date Formatting**: Uses `Intl.DateTimeFormat` (available in Node.js 13+)
206
+ 4. **Locale Detection**: Falls back to 'en-US' on server if `navigator` is unavailable
207
+
208
+ ### Client-Side Rendering (CSR)
209
+
210
+ All features work identically in CSR mode. No special configuration needed.
211
+
212
+ ### SSR vs CSR Differences
213
+
214
+ | Aspect | SSR | CSR | Notes |
215
+ |--------|-----|-----|-------|
216
+ | **Initial Render** | Server | Browser | Component renders on both |
217
+ | **DOM Access** | ❌ Not Available | βœ… Available | Guarded with `isPlatformBrowser()` |
218
+ | **Event Listeners** | ❌ Not Attached | βœ… Attached | Only in browser |
219
+ | **Date Formatting** | βœ… Works | βœ… Works | Uses `Intl` API |
220
+ | **Locale Detection** | ⚠️ Limited | βœ… Full | Server uses default, browser detects |
221
+ | **Performance** | βœ… Fast Initial Load | βœ… Interactive | SSR improves SEO and initial load |
222
+
223
+ ### SSR Setup Example
224
+
225
+ ```typescript
226
+ // app.config.ts
227
+ import { ApplicationConfig } from '@angular/core';
228
+ import { provideClientHydration } from '@angular/platform-browser';
229
+
230
+ export const appConfig: ApplicationConfig = {
231
+ providers: [
232
+ provideClientHydration(), // Enable SSR hydration
233
+ // ... other providers
234
+ ]
235
+ };
236
+ ```
237
+
238
+ ```typescript
239
+ // Component usage (works in both SSR and CSR)
240
+ @Component({
241
+ template: `
242
+ <ngxsmk-datepicker
243
+ [locale]="'en-US'"
244
+ mode="single">
245
+ </ngxsmk-datepicker>
246
+ `
247
+ })
248
+ export class MyComponent {
249
+ // Component automatically handles SSR/CSR differences
250
+ }
251
+ ```
252
+
253
+ ## 🧩 Shadow DOM & Web Components Compatibility
254
+
255
+ `ngxsmk-datepicker` is fully compatible with **Shadow DOM encapsulation** (`ViewEncapsulation.ShadowDom`) and deployment as an **Angular Element (Custom Web Component)** inside other frameworks (React, Vue, etc.).
256
+
257
+ ### Composed Path Event Retargeting
258
+ When components are loaded inside a Shadow root, the browser retargets event targets when they bubble outside of the Shadow boundary. Standard `.contains()` checks on the host node will fail when checking external interaction listeners (e.g. document close listeners).
259
+
260
+ `ngxsmk-datepicker` natively handles this by tracking event composed paths:
261
+ * Inspects `event.composedPath()` when available to accurately check event origins inside Shadow DOM trees.
262
+ * Falls back to standard light DOM `.contains(target)` when composed paths are not supported by the environment.
263
+ * Supported across both the primary Datepicker component and Custom Select dropdown components.
264
+
265
+ ## πŸ”§ Feature Compatibility Matrix
266
+
267
+ ### By Angular Version
268
+
269
+ | Feature | Angular 17 | Angular 18 | Angular 19 | Angular 20 | Angular 21+ |
270
+ |---------|------------|-----------|------------|------------|-------------|
271
+ | **Standalone Component** | βœ… | βœ… | βœ… | βœ… | βœ… |
272
+ | **Signals** | βœ… | βœ… | βœ… | βœ… | βœ… |
273
+ | **Shadow DOM Support** | βœ… | βœ… | βœ… | βœ… | βœ… |
274
+ | **Computed Signals** | βœ… | βœ… | βœ… | βœ… | βœ… |
275
+ | **Effects** | ⚠️ Limited | βœ… | βœ… | βœ… | βœ… |
276
+ | **Signal Forms** | ❌ | ❌ | ❌ | ❌ | βœ… |
277
+ | **ControlValueAccessor** | βœ… | βœ… | βœ… | βœ… | βœ… |
278
+ | **Reactive Forms** | βœ… | βœ… | βœ… | βœ… | βœ… |
279
+ | **OnPush Strategy** | βœ… | βœ… | βœ… | βœ… | βœ… |
280
+ | **SSR Support** | βœ… | βœ… | βœ… | βœ… | βœ… |
281
+ | **Zoneless Support** | βœ… | βœ… | βœ… | βœ… | βœ… |
282
+ | **Translations/i18n** | βœ… | βœ… | βœ… | βœ… | βœ… |
283
+ | **Locale Registry** | βœ… | βœ… | βœ… | βœ… | βœ… |
284
+
285
+ ### By Configuration
286
+
287
+ | Configuration | Zone.js | Zoneless | SSR | CSR |
288
+ |---------------|---------|----------|-----|-----|
289
+ | **Change Detection** | βœ… Auto | βœ… Manual | βœ… Works | βœ… Works |
290
+ | **Form Integration** | βœ… Works | βœ… Works | βœ… Works | βœ… Works |
291
+ | **Event Handling** | βœ… Works | βœ… Works | ⚠️ Browser Only | βœ… Works |
292
+ | **Signal Updates** | βœ… Works | βœ… Works | βœ… Works | βœ… Works |
293
+ | **Date Formatting** | βœ… Works | βœ… Works | βœ… Works | βœ… Works |
294
+ | **Keyboard Navigation** | βœ… Works | βœ… Works | ⚠️ Browser Only | βœ… Works |
295
+ | **Touch Gestures** | βœ… Works | βœ… Works | ⚠️ Browser Only | βœ… Works |
296
+
297
+ ## πŸ“ Migration Guides
298
+
299
+ ### Upgrading from Angular 17 to 21
300
+
301
+ 1. **Update Angular dependencies**:
302
+ ```bash
303
+ ng update @angular/core @angular/cli
304
+ ```
305
+
306
+ 2. **Enable Signal Forms** (Angular 21+):
307
+ ```typescript
308
+ // Before (Angular 17-20)
309
+ <ngxsmk-datepicker
310
+ [value]="dateValue"
311
+ (valueChange)="dateValue = $event">
312
+ </ngxsmk-datepicker>
313
+
314
+ // After (Angular 21+)
315
+ <ngxsmk-datepicker
316
+ [field]="myForm.myDate">
317
+ </ngxsmk-datepicker>
318
+ ```
319
+
320
+ 3. **No breaking changes** - all existing code continues to work
321
+
322
+ ### Migrating to Zoneless
323
+
324
+ 1. **Remove Zone.js** (optional):
325
+ ```bash
326
+ npm uninstall zone.js
327
+ ```
328
+
329
+ 2. **Update bootstrap** (if needed):
330
+ ```typescript
331
+ // No changes needed - component is already zoneless-ready
332
+ ```
333
+
334
+ 3. **Verify OnPush strategy** (already used):
335
+ ```typescript
336
+ // Component already uses OnPush
337
+ changeDetection: ChangeDetectionStrategy.OnPush
338
+ ```
339
+
340
+ ### Enabling SSR
341
+
342
+ 1. **Install Angular Universal**:
343
+ ```bash
344
+ ng add @angular/ssr
345
+ ```
346
+
347
+ 2. **Configure SSR**:
348
+ ```typescript
349
+ // app.config.ts
350
+ import { provideClientHydration } from '@angular/platform-browser';
351
+
352
+ export const appConfig: ApplicationConfig = {
353
+ providers: [provideClientHydration()]
354
+ };
355
+ ```
356
+
357
+ 3. **No component changes needed** - component is SSR-safe
358
+
359
+ ## ⚠️ Known Limitations
360
+
361
+ ### Angular 17
362
+ - Effects support is limited (use signals/computed instead)
363
+ - Signal Forms not available (use `[value]` binding)
364
+
365
+ ### SSR
366
+ - DOM-dependent features only work in browser (keyboard navigation, touch gestures)
367
+ - Locale auto-detection falls back to 'en-US' on server
368
+
369
+ ### Zoneless
370
+ - Requires manual change detection (handled automatically by component)
371
+ - Form integration works the same as with Zone.js
372
+
373
+ ## πŸ§ͺ Testing Compatibility
374
+
375
+ The component is tested against:
376
+ - βœ… Angular 17, 18, 19, 20, 21
377
+ - βœ… With and without Zone.js
378
+ - βœ… SSR and CSR modes
379
+ - βœ… Various browser environments
380
+ - βœ… **Vitest Compatible**: Works in Angular 21 applications using Vitest-based test setups
381
+ - Library tests use Karma/Jasmine, but the library itself is fully compatible with Vitest-based apps
382
+ - No changes needed when using Vitest in your Angular 21 application
383
+
384
+ ## πŸ†• Angular 21 New Features Support
385
+
386
+ ### Signal Forms (Experimental)
387
+ - βœ… **Full Support**: `[field]` input binding for direct Signal Forms integration
388
+ - βœ… **Automatic Sync**: Two-way binding with signal form fields
389
+ - βœ… **Validation**: Respects field validation and disabled state
390
+ - βœ… **Server Integration**: Works with `httpResource` and `linkedSignal` patterns
391
+
392
+ ### Zoneless by Default
393
+ - βœ… **Fully Compatible**: Works in Angular 21 apps without Zone.js
394
+ - βœ… **OnPush Strategy**: Uses OnPush change detection for optimal performance
395
+ - βœ… **Signal-Based**: Leverages signals for reactive updates
396
+ - βœ… **No Changes Needed**: Existing code works without modification
397
+
398
+ ### Vitest Test Runner
399
+ - βœ… **Compatible**: Library works in apps using Vitest-based setups
400
+ - βœ… **No Migration Required**: Use the library as-is in Vitest-based projects
401
+ - βœ… **Test Suite**: Library tests use Karma/Jasmine but library is Vitest-compatible
402
+
403
+ ### Angular Aria Compatibility
404
+ - βœ… **ARIA Support**: Built-in ARIA attributes and screen reader support
405
+ - βœ… **AriaLiveService**: Custom service for live region announcements
406
+ - βœ… **Compatible**: Works alongside Angular Aria components
407
+ - βœ… **Accessibility First**: All interactive elements have proper ARIA labels
408
+
409
+ ## πŸ“š Additional Resources
410
+
411
+ - [Angular Signals Documentation](https://angular.dev/guide/signals)
412
+ - [Angular SSR Guide](https://angular.dev/guide/ssr)
413
+ - [Zoneless Angular Guide](https://angular.dev/guide/zoneless)
414
+ - [Signal Forms Documentation](https://angular.dev/guide/forms/signal-forms)
415
+ - [Vitest Documentation](https://vitest.dev/)
416
+ - [Angular Aria Documentation](https://angular.dev/guide/accessibility/angular-aria)
417
+
418
+ ## πŸ” Version Detection
419
+
420
+ To check your Angular version:
421
+
422
+ ```bash
423
+ ng version
424
+ ```
425
+
426
+ To verify compatibility:
427
+
428
+ ```bash
429
+ npm list @angular/core @angular/common @angular/forms
430
+ ```
431
+
432
+ ## πŸ’‘ Best Practices
433
+
434
+ 1. **Use Signal Forms** (Angular 21+): Prefer `[field]` input for better integration
435
+ 2. **Enable SSR**: Improves SEO and initial load performance
436
+ 3. **Consider Zoneless**: Better performance, component is ready
437
+ 4. **Use OnPush**: Already enabled, ensures optimal change detection
438
+ 5. **Platform Checks**: Component handles SSR/CSR automatically
439
+
440
+ ## πŸ†˜ Troubleshooting
441
+
442
+ ### Issue: Component not updating in zoneless app
443
+ **Solution**: Component uses `markForCheck()` internally. Ensure you're using signals for reactive updates.
444
+
445
+ ### Issue: SSR errors with DOM access
446
+ **Solution**: Component guards all DOM access. Check if you're using any custom code that accesses DOM directly.
447
+
448
+ ### Issue: Signal Forms not working (Angular 21+)
449
+ **Solution**: Ensure you're using Angular 21+ and the `[field]` input with a signal form field.
450
+
451
+ ### Issue: Translations not working in SSR
452
+ **Solution**: Translations work in SSR. Ensure locale is explicitly set if auto-detection fails on server.
453
+
454
+ ## CI and Angular peer matrix (maintainers)
455
+
456
+ Recommended validation before tagging a release:
457
+
458
+ | Step | Command | Notes |
459
+ |------|---------|--------|
460
+ | Library build | `npx ng build ngxsmk-datepicker --configuration production` | Ensures `dist/ngxsmk-datepicker` artifacts |
461
+ | Unit tests | `npm run test:coverage` | Karma/Jasmine for `ngxsmk-datepicker` project |
462
+ | Demo build | `npx ng build demo-app --configuration production` | Catches app integration issues |
463
+ | Lint | `npm run lint` | ESLint across workspace |
464
+ | E2E (optional CI) | `npm run e2e` with `BASE_URL` pointing at served demo | Playwright; set `CI=1` and start demo separately in pipelines |
465
+
466
+ **Angular minors**: Keep `@angular/*` on the same minor within the workspace (`package.json`). Bump peers in library `projects/ngxsmk-datepicker/package.json` when raising supported ceiling; update this doc’s matrix table and peer JSON block together.
467
+
468
+ **Ionic/Capacitor sample**: The `examples/ionic-test-app` project may require `npm install --legacy-peer-deps` when Ionic’s peers lag Angularβ€”see [examples/ionic-test-app/README.md](../../../examples/ionic-test-app/README.md).
469
+
470
+
471
+