@oneluiz/dual-datepicker 3.2.0 → 3.3.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
@@ -36,6 +36,7 @@ npm install @oneluiz/dual-datepicker
36
36
  - [Date Adapter System](#date-adapter-system)
37
37
  - [Keyboard Navigation](#keyboard-navigation)
38
38
  - [Customization](#-customization)
39
+ - [Theming System](#theming-system)
39
40
  - [Styling Options](#styling-options)
40
41
  - [Localization (i18n)](#localization-i18n)
41
42
  - [API Reference](#-api-reference)
@@ -60,7 +61,8 @@ npm install @oneluiz/dual-datepicker
60
61
  - 🚫 **Disabled Dates** – Block weekends, holidays, or custom logic
61
62
  - 🎨 **Display Format** – Customize date display (DD/MM/YYYY, MM/DD/YYYY, etc.)
62
63
  - ✅ **Apply/Confirm Button** – Require confirmation before emitting (perfect for dashboards)
63
- - 🎨 **Fully Customizable** – Every color, padding, border configurable
64
+ - **Theming System** – Built-in themes for Bootstrap, Bulma, Foundation, Tailwind, + Custom
65
+ - �🎨 **Fully Customizable** – Every color, padding, border configurable
64
66
  - 📦 **Lightweight** – ~60 KB gzipped total bundle
65
67
  - 🚀 **Performance** – OnPush change detection + trackBy optimization
66
68
  - ♿ **Accessible** – Full keyboard navigation, ARIA labels, WCAG 2.1 AA compliant
@@ -662,6 +664,29 @@ export class AppComponent {}
662
664
 
663
665
  ## 🎨 Customization
664
666
 
667
+ ### Theming System
668
+
669
+ The datepicker now supports 6 built-in themes: `default`, `bootstrap`, `bulma`, `foundation`, `tailwind`, and `custom`.
670
+
671
+ ```typescript
672
+ <ngx-dual-datepicker theme="bootstrap"></ngx-dual-datepicker>
673
+ ```
674
+
675
+ ```scss
676
+ // In your styles.scss
677
+ @import '@oneluiz/dual-datepicker/themes/bootstrap';
678
+ ```
679
+
680
+ **Available Themes:**
681
+ - `default` - Original styling (no import needed)
682
+ - `bootstrap` - Bootstrap 5 compatible styling
683
+ - `bulma` - Bulma CSS compatible styling
684
+ - `foundation` - Foundation CSS compatible styling
685
+ - `tailwind` - Tailwind CSS compatible styling
686
+ - `custom` - CSS variables-based customization
687
+
688
+ **📚 For detailed theming documentation, see [THEMING.md](./THEMING.md)**
689
+
665
690
  ### Styling Options
666
691
 
667
692
  ```html
package/THEMING.md ADDED
@@ -0,0 +1,313 @@
1
+ # Theming System
2
+
3
+ The `ng-dual-datepicker` component comes with a flexible theming system that allows you to style it according to your preferred CSS framework or custom design.
4
+
5
+ ## Available Themes
6
+
7
+ - **default** - Original styling (no additional imports needed)
8
+ - **bootstrap** - Bootstrap 5 compatible styling
9
+ - **bulma** - Bulma CSS compatible styling
10
+ - **foundation** - Foundation CSS compatible styling
11
+ - **tailwind** - Tailwind CSS compatible styling
12
+ - **custom** - Customizable theme with CSS variables
13
+
14
+ ## Usage
15
+
16
+ ### 1. Set the Theme
17
+
18
+ Add the `theme` input to your component:
19
+
20
+ ```html
21
+ <ngx-dual-datepicker
22
+ theme="bootstrap"
23
+ [presets]="presets"
24
+ (dateRangeChange)="onDateRangeChange($event)">
25
+ </ngx-dual-datepicker>
26
+ ```
27
+
28
+ ### 2. Import the Theme Styles
29
+
30
+ Import the corresponding theme stylesheet in your global `styles.scss`:
31
+
32
+ ```scss
33
+ // For Bootstrap theme
34
+ @import '@oneluiz/dual-datepicker/themes/bootstrap';
35
+
36
+ // For Bulma theme
37
+ @import '@oneluiz/dual-datepicker/themes/bulma';
38
+
39
+ // For Foundation theme
40
+ @import '@oneluiz/dual-datepicker/themes/foundation';
41
+
42
+ // For Tailwind theme
43
+ @import '@oneluiz/dual-datepicker/themes/tailwind';
44
+
45
+ // For Custom theme
46
+ @import '@oneluiz/dual-datepicker/themes/custom';
47
+ ```
48
+
49
+ ## Theme Details
50
+
51
+ ### Default Theme
52
+
53
+ No additional configuration needed. This is the original styling that works out of the box.
54
+
55
+ ```html
56
+ <ngx-dual-datepicker [presets]="presets"></ngx-dual-datepicker>
57
+ ```
58
+
59
+ ### Bootstrap Theme
60
+
61
+ Compatible with Bootstrap 5. Make sure you have Bootstrap CSS loaded in your project.
62
+
63
+ ```html
64
+ <ngx-dual-datepicker theme="bootstrap" [presets]="presets"></ngx-dual-datepicker>
65
+ ```
66
+
67
+ ```scss
68
+ @import '@oneluiz/dual-datepicker/themes/bootstrap';
69
+ ```
70
+
71
+ ### Bulma Theme
72
+
73
+ Compatible with Bulma CSS. Make sure you have Bulma CSS loaded in your project.
74
+
75
+ ```html
76
+ <ngx-dual-datepicker theme="bulma" [presets]="presets"></ngx-dual-datepicker>
77
+ ```
78
+
79
+ ```scss
80
+ @import '@oneluiz/dual-datepicker/themes/bulma';
81
+ ```
82
+
83
+ ### Foundation Theme
84
+
85
+ Compatible with Foundation CSS. Make sure you have Foundation CSS loaded in your project.
86
+
87
+ ```html
88
+ <ngx-dual-datepicker theme="foundation" [presets]="presets"></ngx-dual-datepicker>
89
+ ```
90
+
91
+ ```scss
92
+ @import '@oneluiz/dual-datepicker/themes/foundation';
93
+ ```
94
+
95
+ ### Tailwind CSS Theme
96
+
97
+ Compatible with Tailwind CSS. Make sure you have Tailwind configured in your project.
98
+
99
+ ```html
100
+ <ngx-dual-datepicker theme="tailwind" [presets]="presets"></ngx-dual-datepicker>
101
+ ```
102
+
103
+ ```scss
104
+ @import '@oneluiz/dual-datepicker/themes/tailwind';
105
+ ```
106
+
107
+ ### Custom Theme
108
+
109
+ The custom theme provides CSS variables that you can easily override to match your brand colors.
110
+
111
+ ```html
112
+ <ngx-dual-datepicker theme="custom" [presets]="presets"></ngx-dual-datepicker>
113
+ ```
114
+
115
+ ```scss
116
+ @import '@oneluiz/dual-datepicker/themes/custom';
117
+
118
+ // Override the CSS variables
119
+ .datepicker-wrapper.theme-custom {
120
+ --dp-primary-color: #ff6b6b;
121
+ --dp-primary-hover: #ee5a6f;
122
+ --dp-danger-color: #fa5252;
123
+ --dp-danger-hover: #e03131;
124
+ --dp-text-color: #2d3748;
125
+ --dp-text-muted: #718096;
126
+ --dp-border-color: #e2e8f0;
127
+ --dp-border-hover: #cbd5e0;
128
+ --dp-bg-color: #ffffff;
129
+ --dp-bg-hover: #f7fafc;
130
+ --dp-bg-disabled: #edf2f7;
131
+ --dp-border-radius: 0.5rem;
132
+ }
133
+ ```
134
+
135
+ ## Available CSS Variables (Custom Theme)
136
+
137
+ | Variable | Default Value | Description |
138
+ |----------|--------------|-------------|
139
+ | `--dp-primary-color` | `#3b82f6` | Primary button and selection color |
140
+ | `--dp-primary-hover` | `#2563eb` | Primary hover state color |
141
+ | `--dp-danger-color` | `#ef4444` | Danger/close button color |
142
+ | `--dp-danger-hover` | `#dc2626` | Danger hover state color |
143
+ | `--dp-text-color` | `#1f2937` | Main text color |
144
+ | `--dp-text-muted` | `#6b7280` | Muted/placeholder text color |
145
+ | `--dp-border-color` | `#d1d5db` | Border color |
146
+ | `--dp-border-hover` | `#9ca3af` | Border hover color |
147
+ | `--dp-bg-color` | `#ffffff` | Background color |
148
+ | `--dp-bg-hover` | `#f3f4f6` | Hover background color |
149
+ | `--dp-bg-disabled` | `#f9fafb` | Disabled state background |
150
+ | `--dp-border-radius` | `0.375rem` | Border radius for elements |
151
+ | `--dp-transition` | `all 0.15s ease` | Transition effect |
152
+
153
+ ## Creating Your Own Theme
154
+
155
+ You can create your own theme by:
156
+
157
+ 1. Creating a new SCSS file (e.g., `my-theme.scss`)
158
+ 2. Targeting the `.datepicker-wrapper.theme-custom` class
159
+ 3. Defining your custom styles
160
+
161
+ Example:
162
+
163
+ ```scss
164
+ // my-theme.scss
165
+ .datepicker-wrapper.theme-custom {
166
+ .datepicker-input {
167
+ // Your custom styles
168
+ border: 2px solid #your-color;
169
+ border-radius: 12px;
170
+ }
171
+
172
+ .date-picker-dropdown {
173
+ // Your custom styles
174
+ box-shadow: 0 20px 25px rgba(0, 0, 0, 0.15);
175
+ }
176
+
177
+ .day.selected {
178
+ // Your custom styles
179
+ background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
180
+ }
181
+ }
182
+ ```
183
+
184
+ ## TypeScript Type
185
+
186
+ The theme type is exported from the library:
187
+
188
+ ```typescript
189
+ import { ThemeType } from '@oneluiz/dual-datepicker';
190
+
191
+ const myTheme: ThemeType = 'bootstrap';
192
+ ```
193
+
194
+ ## Mixing Themes and Custom Inputs
195
+
196
+ You can still use the custom styling inputs (`inputBackgroundColor`, `inputBorderColor`, etc.) along with themes. The input properties will override the theme styles:
197
+
198
+ ```html
199
+ <ngx-dual-datepicker
200
+ theme="bootstrap"
201
+ inputBorderColor="#ff0000"
202
+ inputBorderColorFocus="#00ff00"
203
+ [presets]="presets">
204
+ </ngx-dual-datepicker>
205
+ ```
206
+
207
+ ## Best Practices
208
+
209
+ 1. **Choose One Theme**: Select one theme that matches your project's CSS framework
210
+ 2. **Import Only What You Need**: Only import the theme stylesheet you're using
211
+ 3. **Consistent Styling**: Use the same theme across all datepicker instances
212
+ 4. **Custom Variables**: For small adjustments, use the Custom theme with CSS variables instead of creating a whole new theme
213
+
214
+ ## Examples
215
+
216
+ ### Bootstrap Project
217
+
218
+ ```typescript
219
+ // app.component.ts
220
+ import { Component } from '@angular/core';
221
+ import { DualDatepickerComponent } from '@oneluiz/dual-datepicker';
222
+
223
+ @Component({
224
+ selector: 'app-root',
225
+ standalone: true,
226
+ imports: [DualDatepickerComponent],
227
+ template: `
228
+ <ngx-dual-datepicker
229
+ theme="bootstrap"
230
+ [presets]="presets"
231
+ (dateRangeChange)="onDateRangeChange($event)">
232
+ </ngx-dual-datepicker>
233
+ `
234
+ })
235
+ export class AppComponent {
236
+ // ...
237
+ }
238
+ ```
239
+
240
+ ```scss
241
+ // styles.scss
242
+ @import 'bootstrap/scss/bootstrap';
243
+ @import '@oneluiz/dual-datepicker/themes/bootstrap';
244
+ ```
245
+
246
+ ### Tailwind Project
247
+
248
+ ```typescript
249
+ // app.component.ts
250
+ template: `
251
+ <ngx-dual-datepicker
252
+ theme="tailwind"
253
+ [presets]="presets">
254
+ </ngx-dual-datepicker>
255
+ `
256
+ ```
257
+
258
+ ```scss
259
+ // styles.scss
260
+ @import 'tailwindcss/base';
261
+ @import 'tailwindcss/components';
262
+ @import 'tailwindcss/utilities';
263
+ @import '@oneluiz/dual-datepicker/themes/tailwind';
264
+ ```
265
+
266
+ ### Custom Branded Theme
267
+
268
+ ```typescript
269
+ // app.component.ts
270
+ template: `
271
+ <ngx-dual-datepicker
272
+ theme="custom"
273
+ [presets]="presets">
274
+ </ngx-dual-datepicker>
275
+ `
276
+ ```
277
+
278
+ ```scss
279
+ // styles.scss
280
+ @import '@oneluiz/dual-datepicker/themes/custom';
281
+
282
+ .datepicker-wrapper.theme-custom {
283
+ --dp-primary-color: #your-brand-color;
284
+ --dp-primary-hover: #your-brand-hover-color;
285
+ --dp-border-radius: 0.75rem;
286
+ }
287
+ ```
288
+
289
+ ## FAQ
290
+
291
+ **Q: Can I use multiple themes in the same application?**
292
+ A: Yes, but you'll need to import all the theme stylesheets you plan to use. Each component can have its own theme.
293
+
294
+ **Q: Do I need to import Bootstrap/Bulma/Foundation/Tailwind CSS separately?**
295
+ A: Yes, the theme stylesheets only provide datepicker-specific styles. You need to have the base framework CSS loaded in your project.
296
+
297
+ **Q: Can I switch themes dynamically?**
298
+ A: Yes, you can bind the `theme` input to a variable and change it at runtime.
299
+
300
+ ```typescript
301
+ currentTheme: ThemeType = 'bootstrap';
302
+
303
+ switchTheme() {
304
+ this.currentTheme = this.currentTheme === 'bootstrap' ? 'bulma' : 'bootstrap';
305
+ }
306
+ ```
307
+
308
+ **Q: What happens if I don't import the theme stylesheet?**
309
+ A: The component will still work but will use the default inline styles. The theme-specific styles won't be applied.
310
+
311
+ ## Support
312
+
313
+ For issues or questions about theming, please visit [GitHub Issues](https://github.com/oneluiz/ng-dual-datepicker/issues).
@@ -24,6 +24,7 @@ export interface LocaleConfig {
24
24
  dayNamesShort?: string[];
25
25
  firstDayOfWeek?: number;
26
26
  }
27
+ export type ThemeType = 'default' | 'bootstrap' | 'bulma' | 'foundation' | 'tailwind' | 'custom';
27
28
  export declare class DualDatepickerComponent implements OnInit, OnChanges, ControlValueAccessor {
28
29
  private elementRef;
29
30
  placeholder: string;
@@ -37,6 +38,7 @@ export declare class DualDatepickerComponent implements OnInit, OnChanges, Contr
37
38
  closeOnClickOutside: boolean;
38
39
  enableKeyboardNavigation: boolean;
39
40
  presets: PresetConfig[];
41
+ theme: ThemeType;
40
42
  inputBackgroundColor: string;
41
43
  inputTextColor: string;
42
44
  inputBorderColor: string;
@@ -126,5 +128,5 @@ export declare class DualDatepickerComponent implements OnInit, OnChanges, Contr
126
128
  registerOnTouched(fn: () => void): void;
127
129
  setDisabledState(isDisabled: boolean): void;
128
130
  static ɵfac: i0.ɵɵFactoryDeclaration<DualDatepickerComponent, never>;
129
- static ɵcmp: i0.ɵɵComponentDeclaration<DualDatepickerComponent, "ngx-dual-datepicker", never, { "placeholder": { "alias": "placeholder"; "required": false; }; "startDate": { "alias": "startDate"; "required": false; }; "endDate": { "alias": "endDate"; "required": false; }; "showPresets": { "alias": "showPresets"; "required": false; }; "showClearButton": { "alias": "showClearButton"; "required": false; }; "multiRange": { "alias": "multiRange"; "required": false; }; "closeOnSelection": { "alias": "closeOnSelection"; "required": false; }; "closeOnPresetSelection": { "alias": "closeOnPresetSelection"; "required": false; }; "closeOnClickOutside": { "alias": "closeOnClickOutside"; "required": false; }; "enableKeyboardNavigation": { "alias": "enableKeyboardNavigation"; "required": false; }; "presets": { "alias": "presets"; "required": false; }; "inputBackgroundColor": { "alias": "inputBackgroundColor"; "required": false; }; "inputTextColor": { "alias": "inputTextColor"; "required": false; }; "inputBorderColor": { "alias": "inputBorderColor"; "required": false; }; "inputBorderColorHover": { "alias": "inputBorderColorHover"; "required": false; }; "inputBorderColorFocus": { "alias": "inputBorderColorFocus"; "required": false; }; "inputPadding": { "alias": "inputPadding"; "required": false; }; "locale": { "alias": "locale"; "required": false; }; "disabledDates": { "alias": "disabledDates"; "required": false; }; "displayFormat": { "alias": "displayFormat"; "required": false; }; "requireApply": { "alias": "requireApply"; "required": false; }; }, { "dateRangeChange": "dateRangeChange"; "dateRangeSelected": "dateRangeSelected"; "multiDateRangeChange": "multiDateRangeChange"; "multiDateRangeSelected": "multiDateRangeSelected"; }, never, never, true, never>;
131
+ static ɵcmp: i0.ɵɵComponentDeclaration<DualDatepickerComponent, "ngx-dual-datepicker", never, { "placeholder": { "alias": "placeholder"; "required": false; }; "startDate": { "alias": "startDate"; "required": false; }; "endDate": { "alias": "endDate"; "required": false; }; "showPresets": { "alias": "showPresets"; "required": false; }; "showClearButton": { "alias": "showClearButton"; "required": false; }; "multiRange": { "alias": "multiRange"; "required": false; }; "closeOnSelection": { "alias": "closeOnSelection"; "required": false; }; "closeOnPresetSelection": { "alias": "closeOnPresetSelection"; "required": false; }; "closeOnClickOutside": { "alias": "closeOnClickOutside"; "required": false; }; "enableKeyboardNavigation": { "alias": "enableKeyboardNavigation"; "required": false; }; "presets": { "alias": "presets"; "required": false; }; "theme": { "alias": "theme"; "required": false; }; "inputBackgroundColor": { "alias": "inputBackgroundColor"; "required": false; }; "inputTextColor": { "alias": "inputTextColor"; "required": false; }; "inputBorderColor": { "alias": "inputBorderColor"; "required": false; }; "inputBorderColorHover": { "alias": "inputBorderColorHover"; "required": false; }; "inputBorderColorFocus": { "alias": "inputBorderColorFocus"; "required": false; }; "inputPadding": { "alias": "inputPadding"; "required": false; }; "locale": { "alias": "locale"; "required": false; }; "disabledDates": { "alias": "disabledDates"; "required": false; }; "displayFormat": { "alias": "displayFormat"; "required": false; }; "requireApply": { "alias": "requireApply"; "required": false; }; }, { "dateRangeChange": "dateRangeChange"; "dateRangeSelected": "dateRangeSelected"; "multiDateRangeChange": "multiDateRangeChange"; "multiDateRangeSelected": "multiDateRangeSelected"; }, never, never, true, never>;
130
132
  }