@oneluiz/dual-datepicker 2.4.0 β†’ 2.6.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.
package/README.md CHANGED
@@ -1,30 +1,84 @@
1
- # @oneluiz/dual-datepicker
1
+ # ng-dual-datepicker
2
2
 
3
- A beautiful, customizable dual-calendar date range picker for Angular 17+. Built as a standalone component with full TypeScript support.
3
+ A lightweight, zero-dependency date range picker for Angular 17+. Built with standalone components, Reactive Forms, and Angular Signals. No Angular Material required.
4
4
 
5
5
  [![npm version](https://img.shields.io/npm/v/@oneluiz/dual-datepicker)](https://www.npmjs.com/package/@oneluiz/dual-datepicker)
6
6
  ![license](https://img.shields.io/npm/l/@oneluiz/dual-datepicker)
7
7
  ![Angular](https://img.shields.io/badge/Angular-17%2B-red)
8
8
 
9
+ ```bash
10
+ npm install @oneluiz/dual-datepicker
11
+ ```
12
+
9
13
  ## 🎯 [Live Demo](https://oneluiz.github.io/ng-dual-datepicker/)
10
14
 
11
15
  **[Check out the interactive examples β†’](https://oneluiz.github.io/ng-dual-datepicker/)**
12
16
 
13
- ## ✨ Features
14
-
15
- - πŸ“… **Dual Calendar Display** - Side-by-side month view for easy range selection
16
- - 🎨 **Fully Customizable** - Color scheme, padding, and styling
17
- - ⚑ **Preset Ranges** - Configurable quick-select options
18
- - 🧹 **Clear Button** - Built-in button to reset selection
19
- - 🎯 **Standalone Component** - No module imports required
20
- - πŸš€ **Zero Dependencies** - No Bootstrap or other CSS frameworks required
21
- - 🌍 **i18n Support** - Customizable month and day names for any language
22
- - πŸ“± **Responsive Design** - Works on desktop and mobile
23
- - 🌐 **TypeScript** - Full type safety
24
- - β™Ώ **Accessible** - Keyboard navigation and ARIA labels
25
- - 🎭 **Flexible Behavior** - Control when the picker closes
26
- - πŸ”„ **Reactive Forms Support** - Full ControlValueAccessor implementation
27
- - ⚑ **Angular Signals** - Modern reactive state management
17
+ ## Why ng-dual-datepicker?
18
+
19
+ | Feature | ng-dual-datepicker | Angular Material DateRangePicker |
20
+ |---------|-------------------|----------------------------------|
21
+ | **Bundle Size** | ~60 KB gzipped | ~300+ KB (with dependencies) |
22
+ | **Dependencies** | Zero | Requires @angular/material, @angular/cdk |
23
+ | **Standalone** | βœ… Native | ⚠️ Requires module setup |
24
+ | **Signals Support** | βœ… Built-in | ❌ Not yet |
25
+ | **Customization** | Full styling control | Theme-constrained |
26
+ | **Learning Curve** | Minimal | Requires Material knowledge |
27
+ | **Change Detection** | OnPush optimized | Default |
28
+ | **Setup Time** | < 1 minute | ~10+ minutes (theming, modules) |
29
+
30
+ ## ✨ Key Features
31
+
32
+ - πŸͺΆ **Zero Dependencies** – No external libraries required
33
+ - 🎯 **Standalone Component** – No NgModule imports needed
34
+ - ⚑ **Angular Signals** – Modern reactive state management
35
+ - πŸ”„ **Reactive Forms** – Full ControlValueAccessor implementation
36
+ - 🎨 **Fully Customizable** – Every color, padding, border configurable
37
+ - πŸ“¦ **Lightweight** – ~60 KB gzipped total bundle
38
+ - πŸš€ **Performance** – OnPush change detection + trackBy optimization
39
+ - β™Ώ **Accessible** – ARIA labels, semantic HTML, keyboard navigation (in progress)
40
+ - 🌍 **i18n Ready** – Customizable month/day names
41
+ - πŸ“± **Responsive** – Works on desktop and mobile
42
+
43
+ ## πŸ€” When Should I Use This?
44
+
45
+ **Use ng-dual-datepicker if you:**
46
+ - Don't want to install Angular Material just for a date picker
47
+ - Need precise control over styling and behavior
48
+ - Want minimal bundle size impact
49
+ - Prefer standalone components over NgModules
50
+ - Need Angular Signals support now
51
+ - Are building a custom design system
52
+
53
+ **Use Angular Material DateRangePicker if you:**
54
+ - Already use Angular Material throughout your app
55
+ - Need Material Design compliance
56
+ - Want a battle-tested enterprise solution with extensive ecosystem support
57
+
58
+ ## ⚑ Performance
59
+
60
+ ```typescript
61
+ @Component({
62
+ changeDetection: ChangeDetectionStrategy.OnPush, // βœ… Optimized
63
+ standalone: true // βœ… No module overhead
64
+ })
65
+ ```
66
+
67
+ - **OnPush change detection** – Minimal re-renders
68
+ - **trackBy functions** – Efficient list rendering
69
+ - **No external CSS** – No runtime stylesheet downloads
70
+ - **Tree-shakeable** – Only import what you use
71
+
72
+ ## β™Ώ Accessibility (A11y)
73
+
74
+ **Current Status:**
75
+ - βœ… **Screen reader support** - ARIA labels included for all interactive elements
76
+ - βœ… **Semantic HTML** - Proper HTML structure
77
+ - 🚧 **Full keyboard navigation** - In active development (see [Roadmap](#-roadmap))
78
+ - Mouse/touch interaction: βœ… Fully supported
79
+ - Keyboard navigation: 🚧 In progress
80
+
81
+ > **Note:** Full keyboard navigation support is planned and will be included in a future release. This includes arrow key navigation, Enter/Space selection, and Escape to close.
28
82
 
29
83
  ## πŸ“¦ Installation
30
84
 
@@ -34,7 +88,7 @@ npm install @oneluiz/dual-datepicker
34
88
 
35
89
  ## πŸš€ Quick Start
36
90
 
37
- ### 1. Import the Component
91
+ ### Basic Usage
38
92
 
39
93
  ```typescript
40
94
  import { Component } from '@angular/core';
@@ -46,104 +100,58 @@ import { DualDatepickerComponent, DateRange } from '@oneluiz/dual-datepicker';
46
100
  imports: [DualDatepickerComponent],
47
101
  template: `
48
102
  <ngx-dual-datepicker
49
- [(ngModel)]="dateRange"
50
- placeholder="Select date range">
103
+ (dateRangeChange)="onRangeChange($event)">
51
104
  </ngx-dual-datepicker>
52
105
  `
53
106
  })
54
107
  export class AppComponent {
55
- dateRange: DateRange = { start: null, end: null };
108
+ onRangeChange(range: DateRange) {
109
+ console.log('Start:', range.fechaInicio);
110
+ console.log('End:', range.fechaFin);
111
+ }
56
112
  }
57
113
  ```
58
114
 
59
- ### 2. Use with Forms
115
+ ### With Reactive Forms
60
116
 
61
117
  ```typescript
62
- import { Component } from '@angular/core';
63
- import { FormsModule } from '@angular/forms';
64
- import { DualDatepickerComponent } from '@oneluiz/dual-datepicker';
118
+ import { FormControl } from '@angular/forms';
119
+ import { DateRange } from '@oneluiz/dual-datepicker';
65
120
 
66
- @Component({
67
- selector: 'app-example',
68
- standalone: true,
69
- imports: [FormsModule, DualDatepickerComponent],
70
- template: `
71
- <ngx-dual-datepicker
72
- [fechaInicio]="fechaInicio"
73
- [fechaFin]="fechaFin"
74
- [presets]="customPresets"
75
- (dateRangeChange)="onDateChange($event)">
76
- </ngx-dual-datepicker>
77
- `
78
- })
79
- export class ExampleComponent {
80
- fechaInicio = '';
81
- fechaFin = '';
82
-
83
- customPresets = [
84
- { label: 'Last 7 days', daysAgo: 7 },
85
- { label: 'Last 30 days', daysAgo: 30 },
86
- { label: 'Last 90 days', daysAgo: 90 }
87
- ];
121
+ dateRange = new FormControl<DateRange | null>(null);
122
+ ```
88
123
 
89
- onDateChange(range: DateRange) {
90
- console.log('Date range selected:', range);
91
- this.fechaInicio = range.fechaInicio;
92
- this.fechaFin = range.fechaFin;
93
- }
94
- }
124
+ ```html
125
+ <ngx-dual-datepicker [formControl]="dateRange"></ngx-dual-datepicker>
95
126
  ```
96
127
 
97
- ### 3. Use with Reactive Forms ✨ New!
128
+ ### With Angular Signals
98
129
 
99
130
  ```typescript
100
- import { Component, OnInit } from '@angular/core';
101
- import { FormBuilder, FormGroup, ReactiveFormsModule } from '@angular/forms';
102
- import { DualDatepickerComponent, DateRange } from '@oneluiz/dual-datepicker';
131
+ import { signal } from '@angular/core';
103
132
 
104
- @Component({
105
- selector: 'app-reactive-form',
106
- standalone: true,
107
- imports: [ReactiveFormsModule, DualDatepickerComponent],
108
- template: `
109
- <form [formGroup]="form" (ngSubmit)="onSubmit()">
110
- <label>Select Date Range:</label>
111
- <ngx-dual-datepicker
112
- formControlName="dateRange"
113
- placeholder="Choose dates"
114
- [showClearButton]="true">
115
- </ngx-dual-datepicker>
116
-
117
- <button type="submit" [disabled]="!form.valid">Submit</button>
118
-
119
- @if (form.value.dateRange) {
120
- <div>
121
- Selected: {{ form.value.dateRange.fechaInicio }} to {{ form.value.dateRange.fechaFin }}
122
- </div>
123
- }
124
- </form>
125
- `
126
- })
127
- export class ReactiveFormComponent implements OnInit {
128
- form!: FormGroup;
133
+ dateRange = signal<DateRange | null>(null);
134
+ ```
129
135
 
130
- constructor(private fb: FormBuilder) {}
136
+ ```html
137
+ <ngx-dual-datepicker
138
+ [(ngModel)]="dateRange()"
139
+ (dateRangeChange)="dateRange.set($event)">
140
+ </ngx-dual-datepicker>
141
+ ```
131
142
 
132
- ngOnInit() {
133
- this.form = this.fb.group({
134
- dateRange: [null] // Will receive DateRange object
135
- });
136
-
137
- // Listen to changes
138
- this.form.get('dateRange')?.valueChanges.subscribe(value => {
139
- console.log('Date range changed:', value);
140
- });
141
- }
143
+ ### Custom Styling
142
144
 
143
- onSubmit() {
144
- const dateRange: DateRange = this.form.value.dateRange;
145
- console.log('Form submitted:', dateRange);
146
- }
145
+ ```html
146
+ <ngx-dual-datepicker
147
+ inputBackgroundColor="#1a1a2e"
148
+ inputTextColor="#eee"
149
+ inputBorderColor="#4a5568"
150
+ inputBorderColorFocus="#3182ce">
151
+ </ngx-dual-datepicker>
152
+ ```
153
+
154
+ ## πŸ“š Advanced Usage
147
155
  }
148
156
  ```
149
157
 
@@ -203,6 +211,221 @@ export class SignalsExampleComponent {
203
211
  }
204
212
  ```
205
213
 
214
+ ## πŸ”Œ Date Adapter System
215
+
216
+ The library supports custom date adapters, allowing you to use different date libraries (DayJS, date-fns, Luxon) or custom backend models instead of native JavaScript `Date` objects.
217
+
218
+ ### Using Native Date (Default)
219
+
220
+ By default, the component uses `NativeDateAdapter` which works with JavaScript `Date` objects:
221
+
222
+ ```typescript
223
+ import { DualDatepickerComponent } from '@oneluiz/dual-datepicker';
224
+
225
+ @Component({
226
+ standalone: true,
227
+ imports: [DualDatepickerComponent],
228
+ template: `<ngx-dual-datepicker></ngx-dual-datepicker>`
229
+ })
230
+ export class AppComponent {}
231
+ ```
232
+
233
+ ### Creating a Custom Adapter
234
+
235
+ Example using **date-fns**:
236
+
237
+ ```typescript
238
+ import { Injectable } from '@angular/core';
239
+ import { DateAdapter } from '@oneluiz/dual-datepicker';
240
+ import {
241
+ parse, format, addDays, addMonths,
242
+ getYear, getMonth, getDate, getDay,
243
+ isSameDay, isBefore, isAfter, isWithinInterval,
244
+ isValid
245
+ } from 'date-fns';
246
+
247
+ @Injectable()
248
+ export class DateFnsAdapter extends DateAdapter<Date> {
249
+ parse(value: any): Date | null {
250
+ if (!value) return null;
251
+ if (value instanceof Date) return value;
252
+
253
+ const parsed = parse(value, 'yyyy-MM-dd', new Date());
254
+ return isValid(parsed) ? parsed : null;
255
+ }
256
+
257
+ format(date: Date, formatStr: string = 'yyyy-MM-dd'): string {
258
+ return format(date, formatStr);
259
+ }
260
+
261
+ addDays(date: Date, days: number): Date {
262
+ return addDays(date, days);
263
+ }
264
+
265
+ addMonths(date: Date, months: number): Date {
266
+ return addMonths(date, months);
267
+ }
268
+
269
+ getYear(date: Date): number {
270
+ return getYear(date);
271
+ }
272
+
273
+ getMonth(date: Date): number {
274
+ return getMonth(date);
275
+ }
276
+
277
+ getDate(date: Date): number {
278
+ return getDate(date);
279
+ }
280
+
281
+ getDay(date: Date): number {
282
+ return getDay(date);
283
+ }
284
+
285
+ createDate(year: number, month: number, day: number): Date {
286
+ return new Date(year, month, day);
287
+ }
288
+
289
+ today(): Date {
290
+ return new Date();
291
+ }
292
+
293
+ isSameDay(a: Date | null, b: Date | null): boolean {
294
+ if (!a || !b) return false;
295
+ return isSameDay(a, b);
296
+ }
297
+
298
+ isBefore(a: Date | null, b: Date | null): boolean {
299
+ if (!a || !b) return false;
300
+ return isBefore(a, b);
301
+ }
302
+
303
+ isAfter(a: Date | null, b: Date | null): boolean {
304
+ if (!a || !b) return false;
305
+ return isAfter(a, b);
306
+ }
307
+
308
+ isBetween(date: Date | null, start: Date | null, end: Date | null): boolean {
309
+ if (!date || !start || !end) return false;
310
+ return isWithinInterval(date, { start, end });
311
+ }
312
+
313
+ clone(date: Date): Date {
314
+ return new Date(date);
315
+ }
316
+
317
+ isValid(date: any): boolean {
318
+ return isValid(date);
319
+ }
320
+ }
321
+ ```
322
+
323
+ ### Providing Custom Adapter
324
+
325
+ ```typescript
326
+ import { Component } from '@angular/core';
327
+ import { DualDatepickerComponent, DATE_ADAPTER } from '@oneluiz/dual-datepicker';
328
+ import { DateFnsAdapter } from './date-fns-adapter';
329
+
330
+ @Component({
331
+ standalone: true,
332
+ imports: [DualDatepickerComponent],
333
+ providers: [
334
+ { provide: DATE_ADAPTER, useClass: DateFnsAdapter }
335
+ ],
336
+ template: `<ngx-dual-datepicker></ngx-dual-datepicker>`
337
+ })
338
+ export class AppComponent {}
339
+ ```
340
+
341
+ ### Example: DayJS Adapter
342
+
343
+ ```typescript
344
+ import { Injectable } from '@angular/core';
345
+ import { DateAdapter } from '@oneluiz/dual-datepicker';
346
+ import dayjs, { Dayjs } from 'dayjs';
347
+
348
+ @Injectable()
349
+ export class DayJSAdapter extends DateAdapter<Dayjs> {
350
+ parse(value: any): Dayjs | null {
351
+ if (!value) return null;
352
+ const parsed = dayjs(value);
353
+ return parsed.isValid() ? parsed : null;
354
+ }
355
+
356
+ format(date: Dayjs, format: string = 'YYYY-MM-DD'): string {
357
+ return date.format(format);
358
+ }
359
+
360
+ addDays(date: Dayjs, days: number): Dayjs {
361
+ return date.add(days, 'day');
362
+ }
363
+
364
+ addMonths(date: Dayjs, months: number): Dayjs {
365
+ return date.add(months, 'month');
366
+ }
367
+
368
+ getYear(date: Dayjs): number {
369
+ return date.year();
370
+ }
371
+
372
+ getMonth(date: Dayjs): number {
373
+ return date.month();
374
+ }
375
+
376
+ getDate(date: Dayjs): number {
377
+ return date.date();
378
+ }
379
+
380
+ getDay(date: Dayjs): number {
381
+ return date.day();
382
+ }
383
+
384
+ createDate(year: number, month: number, day: number): Dayjs {
385
+ return dayjs().year(year).month(month).date(day);
386
+ }
387
+
388
+ today(): Dayjs {
389
+ return dayjs();
390
+ }
391
+
392
+ isSameDay(a: Dayjs | null, b: Dayjs | null): boolean {
393
+ if (!a || !b) return false;
394
+ return a.isSame(b, 'day');
395
+ }
396
+
397
+ isBefore(a: Dayjs | null, b: Dayjs | null): boolean {
398
+ if (!a || !b) return false;
399
+ return a.isBefore(b);
400
+ }
401
+
402
+ isAfter(a: Dayjs | null, b: Dayjs | null): boolean {
403
+ if (!a || !b) return false;
404
+ return a.isAfter(b);
405
+ }
406
+
407
+ isBetween(date: Dayjs | null, start: Dayjs | null, end: Dayjs | null): boolean {
408
+ if (!date || !start || !end) return false;
409
+ return date.isAfter(start) && date.isBefore(end) || date.isSame(start) || date.isSame(end);
410
+ }
411
+
412
+ clone(date: Dayjs): Dayjs {
413
+ return date.clone();
414
+ }
415
+
416
+ isValid(date: any): boolean {
417
+ return dayjs.isDayjs(date) && date.isValid();
418
+ }
419
+ }
420
+ ```
421
+
422
+ ### Benefits of Date Adapters
423
+
424
+ - βœ… **Zero vendor lock-in** - Use any date library you prefer
425
+ - βœ… **Consistency** - Use the same date library across your entire app
426
+ - βœ… **Custom backend models** - Adapt to your API's date format
427
+ - βœ… **Type safety** - Full TypeScript support with generics
428
+
206
429
  ## 🎨 Customization
207
430
 
208
431
  ### Custom Colors (Bootstrap Style)
@@ -233,7 +456,11 @@ export class SignalsExampleComponent {
233
456
  </ngx-dual-datepicker>
234
457
  ```
235
458
 
236
- ### Custom Presets
459
+ ### ⚑ Custom Presets (Power Feature)
460
+
461
+ **This is where our library shines!** Unlike Angular Material, we offer an incredibly flexible preset system perfect for dashboards, reporting, POS, BI apps, and ERP systems.
462
+
463
+ #### Simple Pattern (Backward Compatible)
237
464
 
238
465
  ```typescript
239
466
  customPresets: PresetConfig[] = [
@@ -244,6 +471,132 @@ customPresets: PresetConfig[] = [
244
471
  ];
245
472
  ```
246
473
 
474
+ #### **NEW v2.6.0** - Flexible Pattern with `getValue()` πŸ”₯
475
+
476
+ The real power comes with the `getValue()` pattern. Define **any custom logic** you need:
477
+
478
+ ```typescript
479
+ import { PresetConfig } from '@oneluiz/dual-datepicker';
480
+
481
+ customPresets: PresetConfig[] = [
482
+ {
483
+ label: 'Today',
484
+ getValue: () => {
485
+ const today = new Date();
486
+ return {
487
+ start: formatDate(today),
488
+ end: formatDate(today)
489
+ };
490
+ }
491
+ },
492
+ {
493
+ label: 'This Month',
494
+ getValue: () => {
495
+ const today = new Date();
496
+ const start = new Date(today.getFullYear(), today.getMonth(), 1);
497
+ const end = new Date(today.getFullYear(), today.getMonth() + 1, 0);
498
+ return {
499
+ start: formatDate(start),
500
+ end: formatDate(end)
501
+ };
502
+ }
503
+ },
504
+ {
505
+ label: 'Last Month',
506
+ getValue: () => {
507
+ const today = new Date();
508
+ const start = new Date(today.getFullYear(), today.getMonth() - 1, 1);
509
+ const end = new Date(today.getFullYear(), today.getMonth(), 0);
510
+ return {
511
+ start: formatDate(start),
512
+ end: formatDate(end)
513
+ };
514
+ }
515
+ },
516
+ {
517
+ label: 'Quarter to Date',
518
+ getValue: () => {
519
+ const today = new Date();
520
+ const currentMonth = today.getMonth();
521
+ const quarterStartMonth = Math.floor(currentMonth / 3) * 3;
522
+ const start = new Date(today.getFullYear(), quarterStartMonth, 1);
523
+ return {
524
+ start: formatDate(start),
525
+ end: formatDate(today)
526
+ };
527
+ }
528
+ }
529
+ ];
530
+ ```
531
+
532
+ #### **Even Better** - Use Pre-built Utilities πŸš€
533
+
534
+ We provide **ready-to-use preset utilities** for common scenarios:
535
+
536
+ ```typescript
537
+ import { CommonPresets } from '@oneluiz/dual-datepicker';
538
+
539
+ // Dashboard presets
540
+ presets = CommonPresets.dashboard;
541
+ // β†’ Today, Yesterday, Last 7 days, Last 30 days, This month, Last month
542
+
543
+ // Reporting presets
544
+ presets = CommonPresets.reporting;
545
+ // β†’ Today, This week, Last week, This month, Last month, This quarter, Last quarter
546
+
547
+ // Financial/ERP presets
548
+ presets = CommonPresets.financial;
549
+ // β†’ Month to date, Quarter to date, Year to date, Last month, Last quarter, Last year
550
+
551
+ // Analytics/BI presets
552
+ presets = CommonPresets.analytics;
553
+ // β†’ Last 7/14/30/60/90/180/365 days
554
+
555
+ // Simple presets
556
+ presets = CommonPresets.simple;
557
+ // β†’ Today, Last 7 days, Last 30 days, This year
558
+ ```
559
+
560
+ #### Create Your Own Utilities
561
+
562
+ Import individual utilities and mix them:
563
+
564
+ ```typescript
565
+ import {
566
+ getToday,
567
+ getThisMonth,
568
+ getLastMonth,
569
+ getQuarterToDate,
570
+ getYearToDate,
571
+ PresetConfig
572
+ } from '@oneluiz/dual-datepicker';
573
+
574
+ customPresets: PresetConfig[] = [
575
+ { label: 'Today', getValue: getToday },
576
+ { label: 'This Month', getValue: getThisMonth },
577
+ { label: 'Last Month', getValue: getLastMonth },
578
+ { label: 'Quarter to Date', getValue: getQuarterToDate },
579
+ { label: 'Year to Date', getValue: getYearToDate },
580
+ {
581
+ label: 'Custom Logic',
582
+ getValue: () => {
583
+ // Your custom date calculation
584
+ return { start: '2026-01-01', end: '2026-12-31' };
585
+ }
586
+ }
587
+ ];
588
+ ```
589
+
590
+ #### Why This Is Powerful
591
+
592
+ βœ… **Perfect for Dashboards** - "Last 7 days", "Month to date", "Quarter to date"
593
+ βœ… **Perfect for Reporting** - "This week", "Last week", "This quarter"
594
+ βœ… **Perfect for Financial Systems** - "Quarter to date", "Year to date", "Fiscal year"
595
+ βœ… **Perfect for Analytics** - Consistent date ranges for BI tools
596
+ βœ… **Perfect for ERP** - Custom business logic and fiscal calendars
597
+
598
+ **Angular Material doesn't offer this level of flexibility!** 🎯
599
+
247
600
  ```html
248
601
  <ngx-dual-datepicker
249
602
  [(ngModel)]="dateRange"
@@ -311,14 +664,23 @@ export class MyComponent {
311
664
  ### Types
312
665
 
313
666
  ```typescript
314
- infechaInicio: string; // ISO date format: 'YYYY-MM-DD'
667
+ interface DateRange {
668
+ fechaInicio: string; // ISO date format: 'YYYY-MM-DD'
315
669
  fechaFin: string; // ISO date format: 'YYYY-MM-DD'
316
670
  rangoTexto: string; // Display text: 'DD Mon - DD Mon'
317
671
  }
318
672
 
673
+ interface PresetRange {
674
+ start: string; // ISO date format: 'YYYY-MM-DD'
675
+ end: string; // ISO date format: 'YYYY-MM-DD'
676
+ }
677
+
319
678
  interface PresetConfig {
320
679
  label: string;
321
- daysAgo: number;
680
+ /** @deprecated Use getValue() instead for more flexibility */
681
+ daysAgo?: number;
682
+ /** NEW v2.6.0 - Function that returns date range with custom logic */
683
+ getValue?: () => PresetRange;
322
684
  }
323
685
 
324
686
  interface LocaleConfig {
@@ -327,7 +689,6 @@ interface LocaleConfig {
327
689
  dayNames?: string[]; // Full day names (7 items, starting Sunday)
328
690
  dayNamesShort?: string[]; // Short day names (7 items, starting Sunday)
329
691
  firstDayOfWeek?: number; // 0 = Sunday, 1 = Monday, etc. (not yet implemented)
330
- daysAgo: number;
331
692
  }
332
693
  ```
333
694
 
@@ -455,6 +816,25 @@ export class ExampleComponent {
455
816
  - Angular 19.0.0 or higher
456
817
  - Angular 20.0.0 or higher
457
818
 
819
+ ## πŸ—ΊοΈ Roadmap
820
+
821
+ Recently shipped:
822
+
823
+ **v2.6.0:**
824
+ - βœ… **Flexible Preset System** - `getValue()` pattern for custom date logic (This month, Last month, Quarter to date, etc.)
825
+ - βœ… **Pre-built Preset Utilities** - CommonPresets for Dashboard, Reporting, Financial, Analytics
826
+ - βœ… **Real Differentiator** - Perfect for ERP, BI, POS, and Reporting systems
827
+
828
+ **v2.5.0:**
829
+ - βœ… **Date Adapter System** - Support for DayJS, date-fns, Luxon, and custom date libraries
830
+
831
+ Planned features and improvements:
832
+
833
+ - ⬜ **Complete keyboard navigation** - Arrow keys, Enter/Space, Tab, Escape
834
+ - ⬜ **Full accessibility audit** - WCAG 2.1 AA compliance
835
+ - ⬜ **Multi-range support** - Select multiple date ranges
836
+ - ⬜ **Theming system** - Pre-built theme presets
837
+
458
838
  ## πŸ“„ License
459
839
 
460
840
  MIT Β© Luis Cortes