@oneluiz/dual-datepicker 3.9.3 → 4.0.1

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.
Files changed (65) hide show
  1. package/README.md +26 -2
  2. package/fesm2022/oneluiz-dual-datepicker.mjs +696 -1040
  3. package/fesm2022/oneluiz-dual-datepicker.mjs.map +1 -1
  4. package/package.json +16 -8
  5. package/core/built-in-presets.d.ts +0 -98
  6. package/core/calendar-grid/cache.config.d.ts +0 -34
  7. package/core/calendar-grid/calendar-grid.cache.d.ts +0 -39
  8. package/core/calendar-grid/calendar-grid.factory.d.ts +0 -26
  9. package/core/calendar-grid/calendar-grid.types.d.ts +0 -57
  10. package/core/calendar-grid/index.d.ts +0 -56
  11. package/core/calendar-grid/range-highlighter.cache.d.ts +0 -106
  12. package/core/calendar-grid/range-highlighter.d.ts +0 -85
  13. package/core/calendar-grid/range-highlighter.types.d.ts +0 -182
  14. package/core/calendar-grid/virtual-weeks.logic.d.ts +0 -116
  15. package/core/calendar-grid/virtual-weeks.types.d.ts +0 -71
  16. package/core/date-adapter.d.ts +0 -298
  17. package/core/date-clock.d.ts +0 -82
  18. package/core/dual-date-range.store.d.ts +0 -113
  19. package/core/index.d.ts +0 -33
  20. package/core/native-date-adapter.d.ts +0 -152
  21. package/core/preset-providers.d.ts +0 -176
  22. package/core/preset-registry.d.ts +0 -181
  23. package/core/preset.engine.d.ts +0 -124
  24. package/core/range-preset.plugin.d.ts +0 -188
  25. package/core/range.validator.d.ts +0 -37
  26. package/core/system-clock.d.ts +0 -13
  27. package/date-adapter.d.ts +0 -116
  28. package/dual-datepicker.component.d.ts +0 -243
  29. package/esm2022/core/built-in-presets.mjs +0 -289
  30. package/esm2022/core/calendar-grid/cache.config.mjs +0 -35
  31. package/esm2022/core/calendar-grid/calendar-grid.cache.mjs +0 -98
  32. package/esm2022/core/calendar-grid/calendar-grid.factory.mjs +0 -97
  33. package/esm2022/core/calendar-grid/calendar-grid.types.mjs +0 -8
  34. package/esm2022/core/calendar-grid/index.mjs +0 -57
  35. package/esm2022/core/calendar-grid/range-highlighter.cache.mjs +0 -200
  36. package/esm2022/core/calendar-grid/range-highlighter.mjs +0 -185
  37. package/esm2022/core/calendar-grid/range-highlighter.types.mjs +0 -11
  38. package/esm2022/core/calendar-grid/virtual-weeks.logic.mjs +0 -149
  39. package/esm2022/core/calendar-grid/virtual-weeks.types.mjs +0 -11
  40. package/esm2022/core/date-adapter.mjs +0 -77
  41. package/esm2022/core/date-clock.mjs +0 -65
  42. package/esm2022/core/dual-date-range.store.mjs +0 -329
  43. package/esm2022/core/index.mjs +0 -37
  44. package/esm2022/core/native-date-adapter.mjs +0 -286
  45. package/esm2022/core/preset-providers.mjs +0 -243
  46. package/esm2022/core/preset-registry.mjs +0 -277
  47. package/esm2022/core/preset.engine.mjs +0 -179
  48. package/esm2022/core/range-preset.plugin.mjs +0 -70
  49. package/esm2022/core/range.validator.mjs +0 -105
  50. package/esm2022/core/system-clock.mjs +0 -34
  51. package/esm2022/date-adapter.mjs +0 -12
  52. package/esm2022/dual-datepicker.component.mjs +0 -1312
  53. package/esm2022/native-date-adapter.mjs +0 -117
  54. package/esm2022/oneluiz-dual-datepicker.mjs +0 -5
  55. package/esm2022/preset-utils.mjs +0 -276
  56. package/esm2022/public-api.mjs +0 -13
  57. package/index.d.ts +0 -5
  58. package/native-date-adapter.d.ts +0 -26
  59. package/preset-utils.d.ts +0 -91
  60. package/public-api.d.ts +0 -9
  61. package/src/themes/bootstrap.scss +0 -202
  62. package/src/themes/bulma.scss +0 -209
  63. package/src/themes/custom.scss +0 -236
  64. package/src/themes/foundation.scss +0 -201
  65. package/src/themes/tailwind.scss +0 -109
@@ -1,82 +0,0 @@
1
- /**
2
- * Date Clock Abstraction for SSR-Safe Date Resolution
3
- *
4
- * Problem:
5
- * Presets like "Last 7 Days" or "This Month" use new Date() which causes:
6
- * - SSR hydration mismatch
7
- * - Server renders "2026-02-14", client renders "2026-02-15"
8
- * - Different filters in dashboards
9
- * - Different queries in ERP/BI
10
- * - Cache inconsistency
11
- *
12
- * Solution:
13
- * Inject a DateClock to control time deterministically:
14
- *
15
- * Server (SSR):
16
- * provide(DATE_CLOCK, {
17
- * useValue: { now: () => new Date('2026-02-21T00:00:00Z') }
18
- * })
19
- *
20
- * Client (Browser):
21
- * Uses SystemClock by default (new Date())
22
- *
23
- * Testing:
24
- * provide(DATE_CLOCK, {
25
- * useValue: { now: () => new Date('2026-01-15T10:30:00Z') }
26
- * })
27
- *
28
- * Architecture:
29
- * - PresetEngine receives DateClock via DI
30
- * - All preset calculations use clock.now() instead of new Date()
31
- * - Deterministic: Same clock.now() → Same preset result
32
- * - SSR-compatible: Server and client resolve identical ranges
33
- */
34
- import { InjectionToken } from '@angular/core';
35
- /**
36
- * Clock abstraction for deterministic date resolution
37
- *
38
- * Use cases:
39
- * - SSR: Ensure server and client generate identical presets
40
- * - Testing: Control time for predictable test results
41
- * - Replay: Reproduce exact user state from past sessions
42
- * - Demo: Freeze time for reproducible demos
43
- */
44
- export interface DateClock {
45
- /**
46
- * Get current date/time
47
- *
48
- * Default implementation returns new Date()
49
- * Override for SSR, testing, or time-travel scenarios
50
- */
51
- now(): Date;
52
- }
53
- /**
54
- * Injection token for DateClock
55
- *
56
- * Usage:
57
- * ```typescript
58
- * // Default (uses SystemClock)
59
- * bootstrapApplication(AppComponent);
60
- *
61
- * // SSR Override
62
- * bootstrapApplication(AppComponent, {
63
- * providers: [
64
- * {
65
- * provide: DATE_CLOCK,
66
- * useValue: { now: () => new Date('2026-02-21T00:00:00Z') }
67
- * }
68
- * ]
69
- * });
70
- *
71
- * // Testing Override
72
- * TestBed.configureTestingModule({
73
- * providers: [
74
- * {
75
- * provide: DATE_CLOCK,
76
- * useValue: { now: () => new Date('2026-01-15T12:00:00Z') }
77
- * }
78
- * ]
79
- * });
80
- * ```
81
- */
82
- export declare const DATE_CLOCK: InjectionToken<DateClock>;
@@ -1,113 +0,0 @@
1
- import * as i0 from "@angular/core";
2
- export interface DateRangeState {
3
- start: string;
4
- end: string;
5
- startTime?: string;
6
- endTime?: string;
7
- }
8
- export interface DateRangeConfig {
9
- minDate?: Date;
10
- maxDate?: Date;
11
- disabledDates?: Date[] | ((date: Date) => boolean);
12
- enableTimePicker?: boolean;
13
- defaultStartTime?: string;
14
- defaultEndTime?: string;
15
- }
16
- export declare class DualDateRangeStore {
17
- private presetEngine;
18
- private clock;
19
- private adapter;
20
- constructor();
21
- private config;
22
- private _startDate;
23
- private _endDate;
24
- private _leftMonth;
25
- private _rightMonth;
26
- private _selectingStart;
27
- private _startTime;
28
- private _endTime;
29
- private _pendingStart;
30
- private _pendingEnd;
31
- private _hasPendingChanges;
32
- readonly startDate: import("@angular/core").Signal<Date>;
33
- readonly endDate: import("@angular/core").Signal<Date>;
34
- readonly leftMonth: import("@angular/core").Signal<Date>;
35
- readonly rightMonth: import("@angular/core").Signal<Date>;
36
- readonly selectingStart: import("@angular/core").Signal<boolean>;
37
- readonly startTime: import("@angular/core").Signal<string>;
38
- readonly endTime: import("@angular/core").Signal<string>;
39
- readonly hasPendingChanges: import("@angular/core").Signal<boolean>;
40
- readonly range: import("@angular/core").Signal<DateRangeState>;
41
- readonly isValid: import("@angular/core").Signal<boolean>;
42
- readonly rangeText: import("@angular/core").Signal<string>;
43
- /**
44
- * Configure the store
45
- */
46
- configure(config: Partial<DateRangeConfig>): void;
47
- /**
48
- * Set start date (with validation)
49
- */
50
- setStart(date: Date | string | null): void;
51
- /**
52
- * Set end date (with validation)
53
- */
54
- setEnd(date: Date | string | null): void;
55
- /**
56
- * Set complete range at once
57
- */
58
- setRange(start: Date | string | null, end: Date | string | null): void;
59
- /**
60
- * Set pending selection (for requireApply mode)
61
- */
62
- setPendingStart(date: Date | string | null): void;
63
- setPendingEnd(date: Date | string | null): void;
64
- /**
65
- * Apply pending changes
66
- */
67
- applyPending(): void;
68
- /**
69
- * Cancel pending changes
70
- */
71
- cancelPending(): void;
72
- private clearPending;
73
- /**
74
- * Reset to empty state
75
- */
76
- reset(): void;
77
- /**
78
- * Apply a preset by key
79
- *
80
- * SSR-Safe: Uses injected DateClock for deterministic resolution
81
- *
82
- * @param presetKey - Preset identifier (e.g., 'TODAY', 'LAST_7_DAYS')
83
- * @param now - Optional date override (defaults to clock.now())
84
- */
85
- applyPreset(presetKey: string, now?: Date): void;
86
- /**
87
- * Navigate left calendar month
88
- */
89
- setLeftMonth(date: Date): void;
90
- /**
91
- * Navigate right calendar month
92
- */
93
- setRightMonth(date: Date): void;
94
- /**
95
- * Set time values
96
- */
97
- setStartTime(time: string): void;
98
- setEndTime(time: string): void;
99
- /**
100
- * Get current state as snapshot
101
- */
102
- getSnapshot(): DateRangeState;
103
- /**
104
- * Load state from snapshot
105
- */
106
- loadSnapshot(snapshot: DateRangeState): void;
107
- private parseDate;
108
- private getNextMonth;
109
- private getPreviousMonth;
110
- private formatDateShort;
111
- static ɵfac: i0.ɵɵFactoryDeclaration<DualDateRangeStore, never>;
112
- static ɵprov: i0.ɵɵInjectableDeclaration<DualDateRangeStore>;
113
- }
package/core/index.d.ts DELETED
@@ -1,33 +0,0 @@
1
- /**
2
- * Core headless date range logic
3
- *
4
- * v3.6.0: Plugin Architecture
5
- * - RangePresetPlugin interface for extensible presets
6
- * - PresetRegistry for plugin management
7
- * - Built-in presets as plugins
8
- * - Provider functions for custom presets
9
- *
10
- * v3.7.0: Calendar Grid Cache
11
- * - CalendarGridFactory for deterministic grid generation
12
- * - CalendarGridCache with LRU memoization
13
- * - Separates grid structure from decorations for performance
14
- *
15
- * v3.8.0: Range Highlight Cache
16
- * - RangeHighlighter for decoration logic (pure computation)
17
- * - RangeHighlighterCache with LRU (48 grids)
18
- * - Eliminates redundant decoration recomputations
19
- *
20
- * Import from here for clean barrel exports
21
- */
22
- export * from './dual-date-range.store';
23
- export * from './preset.engine';
24
- export * from './range.validator';
25
- export * from './date-clock';
26
- export * from './system-clock';
27
- export * from './date-adapter';
28
- export * from './native-date-adapter';
29
- export * from './range-preset.plugin';
30
- export * from './preset-registry';
31
- export * from './built-in-presets';
32
- export * from './preset-providers';
33
- export * from './calendar-grid';
@@ -1,152 +0,0 @@
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
- }
@@ -1,176 +0,0 @@
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;