quang 19.3.16-1 → 19.4.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/components/autocomplete/README.md +34 -0
- package/components/autocomplete/autocomplete.component.d.ts +2 -0
- package/components/date/date.component.d.ts +10 -1
- package/components/select/README.md +34 -0
- package/components/select/select.component.d.ts +1 -0
- package/components/shared/option-list/option-list.component.d.ts +7 -1
- package/components/shared/quang-base-component.directive.d.ts +3 -1
- package/fesm2022/quang-components-autocomplete.mjs +9 -3
- package/fesm2022/quang-components-autocomplete.mjs.map +1 -1
- package/fesm2022/quang-components-checkbox.mjs +2 -2
- package/fesm2022/quang-components-checkbox.mjs.map +1 -1
- package/fesm2022/quang-components-date.mjs +249 -132
- package/fesm2022/quang-components-date.mjs.map +1 -1
- package/fesm2022/quang-components-input.mjs +2 -2
- package/fesm2022/quang-components-input.mjs.map +1 -1
- package/fesm2022/quang-components-select.mjs +6 -3
- package/fesm2022/quang-components-select.mjs.map +1 -1
- package/fesm2022/quang-components-shared.mjs +35 -14
- package/fesm2022/quang-components-shared.mjs.map +1 -1
- package/package.json +36 -36
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { NgClass } from '@angular/common';
|
|
2
2
|
import * as i0 from '@angular/core';
|
|
3
|
-
import { input, viewChild, computed, signal,
|
|
3
|
+
import { inject, NgZone, ChangeDetectorRef, ApplicationRef, input, viewChild, computed, signal, effect, forwardRef, ChangeDetectionStrategy, Component } from '@angular/core';
|
|
4
4
|
import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
|
|
5
5
|
import { NG_VALUE_ACCESSOR } from '@angular/forms';
|
|
6
6
|
import { TranslocoPipe } from '@jsverse/transloco';
|
|
@@ -28,6 +28,10 @@ import { QuangBaseComponent } from 'quang/components/shared';
|
|
|
28
28
|
class QuangDateComponent extends QuangBaseComponent {
|
|
29
29
|
constructor() {
|
|
30
30
|
super();
|
|
31
|
+
this._ngZone = inject(NgZone);
|
|
32
|
+
this._cdr = inject(ChangeDetectorRef);
|
|
33
|
+
this._appRef = inject(ApplicationRef);
|
|
34
|
+
this._tickScheduled = false;
|
|
31
35
|
/**
|
|
32
36
|
* Format to use to show on the input field.
|
|
33
37
|
* The format is based on the standard {@link https://www.unicode.org/reports/tr35/tr35-dates.html#Date_Field_Symbol_Table}
|
|
@@ -70,7 +74,7 @@ class QuangDateComponent extends QuangBaseComponent {
|
|
|
70
74
|
this._inputForDate = viewChild('inputForDate');
|
|
71
75
|
this.contentTemplate = viewChild.required('calendarButton');
|
|
72
76
|
this.hasNoContent = computed(() => this.contentTemplate()?.nativeElement.children.length === 0);
|
|
73
|
-
this._quangTranslationService = signal(inject(QuangTranslationService));
|
|
77
|
+
this._quangTranslationService = signal(inject(QuangTranslationService, { optional: true }) ?? undefined);
|
|
74
78
|
this._quangTranslationActiveLang = computed(() => this._quangTranslationService()?.activeLang() ?? null);
|
|
75
79
|
this.multipleDatesSeparator = input(' - ');
|
|
76
80
|
this.rangeSelection = input(false);
|
|
@@ -84,6 +88,9 @@ class QuangDateComponent extends QuangBaseComponent {
|
|
|
84
88
|
return navigator.language;
|
|
85
89
|
});
|
|
86
90
|
this._airDatepickerInstance = signal(undefined);
|
|
91
|
+
// AirDatepicker doesn't reliably support toggling `inline` at runtime via `update()`.
|
|
92
|
+
// Track the mode used to create the current instance and recreate when it changes.
|
|
93
|
+
this._airDatepickerInlineMode = signal(null);
|
|
87
94
|
this.searchTextDebounce = input(500);
|
|
88
95
|
this.targetPosition = signal('bottom left');
|
|
89
96
|
this._generateAirDatepickerEffect = effect(() => {
|
|
@@ -96,6 +103,7 @@ class QuangDateComponent extends QuangBaseComponent {
|
|
|
96
103
|
this.showTimepicker = computed(() => !this.rangeSelection() && (this.timepicker() || this.showOnlyTimepicker()));
|
|
97
104
|
this.isMouseInsideCalendar = signal(false);
|
|
98
105
|
this.isMouseOutsideCalendar = computed(() => !this.isMouseInsideCalendar());
|
|
106
|
+
this._shouldRefocusInputOnHide = signal(false);
|
|
99
107
|
fromEvent(document, 'scroll', { capture: true })
|
|
100
108
|
.pipe(takeUntilDestroyed(), debounceTime(250))
|
|
101
109
|
.subscribe(() => {
|
|
@@ -105,111 +113,147 @@ class QuangDateComponent extends QuangBaseComponent {
|
|
|
105
113
|
});
|
|
106
114
|
}
|
|
107
115
|
setupCalendar() {
|
|
108
|
-
if (this._inputForDate()?.nativeElement)
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
+
if (!this._inputForDate()?.nativeElement)
|
|
117
|
+
return;
|
|
118
|
+
const desiredInlineMode = this.showInline();
|
|
119
|
+
const existingInstance = this._airDatepickerInstance();
|
|
120
|
+
const existingInlineMode = this._airDatepickerInlineMode();
|
|
121
|
+
if (existingInstance && existingInlineMode !== null && existingInlineMode !== desiredInlineMode) {
|
|
122
|
+
const maybeDestroy = existingInstance;
|
|
123
|
+
maybeDestroy.destroy?.();
|
|
124
|
+
this._airDatepickerInstance.set(undefined);
|
|
125
|
+
}
|
|
126
|
+
let currentValue = this._value();
|
|
127
|
+
let targetDate;
|
|
128
|
+
if (currentValue && typeof currentValue === 'string') {
|
|
129
|
+
if (!this.showTimepicker()) {
|
|
130
|
+
currentValue = currentValue.split('T')[0];
|
|
116
131
|
}
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
if (currentValue.dateTo) {
|
|
127
|
-
let targetDateTo = currentValue.dateTo;
|
|
128
|
-
if (!this.showTimepicker()) {
|
|
129
|
-
targetDateTo = currentValue.dateTo.split('T')[0];
|
|
130
|
-
}
|
|
131
|
-
targetDate.push(targetDateTo);
|
|
132
|
-
}
|
|
132
|
+
targetDate = [currentValue];
|
|
133
|
+
}
|
|
134
|
+
else if (currentValue && typeof currentValue === 'object') {
|
|
135
|
+
targetDate = [];
|
|
136
|
+
if (currentValue.dateFrom) {
|
|
137
|
+
const targetDateFrom = this.showTimepicker()
|
|
138
|
+
? currentValue.dateFrom
|
|
139
|
+
: currentValue.dateFrom.split('T')[0];
|
|
140
|
+
targetDate.push(targetDateFrom);
|
|
133
141
|
}
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
142
|
+
if (currentValue.dateTo) {
|
|
143
|
+
const targetDateTo = this.showTimepicker() ? currentValue.dateTo : currentValue.dateTo.split('T')[0];
|
|
144
|
+
targetDate.push(targetDateTo);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
this.setCalendarPosition();
|
|
148
|
+
const userDatepickerOptions = this.datepickerOptions() ?? {};
|
|
149
|
+
const userOnSelect = userDatepickerOptions.onSelect;
|
|
150
|
+
const userOnHide = userDatepickerOptions.onHide;
|
|
151
|
+
const userOnShow = userDatepickerOptions.onShow;
|
|
152
|
+
const airDatepickerOpts = {
|
|
153
|
+
...userDatepickerOptions,
|
|
154
|
+
autoClose: !this.showInline(),
|
|
155
|
+
showEvent: 'click',
|
|
156
|
+
classes: this.calendarClasses(),
|
|
157
|
+
dateFormat: this.dateFormat(),
|
|
158
|
+
inline: this.showInline(),
|
|
159
|
+
isMobile: false,
|
|
160
|
+
multipleDatesSeparator: this.multipleDatesSeparator(),
|
|
161
|
+
range: this.rangeSelection(),
|
|
162
|
+
timepicker: this.showTimepicker(),
|
|
163
|
+
onlyTimepicker: this.showOnlyTimepicker(),
|
|
164
|
+
timeFormat: this.timeFormat(),
|
|
165
|
+
minHours: this.minHour(),
|
|
166
|
+
maxHours: this.maxHour(),
|
|
167
|
+
minMinutes: this.minMinute(),
|
|
168
|
+
maxMinutes: this.maxMinute(),
|
|
169
|
+
minDate: this.minDate(),
|
|
170
|
+
maxDate: this.maxDate(),
|
|
171
|
+
toggleSelected: false,
|
|
172
|
+
multipleDates: false,
|
|
173
|
+
selectedDates: targetDate,
|
|
174
|
+
position: this.targetPosition(),
|
|
175
|
+
locale: this.getLocale(),
|
|
176
|
+
onSelect: (args) => {
|
|
177
|
+
const { date } = args;
|
|
178
|
+
// AirDatepicker callbacks may fire outside Angular's zone in some app setups.
|
|
179
|
+
// Ensure CVA propagation happens inside the zone so the connected FormControl updates reliably.
|
|
180
|
+
this._ngZone.run(() => {
|
|
181
|
+
this._shouldRefocusInputOnHide.set(true);
|
|
182
|
+
if (Array.isArray(date)) {
|
|
183
|
+
// Range selection: AirDatepicker emits partial selections too (only start date).
|
|
184
|
+
// Committing `_value` for partial selections can trigger `setupCalendar()` re-sync and
|
|
185
|
+
// break the second click. Only commit once the range is complete.
|
|
186
|
+
const [from, to] = date;
|
|
187
|
+
if (!from || !to) {
|
|
188
|
+
return;
|
|
162
189
|
}
|
|
190
|
+
const value = {
|
|
191
|
+
dateFrom: (this.showTimepicker() ? from : this.dateToUtc(from)).toISOString(),
|
|
192
|
+
dateTo: (this.showTimepicker() ? to : this.dateToUtc(to)).toISOString(),
|
|
193
|
+
};
|
|
194
|
+
this.onChangedHandler(value);
|
|
195
|
+
}
|
|
196
|
+
else if (date) {
|
|
197
|
+
const selectTargetDate = this.showTimepicker() ? date : this.dateToUtc(date);
|
|
163
198
|
this.onChangedHandler(selectTargetDate.toISOString());
|
|
164
199
|
}
|
|
165
200
|
if (this.showInline()) {
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
onHide: (isAnimationComplete) => {
|
|
170
|
-
if (isAnimationComplete) {
|
|
171
|
-
this.onHideCalendar();
|
|
201
|
+
// Inline mode should update the connected control immediately.
|
|
202
|
+
// Do not rely on `onHideCalendar()` because inline never hides and the input may be visually hidden.
|
|
203
|
+
this.propagateValueToControl();
|
|
172
204
|
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
this.isMouseInsideCalendar.set(true);
|
|
180
|
-
};
|
|
181
|
-
datepicker.onmouseleave = () => {
|
|
182
|
-
this.isMouseInsideCalendar.set(false);
|
|
183
|
-
};
|
|
184
|
-
}
|
|
185
|
-
if (isAnimationComplete || !this.showTimepicker()) {
|
|
186
|
-
return;
|
|
187
|
-
}
|
|
188
|
-
this.setupTimepicker();
|
|
189
|
-
},
|
|
190
|
-
};
|
|
191
|
-
if (this._airDatepickerInstance()) {
|
|
192
|
-
if (this._airDatepickerInstance()?.visible) {
|
|
193
|
-
this._airDatepickerInstance()?.update(airDatepickerOpts);
|
|
205
|
+
});
|
|
206
|
+
userOnSelect?.(args);
|
|
207
|
+
},
|
|
208
|
+
onHide: (isAnimationComplete) => {
|
|
209
|
+
if (isAnimationComplete) {
|
|
210
|
+
this.onHideCalendar();
|
|
194
211
|
}
|
|
195
|
-
|
|
196
|
-
|
|
212
|
+
userOnHide?.(isAnimationComplete);
|
|
213
|
+
},
|
|
214
|
+
onShow: (isAnimationComplete) => {
|
|
215
|
+
const datepicker = this._airDatepickerInstance()?.$datepicker;
|
|
216
|
+
if (datepicker) {
|
|
217
|
+
datepicker.onmouseenter = () => {
|
|
218
|
+
this.isMouseInsideCalendar.set(true);
|
|
219
|
+
};
|
|
220
|
+
datepicker.onmouseleave = () => {
|
|
221
|
+
this.isMouseInsideCalendar.set(false);
|
|
222
|
+
};
|
|
197
223
|
}
|
|
198
|
-
if (!
|
|
199
|
-
|
|
200
|
-
this._airDatepickerInstance()?.clear({ silent: true });
|
|
201
|
-
}
|
|
202
|
-
else {
|
|
203
|
-
this._airDatepickerInstance()?.selectDate(targetDate, { updateTime: true });
|
|
224
|
+
if (isAnimationComplete || !this.showTimepicker()) {
|
|
225
|
+
return;
|
|
204
226
|
}
|
|
227
|
+
this.setupTimepicker();
|
|
228
|
+
userOnShow?.(isAnimationComplete);
|
|
229
|
+
},
|
|
230
|
+
};
|
|
231
|
+
if (this._airDatepickerInstance()) {
|
|
232
|
+
if (this._airDatepickerInstance()?.visible) {
|
|
233
|
+
this._airDatepickerInstance()?.update(airDatepickerOpts);
|
|
205
234
|
}
|
|
206
235
|
else {
|
|
207
|
-
this._airDatepickerInstance
|
|
236
|
+
this._airDatepickerInstance()?.update(airDatepickerOpts, { silent: true });
|
|
208
237
|
}
|
|
209
|
-
if (
|
|
210
|
-
this.
|
|
238
|
+
if (targetDate) {
|
|
239
|
+
this._airDatepickerInstance()?.selectDate(targetDate, { updateTime: true, silent: true });
|
|
240
|
+
}
|
|
241
|
+
else {
|
|
242
|
+
this._airDatepickerInstance()?.setFocusDate(false);
|
|
243
|
+
this._airDatepickerInstance()?.clear({ silent: true });
|
|
211
244
|
}
|
|
212
245
|
}
|
|
246
|
+
else {
|
|
247
|
+
this._airDatepickerInstance.set(new AirDatepicker(this._inputForDate()?.nativeElement, airDatepickerOpts));
|
|
248
|
+
}
|
|
249
|
+
this._airDatepickerInlineMode.set(desiredInlineMode);
|
|
250
|
+
if (desiredInlineMode) {
|
|
251
|
+
// Ensure inline calendar is visible after re-creation/update.
|
|
252
|
+
this._airDatepickerInstance()?.show?.();
|
|
253
|
+
}
|
|
254
|
+
if (this.showInline()) {
|
|
255
|
+
this.setupTimepicker();
|
|
256
|
+
}
|
|
213
257
|
}
|
|
214
258
|
onChangeText($event) {
|
|
215
259
|
const value = $event.target?.value;
|
|
@@ -217,14 +261,23 @@ class QuangDateComponent extends QuangBaseComponent {
|
|
|
217
261
|
// TODO: check format for DateRange
|
|
218
262
|
if (value.length === this.valueFormat().length && isMatch(value, this.valueFormat())) {
|
|
219
263
|
this.onChangedHandler(this.setupInputStringToDate(value).toISOString());
|
|
264
|
+
if (this.showInline()) {
|
|
265
|
+
this.propagateValueToControl();
|
|
266
|
+
}
|
|
220
267
|
}
|
|
221
268
|
}
|
|
222
269
|
else {
|
|
223
270
|
this.onChangedHandler(value);
|
|
271
|
+
if (this.showInline()) {
|
|
272
|
+
this.propagateValueToControl();
|
|
273
|
+
}
|
|
224
274
|
}
|
|
225
275
|
}
|
|
226
276
|
onBlurHandler() {
|
|
227
277
|
super.onBlurHandler();
|
|
278
|
+
if (this.showInline()) {
|
|
279
|
+
return;
|
|
280
|
+
}
|
|
228
281
|
if (this.isMouseOutsideCalendar() && this._airDatepickerInstance()?.visible) {
|
|
229
282
|
this._airDatepickerInstance()?.hide();
|
|
230
283
|
}
|
|
@@ -234,9 +287,9 @@ class QuangDateComponent extends QuangBaseComponent {
|
|
|
234
287
|
if (value.length !== targetValueFormat.length) {
|
|
235
288
|
targetValueFormat = targetValueFormat.replace('yyyy', 'yy');
|
|
236
289
|
}
|
|
237
|
-
|
|
290
|
+
const targetDate = parse(value, targetValueFormat, new Date());
|
|
238
291
|
if (!this.showTimepicker()) {
|
|
239
|
-
|
|
292
|
+
return this.dateToUtc(targetDate);
|
|
240
293
|
}
|
|
241
294
|
return targetDate;
|
|
242
295
|
}
|
|
@@ -275,6 +328,42 @@ class QuangDateComponent extends QuangBaseComponent {
|
|
|
275
328
|
}
|
|
276
329
|
this._value.set(targetDate);
|
|
277
330
|
}
|
|
331
|
+
propagateValueToControl() {
|
|
332
|
+
if (this.formControl()?.getRawValue() !== this._value()) {
|
|
333
|
+
super.onChangedHandler(this._value());
|
|
334
|
+
}
|
|
335
|
+
else if (this.onTouched) {
|
|
336
|
+
this.onTouched();
|
|
337
|
+
}
|
|
338
|
+
this.requestRender();
|
|
339
|
+
}
|
|
340
|
+
requestRender() {
|
|
341
|
+
// Inline datepicker interactions can happen outside Angular-managed events.
|
|
342
|
+
// Marking the view dirty is not always enough in zoneless/event-coalesced setups,
|
|
343
|
+
// so we coalesce a manual tick.
|
|
344
|
+
this._cdr.markForCheck();
|
|
345
|
+
if (this._tickScheduled) {
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
this._tickScheduled = true;
|
|
349
|
+
queueMicrotask(() => {
|
|
350
|
+
this._tickScheduled = false;
|
|
351
|
+
this._appRef.tick();
|
|
352
|
+
});
|
|
353
|
+
}
|
|
354
|
+
syncValueFromDatepickerSelection() {
|
|
355
|
+
if (!this.showInline()) {
|
|
356
|
+
return;
|
|
357
|
+
}
|
|
358
|
+
const datepickerInstance = this._airDatepickerInstance();
|
|
359
|
+
const selectedDate = datepickerInstance?.selectedDates?.[0];
|
|
360
|
+
if (!(selectedDate instanceof Date)) {
|
|
361
|
+
return;
|
|
362
|
+
}
|
|
363
|
+
const targetDate = this.showTimepicker() ? selectedDate : this.dateToUtc(selectedDate);
|
|
364
|
+
this.onChangedHandler(targetDate.toISOString());
|
|
365
|
+
this.propagateValueToControl();
|
|
366
|
+
}
|
|
278
367
|
onHideCalendar() {
|
|
279
368
|
const valueInput = this._inputForDate()?.nativeElement.value;
|
|
280
369
|
let value = valueInput;
|
|
@@ -283,18 +372,14 @@ class QuangDateComponent extends QuangBaseComponent {
|
|
|
283
372
|
const [dateFrom, dateTo] = valueInput.split(this.multipleDatesSeparator());
|
|
284
373
|
value.dateFrom = dateFrom ?? '';
|
|
285
374
|
value.dateTo = dateTo ?? '';
|
|
286
|
-
|
|
287
|
-
value.dateFrom
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
}
|
|
295
|
-
else {
|
|
296
|
-
value.dateTo = this.setupInputStringToDate(value.dateTo).toISOString();
|
|
297
|
-
}
|
|
375
|
+
value.dateFrom =
|
|
376
|
+
!value.dateFrom || !this.checkDateMatch(value.dateFrom)
|
|
377
|
+
? null
|
|
378
|
+
: this.setupInputStringToDate(value.dateFrom).toISOString();
|
|
379
|
+
value.dateTo =
|
|
380
|
+
!value.dateTo || !this.checkDateMatch(value.dateTo)
|
|
381
|
+
? null
|
|
382
|
+
: this.setupInputStringToDate(value.dateTo).toISOString();
|
|
298
383
|
this.onChangedHandler(value);
|
|
299
384
|
}
|
|
300
385
|
else if (this.checkDateMatch(value)) {
|
|
@@ -303,20 +388,19 @@ class QuangDateComponent extends QuangBaseComponent {
|
|
|
303
388
|
else {
|
|
304
389
|
this.onChangedHandler(null);
|
|
305
390
|
}
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
else if (this.onTouched) {
|
|
310
|
-
this.onTouched();
|
|
391
|
+
this.propagateValueToControl();
|
|
392
|
+
if (this.showInline()) {
|
|
393
|
+
return;
|
|
311
394
|
}
|
|
312
|
-
// Only focus the input
|
|
313
|
-
// (e.g., user selected a date via keyboard or mouse click on the calendar).
|
|
395
|
+
// Only focus the input when the user actually interacted with the calendar.
|
|
314
396
|
// Avoids infinite focus loop when tabbing between multiple datepickers.
|
|
315
397
|
const activeElement = document.activeElement;
|
|
316
398
|
const calendarElement = this._airDatepickerInstance()?.$datepicker;
|
|
317
399
|
const inputElement = this._inputForDate()?.nativeElement;
|
|
318
400
|
const isCalendarFocused = calendarElement?.contains(activeElement);
|
|
319
|
-
|
|
401
|
+
const shouldRefocus = this._shouldRefocusInputOnHide() || isCalendarFocused || this.isMouseInsideCalendar();
|
|
402
|
+
this._shouldRefocusInputOnHide.set(false);
|
|
403
|
+
if (shouldRefocus) {
|
|
320
404
|
inputElement?.focus();
|
|
321
405
|
}
|
|
322
406
|
this.onBlurHandler();
|
|
@@ -326,6 +410,9 @@ class QuangDateComponent extends QuangBaseComponent {
|
|
|
326
410
|
return format(val, this.valueFormat());
|
|
327
411
|
}
|
|
328
412
|
if (val && typeof val === 'object') {
|
|
413
|
+
if (!val.dateFrom && !val.dateTo) {
|
|
414
|
+
return '';
|
|
415
|
+
}
|
|
329
416
|
let dateFromFormat = '';
|
|
330
417
|
let dateToFormat = '';
|
|
331
418
|
if (val.dateFrom) {
|
|
@@ -339,8 +426,29 @@ class QuangDateComponent extends QuangBaseComponent {
|
|
|
339
426
|
return '';
|
|
340
427
|
}
|
|
341
428
|
openDatePicker() {
|
|
342
|
-
|
|
343
|
-
|
|
429
|
+
const inputEl = this._inputForDate()?.nativeElement;
|
|
430
|
+
if (!inputEl || this._isDisabled()) {
|
|
431
|
+
return;
|
|
432
|
+
}
|
|
433
|
+
inputEl.focus();
|
|
434
|
+
if (!this._airDatepickerInstance()) {
|
|
435
|
+
this.setupCalendar();
|
|
436
|
+
}
|
|
437
|
+
this._airDatepickerInstance()?.show();
|
|
438
|
+
}
|
|
439
|
+
onInputKeydown(event) {
|
|
440
|
+
if (this._isDisabled()) {
|
|
441
|
+
return;
|
|
442
|
+
}
|
|
443
|
+
const datepickerInstance = this._airDatepickerInstance();
|
|
444
|
+
if (event.key === 'Escape' && datepickerInstance?.visible) {
|
|
445
|
+
event.preventDefault();
|
|
446
|
+
datepickerInstance.hide();
|
|
447
|
+
return;
|
|
448
|
+
}
|
|
449
|
+
if (event.key === 'Enter' || event.key === 'ArrowDown') {
|
|
450
|
+
event.preventDefault();
|
|
451
|
+
this.openDatePicker();
|
|
344
452
|
}
|
|
345
453
|
}
|
|
346
454
|
interceptInputInteraction($event) {
|
|
@@ -353,13 +461,13 @@ class QuangDateComponent extends QuangBaseComponent {
|
|
|
353
461
|
getLocale() {
|
|
354
462
|
switch (this._activeLanguage()?.toLowerCase()) {
|
|
355
463
|
case 'en':
|
|
356
|
-
return en.default
|
|
464
|
+
return en.default ?? en;
|
|
357
465
|
case 'it':
|
|
358
|
-
return it.default
|
|
466
|
+
return it.default ?? it;
|
|
359
467
|
case 'fr':
|
|
360
|
-
return fr.default
|
|
468
|
+
return fr.default ?? fr;
|
|
361
469
|
default:
|
|
362
|
-
return en.default
|
|
470
|
+
return en.default ?? en;
|
|
363
471
|
}
|
|
364
472
|
}
|
|
365
473
|
onCancel() {
|
|
@@ -369,10 +477,6 @@ class QuangDateComponent extends QuangBaseComponent {
|
|
|
369
477
|
// convert to UTC time removing the timezone
|
|
370
478
|
return new Date(date.getTime() - date.getTimezoneOffset() * 60000);
|
|
371
479
|
}
|
|
372
|
-
dateToLocal(date) {
|
|
373
|
-
// convert to local time adding the timezone
|
|
374
|
-
return new Date(date.getTime() + date.getTimezoneOffset() * 60000);
|
|
375
|
-
}
|
|
376
480
|
setCalendarPosition() {
|
|
377
481
|
const windowInnerHeight = window.innerHeight;
|
|
378
482
|
const inputBoundingClientRect = this._inputForDate()?.nativeElement.getBoundingClientRect();
|
|
@@ -385,8 +489,23 @@ class QuangDateComponent extends QuangBaseComponent {
|
|
|
385
489
|
}
|
|
386
490
|
}
|
|
387
491
|
setupTimepicker() {
|
|
388
|
-
const
|
|
389
|
-
if (
|
|
492
|
+
const datepickerRoot = this._airDatepickerInstance()?.$datepicker;
|
|
493
|
+
if (!datepickerRoot) {
|
|
494
|
+
return;
|
|
495
|
+
}
|
|
496
|
+
// AirDatepicker may re-render time inputs; use delegated listeners so we don't lose handlers.
|
|
497
|
+
if (!datepickerRoot.dataset['quangTimepickerListeners']) {
|
|
498
|
+
datepickerRoot.dataset['quangTimepickerListeners'] = 'true';
|
|
499
|
+
datepickerRoot.addEventListener('input', () => {
|
|
500
|
+
if (!this.showInline()) {
|
|
501
|
+
return;
|
|
502
|
+
}
|
|
503
|
+
// Let AirDatepicker update its internal selection first.
|
|
504
|
+
setTimeout(() => this._ngZone.run(() => this.syncValueFromDatepickerSelection()), 0);
|
|
505
|
+
}, { capture: true });
|
|
506
|
+
}
|
|
507
|
+
const timepickers = datepickerRoot.getElementsByClassName('air-datepicker-time');
|
|
508
|
+
for (const timepicker of Array.from(timepickers)) {
|
|
390
509
|
const inputs = timepicker.getElementsByTagName('input');
|
|
391
510
|
for (const input of Array.from(inputs)) {
|
|
392
511
|
input.setAttribute('type', 'number');
|
|
@@ -396,7 +515,7 @@ class QuangDateComponent extends QuangBaseComponent {
|
|
|
396
515
|
evt.stopImmediatePropagation();
|
|
397
516
|
};
|
|
398
517
|
input.onblur = () => {
|
|
399
|
-
if (this.isMouseOutsideCalendar()) {
|
|
518
|
+
if (!this.showInline() && this.isMouseOutsideCalendar()) {
|
|
400
519
|
this._airDatepickerInstance()?.hide();
|
|
401
520
|
}
|
|
402
521
|
};
|
|
@@ -407,14 +526,12 @@ class QuangDateComponent extends QuangBaseComponent {
|
|
|
407
526
|
return isMatch(date, this.valueFormat()) || isMatch(date, this.valueFormat().replace('yyyy', 'yy'));
|
|
408
527
|
}
|
|
409
528
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: QuangDateComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
410
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: QuangDateComponent, isStandalone: true, selector: "quang-date", inputs: { dateFormat: { classPropertyName: "dateFormat", publicName: "dateFormat", isSignal: true, isRequired: false, transformFunction: null }, timeFormat: { classPropertyName: "timeFormat", publicName: "timeFormat", isSignal: true, isRequired: false, transformFunction: null }, activeLanguageOverride: { classPropertyName: "activeLanguageOverride", publicName: "activeLanguageOverride", isSignal: true, isRequired: false, transformFunction: null }, timepicker: { classPropertyName: "timepicker", publicName: "timepicker", isSignal: true, isRequired: false, transformFunction: null }, invalidDateMessage: { classPropertyName: "invalidDateMessage", publicName: "invalidDateMessage", isSignal: true, isRequired: false, transformFunction: null }, showOnlyTimepicker: { classPropertyName: "showOnlyTimepicker", publicName: "showOnlyTimepicker", isSignal: true, isRequired: false, transformFunction: null }, minHour: { classPropertyName: "minHour", publicName: "minHour", isSignal: true, isRequired: false, transformFunction: null }, maxHour: { classPropertyName: "maxHour", publicName: "maxHour", isSignal: true, isRequired: false, transformFunction: null }, minMinute: { classPropertyName: "minMinute", publicName: "minMinute", isSignal: true, isRequired: false, transformFunction: null }, maxMinute: { classPropertyName: "maxMinute", publicName: "maxMinute", isSignal: true, isRequired: false, transformFunction: null }, minDate: { classPropertyName: "minDate", publicName: "minDate", isSignal: true, isRequired: false, transformFunction: null }, maxDate: { classPropertyName: "maxDate", publicName: "maxDate", isSignal: true, isRequired: false, transformFunction: null }, showInline: { classPropertyName: "showInline", publicName: "showInline", isSignal: true, isRequired: false, transformFunction: null }, calendarClasses: { classPropertyName: "calendarClasses", publicName: "calendarClasses", isSignal: true, isRequired: false, transformFunction: null }, buttonClass: { classPropertyName: "buttonClass", publicName: "buttonClass", isSignal: true, isRequired: false, transformFunction: null }, datepickerOptions: { classPropertyName: "datepickerOptions", publicName: "datepickerOptions", isSignal: true, isRequired: false, transformFunction: null }, multipleDatesSeparator: { classPropertyName: "multipleDatesSeparator", publicName: "multipleDatesSeparator", isSignal: true, isRequired: false, transformFunction: null }, rangeSelection: { classPropertyName: "rangeSelection", publicName: "rangeSelection", isSignal: true, isRequired: false, transformFunction: null }, searchTextDebounce: { classPropertyName: "searchTextDebounce", publicName: "searchTextDebounce", isSignal: true, isRequired: false, transformFunction: null } }, providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => QuangDateComponent), multi: true }], viewQueries: [{ propertyName: "_inputForDate", first: true, predicate: ["inputForDate"], descendants: true, isSignal: true }, { propertyName: "contentTemplate", first: true, predicate: ["calendarButton"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"mb-3\">\n @if (componentLabel()) {\n <label\n [htmlFor]=\"componentId()\"\n class=\"form-label\"\n >\n {{ componentLabel() | transloco }}\n <span [hidden]=\"!_isRequired()\">*</span>\n </label>\n }\n <div\n [class.is-invalid]=\"_showErrors()\"\n [class.is-valid]=\"_showSuccess()\"\n class=\"input-date-container\"\n >\n <input\n [attr.required]=\"getIsRequiredControl()\"\n [autocomplete]=\"'off'\"\n [class.is-invalid]=\"_showErrors()\"\n [class.is-valid]=\"_showSuccess()\"\n [class.
|
|
529
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.2.15", type: QuangDateComponent, isStandalone: true, selector: "quang-date", inputs: { dateFormat: { classPropertyName: "dateFormat", publicName: "dateFormat", isSignal: true, isRequired: false, transformFunction: null }, timeFormat: { classPropertyName: "timeFormat", publicName: "timeFormat", isSignal: true, isRequired: false, transformFunction: null }, activeLanguageOverride: { classPropertyName: "activeLanguageOverride", publicName: "activeLanguageOverride", isSignal: true, isRequired: false, transformFunction: null }, timepicker: { classPropertyName: "timepicker", publicName: "timepicker", isSignal: true, isRequired: false, transformFunction: null }, invalidDateMessage: { classPropertyName: "invalidDateMessage", publicName: "invalidDateMessage", isSignal: true, isRequired: false, transformFunction: null }, showOnlyTimepicker: { classPropertyName: "showOnlyTimepicker", publicName: "showOnlyTimepicker", isSignal: true, isRequired: false, transformFunction: null }, minHour: { classPropertyName: "minHour", publicName: "minHour", isSignal: true, isRequired: false, transformFunction: null }, maxHour: { classPropertyName: "maxHour", publicName: "maxHour", isSignal: true, isRequired: false, transformFunction: null }, minMinute: { classPropertyName: "minMinute", publicName: "minMinute", isSignal: true, isRequired: false, transformFunction: null }, maxMinute: { classPropertyName: "maxMinute", publicName: "maxMinute", isSignal: true, isRequired: false, transformFunction: null }, minDate: { classPropertyName: "minDate", publicName: "minDate", isSignal: true, isRequired: false, transformFunction: null }, maxDate: { classPropertyName: "maxDate", publicName: "maxDate", isSignal: true, isRequired: false, transformFunction: null }, showInline: { classPropertyName: "showInline", publicName: "showInline", isSignal: true, isRequired: false, transformFunction: null }, calendarClasses: { classPropertyName: "calendarClasses", publicName: "calendarClasses", isSignal: true, isRequired: false, transformFunction: null }, buttonClass: { classPropertyName: "buttonClass", publicName: "buttonClass", isSignal: true, isRequired: false, transformFunction: null }, datepickerOptions: { classPropertyName: "datepickerOptions", publicName: "datepickerOptions", isSignal: true, isRequired: false, transformFunction: null }, multipleDatesSeparator: { classPropertyName: "multipleDatesSeparator", publicName: "multipleDatesSeparator", isSignal: true, isRequired: false, transformFunction: null }, rangeSelection: { classPropertyName: "rangeSelection", publicName: "rangeSelection", isSignal: true, isRequired: false, transformFunction: null }, searchTextDebounce: { classPropertyName: "searchTextDebounce", publicName: "searchTextDebounce", isSignal: true, isRequired: false, transformFunction: null } }, providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => QuangDateComponent), multi: true }], viewQueries: [{ propertyName: "_inputForDate", first: true, predicate: ["inputForDate"], descendants: true, isSignal: true }, { propertyName: "contentTemplate", first: true, predicate: ["calendarButton"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<div class=\"mb-3\">\n @if (componentLabel()) {\n <label\n [htmlFor]=\"componentId()\"\n class=\"form-label\"\n >\n {{ componentLabel() | transloco }}\n <span [hidden]=\"!_isRequired()\">*</span>\n </label>\n }\n <div\n [class.is-invalid]=\"_showErrors()\"\n [class.is-valid]=\"_showSuccess()\"\n class=\"input-date-container\"\n >\n <input\n [attr.aria-hidden]=\"showInline() ? 'true' : null\"\n [attr.required]=\"getIsRequiredControl()\"\n [autocomplete]=\"'off'\"\n [class.is-invalid]=\"_showErrors()\"\n [class.is-valid]=\"_showSuccess()\"\n [class.quang-date-inline-hidden]=\"showInline()\"\n [class.with-button-calendar]=\"!hasNoContent()\"\n [disabled]=\"_isDisabled()\"\n [id]=\"componentId()\"\n [ngClass]=\"componentClass()\"\n [placeholder]=\"componentPlaceholder() | transloco\"\n [readOnly]=\"isReadonly()\"\n [tabIndex]=\"componentTabIndex()\"\n [value]=\"inputValueString()\"\n (blur)=\"onBlurHandler()\"\n (focus)=\"interceptInputInteraction($event)\"\n (input)=\"onChangeText($event)\"\n (keydown)=\"onInputKeydown($event)\"\n (mouseenter)=\"isMouseInsideCalendar.set(true)\"\n (mouseleave)=\"isMouseInsideCalendar.set(false)\"\n (search)=\"onCancel()\"\n #inputForDate\n class=\"form-control\"\n type=\"search\"\n />\n <button\n [attr.aria-hidden]=\"showInline() ? 'true' : null\"\n [attr.required]=\"getIsRequiredControl()\"\n [class.border-danger]=\"_showErrors()\"\n [class.border-success]=\"_showSuccess()\"\n [class.quang-date-inline-hidden]=\"showInline()\"\n [hidden]=\"hasNoContent() || _isDisabled()\"\n [ngClass]=\"buttonClass()\"\n (click)=\"_ngControl()?.disabled ? null : openDatePicker()\"\n #calendarButton\n aria-label=\"calendar-button\"\n class=\"btn btn-outline-secondary btn-outline-calendar\"\n type=\"button\"\n >\n <ng-content></ng-content>\n </button>\n </div>\n <div class=\"valid-feedback\">\n {{ successMessage() | transloco }}\n </div>\n <div class=\"invalid-feedback\">\n {{ _currentErrorMessage() | transloco: _currentErrorMessageExtraData() }}\n </div>\n @if (helpMessage()) {\n <small\n [hidden]=\"_showSuccess() || _showErrors()\"\n aria-live=\"assertive\"\n class=\"form-text text-muted\"\n >\n {{ helpMessage() | transloco }}\n </small>\n }\n</div>\n", styles: ["input::-webkit-search-cancel-button{-webkit-appearance:none;height:.75rem;width:.75rem;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 3 1024 1024' width='12' height='12' fill='currentColor'%3E%3Cpath d='M9 1018q5 4 10.5 6.5 5.5 2.5 11.5 2.5 6 0 11.5-2.5 5.5-2.5 10.5-6.5l459-459 459 459q5 4 10.5 6.5 5.5 2.5 11.5 2.5 6 0 11.5-2.5 5.5-2.5 10.5-6.5 9-9 9-22 0-13-9-22l-459-459 459-459q9-9 9-22 0-13-9-22-9-9-22-9-13 0-22 9l-459 459-459-459q-9-9-22-9-13 0-22 9-9 9-9 22 0 13 9 22l459 459-459 459q-9 9-9 22 0 13 9 22l0 0z'/%3E%3C/svg%3E%0A\");cursor:pointer}::ng-deep .air-datepicker{z-index:99999}::ng-deep .air-datepicker.-inline-{z-index:unset}::ng-deep .air-datepicker .air-datepicker--pointer{display:none}::ng-deep .air-datepicker .air-datepicker-time{display:block}::ng-deep .air-datepicker .air-datepicker-time .air-datepicker-time--current{display:none}::ng-deep .air-datepicker .air-datepicker-time .air-datepicker-time--sliders{display:flex;justify-content:center;padding-top:.25rem;gap:1rem}::ng-deep .air-datepicker .air-datepicker-time .air-datepicker-time--sliders .air-datepicker-time--row{width:100%;position:relative}::ng-deep .air-datepicker .air-datepicker-time .air-datepicker-time--sliders .air-datepicker-time--row:first-child:after{content:\":\";display:inline;font-size:1rem;position:absolute;right:-.65rem}::ng-deep .air-datepicker .air-datepicker-time .air-datepicker-time--sliders .air-datepicker-time--row input{width:100%;text-align:center;padding:0;padding-left:1rem;border-color:var(--bs-border-color)}::ng-deep .air-datepicker .air-datepicker-time .air-datepicker-time--sliders .air-datepicker-time--row .form-control:focus{box-shadow:unset!important}::ng-deep .air-datepicker.-inline-.-only-timepicker-{border:0;padding:0!important}::ng-deep .air-datepicker.-inline-.-only-timepicker- .air-datepicker--time{border:0;padding:0!important}::ng-deep .air-datepicker.-inline-.-only-timepicker- .air-datepicker-time{padding:0!important}:host{display:block}:host .quang-date-inline-hidden{position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:0!important;border:0!important;opacity:0!important;pointer-events:none!important;overflow:hidden!important;white-space:nowrap!important;clip:rect(0 0 0 0)!important;clip-path:inset(50%)!important}:host .input-date-container{display:flex}:host input{flex:1}:host input.with-button-calendar{border-top-right-radius:0;border-bottom-right-radius:0}:host input:disabled{border-radius:var(--bs-border-radius)}:host .btn-outline-calendar{border-left:0;border-top-left-radius:0;border-bottom-left-radius:0;min-width:unset;display:flex;border-color:var(--bs-border-color)}:host .border-danger{border-color:var(--bs-form-invalid-border-color)}:host .border-success{border-color:var(--bs-form-valid-border-color)}\n"], dependencies: [{ kind: "pipe", type: TranslocoPipe, name: "transloco" }, { kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
411
530
|
}
|
|
412
531
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.2.15", ngImport: i0, type: QuangDateComponent, decorators: [{
|
|
413
532
|
type: Component,
|
|
414
|
-
args: [{ selector: 'quang-date', providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => QuangDateComponent), multi: true }], imports: [TranslocoPipe, NgClass], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"mb-3\">\n @if (componentLabel()) {\n <label\n [htmlFor]=\"componentId()\"\n class=\"form-label\"\n >\n {{ componentLabel() | transloco }}\n <span [hidden]=\"!_isRequired()\">*</span>\n </label>\n }\n <div\n [class.is-invalid]=\"_showErrors()\"\n [class.is-valid]=\"_showSuccess()\"\n class=\"input-date-container\"\n >\n <input\n [attr.required]=\"getIsRequiredControl()\"\n [autocomplete]=\"'off'\"\n [class.is-invalid]=\"_showErrors()\"\n [class.is-valid]=\"_showSuccess()\"\n [class.
|
|
415
|
-
}], ctorParameters: () => []
|
|
416
|
-
type: Optional
|
|
417
|
-
}] } });
|
|
533
|
+
args: [{ selector: 'quang-date', providers: [{ provide: NG_VALUE_ACCESSOR, useExisting: forwardRef(() => QuangDateComponent), multi: true }], imports: [TranslocoPipe, NgClass], changeDetection: ChangeDetectionStrategy.OnPush, template: "<div class=\"mb-3\">\n @if (componentLabel()) {\n <label\n [htmlFor]=\"componentId()\"\n class=\"form-label\"\n >\n {{ componentLabel() | transloco }}\n <span [hidden]=\"!_isRequired()\">*</span>\n </label>\n }\n <div\n [class.is-invalid]=\"_showErrors()\"\n [class.is-valid]=\"_showSuccess()\"\n class=\"input-date-container\"\n >\n <input\n [attr.aria-hidden]=\"showInline() ? 'true' : null\"\n [attr.required]=\"getIsRequiredControl()\"\n [autocomplete]=\"'off'\"\n [class.is-invalid]=\"_showErrors()\"\n [class.is-valid]=\"_showSuccess()\"\n [class.quang-date-inline-hidden]=\"showInline()\"\n [class.with-button-calendar]=\"!hasNoContent()\"\n [disabled]=\"_isDisabled()\"\n [id]=\"componentId()\"\n [ngClass]=\"componentClass()\"\n [placeholder]=\"componentPlaceholder() | transloco\"\n [readOnly]=\"isReadonly()\"\n [tabIndex]=\"componentTabIndex()\"\n [value]=\"inputValueString()\"\n (blur)=\"onBlurHandler()\"\n (focus)=\"interceptInputInteraction($event)\"\n (input)=\"onChangeText($event)\"\n (keydown)=\"onInputKeydown($event)\"\n (mouseenter)=\"isMouseInsideCalendar.set(true)\"\n (mouseleave)=\"isMouseInsideCalendar.set(false)\"\n (search)=\"onCancel()\"\n #inputForDate\n class=\"form-control\"\n type=\"search\"\n />\n <button\n [attr.aria-hidden]=\"showInline() ? 'true' : null\"\n [attr.required]=\"getIsRequiredControl()\"\n [class.border-danger]=\"_showErrors()\"\n [class.border-success]=\"_showSuccess()\"\n [class.quang-date-inline-hidden]=\"showInline()\"\n [hidden]=\"hasNoContent() || _isDisabled()\"\n [ngClass]=\"buttonClass()\"\n (click)=\"_ngControl()?.disabled ? null : openDatePicker()\"\n #calendarButton\n aria-label=\"calendar-button\"\n class=\"btn btn-outline-secondary btn-outline-calendar\"\n type=\"button\"\n >\n <ng-content></ng-content>\n </button>\n </div>\n <div class=\"valid-feedback\">\n {{ successMessage() | transloco }}\n </div>\n <div class=\"invalid-feedback\">\n {{ _currentErrorMessage() | transloco: _currentErrorMessageExtraData() }}\n </div>\n @if (helpMessage()) {\n <small\n [hidden]=\"_showSuccess() || _showErrors()\"\n aria-live=\"assertive\"\n class=\"form-text text-muted\"\n >\n {{ helpMessage() | transloco }}\n </small>\n }\n</div>\n", styles: ["input::-webkit-search-cancel-button{-webkit-appearance:none;height:.75rem;width:.75rem;background-image:url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 3 1024 1024' width='12' height='12' fill='currentColor'%3E%3Cpath d='M9 1018q5 4 10.5 6.5 5.5 2.5 11.5 2.5 6 0 11.5-2.5 5.5-2.5 10.5-6.5l459-459 459 459q5 4 10.5 6.5 5.5 2.5 11.5 2.5 6 0 11.5-2.5 5.5-2.5 10.5-6.5 9-9 9-22 0-13-9-22l-459-459 459-459q9-9 9-22 0-13-9-22-9-9-22-9-13 0-22 9l-459 459-459-459q-9-9-22-9-13 0-22 9-9 9-9 22 0 13 9 22l459 459-459 459q-9 9-9 22 0 13 9 22l0 0z'/%3E%3C/svg%3E%0A\");cursor:pointer}::ng-deep .air-datepicker{z-index:99999}::ng-deep .air-datepicker.-inline-{z-index:unset}::ng-deep .air-datepicker .air-datepicker--pointer{display:none}::ng-deep .air-datepicker .air-datepicker-time{display:block}::ng-deep .air-datepicker .air-datepicker-time .air-datepicker-time--current{display:none}::ng-deep .air-datepicker .air-datepicker-time .air-datepicker-time--sliders{display:flex;justify-content:center;padding-top:.25rem;gap:1rem}::ng-deep .air-datepicker .air-datepicker-time .air-datepicker-time--sliders .air-datepicker-time--row{width:100%;position:relative}::ng-deep .air-datepicker .air-datepicker-time .air-datepicker-time--sliders .air-datepicker-time--row:first-child:after{content:\":\";display:inline;font-size:1rem;position:absolute;right:-.65rem}::ng-deep .air-datepicker .air-datepicker-time .air-datepicker-time--sliders .air-datepicker-time--row input{width:100%;text-align:center;padding:0;padding-left:1rem;border-color:var(--bs-border-color)}::ng-deep .air-datepicker .air-datepicker-time .air-datepicker-time--sliders .air-datepicker-time--row .form-control:focus{box-shadow:unset!important}::ng-deep .air-datepicker.-inline-.-only-timepicker-{border:0;padding:0!important}::ng-deep .air-datepicker.-inline-.-only-timepicker- .air-datepicker--time{border:0;padding:0!important}::ng-deep .air-datepicker.-inline-.-only-timepicker- .air-datepicker-time{padding:0!important}:host{display:block}:host .quang-date-inline-hidden{position:absolute!important;width:1px!important;height:1px!important;padding:0!important;margin:0!important;border:0!important;opacity:0!important;pointer-events:none!important;overflow:hidden!important;white-space:nowrap!important;clip:rect(0 0 0 0)!important;clip-path:inset(50%)!important}:host .input-date-container{display:flex}:host input{flex:1}:host input.with-button-calendar{border-top-right-radius:0;border-bottom-right-radius:0}:host input:disabled{border-radius:var(--bs-border-radius)}:host .btn-outline-calendar{border-left:0;border-top-left-radius:0;border-bottom-left-radius:0;min-width:unset;display:flex;border-color:var(--bs-border-color)}:host .border-danger{border-color:var(--bs-form-invalid-border-color)}:host .border-success{border-color:var(--bs-form-valid-border-color)}\n"] }]
|
|
534
|
+
}], ctorParameters: () => [] });
|
|
418
535
|
|
|
419
536
|
/**
|
|
420
537
|
* Generated bundle index. Do not edit.
|