@oneluiz/dual-datepicker 3.5.0 → 3.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 +51 -3
- package/core/built-in-presets.d.ts +98 -0
- package/core/date-adapter.d.ts +298 -0
- package/core/date-clock.d.ts +82 -0
- package/core/dual-date-range.store.d.ts +9 -0
- package/core/index.d.ts +15 -0
- package/core/native-date-adapter.d.ts +152 -0
- package/core/preset-providers.d.ts +176 -0
- package/core/preset-registry.d.ts +181 -0
- package/core/preset.engine.d.ts +79 -9
- package/core/range-preset.plugin.d.ts +188 -0
- package/core/system-clock.d.ts +13 -0
- package/dual-datepicker.component.d.ts +17 -11
- package/esm2022/core/built-in-presets.mjs +289 -0
- package/esm2022/core/date-adapter.mjs +77 -0
- package/esm2022/core/date-clock.mjs +65 -0
- package/esm2022/core/dual-date-range.store.mjs +51 -15
- package/esm2022/core/index.mjs +17 -1
- package/esm2022/core/native-date-adapter.mjs +286 -0
- package/esm2022/core/preset-providers.mjs +243 -0
- package/esm2022/core/preset-registry.mjs +277 -0
- package/esm2022/core/preset.engine.mjs +139 -169
- package/esm2022/core/range-preset.plugin.mjs +70 -0
- package/esm2022/core/system-clock.mjs +34 -0
- package/esm2022/dual-datepicker.component.mjs +264 -196
- package/fesm2022/oneluiz-dual-datepicker.mjs +3219 -1822
- package/fesm2022/oneluiz-dual-datepicker.mjs.map +1 -1
- package/package.json +5 -3
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { DateAdapter } from './date-adapter';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
export declare class NativeDateAdapter implements DateAdapter {
|
|
4
|
+
/**
|
|
5
|
+
* Normalize date to start of day (00:00:00.000) in local timezone
|
|
6
|
+
*
|
|
7
|
+
* This is the foundation of timezone-safe operations.
|
|
8
|
+
* All other methods use normalized dates for comparisons.
|
|
9
|
+
*/
|
|
10
|
+
normalize(date: Date): Date;
|
|
11
|
+
/**
|
|
12
|
+
* Check if two dates are the same calendar day
|
|
13
|
+
*
|
|
14
|
+
* Implementation: Compare YYYY-MM-DD components directly
|
|
15
|
+
* Avoids timezone issues from valueOf() comparisons
|
|
16
|
+
*/
|
|
17
|
+
isSameDay(a: Date, b: Date): boolean;
|
|
18
|
+
/**
|
|
19
|
+
* Check if date A is before date B (calendar day level)
|
|
20
|
+
*
|
|
21
|
+
* Implementation: Compare normalized dates using valueOf()
|
|
22
|
+
*/
|
|
23
|
+
isBeforeDay(a: Date, b: Date): boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Check if date A is after date B (calendar day level)
|
|
26
|
+
*
|
|
27
|
+
* Implementation: Compare normalized dates using valueOf()
|
|
28
|
+
*/
|
|
29
|
+
isAfterDay(a: Date, b: Date): boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Add days to a date
|
|
32
|
+
*
|
|
33
|
+
* Implementation: Use setDate() which handles month rollover automatically
|
|
34
|
+
*
|
|
35
|
+
* Example:
|
|
36
|
+
* Jan 31 + 3 days → Feb 3 ✅
|
|
37
|
+
* Feb 28 + 1 day → Mar 1 ✅ (non-leap year)
|
|
38
|
+
*/
|
|
39
|
+
addDays(date: Date, days: number): Date;
|
|
40
|
+
/**
|
|
41
|
+
* Add months to a date
|
|
42
|
+
*
|
|
43
|
+
* CRITICAL: Handles month overflow correctly
|
|
44
|
+
*
|
|
45
|
+
* Algorithm:
|
|
46
|
+
* 1. Add months using setMonth()
|
|
47
|
+
* 2. If day-of-month changed (overflow), set to last day of target month
|
|
48
|
+
*
|
|
49
|
+
* Examples:
|
|
50
|
+
* - Jan 31 + 1 month → Feb 28 (or Feb 29 in leap year) ✅
|
|
51
|
+
* - Jan 31 + 2 months → Mar 31 ✅
|
|
52
|
+
* - Mar 31 + 1 month → Apr 30 ✅
|
|
53
|
+
* - Dec 31 + 1 month → Jan 31 (next year) ✅
|
|
54
|
+
*/
|
|
55
|
+
addMonths(date: Date, months: number): Date;
|
|
56
|
+
/**
|
|
57
|
+
* Get start of day (00:00:00.000)
|
|
58
|
+
*
|
|
59
|
+
* Alias for normalize() with explicit intent
|
|
60
|
+
*/
|
|
61
|
+
startOfDay(date: Date): Date;
|
|
62
|
+
/**
|
|
63
|
+
* Get end of day (23:59:59.999)
|
|
64
|
+
*
|
|
65
|
+
* Useful for inclusive range queries
|
|
66
|
+
*/
|
|
67
|
+
endOfDay(date: Date): Date;
|
|
68
|
+
/**
|
|
69
|
+
* Get first day of month (00:00:00.000)
|
|
70
|
+
*/
|
|
71
|
+
startOfMonth(date: Date): Date;
|
|
72
|
+
/**
|
|
73
|
+
* Get last day of month (23:59:59.999)
|
|
74
|
+
*
|
|
75
|
+
* Algorithm: Go to 1st of next month, subtract 1 day
|
|
76
|
+
*/
|
|
77
|
+
endOfMonth(date: Date): Date;
|
|
78
|
+
/**
|
|
79
|
+
* Get year (4-digit)
|
|
80
|
+
*/
|
|
81
|
+
getYear(date: Date): number;
|
|
82
|
+
/**
|
|
83
|
+
* Get month (0-11)
|
|
84
|
+
*/
|
|
85
|
+
getMonth(date: Date): number;
|
|
86
|
+
/**
|
|
87
|
+
* Get day of month (1-31)
|
|
88
|
+
*/
|
|
89
|
+
getDate(date: Date): number;
|
|
90
|
+
/**
|
|
91
|
+
* Get day of week (0-6, Sunday=0)
|
|
92
|
+
*/
|
|
93
|
+
getDay(date: Date): number;
|
|
94
|
+
/**
|
|
95
|
+
* Convert Date to ISO date string (YYYY-MM-DD)
|
|
96
|
+
*
|
|
97
|
+
* CRITICAL: DO NOT use toISOString() - it converts to UTC!
|
|
98
|
+
*
|
|
99
|
+
* Manual construction ensures local timezone is preserved:
|
|
100
|
+
*
|
|
101
|
+
* Example problem with toISOString():
|
|
102
|
+
* ```
|
|
103
|
+
* // Local timezone: GMT-6 (CST)
|
|
104
|
+
* const date = new Date('2026-02-21T23:00:00'); // 11 PM Feb 21 local
|
|
105
|
+
*
|
|
106
|
+
* // WRONG ❌
|
|
107
|
+
* date.toISOString().split('T')[0]
|
|
108
|
+
* // Returns "2026-02-22" (converted to UTC = Feb 22 05:00 AM)
|
|
109
|
+
*
|
|
110
|
+
* // CORRECT ✅
|
|
111
|
+
* toISODate(date)
|
|
112
|
+
* // Returns "2026-02-21" (local date preserved)
|
|
113
|
+
* ```
|
|
114
|
+
*
|
|
115
|
+
* Implementation: Build YYYY-MM-DD manually from local date components
|
|
116
|
+
*/
|
|
117
|
+
toISODate(date: Date): string;
|
|
118
|
+
/**
|
|
119
|
+
* Parse ISO date string (YYYY-MM-DD) to Date
|
|
120
|
+
*
|
|
121
|
+
* CRITICAL: DO NOT use new Date(isoString) - may parse as UTC!
|
|
122
|
+
*
|
|
123
|
+
* Example problem with Date constructor:
|
|
124
|
+
* ```
|
|
125
|
+
* // Local timezone: GMT-6 (CST)
|
|
126
|
+
*
|
|
127
|
+
* // WRONG ❌
|
|
128
|
+
* new Date('2026-02-21')
|
|
129
|
+
* // Parsed as UTC: 2026-02-21T00:00:00Z
|
|
130
|
+
* // In local timezone: Feb 20, 2026 6:00 PM (previous day!)
|
|
131
|
+
*
|
|
132
|
+
* // CORRECT ✅
|
|
133
|
+
* parseISODate('2026-02-21')
|
|
134
|
+
* // Returns: 2026-02-21T00:00:00 local time
|
|
135
|
+
* ```
|
|
136
|
+
*
|
|
137
|
+
* Implementation: Parse components and construct Date in local timezone
|
|
138
|
+
*/
|
|
139
|
+
parseISODate(isoDate: string): Date | null;
|
|
140
|
+
/**
|
|
141
|
+
* Get week start day for locale
|
|
142
|
+
*
|
|
143
|
+
* Default: Sunday (0) for most locales
|
|
144
|
+
* Monday (1) for Europe, ISO 8601
|
|
145
|
+
*
|
|
146
|
+
* Implementation: Simple locale detection
|
|
147
|
+
* For advanced needs, use Intl.Locale or external library
|
|
148
|
+
*/
|
|
149
|
+
getWeekStart(locale?: string): 0 | 1 | 2 | 3 | 4 | 5 | 6;
|
|
150
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<NativeDateAdapter, never>;
|
|
151
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<NativeDateAdapter>;
|
|
152
|
+
}
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider Functions for Built-in Presets
|
|
3
|
+
*
|
|
4
|
+
* Version: 3.6.0
|
|
5
|
+
*
|
|
6
|
+
* Automatic registration of built-in date range presets.
|
|
7
|
+
* These providers ensure backward compatibility by auto-registering
|
|
8
|
+
* all standard presets (TODAY, LAST_7_DAYS, THIS_MONTH, etc.)
|
|
9
|
+
*
|
|
10
|
+
* USAGE IN LIBRARY (Internal):
|
|
11
|
+
* Built-in presets are registered automatically via Angular providers.
|
|
12
|
+
* Library consumers don't need to do anything.
|
|
13
|
+
*
|
|
14
|
+
* USAGE IN APP (Custom Presets):
|
|
15
|
+
* ```typescript
|
|
16
|
+
* // app.config.ts
|
|
17
|
+
* export const appConfig: ApplicationConfig = {
|
|
18
|
+
* providers: [
|
|
19
|
+
* // ... other providers
|
|
20
|
+
* provideCustomPresets([
|
|
21
|
+
* {
|
|
22
|
+
* key: 'THIS_FISCAL_QUARTER',
|
|
23
|
+
* resolve: (clock, adapter) => {
|
|
24
|
+
* const now = clock.now();
|
|
25
|
+
* // ... fiscal logic
|
|
26
|
+
* return { start, end };
|
|
27
|
+
* }
|
|
28
|
+
* }
|
|
29
|
+
* ])
|
|
30
|
+
* ]
|
|
31
|
+
* };
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
import { EnvironmentProviders } from '@angular/core';
|
|
35
|
+
import { RangePresetPlugin } from './range-preset.plugin';
|
|
36
|
+
/**
|
|
37
|
+
* Provide built-in date range presets
|
|
38
|
+
*
|
|
39
|
+
* This provider is automatically included in the library's root providers.
|
|
40
|
+
* Library consumers don't need to add this manually.
|
|
41
|
+
*
|
|
42
|
+
* @returns EnvironmentProviders for built-in presets
|
|
43
|
+
*
|
|
44
|
+
* @internal
|
|
45
|
+
*/
|
|
46
|
+
export declare function provideBuiltInPresets(): EnvironmentProviders;
|
|
47
|
+
/**
|
|
48
|
+
* Provide custom date range presets
|
|
49
|
+
*
|
|
50
|
+
* Use this to register your own industry-specific presets:
|
|
51
|
+
* - Fiscal presets
|
|
52
|
+
* - Hotel/hospitality presets
|
|
53
|
+
* - Logistics presets
|
|
54
|
+
* - Custom business logic
|
|
55
|
+
*
|
|
56
|
+
* @param presets - Array of custom RangePresetPlugin implementations
|
|
57
|
+
* @returns EnvironmentProviders for custom presets
|
|
58
|
+
*
|
|
59
|
+
* @example
|
|
60
|
+
* ```typescript
|
|
61
|
+
* // Fiscal presets
|
|
62
|
+
* const FISCAL_PRESETS: RangePresetPlugin[] = [
|
|
63
|
+
* {
|
|
64
|
+
* key: 'THIS_FISCAL_QUARTER',
|
|
65
|
+
* resolve: (clock, adapter) => {
|
|
66
|
+
* const now = clock.now();
|
|
67
|
+
* const month = adapter.getMonth(now);
|
|
68
|
+
*
|
|
69
|
+
* // Fiscal year starts April (month 3)
|
|
70
|
+
* const fiscalMonth = (month + 9) % 12;
|
|
71
|
+
* const quarterStart = Math.floor(fiscalMonth / 3) * 3;
|
|
72
|
+
* const calendarMonth = (quarterStart - 9 + 12) % 12;
|
|
73
|
+
*
|
|
74
|
+
* const year = adapter.getYear(now);
|
|
75
|
+
* const fiscalYear = month < 3 ? year - 1 : year;
|
|
76
|
+
*
|
|
77
|
+
* const start = new Date(fiscalYear, calendarMonth, 1);
|
|
78
|
+
* const end = new Date(fiscalYear, calendarMonth + 3, 0);
|
|
79
|
+
*
|
|
80
|
+
* return {
|
|
81
|
+
* start: adapter.normalize(start),
|
|
82
|
+
* end: adapter.normalize(end)
|
|
83
|
+
* };
|
|
84
|
+
* }
|
|
85
|
+
* },
|
|
86
|
+
* {
|
|
87
|
+
* key: 'FISCAL_YEAR_TO_DATE',
|
|
88
|
+
* resolve: (clock, adapter) => {
|
|
89
|
+
* const now = clock.now();
|
|
90
|
+
* const month = adapter.getMonth(now);
|
|
91
|
+
* const year = adapter.getYear(now);
|
|
92
|
+
*
|
|
93
|
+
* // Fiscal year starts April 1
|
|
94
|
+
* const fiscalYearStart = month >= 3
|
|
95
|
+
* ? new Date(year, 3, 1)
|
|
96
|
+
* : new Date(year - 1, 3, 1);
|
|
97
|
+
*
|
|
98
|
+
* return {
|
|
99
|
+
* start: adapter.normalize(fiscalYearStart),
|
|
100
|
+
* end: adapter.normalize(now)
|
|
101
|
+
* };
|
|
102
|
+
* }
|
|
103
|
+
* }
|
|
104
|
+
* ];
|
|
105
|
+
*
|
|
106
|
+
* // In app.config.ts
|
|
107
|
+
* export const appConfig: ApplicationConfig = {
|
|
108
|
+
* providers: [
|
|
109
|
+
* provideCustomPresets(FISCAL_PRESETS)
|
|
110
|
+
* ]
|
|
111
|
+
* };
|
|
112
|
+
*
|
|
113
|
+
* // Use in components
|
|
114
|
+
* store.applyPreset('THIS_FISCAL_QUARTER');
|
|
115
|
+
* store.applyPreset('FISCAL_YEAR_TO_DATE');
|
|
116
|
+
* ```
|
|
117
|
+
*
|
|
118
|
+
* @example
|
|
119
|
+
* ```typescript
|
|
120
|
+
* // Hotel presets
|
|
121
|
+
* const HOTEL_PRESETS: RangePresetPlugin[] = [
|
|
122
|
+
* {
|
|
123
|
+
* key: 'CHECK_IN_WEEK',
|
|
124
|
+
* resolve: (clock, adapter) => {
|
|
125
|
+
* const now = clock.now();
|
|
126
|
+
* const dayOfWeek = adapter.getDayOfWeek(now);
|
|
127
|
+
*
|
|
128
|
+
* // Check-in week: Friday to Friday
|
|
129
|
+
* const daysToNextFriday = dayOfWeek <= 5
|
|
130
|
+
* ? 5 - dayOfWeek
|
|
131
|
+
* : 7 - dayOfWeek + 5;
|
|
132
|
+
*
|
|
133
|
+
* const nextFriday = adapter.addDays(now, daysToNextFriday);
|
|
134
|
+
* const followingFriday = adapter.addDays(nextFriday, 7);
|
|
135
|
+
*
|
|
136
|
+
* return { start: nextFriday, end: followingFriday };
|
|
137
|
+
* }
|
|
138
|
+
* },
|
|
139
|
+
* {
|
|
140
|
+
* key: 'NEXT_30_NIGHTS',
|
|
141
|
+
* resolve: (clock, adapter) => {
|
|
142
|
+
* const now = clock.now();
|
|
143
|
+
* const tomorrow = adapter.addDays(now, 1);
|
|
144
|
+
* const end = adapter.addDays(tomorrow, 30);
|
|
145
|
+
* return { start: tomorrow, end };
|
|
146
|
+
* }
|
|
147
|
+
* }
|
|
148
|
+
* ];
|
|
149
|
+
*
|
|
150
|
+
* providers: [provideCustomPresets(HOTEL_PRESETS)]
|
|
151
|
+
* ```
|
|
152
|
+
*/
|
|
153
|
+
export declare function provideCustomPresets(presets: RangePresetPlugin[]): EnvironmentProviders;
|
|
154
|
+
/**
|
|
155
|
+
* Provide preset package
|
|
156
|
+
*
|
|
157
|
+
* Convenience function for external preset packages.
|
|
158
|
+
*
|
|
159
|
+
* @param packageName - Name of the preset package (for logging)
|
|
160
|
+
* @param presets - Array of presets from the package
|
|
161
|
+
* @returns EnvironmentProviders
|
|
162
|
+
*
|
|
163
|
+
* @example
|
|
164
|
+
* ```typescript
|
|
165
|
+
* // @acme/fiscal-presets package
|
|
166
|
+
* export function provideFiscalPresets(): EnvironmentProviders {
|
|
167
|
+
* return providePresetPackage('@acme/fiscal-presets', FISCAL_PRESETS);
|
|
168
|
+
* }
|
|
169
|
+
*
|
|
170
|
+
* // In app
|
|
171
|
+
* import { provideFiscalPresets } from '@acme/fiscal-presets';
|
|
172
|
+
*
|
|
173
|
+
* providers: [provideFiscalPresets()]
|
|
174
|
+
* ```
|
|
175
|
+
*/
|
|
176
|
+
export declare function providePresetPackage(packageName: string, presets: RangePresetPlugin[]): EnvironmentProviders;
|
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
import { RangePresetPlugin } from './range-preset.plugin';
|
|
2
|
+
import * as i0 from "@angular/core";
|
|
3
|
+
/**
|
|
4
|
+
* Preset Registry Service
|
|
5
|
+
*
|
|
6
|
+
* Manages registration and retrieval of date range preset plugins.
|
|
7
|
+
*
|
|
8
|
+
* DESIGN:
|
|
9
|
+
* - Uses Map for O(1) lookups
|
|
10
|
+
* - Immutable getAll() returns copy
|
|
11
|
+
* - Supports plugin override (last registration wins)
|
|
12
|
+
* - Validates plugins before registration
|
|
13
|
+
*/
|
|
14
|
+
export declare class PresetRegistry {
|
|
15
|
+
/**
|
|
16
|
+
* Internal map of registered presets
|
|
17
|
+
* Key: preset key (e.g., 'TODAY', 'LAST_7_DAYS')
|
|
18
|
+
* Value: RangePresetPlugin instance
|
|
19
|
+
*/
|
|
20
|
+
private readonly presets;
|
|
21
|
+
/**
|
|
22
|
+
* Register a date range preset plugin
|
|
23
|
+
*
|
|
24
|
+
* If a preset with the same key already exists, it will be overridden.
|
|
25
|
+
* This is useful for:
|
|
26
|
+
* - Testing (override built-in presets with mocks)
|
|
27
|
+
* - Customization (replace default behavior)
|
|
28
|
+
* - Hot-reload scenarios
|
|
29
|
+
*
|
|
30
|
+
* @param plugin - The preset plugin to register
|
|
31
|
+
* @throws Error if plugin is invalid (missing key or resolve function)
|
|
32
|
+
*
|
|
33
|
+
* @example
|
|
34
|
+
* ```typescript
|
|
35
|
+
* registry.register({
|
|
36
|
+
* key: 'LAST_BUSINESS_WEEK',
|
|
37
|
+
* resolve: (clock, adapter) => {
|
|
38
|
+
* const now = clock.now();
|
|
39
|
+
* const dayOfWeek = adapter.getDayOfWeek(now);
|
|
40
|
+
*
|
|
41
|
+
* // Go back to last Friday
|
|
42
|
+
* const daysToLastFriday = dayOfWeek === 0 ? 2 : (dayOfWeek + 2) % 7;
|
|
43
|
+
* const lastFriday = adapter.addDays(now, -daysToLastFriday);
|
|
44
|
+
*
|
|
45
|
+
* // Business week: Monday to Friday
|
|
46
|
+
* const monday = adapter.addDays(lastFriday, -4);
|
|
47
|
+
*
|
|
48
|
+
* return { start: monday, end: lastFriday };
|
|
49
|
+
* }
|
|
50
|
+
* });
|
|
51
|
+
* ```
|
|
52
|
+
*/
|
|
53
|
+
register(plugin: RangePresetPlugin): void;
|
|
54
|
+
/**
|
|
55
|
+
* Register multiple preset plugins at once
|
|
56
|
+
*
|
|
57
|
+
* Convenience method for bulk registration.
|
|
58
|
+
* Useful when importing preset packages.
|
|
59
|
+
*
|
|
60
|
+
* @param plugins - Array of preset plugins to register
|
|
61
|
+
*
|
|
62
|
+
* @example
|
|
63
|
+
* ```typescript
|
|
64
|
+
* import { FISCAL_PRESETS } from '@acme/fiscal-presets';
|
|
65
|
+
*
|
|
66
|
+
* registry.registerAll(FISCAL_PRESETS);
|
|
67
|
+
* ```
|
|
68
|
+
*/
|
|
69
|
+
registerAll(plugins: RangePresetPlugin[]): void;
|
|
70
|
+
/**
|
|
71
|
+
* Get a preset plugin by key
|
|
72
|
+
*
|
|
73
|
+
* @param key - Preset key (case-insensitive, e.g., 'today' or 'TODAY')
|
|
74
|
+
* @returns The preset plugin or undefined if not found
|
|
75
|
+
*
|
|
76
|
+
* @example
|
|
77
|
+
* ```typescript
|
|
78
|
+
* const preset = registry.get('LAST_7_DAYS');
|
|
79
|
+
* if (preset) {
|
|
80
|
+
* const range = preset.resolve(clock, adapter);
|
|
81
|
+
* console.log('Range:', range);
|
|
82
|
+
* }
|
|
83
|
+
* ```
|
|
84
|
+
*/
|
|
85
|
+
get(key: string): RangePresetPlugin | undefined;
|
|
86
|
+
/**
|
|
87
|
+
* Check if a preset exists in the registry
|
|
88
|
+
*
|
|
89
|
+
* @param key - Preset key (case-insensitive)
|
|
90
|
+
* @returns true if preset exists, false otherwise
|
|
91
|
+
*
|
|
92
|
+
* @example
|
|
93
|
+
* ```typescript
|
|
94
|
+
* if (registry.has('THIS_FISCAL_QUARTER')) {
|
|
95
|
+
* store.applyPreset('THIS_FISCAL_QUARTER');
|
|
96
|
+
* } else {
|
|
97
|
+
* console.error('Fiscal quarter preset not registered');
|
|
98
|
+
* }
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
101
|
+
has(key: string): boolean;
|
|
102
|
+
/**
|
|
103
|
+
* Get all registered preset plugins
|
|
104
|
+
*
|
|
105
|
+
* Returns a NEW array (immutable) to prevent external modification.
|
|
106
|
+
*
|
|
107
|
+
* @returns Array of all registered preset plugins
|
|
108
|
+
*
|
|
109
|
+
* @example
|
|
110
|
+
* ```typescript
|
|
111
|
+
* const allPresets = registry.getAll();
|
|
112
|
+
* console.log('Available presets:');
|
|
113
|
+
* allPresets.forEach(preset => {
|
|
114
|
+
* console.log(`- ${preset.key}`);
|
|
115
|
+
* });
|
|
116
|
+
* ```
|
|
117
|
+
*/
|
|
118
|
+
getAll(): RangePresetPlugin[];
|
|
119
|
+
/**
|
|
120
|
+
* Get all preset keys
|
|
121
|
+
*
|
|
122
|
+
* Convenience method to list available preset identifiers.
|
|
123
|
+
*
|
|
124
|
+
* @returns Array of preset keys (uppercase)
|
|
125
|
+
*
|
|
126
|
+
* @example
|
|
127
|
+
* ```typescript
|
|
128
|
+
* const keys = registry.getAllKeys();
|
|
129
|
+
* // ['TODAY', 'YESTERDAY', 'LAST_7_DAYS', 'THIS_MONTH', ...]
|
|
130
|
+
* ```
|
|
131
|
+
*/
|
|
132
|
+
getAllKeys(): string[];
|
|
133
|
+
/**
|
|
134
|
+
* Get count of registered presets
|
|
135
|
+
*
|
|
136
|
+
* @returns Number of registered presets
|
|
137
|
+
*
|
|
138
|
+
* @example
|
|
139
|
+
* ```typescript
|
|
140
|
+
* console.log(`${registry.count()} presets available`);
|
|
141
|
+
* ```
|
|
142
|
+
*/
|
|
143
|
+
count(): number;
|
|
144
|
+
/**
|
|
145
|
+
* Unregister a preset plugin
|
|
146
|
+
*
|
|
147
|
+
* Useful for:
|
|
148
|
+
* - Testing cleanup
|
|
149
|
+
* - Dynamic preset management
|
|
150
|
+
* - Removing deprecated presets
|
|
151
|
+
*
|
|
152
|
+
* @param key - Preset key to remove (case-insensitive)
|
|
153
|
+
* @returns true if preset was removed, false if it didn't exist
|
|
154
|
+
*
|
|
155
|
+
* @example
|
|
156
|
+
* ```typescript
|
|
157
|
+
* registry.unregister('MY_TEMPORARY_PRESET');
|
|
158
|
+
* ```
|
|
159
|
+
*/
|
|
160
|
+
unregister(key: string): boolean;
|
|
161
|
+
/**
|
|
162
|
+
* Clear all registered presets
|
|
163
|
+
*
|
|
164
|
+
* ⚠️ USE WITH CAUTION: This removes ALL presets including built-ins.
|
|
165
|
+
*
|
|
166
|
+
* Useful for:
|
|
167
|
+
* - Test teardown
|
|
168
|
+
* - Complete re-initialization scenarios
|
|
169
|
+
*
|
|
170
|
+
* @example
|
|
171
|
+
* ```typescript
|
|
172
|
+
* // In test cleanup
|
|
173
|
+
* afterEach(() => {
|
|
174
|
+
* registry.clear();
|
|
175
|
+
* });
|
|
176
|
+
* ```
|
|
177
|
+
*/
|
|
178
|
+
clear(): void;
|
|
179
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<PresetRegistry, never>;
|
|
180
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<PresetRegistry>;
|
|
181
|
+
}
|
package/core/preset.engine.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
+
import * as i0 from "@angular/core";
|
|
1
2
|
/**
|
|
2
|
-
*
|
|
3
|
-
*
|
|
4
|
-
* Perfect for SSR, global state, dashboard filters
|
|
3
|
+
* @deprecated Use RangePresetPlugin from './range-preset.plugin' instead
|
|
4
|
+
* Kept for backward compatibility
|
|
5
5
|
*/
|
|
6
6
|
export interface RangePreset {
|
|
7
7
|
/**
|
|
@@ -18,37 +18,107 @@ export interface PresetRange {
|
|
|
18
18
|
end: string;
|
|
19
19
|
}
|
|
20
20
|
/**
|
|
21
|
-
*
|
|
22
|
-
*
|
|
21
|
+
* Preset Engine - Plugin-Driven Architecture
|
|
22
|
+
*
|
|
23
|
+
* ARCHITECTURE (v3.6.0):
|
|
24
|
+
* - NO longer contains presets internally
|
|
25
|
+
* - Uses PresetRegistry for plugin management
|
|
26
|
+
* - Injects DateClock for SSR-safe time
|
|
27
|
+
* - Injects DateAdapter for timezone-safe operations
|
|
28
|
+
* - Follows Open/Closed Principle
|
|
29
|
+
*
|
|
30
|
+
* BACKWARD COMPATIBILITY:
|
|
31
|
+
* - Old API unchanged: resolve(), register(), getPresetKeys()
|
|
32
|
+
* - Built-in presets auto-registered via provider
|
|
33
|
+
* - Existing code continues to work
|
|
34
|
+
*
|
|
35
|
+
* EXTENSIBILITY:
|
|
36
|
+
* ```typescript
|
|
37
|
+
* // Register custom preset via registry
|
|
38
|
+
* const registry = inject(PresetRegistry);
|
|
39
|
+
* registry.register({
|
|
40
|
+
* key: 'MY_PRESET',
|
|
41
|
+
* resolve: (clock, adapter) => {
|
|
42
|
+
* const now = clock.now();
|
|
43
|
+
* return { start: now, end: now };
|
|
44
|
+
* }
|
|
45
|
+
* });
|
|
46
|
+
*
|
|
47
|
+
* // Use via engine
|
|
48
|
+
* const engine = inject(PresetEngine);
|
|
49
|
+
* const range = engine.resolve('MY_PRESET');
|
|
50
|
+
* ```
|
|
23
51
|
*/
|
|
24
52
|
export declare class PresetEngine {
|
|
25
|
-
private
|
|
53
|
+
private clock;
|
|
54
|
+
private adapter;
|
|
55
|
+
private registry;
|
|
26
56
|
constructor();
|
|
27
57
|
/**
|
|
28
58
|
* Register a custom preset
|
|
59
|
+
*
|
|
60
|
+
* @deprecated Use PresetRegistry.register() directly for new code
|
|
61
|
+
* Kept for backward compatibility
|
|
62
|
+
*
|
|
63
|
+
* @param key - Preset key (e.g., 'MY_CUSTOM_PRESET')
|
|
64
|
+
* @param preset - Legacy RangePreset object
|
|
29
65
|
*/
|
|
30
66
|
register(key: string, preset: RangePreset): void;
|
|
31
67
|
/**
|
|
32
68
|
* Resolve a preset to date range
|
|
69
|
+
*
|
|
70
|
+
* Plugin Architecture:
|
|
71
|
+
* 1. Looks up plugin in PresetRegistry
|
|
72
|
+
* 2. Calls plugin.resolve(clock, adapter)
|
|
73
|
+
* 3. Returns ISO date range
|
|
74
|
+
*
|
|
75
|
+
* SSR Note: Uses injected DateClock for deterministic resolution
|
|
76
|
+
* Timezone Note: Uses injected DateAdapter for consistent operations
|
|
77
|
+
*
|
|
78
|
+
* @param key - Preset key (e.g., 'TODAY', 'LAST_7_DAYS')
|
|
79
|
+
* @param now - Optional override for current date (defaults to clock.now())
|
|
80
|
+
* @returns ISO date range or null if preset not found
|
|
33
81
|
*/
|
|
34
82
|
resolve(key: string, now?: Date): PresetRange | null;
|
|
35
83
|
/**
|
|
36
84
|
* Get all available preset keys
|
|
85
|
+
*
|
|
86
|
+
* Delegates to PresetRegistry
|
|
87
|
+
*
|
|
88
|
+
* @returns Array of registered preset keys
|
|
37
89
|
*/
|
|
38
90
|
getPresetKeys(): string[];
|
|
39
91
|
/**
|
|
40
|
-
*
|
|
92
|
+
* Check if a preset exists
|
|
93
|
+
*
|
|
94
|
+
* @param key - Preset key to check
|
|
95
|
+
* @returns true if preset is registered
|
|
41
96
|
*/
|
|
42
|
-
|
|
97
|
+
hasPreset(key: string): boolean;
|
|
98
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<PresetEngine, never>;
|
|
99
|
+
static ɵprov: i0.ɵɵInjectableDeclaration<PresetEngine>;
|
|
43
100
|
}
|
|
44
101
|
/**
|
|
45
102
|
* Create a custom preset from a function
|
|
103
|
+
*
|
|
104
|
+
* @deprecated Use RangePresetPlugin interface instead
|
|
105
|
+
* Kept for backward compatibility
|
|
46
106
|
*/
|
|
47
107
|
export declare function createPreset(resolver: (now: Date) => {
|
|
48
108
|
start: Date;
|
|
49
109
|
end: Date;
|
|
50
110
|
}): RangePreset;
|
|
51
111
|
/**
|
|
52
|
-
*
|
|
112
|
+
* @deprecated Use dependency injection instead:
|
|
113
|
+
* ```typescript
|
|
114
|
+
* private engine = inject(PresetEngine);
|
|
115
|
+
* ```
|
|
116
|
+
*
|
|
117
|
+
* Singleton preset engine instance for backward compatibility
|
|
118
|
+
*
|
|
119
|
+
* WARNING: This singleton uses SystemClock directly and is NOT SSR-safe.
|
|
120
|
+
* For SSR applications, inject PresetEngine and override DATE_CLOCK token.
|
|
121
|
+
*
|
|
122
|
+
* This export will be removed in v4.0.0
|
|
53
123
|
*/
|
|
54
124
|
export declare const presetEngine: PresetEngine;
|