ngxsmk-datepicker 1.0.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 +139 -0
- package/fesm2022/ngxsmk-datepicker.mjs +463 -0
- package/fesm2022/ngxsmk-datepicker.mjs.map +1 -0
- package/index.d.ts +100 -0
- package/package.json +23 -0
package/README.md
ADDED
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
# **ngxsmk-datepicker**
|
|
2
|
+
|
|
3
|
+
A powerful, modern, and highly customizable date range picker component for Angular 17+ applications.
|
|
4
|
+
|
|
5
|
+
* Repository (GitHub): https://github.com/toozuuu/ngxsmk-datepicker
|
|
6
|
+
* Live Demo (StackBlitz): https://stackblitz.com/~/github.com/toozuuu/ngxsmk-datepicker
|
|
7
|
+
|
|
8
|
+
Built with Angular Signals for optimal performance and a clean, declarative API. The component is standalone and has zero dependencies, making it lightweight and easy to integrate into any project.
|
|
9
|
+
|
|
10
|
+
## Screenshots
|
|
11
|
+
|
|
12
|
+
<p align="left">
|
|
13
|
+
<img src="https://unpkg.com/ngxsmk-tel-input@latest/docs/1.png" alt="Angular Advanced Date Range Picker" width="420" />
|
|
14
|
+
|
|
15
|
+
<img src="https://unpkg.com/ngxsmk-tel-input@latest/docs/2.png" alt="Angular Localization" width="420" />
|
|
16
|
+
|
|
17
|
+
<img src="https://unpkg.com/ngxsmk-tel-input@latest/docs/3.png" alt="Angular Single Date Selection" width="420" />
|
|
18
|
+
</p>
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
## **✨ Features**
|
|
22
|
+
|
|
23
|
+
* **Single Date or Date Range Selection**: Configure the picker for single or range modes.
|
|
24
|
+
* **Predefined Date Ranges**: Provide a list of common ranges (e.g., "Last 7 Days," "This Month") for one-click selection.
|
|
25
|
+
* **Advanced Localization (i18n)**: Automatically displays month/weekday names and week start days based on the browser's locale or a provided locale string.
|
|
26
|
+
* **Light & Dark Themes**: Includes a beautiful dark mode, controllable via an input.
|
|
27
|
+
* **Highly Customizable**: Themeable with CSS custom properties to match your application's design.
|
|
28
|
+
* **Date Disabling**: Easily disable dates via minDate, maxDate, or a custom function (e.g., to disable weekends).
|
|
29
|
+
* **Modern UI**: Features custom dropdowns for month/year selection and smooth animations.
|
|
30
|
+
* **Flexible Inputs**: Accepts native Date objects, strings, moment, or dayjs objects as inputs.
|
|
31
|
+
* **Built for Angular 17+**: Uses modern features like standalone components and signals.
|
|
32
|
+
|
|
33
|
+
## **🚀 Installation**
|
|
34
|
+
|
|
35
|
+
Install the package using npm:
|
|
36
|
+
|
|
37
|
+
npm install ngxsmk-datepicker
|
|
38
|
+
|
|
39
|
+
## **Usage**
|
|
40
|
+
|
|
41
|
+
ngxsmk-datepicker is a standalone component, so you can import it directly into your component or module.
|
|
42
|
+
|
|
43
|
+
#### **1\. Import the Component**
|
|
44
|
+
|
|
45
|
+
In your component file (e.g., app.component.ts), import NgxsmkDatepickerComponent.
|
|
46
|
+
|
|
47
|
+
import { Component } from '@angular/core';
|
|
48
|
+
import { NgxsmkDatepickerComponent, DateRange } from 'ngxsmk-datepicker';
|
|
49
|
+
|
|
50
|
+
@Component({
|
|
51
|
+
selector: 'app-root',
|
|
52
|
+
standalone: true,
|
|
53
|
+
imports: [NgxsmkDatepickerComponent],
|
|
54
|
+
templateUrl: './app.component.html',
|
|
55
|
+
})
|
|
56
|
+
export class AppComponent {
|
|
57
|
+
// Example for predefined ranges
|
|
58
|
+
public myRanges: DateRange = {
|
|
59
|
+
'Today': [new Date(), new Date()],
|
|
60
|
+
'Last 7 Days': [new Date(new Date().setDate(new Date().getDate() - 6)), new Date()],
|
|
61
|
+
'This Month': [new Date(new Date().getFullYear(), new Date().getMonth(), 1), new Date(new Date().getFullYear(), new Date().getMonth() \+ 1, 0)],
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
// Example for disabling weekends
|
|
65
|
+
isWeekend = (date: Date): boolean => {
|
|
66
|
+
const day = date.getDay();
|
|
67
|
+
return day === 0 || day === 6; // Sunday or Saturday
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
onDateChange(value: Date | { start: Date; end: Date }) {
|
|
71
|
+
console.log('Date changed:', value);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
#### **2\. Add it to Your Template**
|
|
76
|
+
|
|
77
|
+
Use the \<ngxsmk-datepicker\> selector in your HTML template.
|
|
78
|
+
|
|
79
|
+
<!-- app.component.html -->
|
|
80
|
+
|
|
81
|
+
<h2>Advanced Date Range Picker</h2>
|
|
82
|
+
|
|
83
|
+
<ngxsmk-datepicker
|
|
84
|
+
[mode]="'range'"
|
|
85
|
+
[ranges]="myRanges"
|
|
86
|
+
[isInvalidDate]="isWeekend"
|
|
87
|
+
[locale]="'en-US'"
|
|
88
|
+
[theme]="'light'"
|
|
89
|
+
(valueChange)="onDateChange($event)"
|
|
90
|
+
></ngxsmk-datepicker\>
|
|
91
|
+
|
|
92
|
+
## **⚙️ API Reference**
|
|
93
|
+
|
|
94
|
+
### **Inputs**
|
|
95
|
+
|
|
96
|
+
| Property | Type | Default | Description |
|
|
97
|
+
|:--------------|:--------------------------|:-------------------|:----------------------------------------------------------------------------------------------------|
|
|
98
|
+
| mode | 'single' | 'range' | 'single' |
|
|
99
|
+
| locale | string | navigator.language | Sets the locale for language and regional formatting (e.g., 'en-US', 'de-DE'). |
|
|
100
|
+
| theme | 'light' | 'dark' | 'light' |
|
|
101
|
+
| showRanges | boolean | true | If true, displays the predefined ranges panel when in 'range' mode. |
|
|
102
|
+
| minDate | DateInput | null | null | The earliest selectable date. Accepts Date, string, moment, or dayjs objects. |
|
|
103
|
+
| maxDate | DateInput | null | null | The latest selectable date. Accepts Date, string, moment, or dayjs objects. |
|
|
104
|
+
| isInvalidDate | (date: Date) \=\> boolean | () \=\> false | A function to programmatically disable specific dates. Returns true if the date should be disabled. |
|
|
105
|
+
| ranges | DateRange | null | null | An object of predefined date ranges. The key is the label, and the value is a \[start, end\] tuple. |
|
|
106
|
+
|
|
107
|
+
### **Outputs**
|
|
108
|
+
|
|
109
|
+
| Event | Payload | Description |
|
|
110
|
+
|:------------|:--------|:---------------------------|
|
|
111
|
+
| valueChange | Date | { start: Date; end: Date } |
|
|
112
|
+
|
|
113
|
+
## **🎨 Theming**
|
|
114
|
+
|
|
115
|
+
You can easily customize the colors of the datepicker by overriding the CSS custom properties in your own stylesheet.
|
|
116
|
+
|
|
117
|
+
ngxsmk-datepicker {
|
|
118
|
+
--datepicker-primary-color: #d9267d; /* Main color for selected dates */
|
|
119
|
+
--datepicker-primary-contrast: #ffffff; /* Text color on selected dates */
|
|
120
|
+
--datepicker-range-background: #fce7f3; /* Background for the date range bar */
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
To enable the dark theme, simply bind the theme input:
|
|
124
|
+
|
|
125
|
+
<ngxsmk-datepicker [theme]="'dark'"></ngxsmk-datepicker>
|
|
126
|
+
|
|
127
|
+
## **🌍 Localization**
|
|
128
|
+
|
|
129
|
+
The locale input controls all internationalization. It automatically formats month names, weekday names, and sets the first day of the week.
|
|
130
|
+
|
|
131
|
+
<!-- Renders the calendar in German -->
|
|
132
|
+
<ngxsmk-datepicker [locale]="'de-DE'"></ngxsmk-datepicker>
|
|
133
|
+
|
|
134
|
+
<!-- Renders the calendar in French -->
|
|
135
|
+
<ngxsmk-datepicker [locale]="'fr-FR'"></ngxsmk-datepicker>
|
|
136
|
+
|
|
137
|
+
## **📜 License**
|
|
138
|
+
|
|
139
|
+
MIT#
|
|
@@ -0,0 +1,463 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { EventEmitter, HostListener, Output, Input, Component, PLATFORM_ID, HostBinding, Inject } from '@angular/core';
|
|
3
|
+
import * as i1 from '@angular/common';
|
|
4
|
+
import { CommonModule, isPlatformBrowser } from '@angular/common';
|
|
5
|
+
import { FormsModule } from '@angular/forms';
|
|
6
|
+
|
|
7
|
+
// #####################################################################
|
|
8
|
+
// ## Reusable Custom Select Component
|
|
9
|
+
// #####################################################################
|
|
10
|
+
class CustomSelectComponent {
|
|
11
|
+
constructor(elementRef) {
|
|
12
|
+
this.elementRef = elementRef;
|
|
13
|
+
this.options = [];
|
|
14
|
+
this.valueChange = new EventEmitter();
|
|
15
|
+
this.isOpen = false;
|
|
16
|
+
}
|
|
17
|
+
onDocumentClick(event) {
|
|
18
|
+
if (!this.elementRef.nativeElement.contains(event.target))
|
|
19
|
+
this.isOpen = false;
|
|
20
|
+
}
|
|
21
|
+
get displayValue() {
|
|
22
|
+
const selectedOption = this.options.find((opt) => opt.value === this.value);
|
|
23
|
+
return selectedOption ? selectedOption.label : '';
|
|
24
|
+
}
|
|
25
|
+
toggleDropdown() {
|
|
26
|
+
this.isOpen = !this.isOpen;
|
|
27
|
+
}
|
|
28
|
+
selectOption(option) {
|
|
29
|
+
this.value = option.value;
|
|
30
|
+
this.valueChange.emit(this.value);
|
|
31
|
+
this.isOpen = false;
|
|
32
|
+
}
|
|
33
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: CustomSelectComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
34
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: CustomSelectComponent, isStandalone: true, selector: "app-custom-select", inputs: { options: "options", value: "value" }, outputs: { valueChange: "valueChange" }, host: { listeners: { "document:click": "onDocumentClick($event)" } }, ngImport: i0, template: `
|
|
35
|
+
<div class="custom-select-container" (click)="toggleDropdown()">
|
|
36
|
+
<button type="button" class="select-display">
|
|
37
|
+
<span>{{ displayValue }}</span>
|
|
38
|
+
<svg class="arrow-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
|
|
39
|
+
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="48"
|
|
40
|
+
d="M112 184l144 144 144-144"/>
|
|
41
|
+
</svg>
|
|
42
|
+
</button>
|
|
43
|
+
@if (isOpen) {
|
|
44
|
+
<div class="options-panel">
|
|
45
|
+
<ul>
|
|
46
|
+
@for (option of options; track option.value) {
|
|
47
|
+
<li [class.selected]="option.value === value" (click)="selectOption(option); $event.stopPropagation()">
|
|
48
|
+
{{ option.label }}
|
|
49
|
+
</li>
|
|
50
|
+
}
|
|
51
|
+
</ul>
|
|
52
|
+
</div>
|
|
53
|
+
}
|
|
54
|
+
</div>
|
|
55
|
+
`, isInline: true, styles: [":host{position:relative;display:inline-block}.custom-select-container{cursor:pointer}.select-display{display:flex;align-items:center;justify-content:space-between;width:var(--custom-select-width, 115px);background:var(--datepicker-background, #fff);border:1px solid var(--datepicker-border-color, #ccc);color:var(--datepicker-text-color, #333);border-radius:4px;padding:4px 8px;font-size:1rem;text-align:left}.arrow-icon{width:12px;height:12px;margin-left:8px}.options-panel{position:absolute;top:110%;left:0;width:100%;background:var(--datepicker-background, #fff);border:1px solid var(--datepicker-border-color, #ccc);color:var(--datepicker-text-color, #333);border-radius:4px;box-shadow:0 4px 8px #0000001a;max-height:200px;overflow-y:auto;z-index:10}.options-panel ul{list-style:none;padding:4px;margin:0}.options-panel li{padding:8px 12px;border-radius:4px;cursor:pointer}.options-panel li:hover{background-color:var(--datepicker-hover-background, #f0f0f0)}.options-panel li.selected{background-color:var(--datepicker-primary-color, #3880ff);color:var(--datepicker-primary-contrast, #fff)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] }); }
|
|
56
|
+
}
|
|
57
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: CustomSelectComponent, decorators: [{
|
|
58
|
+
type: Component,
|
|
59
|
+
args: [{ selector: 'app-custom-select', standalone: true, imports: [CommonModule], template: `
|
|
60
|
+
<div class="custom-select-container" (click)="toggleDropdown()">
|
|
61
|
+
<button type="button" class="select-display">
|
|
62
|
+
<span>{{ displayValue }}</span>
|
|
63
|
+
<svg class="arrow-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
|
|
64
|
+
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="48"
|
|
65
|
+
d="M112 184l144 144 144-144"/>
|
|
66
|
+
</svg>
|
|
67
|
+
</button>
|
|
68
|
+
@if (isOpen) {
|
|
69
|
+
<div class="options-panel">
|
|
70
|
+
<ul>
|
|
71
|
+
@for (option of options; track option.value) {
|
|
72
|
+
<li [class.selected]="option.value === value" (click)="selectOption(option); $event.stopPropagation()">
|
|
73
|
+
{{ option.label }}
|
|
74
|
+
</li>
|
|
75
|
+
}
|
|
76
|
+
</ul>
|
|
77
|
+
</div>
|
|
78
|
+
}
|
|
79
|
+
</div>
|
|
80
|
+
`, styles: [":host{position:relative;display:inline-block}.custom-select-container{cursor:pointer}.select-display{display:flex;align-items:center;justify-content:space-between;width:var(--custom-select-width, 115px);background:var(--datepicker-background, #fff);border:1px solid var(--datepicker-border-color, #ccc);color:var(--datepicker-text-color, #333);border-radius:4px;padding:4px 8px;font-size:1rem;text-align:left}.arrow-icon{width:12px;height:12px;margin-left:8px}.options-panel{position:absolute;top:110%;left:0;width:100%;background:var(--datepicker-background, #fff);border:1px solid var(--datepicker-border-color, #ccc);color:var(--datepicker-text-color, #333);border-radius:4px;box-shadow:0 4px 8px #0000001a;max-height:200px;overflow-y:auto;z-index:10}.options-panel ul{list-style:none;padding:4px;margin:0}.options-panel li{padding:8px 12px;border-radius:4px;cursor:pointer}.options-panel li:hover{background-color:var(--datepicker-hover-background, #f0f0f0)}.options-panel li.selected{background-color:var(--datepicker-primary-color, #3880ff);color:var(--datepicker-primary-contrast, #fff)}\n"] }]
|
|
81
|
+
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { options: [{
|
|
82
|
+
type: Input
|
|
83
|
+
}], value: [{
|
|
84
|
+
type: Input
|
|
85
|
+
}], valueChange: [{
|
|
86
|
+
type: Output
|
|
87
|
+
}], onDocumentClick: [{
|
|
88
|
+
type: HostListener,
|
|
89
|
+
args: ['document:click', ['$event']]
|
|
90
|
+
}] } });
|
|
91
|
+
class NgxsmkDatepickerComponent {
|
|
92
|
+
set locale(value) {
|
|
93
|
+
this._locale = value;
|
|
94
|
+
}
|
|
95
|
+
get locale() {
|
|
96
|
+
return this._locale;
|
|
97
|
+
}
|
|
98
|
+
get isDarkMode() {
|
|
99
|
+
return this.theme === 'dark';
|
|
100
|
+
}
|
|
101
|
+
set minDate(value) {
|
|
102
|
+
this._minDate = this._normalizeDate(value);
|
|
103
|
+
}
|
|
104
|
+
set maxDate(value) {
|
|
105
|
+
this._maxDate = this._normalizeDate(value);
|
|
106
|
+
}
|
|
107
|
+
set ranges(value) {
|
|
108
|
+
if (!value) {
|
|
109
|
+
this._ranges = null;
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
this._ranges = Object.entries(value).reduce((acc, [key, dates]) => {
|
|
113
|
+
const start = this._normalizeDate(dates[0]);
|
|
114
|
+
const end = this._normalizeDate(dates[1]);
|
|
115
|
+
if (start && end)
|
|
116
|
+
acc[key] = [start, end];
|
|
117
|
+
return acc;
|
|
118
|
+
}, {});
|
|
119
|
+
}
|
|
120
|
+
this.updateRangesArray();
|
|
121
|
+
}
|
|
122
|
+
// FIX: Inject PLATFORM_ID and conditionally access navigator
|
|
123
|
+
constructor(platformId) {
|
|
124
|
+
this.platformId = platformId;
|
|
125
|
+
this.mode = 'single';
|
|
126
|
+
this.isInvalidDate = () => false;
|
|
127
|
+
this.showRanges = true;
|
|
128
|
+
// FIX: Use a private variable for locale with a fallback value.
|
|
129
|
+
this._locale = 'en-US';
|
|
130
|
+
this.theme = 'light';
|
|
131
|
+
this.valueChange = new EventEmitter();
|
|
132
|
+
this._minDate = null;
|
|
133
|
+
this._maxDate = null;
|
|
134
|
+
this._ranges = null;
|
|
135
|
+
this.currentDate = new Date();
|
|
136
|
+
this.daysInMonth = [];
|
|
137
|
+
this.weekDays = [];
|
|
138
|
+
this.today = new Date();
|
|
139
|
+
this.selectedDate = null;
|
|
140
|
+
this.startDate = null;
|
|
141
|
+
this.endDate = null;
|
|
142
|
+
this.hoveredDate = null;
|
|
143
|
+
this.rangesArray = [];
|
|
144
|
+
this.monthOptions = [];
|
|
145
|
+
this.yearOptions = [];
|
|
146
|
+
this.firstDayOfWeek = 0;
|
|
147
|
+
if (isPlatformBrowser(this.platformId)) {
|
|
148
|
+
this._locale = navigator.language;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
get currentMonth() {
|
|
152
|
+
return this._currentMonth;
|
|
153
|
+
}
|
|
154
|
+
set currentMonth(month) {
|
|
155
|
+
if (this._currentMonth !== month) {
|
|
156
|
+
this._currentMonth = month;
|
|
157
|
+
this.currentDate.setMonth(month);
|
|
158
|
+
this.generateCalendar();
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
get currentYear() {
|
|
162
|
+
return this._currentYear;
|
|
163
|
+
}
|
|
164
|
+
set currentYear(year) {
|
|
165
|
+
if (this._currentYear !== year) {
|
|
166
|
+
this._currentYear = year;
|
|
167
|
+
this.currentDate.setFullYear(year);
|
|
168
|
+
this.generateCalendar();
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
ngOnInit() {
|
|
172
|
+
this.today.setHours(0, 0, 0, 0);
|
|
173
|
+
this.generateLocaleData();
|
|
174
|
+
this.generateCalendar();
|
|
175
|
+
}
|
|
176
|
+
ngOnChanges(changes) {
|
|
177
|
+
if (changes['locale']) {
|
|
178
|
+
this.generateLocaleData();
|
|
179
|
+
this.generateCalendar();
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
_normalizeDate(date) {
|
|
183
|
+
if (!date)
|
|
184
|
+
return null;
|
|
185
|
+
const d = (date instanceof Date) ? new Date(date.getTime()) : new Date(date);
|
|
186
|
+
if (isNaN(d.getTime()))
|
|
187
|
+
return null;
|
|
188
|
+
d.setHours(0, 0, 0, 0);
|
|
189
|
+
return d;
|
|
190
|
+
}
|
|
191
|
+
generateLocaleData() {
|
|
192
|
+
this.monthOptions = Array.from({ length: 12 }).map((_, i) => ({
|
|
193
|
+
label: new Date(2024, i, 1).toLocaleDateString(this.locale, { month: 'long' }),
|
|
194
|
+
value: i,
|
|
195
|
+
}));
|
|
196
|
+
try {
|
|
197
|
+
// Use this.locale getter
|
|
198
|
+
this.firstDayOfWeek = (new Intl.Locale(this.locale).weekInfo?.firstDay || 0) % 7;
|
|
199
|
+
}
|
|
200
|
+
catch (e) {
|
|
201
|
+
this.firstDayOfWeek = 0;
|
|
202
|
+
}
|
|
203
|
+
const day = new Date(2024, 0, 7 + this.firstDayOfWeek);
|
|
204
|
+
this.weekDays = Array.from({ length: 7 }).map(() => {
|
|
205
|
+
const weekDay = new Date(day).toLocaleDateString(this.locale, { weekday: 'short' });
|
|
206
|
+
day.setDate(day.getDate() + 1);
|
|
207
|
+
return weekDay;
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
updateRangesArray() {
|
|
211
|
+
this.rangesArray = this._ranges ? Object.entries(this._ranges).map(([key, value]) => ({ key, value })) : [];
|
|
212
|
+
}
|
|
213
|
+
selectRange(range) {
|
|
214
|
+
this.startDate = range[0];
|
|
215
|
+
this.endDate = range[1];
|
|
216
|
+
this.valueChange.emit({ start: this.startDate, end: this.endDate });
|
|
217
|
+
this.currentDate = new Date(this.startDate);
|
|
218
|
+
this.generateCalendar();
|
|
219
|
+
}
|
|
220
|
+
isDateDisabled(date) {
|
|
221
|
+
if (!date)
|
|
222
|
+
return false;
|
|
223
|
+
if (this._minDate && date < this._minDate)
|
|
224
|
+
return true;
|
|
225
|
+
if (this._maxDate && date > this._maxDate)
|
|
226
|
+
return true;
|
|
227
|
+
if (this.isInvalidDate(date))
|
|
228
|
+
return true;
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
231
|
+
onDateClick(day) {
|
|
232
|
+
if (!day || this.isDateDisabled(day))
|
|
233
|
+
return;
|
|
234
|
+
if (this.mode === 'single') {
|
|
235
|
+
this.selectedDate = day;
|
|
236
|
+
this.valueChange.emit(this.selectedDate);
|
|
237
|
+
}
|
|
238
|
+
else {
|
|
239
|
+
if (!this.startDate || (this.startDate && this.endDate)) {
|
|
240
|
+
this.startDate = day;
|
|
241
|
+
this.endDate = null;
|
|
242
|
+
}
|
|
243
|
+
else if (day >= this.startDate) {
|
|
244
|
+
this.endDate = day;
|
|
245
|
+
this.valueChange.emit({ start: this.startDate, end: this.endDate });
|
|
246
|
+
}
|
|
247
|
+
else {
|
|
248
|
+
this.startDate = day;
|
|
249
|
+
this.endDate = null;
|
|
250
|
+
}
|
|
251
|
+
this.hoveredDate = null;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
onDateHover(day) {
|
|
255
|
+
if (this.mode === 'range' && this.startDate && !this.endDate && day) {
|
|
256
|
+
this.hoveredDate = day;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
isPreviewInRange(day) {
|
|
260
|
+
if (this.mode !== 'range' || !this.startDate || this.endDate || !this.hoveredDate || !day)
|
|
261
|
+
return false;
|
|
262
|
+
const start = this.startDate.getTime();
|
|
263
|
+
const end = this.hoveredDate.getTime();
|
|
264
|
+
const time = day.getTime();
|
|
265
|
+
return time > Math.min(start, end) && time < Math.max(start, end);
|
|
266
|
+
}
|
|
267
|
+
generateCalendar() {
|
|
268
|
+
this.daysInMonth = [];
|
|
269
|
+
const year = this.currentDate.getFullYear();
|
|
270
|
+
const month = this.currentDate.getMonth();
|
|
271
|
+
this._currentMonth = month;
|
|
272
|
+
this._currentYear = year;
|
|
273
|
+
this.generateDropdownOptions();
|
|
274
|
+
const firstDayOfMonth = new Date(year, month, 1);
|
|
275
|
+
const lastDayOfMonth = new Date(year, month + 1, 0);
|
|
276
|
+
const startDayOfWeek = firstDayOfMonth.getDay();
|
|
277
|
+
const emptyCellCount = (startDayOfWeek - this.firstDayOfWeek + 7) % 7;
|
|
278
|
+
for (let i = 0; i < emptyCellCount; i++) {
|
|
279
|
+
this.daysInMonth.push(null);
|
|
280
|
+
}
|
|
281
|
+
for (let i = 1; i <= lastDayOfMonth.getDate(); i++) {
|
|
282
|
+
this.daysInMonth.push(this._normalizeDate(new Date(year, month, i)));
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
generateDropdownOptions() {
|
|
286
|
+
const startYear = this._currentYear - 10;
|
|
287
|
+
const endYear = this._currentYear + 10;
|
|
288
|
+
this.yearOptions = [];
|
|
289
|
+
for (let i = startYear; i <= endYear; i++) {
|
|
290
|
+
this.yearOptions.push({ label: `${i}`, value: i });
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
changeMonth(delta) {
|
|
294
|
+
this.currentDate.setMonth(this.currentDate.getMonth() + delta);
|
|
295
|
+
this.generateCalendar();
|
|
296
|
+
}
|
|
297
|
+
isSameDay(d1, d2) {
|
|
298
|
+
if (!d1 || !d2)
|
|
299
|
+
return false;
|
|
300
|
+
return (d1.getFullYear() === d2.getFullYear() &&
|
|
301
|
+
d1.getMonth() === d2.getMonth() &&
|
|
302
|
+
d1.getDate() === d2.getDate());
|
|
303
|
+
}
|
|
304
|
+
isInRange(d) {
|
|
305
|
+
if (!d || !this.startDate || !this.endDate)
|
|
306
|
+
return false;
|
|
307
|
+
return (d.getTime() > this.startDate.getTime() &&
|
|
308
|
+
d.getTime() < this.endDate.getTime());
|
|
309
|
+
}
|
|
310
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: NgxsmkDatepickerComponent, deps: [{ token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Component }); }
|
|
311
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.4", type: NgxsmkDatepickerComponent, isStandalone: true, selector: "ngxsmk-datepicker", inputs: { mode: "mode", isInvalidDate: "isInvalidDate", showRanges: "showRanges", locale: "locale", theme: "theme", minDate: "minDate", maxDate: "maxDate", ranges: "ranges" }, outputs: { valueChange: "valueChange" }, host: { properties: { "class.dark-theme": "this.isDarkMode" } }, usesOnChanges: true, ngImport: i0, template: `
|
|
312
|
+
<div class="datepicker-container">
|
|
313
|
+
@if (showRanges && rangesArray.length > 0 && mode === 'range') {
|
|
314
|
+
<div class="ranges-container">
|
|
315
|
+
<ul>
|
|
316
|
+
@for (range of rangesArray; track range.key) {
|
|
317
|
+
<li (click)="selectRange(range.value)">{{ range.key }}</li>
|
|
318
|
+
}
|
|
319
|
+
</ul>
|
|
320
|
+
</div>
|
|
321
|
+
}
|
|
322
|
+
<div class="calendar-container">
|
|
323
|
+
<div class="header">
|
|
324
|
+
<div class="month-year-selects">
|
|
325
|
+
<app-custom-select class="month-select" [options]="monthOptions"
|
|
326
|
+
[(value)]="currentMonth"></app-custom-select>
|
|
327
|
+
<app-custom-select class="year-select" [options]="yearOptions" [(value)]="currentYear"></app-custom-select>
|
|
328
|
+
</div>
|
|
329
|
+
<div class="nav-buttons">
|
|
330
|
+
<button type="button" class="nav-button" (click)="changeMonth(-1)">
|
|
331
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
|
|
332
|
+
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="48"
|
|
333
|
+
d="M328 112L184 256l144 144"/>
|
|
334
|
+
</svg>
|
|
335
|
+
</button>
|
|
336
|
+
<button type="button" class="nav-button" (click)="changeMonth(1)">
|
|
337
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
|
|
338
|
+
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="48"
|
|
339
|
+
d="M184 112l144 144-144 144"/>
|
|
340
|
+
</svg>
|
|
341
|
+
</button>
|
|
342
|
+
</div>
|
|
343
|
+
</div>
|
|
344
|
+
<div class="days-grid-wrapper">
|
|
345
|
+
<div class="days-grid">
|
|
346
|
+
@for (day of weekDays; track day) {
|
|
347
|
+
<div class="day-name">{{ day }}</div>
|
|
348
|
+
}
|
|
349
|
+
@for (day of daysInMonth; track $index) {
|
|
350
|
+
<div class="day-cell"
|
|
351
|
+
[class.empty]="!day" [class.disabled]="isDateDisabled(day)" [class.today]="isSameDay(day, today)"
|
|
352
|
+
[class.selected]="mode === 'single' && isSameDay(day, selectedDate)"
|
|
353
|
+
[class.start-date]="mode === 'range' && isSameDay(day, startDate)"
|
|
354
|
+
[class.end-date]="mode === 'range' && isSameDay(day, endDate)"
|
|
355
|
+
[class.in-range]="mode === 'range' && isInRange(day)"
|
|
356
|
+
[class.preview-range]="isPreviewInRange(day)"
|
|
357
|
+
(click)="onDateClick(day)" (mouseenter)="onDateHover(day)">
|
|
358
|
+
@if (day) {
|
|
359
|
+
<div class="day-number">{{ day | date : 'd' }}</div>
|
|
360
|
+
}
|
|
361
|
+
</div>
|
|
362
|
+
}
|
|
363
|
+
</div>
|
|
364
|
+
</div>
|
|
365
|
+
</div>
|
|
366
|
+
</div>
|
|
367
|
+
`, isInline: true, styles: [":host{--datepicker-primary-color: #6d28d9;--datepicker-primary-contrast: #ffffff;--datepicker-range-background: #f5f3ff;--datepicker-background: #ffffff;--datepicker-text-color: #222428;--datepicker-subtle-text-color: #9ca3af;--datepicker-border-color: #e9e9e9;--datepicker-hover-background: #f0f0f0}:host(.dark-theme){--datepicker-range-background: rgba(139, 92, 246, .2);--datepicker-background: #1f2937;--datepicker-text-color: #d1d5db;--datepicker-subtle-text-color: #6b7280;--datepicker-border-color: #4b5563;--datepicker-hover-background: #374151}.datepicker-container{display:flex}.calendar-container{width:320px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;border:1px solid var(--datepicker-border-color);border-radius:10px;padding:16px;background:var(--datepicker-background);overflow:hidden}.header{display:flex;justify-content:space-between;align-items:center;margin-bottom:12px;position:relative;z-index:2}.month-year-selects{display:flex;gap:8px}.month-year-selects app-custom-select.month-select{--custom-select-width: 120px}.month-year-selects app-custom-select.year-select{--custom-select-width: 90px}.nav-buttons{display:flex}.nav-button{background:none;border:none;padding:8px;cursor:pointer;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;color:var(--datepicker-text-color)}.nav-button:hover{background-color:var(--datepicker-hover-background)}.nav-button svg{width:18px;height:18px}.days-grid-wrapper{position:relative}.days-grid{display:grid;grid-template-columns:repeat(7,1fr);text-align:center;gap:0}.day-name{font-weight:600;font-size:.8rem;color:var(--datepicker-subtle-text-color);padding:8px 0}.day-cell{position:relative;height:38px;display:flex;justify-content:center;align-items:center;cursor:pointer;border-radius:0}.day-number{width:36px;height:36px;display:flex;justify-content:center;align-items:center;border-radius:50%;color:var(--datepicker-text-color);position:relative;z-index:1}.day-cell:not(.disabled):hover .day-number{background-color:var(--datepicker-hover-background)}.day-cell.start-date .day-number,.day-cell.end-date .day-number,.day-cell.selected .day-number{background-color:var(--datepicker-primary-color);color:var(--datepicker-primary-contrast)}.day-cell.in-range,.day-cell.start-date,.day-cell.end-date,.day-cell.preview-range{background-color:var(--datepicker-range-background)}.day-cell.start-date{border-top-left-radius:50px;border-bottom-left-radius:50px}.day-cell.end-date{border-top-right-radius:50px;border-bottom-right-radius:50px}.day-cell.start-date.end-date{border-radius:50px}.day-cell.disabled{background-color:transparent!important;color:#4b5563;cursor:not-allowed;pointer-events:none;opacity:.5}.day-cell.today .day-number{border:1px solid var(--datepicker-primary-color)}.ranges-container{width:180px;padding:16px;border-right:1px solid var(--datepicker-border-color);background:var(--datepicker-background)}.ranges-container ul{list-style:none;padding:0;margin:0}.ranges-container li{padding:10px;margin-bottom:8px;border-radius:6px;cursor:pointer;color:var(--datepicker-text-color)}.ranges-container li:hover{background-color:var(--datepicker-hover-background)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: CustomSelectComponent, selector: "app-custom-select", inputs: ["options", "value"], outputs: ["valueChange"] }, { kind: "pipe", type: i1.DatePipe, name: "date" }] }); }
|
|
368
|
+
}
|
|
369
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.4", ngImport: i0, type: NgxsmkDatepickerComponent, decorators: [{
|
|
370
|
+
type: Component,
|
|
371
|
+
args: [{ selector: 'ngxsmk-datepicker', standalone: true, imports: [CommonModule, FormsModule, CustomSelectComponent], template: `
|
|
372
|
+
<div class="datepicker-container">
|
|
373
|
+
@if (showRanges && rangesArray.length > 0 && mode === 'range') {
|
|
374
|
+
<div class="ranges-container">
|
|
375
|
+
<ul>
|
|
376
|
+
@for (range of rangesArray; track range.key) {
|
|
377
|
+
<li (click)="selectRange(range.value)">{{ range.key }}</li>
|
|
378
|
+
}
|
|
379
|
+
</ul>
|
|
380
|
+
</div>
|
|
381
|
+
}
|
|
382
|
+
<div class="calendar-container">
|
|
383
|
+
<div class="header">
|
|
384
|
+
<div class="month-year-selects">
|
|
385
|
+
<app-custom-select class="month-select" [options]="monthOptions"
|
|
386
|
+
[(value)]="currentMonth"></app-custom-select>
|
|
387
|
+
<app-custom-select class="year-select" [options]="yearOptions" [(value)]="currentYear"></app-custom-select>
|
|
388
|
+
</div>
|
|
389
|
+
<div class="nav-buttons">
|
|
390
|
+
<button type="button" class="nav-button" (click)="changeMonth(-1)">
|
|
391
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
|
|
392
|
+
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="48"
|
|
393
|
+
d="M328 112L184 256l144 144"/>
|
|
394
|
+
</svg>
|
|
395
|
+
</button>
|
|
396
|
+
<button type="button" class="nav-button" (click)="changeMonth(1)">
|
|
397
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
|
|
398
|
+
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="48"
|
|
399
|
+
d="M184 112l144 144-144 144"/>
|
|
400
|
+
</svg>
|
|
401
|
+
</button>
|
|
402
|
+
</div>
|
|
403
|
+
</div>
|
|
404
|
+
<div class="days-grid-wrapper">
|
|
405
|
+
<div class="days-grid">
|
|
406
|
+
@for (day of weekDays; track day) {
|
|
407
|
+
<div class="day-name">{{ day }}</div>
|
|
408
|
+
}
|
|
409
|
+
@for (day of daysInMonth; track $index) {
|
|
410
|
+
<div class="day-cell"
|
|
411
|
+
[class.empty]="!day" [class.disabled]="isDateDisabled(day)" [class.today]="isSameDay(day, today)"
|
|
412
|
+
[class.selected]="mode === 'single' && isSameDay(day, selectedDate)"
|
|
413
|
+
[class.start-date]="mode === 'range' && isSameDay(day, startDate)"
|
|
414
|
+
[class.end-date]="mode === 'range' && isSameDay(day, endDate)"
|
|
415
|
+
[class.in-range]="mode === 'range' && isInRange(day)"
|
|
416
|
+
[class.preview-range]="isPreviewInRange(day)"
|
|
417
|
+
(click)="onDateClick(day)" (mouseenter)="onDateHover(day)">
|
|
418
|
+
@if (day) {
|
|
419
|
+
<div class="day-number">{{ day | date : 'd' }}</div>
|
|
420
|
+
}
|
|
421
|
+
</div>
|
|
422
|
+
}
|
|
423
|
+
</div>
|
|
424
|
+
</div>
|
|
425
|
+
</div>
|
|
426
|
+
</div>
|
|
427
|
+
`, styles: [":host{--datepicker-primary-color: #6d28d9;--datepicker-primary-contrast: #ffffff;--datepicker-range-background: #f5f3ff;--datepicker-background: #ffffff;--datepicker-text-color: #222428;--datepicker-subtle-text-color: #9ca3af;--datepicker-border-color: #e9e9e9;--datepicker-hover-background: #f0f0f0}:host(.dark-theme){--datepicker-range-background: rgba(139, 92, 246, .2);--datepicker-background: #1f2937;--datepicker-text-color: #d1d5db;--datepicker-subtle-text-color: #6b7280;--datepicker-border-color: #4b5563;--datepicker-hover-background: #374151}.datepicker-container{display:flex}.calendar-container{width:320px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,sans-serif;border:1px solid var(--datepicker-border-color);border-radius:10px;padding:16px;background:var(--datepicker-background);overflow:hidden}.header{display:flex;justify-content:space-between;align-items:center;margin-bottom:12px;position:relative;z-index:2}.month-year-selects{display:flex;gap:8px}.month-year-selects app-custom-select.month-select{--custom-select-width: 120px}.month-year-selects app-custom-select.year-select{--custom-select-width: 90px}.nav-buttons{display:flex}.nav-button{background:none;border:none;padding:8px;cursor:pointer;border-radius:50%;display:inline-flex;align-items:center;justify-content:center;color:var(--datepicker-text-color)}.nav-button:hover{background-color:var(--datepicker-hover-background)}.nav-button svg{width:18px;height:18px}.days-grid-wrapper{position:relative}.days-grid{display:grid;grid-template-columns:repeat(7,1fr);text-align:center;gap:0}.day-name{font-weight:600;font-size:.8rem;color:var(--datepicker-subtle-text-color);padding:8px 0}.day-cell{position:relative;height:38px;display:flex;justify-content:center;align-items:center;cursor:pointer;border-radius:0}.day-number{width:36px;height:36px;display:flex;justify-content:center;align-items:center;border-radius:50%;color:var(--datepicker-text-color);position:relative;z-index:1}.day-cell:not(.disabled):hover .day-number{background-color:var(--datepicker-hover-background)}.day-cell.start-date .day-number,.day-cell.end-date .day-number,.day-cell.selected .day-number{background-color:var(--datepicker-primary-color);color:var(--datepicker-primary-contrast)}.day-cell.in-range,.day-cell.start-date,.day-cell.end-date,.day-cell.preview-range{background-color:var(--datepicker-range-background)}.day-cell.start-date{border-top-left-radius:50px;border-bottom-left-radius:50px}.day-cell.end-date{border-top-right-radius:50px;border-bottom-right-radius:50px}.day-cell.start-date.end-date{border-radius:50px}.day-cell.disabled{background-color:transparent!important;color:#4b5563;cursor:not-allowed;pointer-events:none;opacity:.5}.day-cell.today .day-number{border:1px solid var(--datepicker-primary-color)}.ranges-container{width:180px;padding:16px;border-right:1px solid var(--datepicker-border-color);background:var(--datepicker-background)}.ranges-container ul{list-style:none;padding:0;margin:0}.ranges-container li{padding:10px;margin-bottom:8px;border-radius:6px;cursor:pointer;color:var(--datepicker-text-color)}.ranges-container li:hover{background-color:var(--datepicker-hover-background)}\n"] }]
|
|
428
|
+
}], ctorParameters: () => [{ type: Object, decorators: [{
|
|
429
|
+
type: Inject,
|
|
430
|
+
args: [PLATFORM_ID]
|
|
431
|
+
}] }], propDecorators: { mode: [{
|
|
432
|
+
type: Input
|
|
433
|
+
}], isInvalidDate: [{
|
|
434
|
+
type: Input
|
|
435
|
+
}], showRanges: [{
|
|
436
|
+
type: Input
|
|
437
|
+
}], locale: [{
|
|
438
|
+
type: Input
|
|
439
|
+
}], theme: [{
|
|
440
|
+
type: Input
|
|
441
|
+
}], isDarkMode: [{
|
|
442
|
+
type: HostBinding,
|
|
443
|
+
args: ['class.dark-theme']
|
|
444
|
+
}], valueChange: [{
|
|
445
|
+
type: Output
|
|
446
|
+
}], minDate: [{
|
|
447
|
+
type: Input
|
|
448
|
+
}], maxDate: [{
|
|
449
|
+
type: Input
|
|
450
|
+
}], ranges: [{
|
|
451
|
+
type: Input
|
|
452
|
+
}] } });
|
|
453
|
+
|
|
454
|
+
/*
|
|
455
|
+
* Public API Surface of ngxsmk-datepicker
|
|
456
|
+
*/
|
|
457
|
+
|
|
458
|
+
/**
|
|
459
|
+
* Generated bundle index. Do not edit.
|
|
460
|
+
*/
|
|
461
|
+
|
|
462
|
+
export { CustomSelectComponent, NgxsmkDatepickerComponent };
|
|
463
|
+
//# sourceMappingURL=ngxsmk-datepicker.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ngxsmk-datepicker.mjs","sources":["../../../projects/ngxsmk-datepicker/src/lib/ngxsmk-datepicker.ts","../../../projects/ngxsmk-datepicker/src/public-api.ts","../../../projects/ngxsmk-datepicker/src/ngxsmk-datepicker.ts"],"sourcesContent":["import {\r\n Component,\r\n ElementRef,\r\n EventEmitter,\r\n HostBinding,\r\n HostListener,\r\n Inject,\r\n Input,\r\n OnChanges,\r\n OnInit,\r\n Output,\r\n PLATFORM_ID,\r\n SimpleChanges,\r\n} from '@angular/core';\r\nimport {CommonModule, isPlatformBrowser} from '@angular/common';\r\nimport {FormsModule} from '@angular/forms';\r\n\r\n// #####################################################################\r\n// ## Reusable Custom Select Component\r\n// #####################################################################\r\n@Component({\r\n selector: 'app-custom-select',\r\n standalone: true,\r\n imports: [CommonModule],\r\n template: `\r\n <div class=\"custom-select-container\" (click)=\"toggleDropdown()\">\r\n <button type=\"button\" class=\"select-display\">\r\n <span>{{ displayValue }}</span>\r\n <svg class=\"arrow-icon\" xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\">\r\n <path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"48\"\r\n d=\"M112 184l144 144 144-144\"/>\r\n </svg>\r\n </button>\r\n @if (isOpen) {\r\n <div class=\"options-panel\">\r\n <ul>\r\n @for (option of options; track option.value) {\r\n <li [class.selected]=\"option.value === value\" (click)=\"selectOption(option); $event.stopPropagation()\">\r\n {{ option.label }}\r\n </li>\r\n }\r\n </ul>\r\n </div>\r\n }\r\n </div>\r\n `,\r\n styles: [`\r\n :host {\r\n position: relative;\r\n display: inline-block;\r\n }\r\n\r\n .custom-select-container {\r\n cursor: pointer;\r\n }\r\n\r\n .select-display {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n width: var(--custom-select-width, 115px);\r\n background: var(--datepicker-background, #fff);\r\n border: 1px solid var(--datepicker-border-color, #ccc);\r\n color: var(--datepicker-text-color, #333);\r\n border-radius: 4px;\r\n padding: 4px 8px;\r\n font-size: 1rem;\r\n text-align: left;\r\n }\r\n\r\n .arrow-icon {\r\n width: 12px;\r\n height: 12px;\r\n margin-left: 8px;\r\n }\r\n\r\n .options-panel {\r\n position: absolute;\r\n top: 110%;\r\n left: 0;\r\n width: 100%;\r\n background: var(--datepicker-background, #fff);\r\n border: 1px solid var(--datepicker-border-color, #ccc);\r\n color: var(--datepicker-text-color, #333);\r\n border-radius: 4px;\r\n box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);\r\n max-height: 200px;\r\n overflow-y: auto;\r\n z-index: 10;\r\n }\r\n\r\n .options-panel ul {\r\n list-style: none;\r\n padding: 4px;\r\n margin: 0;\r\n }\r\n\r\n .options-panel li {\r\n padding: 8px 12px;\r\n border-radius: 4px;\r\n cursor: pointer;\r\n }\r\n\r\n .options-panel li:hover {\r\n background-color: var(--datepicker-hover-background, #f0f0f0);\r\n }\r\n\r\n .options-panel li.selected {\r\n background-color: var(--datepicker-primary-color, #3880ff);\r\n color: var(--datepicker-primary-contrast, #fff);\r\n }\r\n `],\r\n})\r\nexport class CustomSelectComponent {\r\n @Input() options: { label: string; value: any }[] = [];\r\n @Input() value: any;\r\n @Output() valueChange = new EventEmitter<any>();\r\n public isOpen = false;\r\n\r\n constructor(private readonly elementRef: ElementRef) {\r\n }\r\n\r\n @HostListener('document:click', ['$event'])\r\n onDocumentClick(event: MouseEvent): void {\r\n if (!this.elementRef.nativeElement.contains(event.target)) this.isOpen = false;\r\n }\r\n\r\n get displayValue(): string {\r\n const selectedOption = this.options.find((opt) => opt.value === this.value);\r\n return selectedOption ? selectedOption.label : '';\r\n }\r\n\r\n toggleDropdown(): void {\r\n this.isOpen = !this.isOpen;\r\n }\r\n\r\n selectOption(option: { label: string; value: any }): void {\r\n this.value = option.value;\r\n this.valueChange.emit(this.value);\r\n this.isOpen = false;\r\n }\r\n}\r\n\r\n// #####################################################################\r\n// ## Datepicker Component\r\n// #####################################################################\r\nexport type DateInput = Date | string | { toDate: () => Date; _isAMomentObject?: boolean; $d?: Date };\r\n\r\nexport interface DateRange {\r\n [key: string]: [DateInput, DateInput];\r\n}\r\n\r\n@Component({\r\n selector: 'ngxsmk-datepicker',\r\n standalone: true,\r\n imports: [CommonModule, FormsModule, CustomSelectComponent],\r\n template: `\r\n <div class=\"datepicker-container\">\r\n @if (showRanges && rangesArray.length > 0 && mode === 'range') {\r\n <div class=\"ranges-container\">\r\n <ul>\r\n @for (range of rangesArray; track range.key) {\r\n <li (click)=\"selectRange(range.value)\">{{ range.key }}</li>\r\n }\r\n </ul>\r\n </div>\r\n }\r\n <div class=\"calendar-container\">\r\n <div class=\"header\">\r\n <div class=\"month-year-selects\">\r\n <app-custom-select class=\"month-select\" [options]=\"monthOptions\"\r\n [(value)]=\"currentMonth\"></app-custom-select>\r\n <app-custom-select class=\"year-select\" [options]=\"yearOptions\" [(value)]=\"currentYear\"></app-custom-select>\r\n </div>\r\n <div class=\"nav-buttons\">\r\n <button type=\"button\" class=\"nav-button\" (click)=\"changeMonth(-1)\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\">\r\n <path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"48\"\r\n d=\"M328 112L184 256l144 144\"/>\r\n </svg>\r\n </button>\r\n <button type=\"button\" class=\"nav-button\" (click)=\"changeMonth(1)\">\r\n <svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 512 512\">\r\n <path fill=\"none\" stroke=\"currentColor\" stroke-linecap=\"round\" stroke-linejoin=\"round\" stroke-width=\"48\"\r\n d=\"M184 112l144 144-144 144\"/>\r\n </svg>\r\n </button>\r\n </div>\r\n </div>\r\n <div class=\"days-grid-wrapper\">\r\n <div class=\"days-grid\">\r\n @for (day of weekDays; track day) {\r\n <div class=\"day-name\">{{ day }}</div>\r\n }\r\n @for (day of daysInMonth; track $index) {\r\n <div class=\"day-cell\"\r\n [class.empty]=\"!day\" [class.disabled]=\"isDateDisabled(day)\" [class.today]=\"isSameDay(day, today)\"\r\n [class.selected]=\"mode === 'single' && isSameDay(day, selectedDate)\"\r\n [class.start-date]=\"mode === 'range' && isSameDay(day, startDate)\"\r\n [class.end-date]=\"mode === 'range' && isSameDay(day, endDate)\"\r\n [class.in-range]=\"mode === 'range' && isInRange(day)\"\r\n [class.preview-range]=\"isPreviewInRange(day)\"\r\n (click)=\"onDateClick(day)\" (mouseenter)=\"onDateHover(day)\">\r\n @if (day) {\r\n <div class=\"day-number\">{{ day | date : 'd' }}</div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n `,\r\n styles: [`\r\n :host {\r\n --datepicker-primary-color: #6d28d9;\r\n --datepicker-primary-contrast: #ffffff;\r\n --datepicker-range-background: #f5f3ff;\r\n --datepicker-background: #ffffff;\r\n --datepicker-text-color: #222428;\r\n --datepicker-subtle-text-color: #9ca3af;\r\n --datepicker-border-color: #e9e9e9;\r\n --datepicker-hover-background: #f0f0f0;\r\n }\r\n\r\n :host(.dark-theme) {\r\n --datepicker-range-background: rgba(139, 92, 246, 0.2);\r\n --datepicker-background: #1f2937;\r\n --datepicker-text-color: #d1d5db;\r\n --datepicker-subtle-text-color: #6b7280;\r\n --datepicker-border-color: #4b5563;\r\n --datepicker-hover-background: #374151;\r\n }\r\n\r\n .datepicker-container {\r\n display: flex;\r\n }\r\n\r\n .calendar-container {\r\n width: 320px;\r\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\r\n border: 1px solid var(--datepicker-border-color);\r\n border-radius: 10px;\r\n padding: 16px;\r\n background: var(--datepicker-background);\r\n overflow: hidden;\r\n }\r\n\r\n .header {\r\n display: flex;\r\n justify-content: space-between;\r\n align-items: center;\r\n margin-bottom: 12px;\r\n position: relative;\r\n z-index: 2;\r\n }\r\n\r\n .month-year-selects {\r\n display: flex;\r\n gap: 8px;\r\n }\r\n\r\n .month-year-selects app-custom-select.month-select {\r\n --custom-select-width: 120px;\r\n }\r\n\r\n .month-year-selects app-custom-select.year-select {\r\n --custom-select-width: 90px;\r\n }\r\n\r\n .nav-buttons {\r\n display: flex;\r\n }\r\n\r\n .nav-button {\r\n background: none;\r\n border: none;\r\n padding: 8px;\r\n cursor: pointer;\r\n border-radius: 50%;\r\n display: inline-flex;\r\n align-items: center;\r\n justify-content: center;\r\n color: var(--datepicker-text-color);\r\n }\r\n\r\n .nav-button:hover {\r\n background-color: var(--datepicker-hover-background);\r\n }\r\n\r\n .nav-button svg {\r\n width: 18px;\r\n height: 18px;\r\n }\r\n\r\n .days-grid-wrapper {\r\n position: relative;\r\n }\r\n\r\n .days-grid {\r\n display: grid;\r\n grid-template-columns: repeat(7, 1fr);\r\n text-align: center;\r\n gap: 0;\r\n }\r\n\r\n .day-name {\r\n font-weight: 600;\r\n font-size: 0.8rem;\r\n color: var(--datepicker-subtle-text-color);\r\n padding: 8px 0;\r\n }\r\n\r\n .day-cell {\r\n position: relative;\r\n height: 38px;\r\n display: flex;\r\n justify-content: center;\r\n align-items: center;\r\n cursor: pointer;\r\n border-radius: 0;\r\n }\r\n\r\n .day-number {\r\n width: 36px;\r\n height: 36px;\r\n display: flex;\r\n justify-content: center;\r\n align-items: center;\r\n border-radius: 50%;\r\n color: var(--datepicker-text-color);\r\n position: relative;\r\n z-index: 1;\r\n }\r\n\r\n .day-cell:not(.disabled):hover .day-number {\r\n background-color: var(--datepicker-hover-background);\r\n }\r\n\r\n .day-cell.start-date .day-number,\r\n .day-cell.end-date .day-number,\r\n .day-cell.selected .day-number {\r\n background-color: var(--datepicker-primary-color);\r\n color: var(--datepicker-primary-contrast);\r\n }\r\n\r\n .day-cell.in-range, .day-cell.start-date, .day-cell.end-date, .day-cell.preview-range {\r\n background-color: var(--datepicker-range-background);\r\n }\r\n\r\n .day-cell.start-date {\r\n border-top-left-radius: 50px;\r\n border-bottom-left-radius: 50px;\r\n }\r\n\r\n .day-cell.end-date {\r\n border-top-right-radius: 50px;\r\n border-bottom-right-radius: 50px;\r\n }\r\n\r\n .day-cell.start-date.end-date {\r\n border-radius: 50px;\r\n }\r\n\r\n .day-cell.disabled {\r\n background-color: transparent !important;\r\n color: #4b5563;\r\n cursor: not-allowed;\r\n pointer-events: none;\r\n opacity: 0.5;\r\n }\r\n\r\n .day-cell.today .day-number {\r\n border: 1px solid var(--datepicker-primary-color);\r\n }\r\n\r\n .ranges-container {\r\n width: 180px;\r\n padding: 16px;\r\n border-right: 1px solid var(--datepicker-border-color);\r\n background: var(--datepicker-background);\r\n }\r\n\r\n .ranges-container ul {\r\n list-style: none;\r\n padding: 0;\r\n margin: 0;\r\n }\r\n\r\n .ranges-container li {\r\n padding: 10px;\r\n margin-bottom: 8px;\r\n border-radius: 6px;\r\n cursor: pointer;\r\n color: var(--datepicker-text-color);\r\n }\r\n\r\n .ranges-container li:hover {\r\n background-color: var(--datepicker-hover-background);\r\n }\r\n `],\r\n})\r\nexport class NgxsmkDatepickerComponent implements OnInit, OnChanges {\r\n @Input() mode: 'single' | 'range' = 'single';\r\n @Input() isInvalidDate: (date: Date) => boolean = () => false;\r\n @Input() showRanges: boolean = true;\r\n\r\n // FIX: Use a private variable for locale with a fallback value.\r\n private _locale: string = 'en-US';\r\n\r\n @Input() set locale(value: string) {\r\n this._locale = value;\r\n }\r\n\r\n get locale(): string {\r\n return this._locale;\r\n }\r\n\r\n @Input() theme: 'light' | 'dark' = 'light';\r\n\r\n @HostBinding('class.dark-theme') get isDarkMode() {\r\n return this.theme === 'dark';\r\n }\r\n\r\n @Output() valueChange = new EventEmitter<Date | { start: Date; end: Date }>();\r\n\r\n private _minDate: Date | null = null;\r\n\r\n @Input() set minDate(value: DateInput | null) {\r\n this._minDate = this._normalizeDate(value);\r\n }\r\n\r\n private _maxDate: Date | null = null;\r\n\r\n @Input() set maxDate(value: DateInput | null) {\r\n this._maxDate = this._normalizeDate(value);\r\n }\r\n\r\n private _ranges: { [key: string]: [Date, Date] } | null = null;\r\n\r\n @Input() set ranges(value: DateRange | null) {\r\n if (!value) {\r\n this._ranges = null;\r\n } else {\r\n this._ranges = Object.entries(value).reduce((acc, [key, dates]) => {\r\n const start = this._normalizeDate(dates[0]);\r\n const end = this._normalizeDate(dates[1]);\r\n if (start && end) acc[key] = [start, end];\r\n return acc;\r\n }, {} as { [key: string]: [Date, Date] });\r\n }\r\n this.updateRangesArray();\r\n }\r\n\r\n public currentDate: Date = new Date();\r\n public daysInMonth: (Date | null)[] = [];\r\n public weekDays: string[] = [];\r\n public readonly today: Date = new Date();\r\n public selectedDate: Date | null = null;\r\n public startDate: Date | null = null;\r\n public endDate: Date | null = null;\r\n public hoveredDate: Date | null = null;\r\n public rangesArray: { key: string; value: [Date, Date] }[] = [];\r\n private _currentMonth!: number;\r\n private _currentYear!: number;\r\n public monthOptions: { label: string; value: number }[] = [];\r\n public yearOptions: { label: string; value: number }[] = [];\r\n private firstDayOfWeek: number = 0;\r\n\r\n // FIX: Inject PLATFORM_ID and conditionally access navigator\r\n constructor(@Inject(PLATFORM_ID) private readonly platformId: Object) {\r\n if (isPlatformBrowser(this.platformId)) {\r\n this._locale = navigator.language;\r\n }\r\n }\r\n\r\n get currentMonth(): number {\r\n return this._currentMonth;\r\n }\r\n\r\n set currentMonth(month: number) {\r\n if (this._currentMonth !== month) {\r\n this._currentMonth = month;\r\n this.currentDate.setMonth(month);\r\n this.generateCalendar();\r\n }\r\n }\r\n\r\n get currentYear(): number {\r\n return this._currentYear;\r\n }\r\n\r\n set currentYear(year: number) {\r\n if (this._currentYear !== year) {\r\n this._currentYear = year;\r\n this.currentDate.setFullYear(year);\r\n this.generateCalendar();\r\n }\r\n }\r\n\r\n ngOnInit(): void {\r\n this.today.setHours(0, 0, 0, 0);\r\n this.generateLocaleData();\r\n this.generateCalendar();\r\n }\r\n\r\n ngOnChanges(changes: SimpleChanges): void {\r\n if (changes['locale']) {\r\n this.generateLocaleData();\r\n this.generateCalendar();\r\n }\r\n }\r\n\r\n private _normalizeDate(date: DateInput | null): Date | null {\r\n if (!date) return null;\r\n const d = (date instanceof Date) ? new Date(date.getTime()) : new Date(date as any);\r\n if (isNaN(d.getTime())) return null;\r\n d.setHours(0, 0, 0, 0);\r\n return d;\r\n }\r\n\r\n private generateLocaleData(): void {\r\n this.monthOptions = Array.from({length: 12}).map((_, i) => ({\r\n label: new Date(2024, i, 1).toLocaleDateString(this.locale, {month: 'long'}),\r\n value: i,\r\n }));\r\n try {\r\n // Use this.locale getter\r\n this.firstDayOfWeek = ((new Intl.Locale(this.locale) as any).weekInfo?.firstDay || 0) % 7;\r\n } catch (e) {\r\n this.firstDayOfWeek = 0;\r\n }\r\n const day = new Date(2024, 0, 7 + this.firstDayOfWeek);\r\n this.weekDays = Array.from({length: 7}).map(() => {\r\n const weekDay = new Date(day).toLocaleDateString(this.locale, {weekday: 'short'});\r\n day.setDate(day.getDate() + 1);\r\n return weekDay;\r\n });\r\n }\r\n\r\n private updateRangesArray(): void {\r\n this.rangesArray = this._ranges ? Object.entries(this._ranges).map(([key, value]) => ({key, value})) : [];\r\n }\r\n\r\n public selectRange(range: [Date, Date]): void {\r\n this.startDate = range[0];\r\n this.endDate = range[1];\r\n this.valueChange.emit({start: this.startDate, end: this.endDate});\r\n this.currentDate = new Date(this.startDate);\r\n this.generateCalendar();\r\n }\r\n\r\n public isDateDisabled(date: Date | null): boolean {\r\n if (!date) return false;\r\n if (this._minDate && date < this._minDate) return true;\r\n if (this._maxDate && date > this._maxDate) return true;\r\n if (this.isInvalidDate(date)) return true;\r\n return false;\r\n }\r\n\r\n public onDateClick(day: Date | null): void {\r\n if (!day || this.isDateDisabled(day)) return;\r\n if (this.mode === 'single') {\r\n this.selectedDate = day;\r\n this.valueChange.emit(this.selectedDate);\r\n } else {\r\n if (!this.startDate || (this.startDate && this.endDate)) {\r\n this.startDate = day;\r\n this.endDate = null;\r\n } else if (day >= this.startDate) {\r\n this.endDate = day;\r\n this.valueChange.emit({start: this.startDate, end: this.endDate});\r\n } else {\r\n this.startDate = day;\r\n this.endDate = null;\r\n }\r\n this.hoveredDate = null;\r\n }\r\n }\r\n\r\n public onDateHover(day: Date | null): void {\r\n if (this.mode === 'range' && this.startDate && !this.endDate && day) {\r\n this.hoveredDate = day;\r\n }\r\n }\r\n\r\n public isPreviewInRange(day: Date | null): boolean {\r\n if (this.mode !== 'range' || !this.startDate || this.endDate || !this.hoveredDate || !day) return false;\r\n const start = this.startDate.getTime();\r\n const end = this.hoveredDate.getTime();\r\n const time = day.getTime();\r\n return time > Math.min(start, end) && time < Math.max(start, end);\r\n }\r\n\r\n public generateCalendar(): void {\r\n this.daysInMonth = [];\r\n const year = this.currentDate.getFullYear();\r\n const month = this.currentDate.getMonth();\r\n this._currentMonth = month;\r\n this._currentYear = year;\r\n this.generateDropdownOptions();\r\n const firstDayOfMonth = new Date(year, month, 1);\r\n const lastDayOfMonth = new Date(year, month + 1, 0);\r\n const startDayOfWeek = firstDayOfMonth.getDay();\r\n const emptyCellCount = (startDayOfWeek - this.firstDayOfWeek + 7) % 7;\r\n\r\n for (let i = 0; i < emptyCellCount; i++) {\r\n this.daysInMonth.push(null);\r\n }\r\n for (let i = 1; i <= lastDayOfMonth.getDate(); i++) {\r\n this.daysInMonth.push(this._normalizeDate(new Date(year, month, i)));\r\n }\r\n }\r\n\r\n private generateDropdownOptions(): void {\r\n const startYear = this._currentYear - 10;\r\n const endYear = this._currentYear + 10;\r\n this.yearOptions = [];\r\n for (let i = startYear; i <= endYear; i++) {\r\n this.yearOptions.push({label: `${i}`, value: i});\r\n }\r\n }\r\n\r\n public changeMonth(delta: number): void {\r\n this.currentDate.setMonth(this.currentDate.getMonth() + delta);\r\n this.generateCalendar();\r\n }\r\n\r\n public isSameDay(d1: Date | null, d2: Date | null): boolean {\r\n if (!d1 || !d2) return false;\r\n return (\r\n d1.getFullYear() === d2.getFullYear() &&\r\n d1.getMonth() === d2.getMonth() &&\r\n d1.getDate() === d2.getDate()\r\n );\r\n }\r\n\r\n public isInRange(d: Date | null): boolean {\r\n if (!d || !this.startDate || !this.endDate) return false;\r\n return (\r\n d.getTime() > this.startDate.getTime() &&\r\n d.getTime() < this.endDate.getTime()\r\n );\r\n }\r\n}\r\n","/*\r\n * Public API Surface of ngxsmk-datepicker\r\n */\r\n\r\nexport * from './lib/ngxsmk-datepicker';\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
|
package/index.d.ts
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { EventEmitter, ElementRef, OnInit, OnChanges, SimpleChanges } from '@angular/core';
|
|
3
|
+
|
|
4
|
+
declare class CustomSelectComponent {
|
|
5
|
+
private readonly elementRef;
|
|
6
|
+
options: {
|
|
7
|
+
label: string;
|
|
8
|
+
value: any;
|
|
9
|
+
}[];
|
|
10
|
+
value: any;
|
|
11
|
+
valueChange: EventEmitter<any>;
|
|
12
|
+
isOpen: boolean;
|
|
13
|
+
constructor(elementRef: ElementRef);
|
|
14
|
+
onDocumentClick(event: MouseEvent): void;
|
|
15
|
+
get displayValue(): string;
|
|
16
|
+
toggleDropdown(): void;
|
|
17
|
+
selectOption(option: {
|
|
18
|
+
label: string;
|
|
19
|
+
value: any;
|
|
20
|
+
}): void;
|
|
21
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<CustomSelectComponent, never>;
|
|
22
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<CustomSelectComponent, "app-custom-select", never, { "options": { "alias": "options"; "required": false; }; "value": { "alias": "value"; "required": false; }; }, { "valueChange": "valueChange"; }, never, never, true, never>;
|
|
23
|
+
}
|
|
24
|
+
type DateInput = Date | string | {
|
|
25
|
+
toDate: () => Date;
|
|
26
|
+
_isAMomentObject?: boolean;
|
|
27
|
+
$d?: Date;
|
|
28
|
+
};
|
|
29
|
+
interface DateRange {
|
|
30
|
+
[key: string]: [DateInput, DateInput];
|
|
31
|
+
}
|
|
32
|
+
declare class NgxsmkDatepickerComponent implements OnInit, OnChanges {
|
|
33
|
+
private readonly platformId;
|
|
34
|
+
mode: 'single' | 'range';
|
|
35
|
+
isInvalidDate: (date: Date) => boolean;
|
|
36
|
+
showRanges: boolean;
|
|
37
|
+
private _locale;
|
|
38
|
+
set locale(value: string);
|
|
39
|
+
get locale(): string;
|
|
40
|
+
theme: 'light' | 'dark';
|
|
41
|
+
get isDarkMode(): boolean;
|
|
42
|
+
valueChange: EventEmitter<Date | {
|
|
43
|
+
start: Date;
|
|
44
|
+
end: Date;
|
|
45
|
+
}>;
|
|
46
|
+
private _minDate;
|
|
47
|
+
set minDate(value: DateInput | null);
|
|
48
|
+
private _maxDate;
|
|
49
|
+
set maxDate(value: DateInput | null);
|
|
50
|
+
private _ranges;
|
|
51
|
+
set ranges(value: DateRange | null);
|
|
52
|
+
currentDate: Date;
|
|
53
|
+
daysInMonth: (Date | null)[];
|
|
54
|
+
weekDays: string[];
|
|
55
|
+
readonly today: Date;
|
|
56
|
+
selectedDate: Date | null;
|
|
57
|
+
startDate: Date | null;
|
|
58
|
+
endDate: Date | null;
|
|
59
|
+
hoveredDate: Date | null;
|
|
60
|
+
rangesArray: {
|
|
61
|
+
key: string;
|
|
62
|
+
value: [Date, Date];
|
|
63
|
+
}[];
|
|
64
|
+
private _currentMonth;
|
|
65
|
+
private _currentYear;
|
|
66
|
+
monthOptions: {
|
|
67
|
+
label: string;
|
|
68
|
+
value: number;
|
|
69
|
+
}[];
|
|
70
|
+
yearOptions: {
|
|
71
|
+
label: string;
|
|
72
|
+
value: number;
|
|
73
|
+
}[];
|
|
74
|
+
private firstDayOfWeek;
|
|
75
|
+
constructor(platformId: Object);
|
|
76
|
+
get currentMonth(): number;
|
|
77
|
+
set currentMonth(month: number);
|
|
78
|
+
get currentYear(): number;
|
|
79
|
+
set currentYear(year: number);
|
|
80
|
+
ngOnInit(): void;
|
|
81
|
+
ngOnChanges(changes: SimpleChanges): void;
|
|
82
|
+
private _normalizeDate;
|
|
83
|
+
private generateLocaleData;
|
|
84
|
+
private updateRangesArray;
|
|
85
|
+
selectRange(range: [Date, Date]): void;
|
|
86
|
+
isDateDisabled(date: Date | null): boolean;
|
|
87
|
+
onDateClick(day: Date | null): void;
|
|
88
|
+
onDateHover(day: Date | null): void;
|
|
89
|
+
isPreviewInRange(day: Date | null): boolean;
|
|
90
|
+
generateCalendar(): void;
|
|
91
|
+
private generateDropdownOptions;
|
|
92
|
+
changeMonth(delta: number): void;
|
|
93
|
+
isSameDay(d1: Date | null, d2: Date | null): boolean;
|
|
94
|
+
isInRange(d: Date | null): boolean;
|
|
95
|
+
static ɵfac: i0.ɵɵFactoryDeclaration<NgxsmkDatepickerComponent, never>;
|
|
96
|
+
static ɵcmp: i0.ɵɵComponentDeclaration<NgxsmkDatepickerComponent, "ngxsmk-datepicker", never, { "mode": { "alias": "mode"; "required": false; }; "isInvalidDate": { "alias": "isInvalidDate"; "required": false; }; "showRanges": { "alias": "showRanges"; "required": false; }; "locale": { "alias": "locale"; "required": false; }; "theme": { "alias": "theme"; "required": false; }; "minDate": { "alias": "minDate"; "required": false; }; "maxDate": { "alias": "maxDate"; "required": false; }; "ranges": { "alias": "ranges"; "required": false; }; }, { "valueChange": "valueChange"; }, never, never, true, never>;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export { CustomSelectComponent, NgxsmkDatepickerComponent };
|
|
100
|
+
export type { DateInput, DateRange };
|
package/package.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "ngxsmk-datepicker",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"peerDependencies": {
|
|
5
|
+
"@angular/common": "^20.3.0",
|
|
6
|
+
"@angular/core": "^20.3.0"
|
|
7
|
+
},
|
|
8
|
+
"dependencies": {
|
|
9
|
+
"tslib": "^2.3.0"
|
|
10
|
+
},
|
|
11
|
+
"sideEffects": false,
|
|
12
|
+
"module": "fesm2022/ngxsmk-datepicker.mjs",
|
|
13
|
+
"typings": "index.d.ts",
|
|
14
|
+
"exports": {
|
|
15
|
+
"./package.json": {
|
|
16
|
+
"default": "./package.json"
|
|
17
|
+
},
|
|
18
|
+
".": {
|
|
19
|
+
"types": "./index.d.ts",
|
|
20
|
+
"default": "./fesm2022/ngxsmk-datepicker.mjs"
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|