@nuralyui/datepicker 0.0.3 → 0.0.5
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/bundle.js +791 -0
- package/datepicker.component.d.ts +189 -0
- package/datepicker.component.js +668 -0
- package/datepicker.component.js.map +1 -0
- package/datepicker.constant.d.ts +60 -0
- package/datepicker.constant.js +60 -0
- package/datepicker.constant.js.map +1 -0
- package/datepicker.style.d.ts +7 -0
- package/datepicker.style.js +456 -0
- package/datepicker.style.js.map +1 -0
- package/datepicker.style.variables.d.ts +11 -0
- package/datepicker.style.variables.js +115 -0
- package/datepicker.style.variables.js.map +1 -0
- package/datepicker.type.d.ts +142 -0
- package/datepicker.type.js +75 -0
- package/datepicker.type.js.map +1 -0
- package/index.d.ts +4 -1
- package/index.js +4 -1
- package/index.js.map +1 -1
- package/package.json +16 -2
- package/react.d.ts +15 -2
- package/react.js +16 -3
- package/react.js.map +1 -1
- package/constants.d.ts +0 -2
- package/constants.d.ts.map +0 -1
- package/constants.js +0 -2
- package/constants.js.map +0 -1
- package/core/day.helper.d.ts +0 -5
- package/core/day.helper.d.ts.map +0 -1
- package/core/day.helper.js +0 -53
- package/core/day.helper.js.map +0 -1
- package/core/formatter.d.ts +0 -2
- package/core/formatter.d.ts.map +0 -1
- package/core/formatter.js +0 -9
- package/core/formatter.js.map +0 -1
- package/core/locale.helper.d.ts +0 -144
- package/core/locale.helper.d.ts.map +0 -1
- package/core/locale.helper.js +0 -151
- package/core/locale.helper.js.map +0 -1
- package/core/month.helper.d.ts +0 -3
- package/core/month.helper.d.ts.map +0 -1
- package/core/month.helper.js +0 -24
- package/core/month.helper.js.map +0 -1
- package/core/string.helper.d.ts +0 -2
- package/core/string.helper.d.ts.map +0 -1
- package/core/string.helper.js +0 -4
- package/core/string.helper.js.map +0 -1
- package/date-picker.component.d.ts +0 -80
- package/date-picker.component.d.ts.map +0 -1
- package/date-picker.component.js +0 -475
- package/date-picker.component.js.map +0 -1
- package/date-picker.style.d.ts +0 -2
- package/date-picker.style.d.ts.map +0 -1
- package/date-picker.style.js +0 -223
- package/date-picker.style.js.map +0 -1
- package/datepicker.types.d.ts +0 -39
- package/datepicker.types.d.ts.map +0 -1
- package/datepicker.types.js +0 -8
- package/datepicker.types.js.map +0 -1
- package/demo/date-picker-demo.d.ts +0 -18
- package/demo/date-picker-demo.d.ts.map +0 -1
- package/demo/date-picker-demo.js +0 -95
- package/demo/date-picker-demo.js.map +0 -1
- package/index.d.ts.map +0 -1
- package/react.d.ts.map +0 -1
- package/templates/days.template.d.ts +0 -4
- package/templates/days.template.d.ts.map +0 -1
- package/templates/days.template.js +0 -28
- package/templates/days.template.js.map +0 -1
- package/templates/headers.template.d.ts +0 -2
- package/templates/headers.template.d.ts.map +0 -1
- package/templates/headers.template.js +0 -5
- package/templates/headers.template.js.map +0 -1
- package/templates/months.template.d.ts +0 -6
- package/templates/months.template.d.ts.map +0 -1
- package/templates/months.template.js +0 -10
- package/templates/months.template.js.map +0 -1
- package/templates/years.template.d.ts +0 -6
- package/templates/years.template.d.ts.map +0 -1
- package/templates/years.template.js +0 -11
- package/templates/years.template.js.map +0 -1
- package/test/datepicker_test.d.ts +0 -2
- package/test/datepicker_test.d.ts.map +0 -1
- package/test/datepicker_test.js +0 -132
- package/test/datepicker_test.js.map +0 -1
|
@@ -0,0 +1,668 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2023 Google Laabidi Aymen
|
|
4
|
+
* SPDX-License-Identifier: MIT
|
|
5
|
+
*/
|
|
6
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
7
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
8
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
9
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
10
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
11
|
+
};
|
|
12
|
+
import { LitElement, html, nothing } from 'lit';
|
|
13
|
+
import { customElement, property, query, state } from 'lit/decorators.js';
|
|
14
|
+
import { choose } from 'lit/directives/choose.js';
|
|
15
|
+
import { classMap } from 'lit/directives/class-map.js';
|
|
16
|
+
import { NuralyUIBaseMixin } from '../../shared/base-mixin.js';
|
|
17
|
+
import { styles } from './datepicker.style.js';
|
|
18
|
+
import { DatePickerMode, DatePickerType, DatePickerSize, DatePickerVariant, DatePickerPlacement, } from './datepicker.type.js';
|
|
19
|
+
import { DEFAULT_DATE_FORMAT, DEFAULT_LOCALE, INPUT_FIELD_ID, CALENDAR_CONTAINER_CLASS, DATE_PICKER_EVENTS, } from './datepicker.constant.js';
|
|
20
|
+
import { DatePickerCalendarController, DatePickerSelectionController, DatePickerKeyboardController, DatePickerPositioningController, } from './controllers/index.js';
|
|
21
|
+
import { SharedDropdownController } from '../../shared/controllers/dropdown.controller.js';
|
|
22
|
+
import dayjs from 'dayjs';
|
|
23
|
+
import { renderMonthsTemplate } from './templates/months.template.js';
|
|
24
|
+
import { renderYearsTemplate } from './templates/years.template.js';
|
|
25
|
+
import { renderDays } from './templates/days.template.js';
|
|
26
|
+
import { capitalizeFirstLetter } from './core/string.helper.js';
|
|
27
|
+
import './core/locale.helper.js';
|
|
28
|
+
/**
|
|
29
|
+
* HyDatePicker - A comprehensive date picker component
|
|
30
|
+
*
|
|
31
|
+
* @element hy-datepicker
|
|
32
|
+
*
|
|
33
|
+
* @fires nr-date-change - Fired when a date is selected
|
|
34
|
+
* @fires nr-range-change - Fired when a date range is selected
|
|
35
|
+
* @fires nr-calendar-open - Fired when calendar is opened
|
|
36
|
+
* @fires nr-calendar-close - Fired when calendar is closed
|
|
37
|
+
* @fires nr-focus - Fired when component receives focus
|
|
38
|
+
* @fires nr-blur - Fired when component loses focus
|
|
39
|
+
* @fires nr-validation - Fired when validation state changes
|
|
40
|
+
*
|
|
41
|
+
* @slot label - Label content for the input field
|
|
42
|
+
* @slot helper-text - Helper text content below the input field
|
|
43
|
+
* @slot icon - Icon content for the input field
|
|
44
|
+
*
|
|
45
|
+
* @csspart input - The input field part
|
|
46
|
+
* @csspart calendar - The calendar container part
|
|
47
|
+
* @csspart header - The calendar header part
|
|
48
|
+
* @csspart days - The days grid part
|
|
49
|
+
* @csspart day - Individual day cell part
|
|
50
|
+
* @csspart months - The months grid part
|
|
51
|
+
* @csspart years - The years grid part
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* ```html
|
|
55
|
+
* <hy-datepicker
|
|
56
|
+
* label="Select Date"
|
|
57
|
+
* field-format="DD/MM/YYYY"
|
|
58
|
+
* @nr-date-change="${this.handleDateChange}">
|
|
59
|
+
* </hy-datepicker>
|
|
60
|
+
* ```
|
|
61
|
+
*
|
|
62
|
+
* @example Range picker
|
|
63
|
+
* ```html
|
|
64
|
+
* <hy-datepicker
|
|
65
|
+
* range
|
|
66
|
+
* label="Select Date Range"
|
|
67
|
+
* @nr-range-change="${this.handleRangeChange}">
|
|
68
|
+
* </hy-datepicker>
|
|
69
|
+
* ```
|
|
70
|
+
*/
|
|
71
|
+
let HyDatePickerElement = class HyDatePickerElement extends NuralyUIBaseMixin(LitElement) {
|
|
72
|
+
constructor() {
|
|
73
|
+
super(...arguments);
|
|
74
|
+
this.requiredComponents = ['nr-input', 'nr-button', 'hy-icon', 'hy-select'];
|
|
75
|
+
// Controllers - following the delegation pattern
|
|
76
|
+
this.calendarController = new DatePickerCalendarController(this);
|
|
77
|
+
this.selectionController = new DatePickerSelectionController(this);
|
|
78
|
+
this.keyboardController = new DatePickerKeyboardController(this, this.calendarController, this.selectionController);
|
|
79
|
+
this.positioningController = new DatePickerPositioningController(this);
|
|
80
|
+
this.dropdownController = new SharedDropdownController(this);
|
|
81
|
+
// Core properties following the architecture pattern
|
|
82
|
+
this.name = '';
|
|
83
|
+
this.value = '';
|
|
84
|
+
this.dateValue = '';
|
|
85
|
+
this.defaultValue = '';
|
|
86
|
+
this.disabled = false;
|
|
87
|
+
this.required = false;
|
|
88
|
+
this.locale = DEFAULT_LOCALE;
|
|
89
|
+
this.fieldFormat = DEFAULT_DATE_FORMAT;
|
|
90
|
+
// Date picker specific properties
|
|
91
|
+
this.range = false;
|
|
92
|
+
// UI properties
|
|
93
|
+
this.type = DatePickerType.Single;
|
|
94
|
+
this.size = DatePickerSize.Medium;
|
|
95
|
+
this.variant = DatePickerVariant.Default;
|
|
96
|
+
this.placement = DatePickerPlacement.Auto;
|
|
97
|
+
this.label = '';
|
|
98
|
+
this.helper = '';
|
|
99
|
+
this.state = "default" /* INPUT_STATE.Default */;
|
|
100
|
+
this.useSelectDropdowns = false;
|
|
101
|
+
// Calendar state
|
|
102
|
+
this.openedCalendar = false;
|
|
103
|
+
this.mode = DatePickerMode.Day;
|
|
104
|
+
// Internal state
|
|
105
|
+
this.currentMode = DatePickerMode.Day;
|
|
106
|
+
this.monthsShort = dayjs().localeData().monthsShort();
|
|
107
|
+
this.months = dayjs().localeData().months();
|
|
108
|
+
this.days = dayjs().localeData().weekdays();
|
|
109
|
+
this.weekdaysShort = dayjs().localeData().weekdaysShort();
|
|
110
|
+
this.inputFieldValue = '';
|
|
111
|
+
this.currentYear = new Date().getFullYear();
|
|
112
|
+
this.currentMonth = new Date().getMonth() + 1;
|
|
113
|
+
this.currentDay = new Date().getDate();
|
|
114
|
+
// Navigation dates for calendar display
|
|
115
|
+
this.navigationDates = {
|
|
116
|
+
start: {
|
|
117
|
+
year: this.currentYear,
|
|
118
|
+
month: this.currentMonth,
|
|
119
|
+
day: this.currentDay,
|
|
120
|
+
},
|
|
121
|
+
};
|
|
122
|
+
// Component constants
|
|
123
|
+
this.INPUT_TYPE = 'calendar';
|
|
124
|
+
// Navigation methods - delegates to controllers
|
|
125
|
+
this.handleMonthChange = (event) => {
|
|
126
|
+
const selectedMonth = parseInt(event.detail.value, 10);
|
|
127
|
+
this.handleMonthSelection(selectedMonth);
|
|
128
|
+
};
|
|
129
|
+
this.handleYearChange = (event) => {
|
|
130
|
+
const selectedYear = parseInt(event.detail.value, 10);
|
|
131
|
+
this.handleYearSelection(selectedYear);
|
|
132
|
+
};
|
|
133
|
+
this.prevMonth = () => this.calendarController.navigateToPreviousMonth();
|
|
134
|
+
this.nextMonth = () => this.calendarController.navigateToNextMonth();
|
|
135
|
+
this.prevYear = () => this.calendarController.navigateToPreviousYear();
|
|
136
|
+
this.nextYear = () => this.calendarController.navigateToNextYear();
|
|
137
|
+
this.selectMonth = (month) => {
|
|
138
|
+
this.currentMonth = month;
|
|
139
|
+
this.navigationDates.start.month = month;
|
|
140
|
+
this.currentMode = DatePickerMode.Day;
|
|
141
|
+
this.calendarController.updateCalendarDisplay();
|
|
142
|
+
};
|
|
143
|
+
this.selectYear = (year) => {
|
|
144
|
+
this.currentYear = year;
|
|
145
|
+
this.navigationDates.start.year = year;
|
|
146
|
+
this.currentMode = DatePickerMode.Day;
|
|
147
|
+
this.calendarController.updateCalendarDisplay();
|
|
148
|
+
};
|
|
149
|
+
this.selectDay = (dayPresentation) => {
|
|
150
|
+
const date = new Date(dayPresentation.year, dayPresentation.month, dayPresentation.date);
|
|
151
|
+
this.selectDate(date);
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
connectedCallback() {
|
|
155
|
+
super.connectedCallback();
|
|
156
|
+
this.initializeComponent();
|
|
157
|
+
// Add dropdown selection event listeners
|
|
158
|
+
this.addEventListener('month-selected', this.handleMonthSelected.bind(this));
|
|
159
|
+
this.addEventListener('year-selected', this.handleYearSelected.bind(this));
|
|
160
|
+
}
|
|
161
|
+
disconnectedCallback() {
|
|
162
|
+
super.disconnectedCallback();
|
|
163
|
+
// Controllers handle their own cleanup
|
|
164
|
+
}
|
|
165
|
+
firstUpdated(_changedProperties) {
|
|
166
|
+
super.firstUpdated(_changedProperties);
|
|
167
|
+
this.initializeRangeIfNeeded();
|
|
168
|
+
this.updateInputField();
|
|
169
|
+
this.setupDropdownController();
|
|
170
|
+
}
|
|
171
|
+
setupDropdownController() {
|
|
172
|
+
// The dropdown controller will be set up dynamically when needed
|
|
173
|
+
// since we have multiple dropdowns (month and year)
|
|
174
|
+
}
|
|
175
|
+
willUpdate(changedProperties) {
|
|
176
|
+
super.willUpdate(changedProperties);
|
|
177
|
+
this.handlePropertyChanges(changedProperties);
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Initialize component state
|
|
181
|
+
*/
|
|
182
|
+
initializeComponent() {
|
|
183
|
+
// Set up event listeners for calendar close requests
|
|
184
|
+
this.addEventListener('calendar-close-request', () => {
|
|
185
|
+
this.positioningController.closeCalendar();
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Initialize range properties if range mode is enabled
|
|
190
|
+
*/
|
|
191
|
+
initializeRangeIfNeeded() {
|
|
192
|
+
if (this.range) {
|
|
193
|
+
this.endYear = this.currentYear;
|
|
194
|
+
this.endMonth = this.currentMonth;
|
|
195
|
+
this.endDay = this.currentDay;
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Handle property changes with proper delegation
|
|
200
|
+
*/
|
|
201
|
+
handlePropertyChanges(changedProperties) {
|
|
202
|
+
if (changedProperties.has('fieldFormat')) {
|
|
203
|
+
this.updateInputField();
|
|
204
|
+
}
|
|
205
|
+
if (changedProperties.has('openedCalendar') && this.openedCalendar) {
|
|
206
|
+
this.calendarController.updateCalendarDisplay();
|
|
207
|
+
// Calendar positioning is now handled by SharedDropdownController in openCalendar()
|
|
208
|
+
}
|
|
209
|
+
if (changedProperties.has('dateValue') && this.dateValue) {
|
|
210
|
+
this.handleDateValueChange();
|
|
211
|
+
}
|
|
212
|
+
if (this.hasDatePropertiesChanged(changedProperties)) {
|
|
213
|
+
this.updateInputField();
|
|
214
|
+
this.dispatchDateChange();
|
|
215
|
+
}
|
|
216
|
+
if (changedProperties.has('locale')) {
|
|
217
|
+
this.updateLocale(this.locale);
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Check if date-related properties have changed
|
|
222
|
+
*/
|
|
223
|
+
hasDatePropertiesChanged(changedProperties) {
|
|
224
|
+
return ((changedProperties.has('currentDay') && changedProperties.get('currentDay')) ||
|
|
225
|
+
(changedProperties.has('currentMonth') && changedProperties.get('currentMonth')) ||
|
|
226
|
+
(changedProperties.has('currentYear') && changedProperties.get('currentYear')));
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Handle date value change
|
|
230
|
+
*/
|
|
231
|
+
handleDateValueChange() {
|
|
232
|
+
const dateObj = dayjs(this.dateValue, this.fieldFormat, true);
|
|
233
|
+
if (dateObj.isValid()) {
|
|
234
|
+
const { years, months, date } = dateObj.toObject();
|
|
235
|
+
this.currentYear = years;
|
|
236
|
+
this.currentMonth = months + 1;
|
|
237
|
+
this.currentDay = date;
|
|
238
|
+
this.navigationDates = Object.assign(Object.assign({}, this.navigationDates), { start: { year: years, month: months + 1, day: date } });
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
// DatePickerHost interface implementation
|
|
242
|
+
getCurrentDate() {
|
|
243
|
+
return new Date(this.currentYear, this.currentMonth - 1, this.currentDay);
|
|
244
|
+
}
|
|
245
|
+
formatDate(date) {
|
|
246
|
+
return dayjs(date).format(this.fieldFormat);
|
|
247
|
+
}
|
|
248
|
+
parseDate(dateString) {
|
|
249
|
+
const parsed = dayjs(dateString, this.fieldFormat, true);
|
|
250
|
+
return parsed.isValid() ? parsed.toDate() : null;
|
|
251
|
+
}
|
|
252
|
+
// Delegation methods - following the architecture pattern
|
|
253
|
+
/**
|
|
254
|
+
* Get currently selected date - DELEGATES to selection controller
|
|
255
|
+
*/
|
|
256
|
+
getSelectedDate() {
|
|
257
|
+
return this.selectionController.getSelectedDate();
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Select a date - DELEGATES to selection controller
|
|
261
|
+
*/
|
|
262
|
+
selectDate(date) {
|
|
263
|
+
this.selectionController.selectDate(date);
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* Clear selection - DELEGATES to selection controller
|
|
267
|
+
*/
|
|
268
|
+
clearSelection() {
|
|
269
|
+
this.selectionController.clearSelection();
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Open calendar - DELEGATES to dropdown controller for better positioning
|
|
273
|
+
*/
|
|
274
|
+
openCalendar() {
|
|
275
|
+
console.log('openCalendar called');
|
|
276
|
+
this.openedCalendar = true;
|
|
277
|
+
this.requestUpdate();
|
|
278
|
+
// Wait for DOM update, then setup positioning
|
|
279
|
+
this.updateComplete.then(() => {
|
|
280
|
+
console.log('DOM updated, checking elements:', {
|
|
281
|
+
calendarContainer: !!this.calendarContainer,
|
|
282
|
+
dateInput: !!this.dateInput
|
|
283
|
+
});
|
|
284
|
+
if (this.calendarContainer && this.dateInput) {
|
|
285
|
+
console.log('Setting up dropdown controller');
|
|
286
|
+
this.dropdownController.setElements(this.calendarContainer, this.dateInput);
|
|
287
|
+
this.dropdownController.open();
|
|
288
|
+
}
|
|
289
|
+
else {
|
|
290
|
+
console.error('Elements not found:', {
|
|
291
|
+
calendarContainer: this.calendarContainer,
|
|
292
|
+
dateInput: this.dateInput
|
|
293
|
+
});
|
|
294
|
+
}
|
|
295
|
+
});
|
|
296
|
+
}
|
|
297
|
+
/**
|
|
298
|
+
* Close calendar - DELEGATES to dropdown controller
|
|
299
|
+
*/
|
|
300
|
+
closeCalendar() {
|
|
301
|
+
this.openedCalendar = false;
|
|
302
|
+
this.dropdownController.close();
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Toggle calendar - DELEGATES to dropdown controller
|
|
306
|
+
*/
|
|
307
|
+
toggleCalendar() {
|
|
308
|
+
if (this.openedCalendar) {
|
|
309
|
+
this.closeCalendar();
|
|
310
|
+
}
|
|
311
|
+
else {
|
|
312
|
+
this.openCalendar();
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Handle keyboard events - DELEGATES to keyboard controller
|
|
317
|
+
*/
|
|
318
|
+
handleKeyDown(event) {
|
|
319
|
+
this.keyboardController.handleKeyDown(event);
|
|
320
|
+
}
|
|
321
|
+
// Utility methods
|
|
322
|
+
updateInputField() {
|
|
323
|
+
if (this.range) {
|
|
324
|
+
this.inputFieldValue = this.selectionController.formatSelectedRange();
|
|
325
|
+
}
|
|
326
|
+
else {
|
|
327
|
+
this.inputFieldValue = this.selectionController.formatSelectedDate();
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
dispatchDateChange() {
|
|
331
|
+
this.dispatchEvent(new CustomEvent(DATE_PICKER_EVENTS.DATE_CHANGE, {
|
|
332
|
+
bubbles: true,
|
|
333
|
+
composed: true,
|
|
334
|
+
detail: { value: this.inputFieldValue },
|
|
335
|
+
}));
|
|
336
|
+
}
|
|
337
|
+
updateLocale(locale) {
|
|
338
|
+
dayjs.locale(locale);
|
|
339
|
+
this.monthsShort = dayjs().localeData().monthsShort();
|
|
340
|
+
this.months = dayjs().localeData().months();
|
|
341
|
+
this.days = dayjs().localeData().weekdays();
|
|
342
|
+
this.weekdaysShort = dayjs().localeData().weekdaysShort();
|
|
343
|
+
}
|
|
344
|
+
// Event handlers
|
|
345
|
+
inputChanged(event) {
|
|
346
|
+
this.inputFieldValue = event.detail.value;
|
|
347
|
+
// Additional input validation logic here
|
|
348
|
+
}
|
|
349
|
+
onFocus() {
|
|
350
|
+
this.dispatchEvent(new CustomEvent(DATE_PICKER_EVENTS.FOCUS, {
|
|
351
|
+
bubbles: true,
|
|
352
|
+
composed: true,
|
|
353
|
+
}));
|
|
354
|
+
}
|
|
355
|
+
// Dropdown event handlers
|
|
356
|
+
handleMonthSelected(event) {
|
|
357
|
+
const customEvent = event;
|
|
358
|
+
const monthIndex = customEvent.detail.monthIndex;
|
|
359
|
+
this.selectMonth(monthIndex + 1); // selectMonth expects 1-based month
|
|
360
|
+
}
|
|
361
|
+
handleYearSelected(event) {
|
|
362
|
+
const customEvent = event;
|
|
363
|
+
const year = customEvent.detail.year;
|
|
364
|
+
this.selectYear(year);
|
|
365
|
+
}
|
|
366
|
+
// Direct selection handlers for dropdown templates
|
|
367
|
+
handleMonthSelection(monthIndex) {
|
|
368
|
+
this.selectMonth(monthIndex); // monthIndex is already 1-based from renderMonthDropdown
|
|
369
|
+
}
|
|
370
|
+
handleYearSelection(year) {
|
|
371
|
+
this.selectYear(year);
|
|
372
|
+
}
|
|
373
|
+
// Render methods following the multiple render pattern
|
|
374
|
+
render() {
|
|
375
|
+
return html `${choose(this.type, [
|
|
376
|
+
[DatePickerType.Single, () => this.renderSingle()],
|
|
377
|
+
[DatePickerType.Range, () => this.renderRange()],
|
|
378
|
+
[DatePickerType.Multiple, () => this.renderMultiple()],
|
|
379
|
+
])}`;
|
|
380
|
+
}
|
|
381
|
+
renderSingle() {
|
|
382
|
+
return html `
|
|
383
|
+
<div
|
|
384
|
+
class="${classMap({
|
|
385
|
+
'datepicker-container': true,
|
|
386
|
+
'datepicker-disabled': this.disabled,
|
|
387
|
+
[`datepicker-size-${this.size}`]: true,
|
|
388
|
+
[`datepicker-variant-${this.variant}`]: true,
|
|
389
|
+
})}"
|
|
390
|
+
data-theme="${this.currentTheme}"
|
|
391
|
+
>
|
|
392
|
+
<nr-input
|
|
393
|
+
id="${INPUT_FIELD_ID}"
|
|
394
|
+
.type="${this.INPUT_TYPE}"
|
|
395
|
+
.value="${this.inputFieldValue}"
|
|
396
|
+
.size="${this.size}"
|
|
397
|
+
.state="${this.state}"
|
|
398
|
+
.disabled="${this.disabled}"
|
|
399
|
+
.required="${this.required}"
|
|
400
|
+
@input="${this.inputChanged}"
|
|
401
|
+
@focus="${this.onFocus}"
|
|
402
|
+
@click="${this.toggleCalendar}"
|
|
403
|
+
@keydown="${this.handleKeyDown}"
|
|
404
|
+
role="combobox"
|
|
405
|
+
aria-expanded="${this.openedCalendar}"
|
|
406
|
+
aria-haspopup="dialog"
|
|
407
|
+
aria-label="${this.label || 'Select date'}"
|
|
408
|
+
>
|
|
409
|
+
${this.label ? html `<span slot="label">${this.label}</span>` : nothing}
|
|
410
|
+
${this.helper ? html `<span slot="helper-text">${this.helper}</span>` : nothing}
|
|
411
|
+
</nr-input>
|
|
412
|
+
${this.openedCalendar ? this.renderCalendar() : nothing}
|
|
413
|
+
</div>
|
|
414
|
+
`;
|
|
415
|
+
}
|
|
416
|
+
renderRange() {
|
|
417
|
+
// Range-specific rendering logic
|
|
418
|
+
return this.renderSingle(); // For now, use single rendering
|
|
419
|
+
}
|
|
420
|
+
renderMultiple() {
|
|
421
|
+
// Multiple selection rendering logic
|
|
422
|
+
return this.renderSingle(); // For now, use single rendering
|
|
423
|
+
}
|
|
424
|
+
renderCalendar() {
|
|
425
|
+
return html `
|
|
426
|
+
<div
|
|
427
|
+
class="${classMap({
|
|
428
|
+
[CALENDAR_CONTAINER_CLASS]: true,
|
|
429
|
+
'calendar-range': this.range && this.currentMode === DatePickerMode.Day,
|
|
430
|
+
[`placement-${this.placement}`]: true,
|
|
431
|
+
})}"
|
|
432
|
+
role="dialog"
|
|
433
|
+
aria-label="Calendar"
|
|
434
|
+
part="calendar"
|
|
435
|
+
>
|
|
436
|
+
<div class="calendar-header" part="header">
|
|
437
|
+
<nr-button
|
|
438
|
+
type="text"
|
|
439
|
+
class="header-prev-button prev-month"
|
|
440
|
+
.icon="${['angle-left']}"
|
|
441
|
+
@click="${this.prevMonth}"
|
|
442
|
+
aria-label="Previous month"
|
|
443
|
+
></nr-button>
|
|
444
|
+
${this.renderCalendarHeader()}
|
|
445
|
+
<nr-button
|
|
446
|
+
type="text"
|
|
447
|
+
class="header-next-button next-month"
|
|
448
|
+
.icon="${['angle-right']}"
|
|
449
|
+
@click="${this.nextMonth}"
|
|
450
|
+
aria-label="Next month"
|
|
451
|
+
></nr-button>
|
|
452
|
+
</div>
|
|
453
|
+
<div class="calendar-content">
|
|
454
|
+
${this.renderCalendarBody()}
|
|
455
|
+
</div>
|
|
456
|
+
</div>
|
|
457
|
+
`;
|
|
458
|
+
}
|
|
459
|
+
get monthOptions() {
|
|
460
|
+
return this.months.map((month, index) => ({
|
|
461
|
+
value: (index + 1).toString(),
|
|
462
|
+
label: capitalizeFirstLetter(month)
|
|
463
|
+
}));
|
|
464
|
+
}
|
|
465
|
+
get yearOptions() {
|
|
466
|
+
const currentYear = this.navigationDates.start.year;
|
|
467
|
+
const years = [];
|
|
468
|
+
for (let year = currentYear - 10; year <= currentYear + 10; year++) {
|
|
469
|
+
years.push({
|
|
470
|
+
value: year.toString(),
|
|
471
|
+
label: year.toString()
|
|
472
|
+
});
|
|
473
|
+
}
|
|
474
|
+
return years;
|
|
475
|
+
}
|
|
476
|
+
renderCalendarHeader() {
|
|
477
|
+
return html `
|
|
478
|
+
<div class="year-month-header">
|
|
479
|
+
${this.currentMode !== DatePickerMode.Year
|
|
480
|
+
? html `
|
|
481
|
+
<div class="month-selector">
|
|
482
|
+
<hy-select
|
|
483
|
+
.options="${this.monthOptions}"
|
|
484
|
+
.value="${this.navigationDates.start.month.toString()}"
|
|
485
|
+
.defaultValue="${[this.navigationDates.start.month.toString()]}"
|
|
486
|
+
@nr-change="${this.handleMonthChange}"
|
|
487
|
+
size="small"
|
|
488
|
+
class="month-select"
|
|
489
|
+
placeholder=""
|
|
490
|
+
.clearable=${false}
|
|
491
|
+
max-height="200px"
|
|
492
|
+
></hy-select>
|
|
493
|
+
</div>
|
|
494
|
+
`
|
|
495
|
+
: nothing}
|
|
496
|
+
|
|
497
|
+
<div class="current-year-container">
|
|
498
|
+
<hy-select
|
|
499
|
+
.options="${this.yearOptions}"
|
|
500
|
+
.value="${this.navigationDates.start.year.toString()}"
|
|
501
|
+
.defaultValue="${[this.navigationDates.start.year.toString()]}"
|
|
502
|
+
@nr-change="${this.handleYearChange}"
|
|
503
|
+
size="small"
|
|
504
|
+
class="year-select"
|
|
505
|
+
placeholder=""
|
|
506
|
+
.clearable=${false}
|
|
507
|
+
max-height="200px"
|
|
508
|
+
></hy-select>
|
|
509
|
+
<div class="year-icons-toggler">
|
|
510
|
+
<nr-button
|
|
511
|
+
class="next-year"
|
|
512
|
+
.icon="${['caret-up']}"
|
|
513
|
+
@click="${this.nextYear}"
|
|
514
|
+
aria-label="Next year"
|
|
515
|
+
></nr-button>
|
|
516
|
+
<nr-button
|
|
517
|
+
class="previous-year"
|
|
518
|
+
.icon="${['caret-down']}"
|
|
519
|
+
@click="${this.prevYear}"
|
|
520
|
+
aria-label="Previous year"
|
|
521
|
+
></nr-button>
|
|
522
|
+
</div>
|
|
523
|
+
</div>
|
|
524
|
+
</div>
|
|
525
|
+
`;
|
|
526
|
+
}
|
|
527
|
+
renderCalendarBody() {
|
|
528
|
+
return html `${choose(this.currentMode, [
|
|
529
|
+
[DatePickerMode.Day, () => this.renderDays()],
|
|
530
|
+
[DatePickerMode.Month, () => this.renderMonths()],
|
|
531
|
+
[DatePickerMode.Year, () => this.renderYears()],
|
|
532
|
+
])}`;
|
|
533
|
+
}
|
|
534
|
+
renderDays() {
|
|
535
|
+
const isRange = this.range && this.currentMode === DatePickerMode.Day;
|
|
536
|
+
return renderDays(this.weekdaysShort, this.navigationDates, (date) => this.selectDay(date), {
|
|
537
|
+
currentYear: this.currentYear,
|
|
538
|
+
currentMonth: this.currentMonth,
|
|
539
|
+
currentDay: this.currentDay,
|
|
540
|
+
endYear: this.endYear || this.currentYear,
|
|
541
|
+
endMonth: this.endMonth || this.currentMonth,
|
|
542
|
+
endDay: this.endDay || this.currentDay,
|
|
543
|
+
}, isRange, this.days);
|
|
544
|
+
}
|
|
545
|
+
renderMonths() {
|
|
546
|
+
return renderMonthsTemplate(this.monthsShort, this.currentMonth, this.selectMonth);
|
|
547
|
+
}
|
|
548
|
+
renderYears() {
|
|
549
|
+
return renderYearsTemplate(this.navigationDates.start.year, this.selectYear);
|
|
550
|
+
}
|
|
551
|
+
};
|
|
552
|
+
HyDatePickerElement.styles = styles;
|
|
553
|
+
__decorate([
|
|
554
|
+
property({ type: String })
|
|
555
|
+
], HyDatePickerElement.prototype, "name", void 0);
|
|
556
|
+
__decorate([
|
|
557
|
+
property({ type: String })
|
|
558
|
+
], HyDatePickerElement.prototype, "value", void 0);
|
|
559
|
+
__decorate([
|
|
560
|
+
property({ type: String, attribute: 'date-value' })
|
|
561
|
+
], HyDatePickerElement.prototype, "dateValue", void 0);
|
|
562
|
+
__decorate([
|
|
563
|
+
property({ type: String, attribute: 'default-value' })
|
|
564
|
+
], HyDatePickerElement.prototype, "defaultValue", void 0);
|
|
565
|
+
__decorate([
|
|
566
|
+
property({ type: Boolean })
|
|
567
|
+
], HyDatePickerElement.prototype, "disabled", void 0);
|
|
568
|
+
__decorate([
|
|
569
|
+
property({ type: Boolean })
|
|
570
|
+
], HyDatePickerElement.prototype, "required", void 0);
|
|
571
|
+
__decorate([
|
|
572
|
+
property({ type: String })
|
|
573
|
+
], HyDatePickerElement.prototype, "locale", void 0);
|
|
574
|
+
__decorate([
|
|
575
|
+
property({ type: String, attribute: 'field-format' })
|
|
576
|
+
], HyDatePickerElement.prototype, "fieldFormat", void 0);
|
|
577
|
+
__decorate([
|
|
578
|
+
property({ type: Boolean })
|
|
579
|
+
], HyDatePickerElement.prototype, "range", void 0);
|
|
580
|
+
__decorate([
|
|
581
|
+
property({ type: String, attribute: 'min-date' })
|
|
582
|
+
], HyDatePickerElement.prototype, "minDate", void 0);
|
|
583
|
+
__decorate([
|
|
584
|
+
property({ type: String, attribute: 'max-date' })
|
|
585
|
+
], HyDatePickerElement.prototype, "maxDate", void 0);
|
|
586
|
+
__decorate([
|
|
587
|
+
property({ type: Array, attribute: 'disabled-dates' })
|
|
588
|
+
], HyDatePickerElement.prototype, "disabledDates", void 0);
|
|
589
|
+
__decorate([
|
|
590
|
+
property({ type: String })
|
|
591
|
+
], HyDatePickerElement.prototype, "type", void 0);
|
|
592
|
+
__decorate([
|
|
593
|
+
property({ type: String })
|
|
594
|
+
], HyDatePickerElement.prototype, "size", void 0);
|
|
595
|
+
__decorate([
|
|
596
|
+
property({ type: String })
|
|
597
|
+
], HyDatePickerElement.prototype, "variant", void 0);
|
|
598
|
+
__decorate([
|
|
599
|
+
property({ type: String })
|
|
600
|
+
], HyDatePickerElement.prototype, "placement", void 0);
|
|
601
|
+
__decorate([
|
|
602
|
+
property({ type: String })
|
|
603
|
+
], HyDatePickerElement.prototype, "label", void 0);
|
|
604
|
+
__decorate([
|
|
605
|
+
property({ type: String })
|
|
606
|
+
], HyDatePickerElement.prototype, "helper", void 0);
|
|
607
|
+
__decorate([
|
|
608
|
+
property({ type: String })
|
|
609
|
+
], HyDatePickerElement.prototype, "state", void 0);
|
|
610
|
+
__decorate([
|
|
611
|
+
property({ type: Boolean, attribute: 'use-select-dropdowns' })
|
|
612
|
+
], HyDatePickerElement.prototype, "useSelectDropdowns", void 0);
|
|
613
|
+
__decorate([
|
|
614
|
+
property({ reflect: true, type: Boolean, attribute: 'opened-calendar' })
|
|
615
|
+
], HyDatePickerElement.prototype, "openedCalendar", void 0);
|
|
616
|
+
__decorate([
|
|
617
|
+
property({ type: String })
|
|
618
|
+
], HyDatePickerElement.prototype, "mode", void 0);
|
|
619
|
+
__decorate([
|
|
620
|
+
state()
|
|
621
|
+
], HyDatePickerElement.prototype, "currentMode", void 0);
|
|
622
|
+
__decorate([
|
|
623
|
+
state()
|
|
624
|
+
], HyDatePickerElement.prototype, "monthsShort", void 0);
|
|
625
|
+
__decorate([
|
|
626
|
+
state()
|
|
627
|
+
], HyDatePickerElement.prototype, "months", void 0);
|
|
628
|
+
__decorate([
|
|
629
|
+
state()
|
|
630
|
+
], HyDatePickerElement.prototype, "days", void 0);
|
|
631
|
+
__decorate([
|
|
632
|
+
state()
|
|
633
|
+
], HyDatePickerElement.prototype, "weekdaysShort", void 0);
|
|
634
|
+
__decorate([
|
|
635
|
+
state()
|
|
636
|
+
], HyDatePickerElement.prototype, "inputFieldValue", void 0);
|
|
637
|
+
__decorate([
|
|
638
|
+
state()
|
|
639
|
+
], HyDatePickerElement.prototype, "currentYear", void 0);
|
|
640
|
+
__decorate([
|
|
641
|
+
state()
|
|
642
|
+
], HyDatePickerElement.prototype, "currentMonth", void 0);
|
|
643
|
+
__decorate([
|
|
644
|
+
state()
|
|
645
|
+
], HyDatePickerElement.prototype, "currentDay", void 0);
|
|
646
|
+
__decorate([
|
|
647
|
+
state()
|
|
648
|
+
], HyDatePickerElement.prototype, "endYear", void 0);
|
|
649
|
+
__decorate([
|
|
650
|
+
state()
|
|
651
|
+
], HyDatePickerElement.prototype, "endMonth", void 0);
|
|
652
|
+
__decorate([
|
|
653
|
+
state()
|
|
654
|
+
], HyDatePickerElement.prototype, "endDay", void 0);
|
|
655
|
+
__decorate([
|
|
656
|
+
state()
|
|
657
|
+
], HyDatePickerElement.prototype, "navigationDates", void 0);
|
|
658
|
+
__decorate([
|
|
659
|
+
query(`#${INPUT_FIELD_ID}`)
|
|
660
|
+
], HyDatePickerElement.prototype, "dateInput", void 0);
|
|
661
|
+
__decorate([
|
|
662
|
+
query(`.${CALENDAR_CONTAINER_CLASS}`)
|
|
663
|
+
], HyDatePickerElement.prototype, "calendarContainer", void 0);
|
|
664
|
+
HyDatePickerElement = __decorate([
|
|
665
|
+
customElement('hy-datepicker')
|
|
666
|
+
], HyDatePickerElement);
|
|
667
|
+
export { HyDatePickerElement };
|
|
668
|
+
//# sourceMappingURL=datepicker.component.js.map
|