@brickclay-org/ui 0.0.95 → 0.0.96
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/fesm2022/brickclay-org-ui.mjs +124 -202
- package/fesm2022/brickclay-org-ui.mjs.map +1 -1
- package/index.d.ts +8 -27
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { Component, EventEmitter, forwardRef, HostListener, ViewChildren,
|
|
2
|
+
import { Component, EventEmitter, forwardRef, HostListener, ViewChildren, Input, Output, Injectable, ViewChild, NgModule, ViewEncapsulation, Optional, Self, Directive, input, model, output, signal, computed, effect, inject, ElementRef, InjectionToken, createComponent, ChangeDetectionStrategy } from '@angular/core';
|
|
3
3
|
import * as i1 from '@angular/common';
|
|
4
4
|
import { CommonModule, NgClass } from '@angular/common';
|
|
5
5
|
import * as i3 from '@angular/forms';
|
|
@@ -44,55 +44,47 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
44
44
|
|
|
45
45
|
class BkTimePicker {
|
|
46
46
|
required = false;
|
|
47
|
-
/** @deprecated Prefer [(ngModel)]
|
|
48
|
-
value = null;
|
|
47
|
+
/** @deprecated Prefer [(ngModel)] */
|
|
48
|
+
value = null;
|
|
49
49
|
label = '';
|
|
50
50
|
placeholder = 'Select time';
|
|
51
51
|
clearable = false;
|
|
52
52
|
position = 'left';
|
|
53
|
-
pickerId = '';
|
|
54
|
-
closePicker = 0;
|
|
55
|
-
timeFormat = 12;
|
|
56
|
-
showSeconds = false;
|
|
53
|
+
pickerId = '';
|
|
54
|
+
closePicker = 0;
|
|
55
|
+
timeFormat = 12;
|
|
56
|
+
showSeconds = false;
|
|
57
57
|
change = new EventEmitter();
|
|
58
|
-
/** Alias for (change) for backward compatibility */
|
|
59
58
|
timeChange = new EventEmitter();
|
|
60
|
-
pickerOpened = new EventEmitter();
|
|
61
|
-
pickerClosed = new EventEmitter();
|
|
62
|
-
/** CVA: called when the control value is set (e.g. ngModel or programmatic) */
|
|
59
|
+
pickerOpened = new EventEmitter();
|
|
60
|
+
pickerClosed = new EventEmitter();
|
|
63
61
|
onChange = () => { };
|
|
64
|
-
/** CVA: called when the control is touched (blur / close picker) */
|
|
65
62
|
onTouched = () => { };
|
|
66
63
|
disabled = false;
|
|
67
64
|
timeScrollElements;
|
|
68
65
|
minuteScrollElements;
|
|
69
66
|
secondScrollElements;
|
|
70
|
-
/** Cyclic wheel: item height and cycle size (0-59). Middle block starts at CYCLE_SIZE * ITEM_HEIGHT */
|
|
71
67
|
ITEM_HEIGHT = 32;
|
|
72
68
|
WHEEL_CYCLE = 60;
|
|
73
|
-
MIDDLE_OFFSET = this.WHEEL_CYCLE * this.ITEM_HEIGHT;
|
|
74
|
-
VIEWPORT_HEIGHT = 95;
|
|
75
|
-
/** Repeated 0-59 for infinite scroll (minutes and seconds) */
|
|
69
|
+
MIDDLE_OFFSET = this.WHEEL_CYCLE * this.ITEM_HEIGHT;
|
|
76
70
|
wheelMinutes = Array.from({ length: this.WHEEL_CYCLE * 3 }, (_, i) => i % this.WHEEL_CYCLE);
|
|
77
71
|
wheelSeconds = Array.from({ length: this.WHEEL_CYCLE * 3 }, (_, i) => i % this.WHEEL_CYCLE);
|
|
78
72
|
showPicker = false;
|
|
79
73
|
currentHour = 12;
|
|
80
74
|
currentMinute = 0;
|
|
81
|
-
currentAMPM = 'PM';
|
|
82
75
|
currentSecond = 0;
|
|
83
|
-
|
|
76
|
+
currentAMPM = 'PM';
|
|
84
77
|
_modelValue = null;
|
|
85
78
|
brickclayIcons = BrickclayIcons;
|
|
86
|
-
|
|
79
|
+
/* ---------------- CVA ---------------- */
|
|
87
80
|
writeValue(value) {
|
|
88
|
-
if (value
|
|
81
|
+
if (!value) {
|
|
89
82
|
this._modelValue = null;
|
|
90
83
|
this.setDefaultsForDropdown();
|
|
84
|
+
return;
|
|
91
85
|
}
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
this.parseTimeValue(value);
|
|
95
|
-
}
|
|
86
|
+
this._modelValue = value;
|
|
87
|
+
this.parseTimeValue(value);
|
|
96
88
|
}
|
|
97
89
|
registerOnChange(fn) {
|
|
98
90
|
this.onChange = fn;
|
|
@@ -103,17 +95,16 @@ class BkTimePicker {
|
|
|
103
95
|
setDisabledState(isDisabled) {
|
|
104
96
|
this.disabled = isDisabled;
|
|
105
97
|
}
|
|
106
|
-
|
|
98
|
+
/* ---------------- Display ---------------- */
|
|
107
99
|
getDisplayValue() {
|
|
108
|
-
if (this._modelValue
|
|
100
|
+
if (!this._modelValue)
|
|
109
101
|
return '';
|
|
110
102
|
return this.formatTimeFromComponents(this.currentHour, this.currentMinute, this.currentSecond, this.currentAMPM);
|
|
111
103
|
}
|
|
112
|
-
/** True when a time is selected (show clear button). */
|
|
113
104
|
get hasValue() {
|
|
114
|
-
return this._modelValue
|
|
105
|
+
return !!this._modelValue;
|
|
115
106
|
}
|
|
116
|
-
|
|
107
|
+
/* ---------------- Defaults ---------------- */
|
|
117
108
|
setDefaultsForDropdown() {
|
|
118
109
|
if (this.timeFormat === 24) {
|
|
119
110
|
this.currentHour = 0;
|
|
@@ -125,7 +116,6 @@ class BkTimePicker {
|
|
|
125
116
|
this.currentMinute = 0;
|
|
126
117
|
this.currentSecond = 0;
|
|
127
118
|
}
|
|
128
|
-
/** Clear the time value and notify CVA. */
|
|
129
119
|
clear() {
|
|
130
120
|
this._modelValue = null;
|
|
131
121
|
this.value = null;
|
|
@@ -135,24 +125,36 @@ class BkTimePicker {
|
|
|
135
125
|
this.timeChange.emit(null);
|
|
136
126
|
this.markAsTouched();
|
|
137
127
|
}
|
|
138
|
-
/** Call when control loses focus or picker closes (for CVA touched state). */
|
|
139
128
|
markAsTouched() {
|
|
140
129
|
this.onTouched();
|
|
141
130
|
}
|
|
131
|
+
/* ---------------- Lifecycle ---------------- */
|
|
142
132
|
ngOnInit() {
|
|
143
|
-
this.parseTimeValue();
|
|
133
|
+
this.parseTimeValue(this._modelValue ?? this.value);
|
|
144
134
|
}
|
|
145
135
|
ngAfterViewInit() {
|
|
146
136
|
if (this.showPicker) {
|
|
147
|
-
setTimeout(() =>
|
|
148
|
-
|
|
149
|
-
|
|
137
|
+
setTimeout(() => this.scrollToSelectedTimes(), 100);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
ngOnChanges(changes) {
|
|
141
|
+
if (changes['value'] && !this._modelValue) {
|
|
142
|
+
this.parseTimeValue(this.value);
|
|
143
|
+
}
|
|
144
|
+
if (changes['closePicker'] && this.showPicker) {
|
|
145
|
+
const newCounter = changes['closePicker'].currentValue;
|
|
146
|
+
if (newCounter > this.previousCloseCounter) {
|
|
147
|
+
this.showPicker = false;
|
|
148
|
+
this.markAsTouched();
|
|
149
|
+
this.pickerClosed.emit(this.pickerId);
|
|
150
|
+
this.previousCloseCounter = newCounter;
|
|
151
|
+
}
|
|
150
152
|
}
|
|
151
153
|
}
|
|
152
|
-
|
|
154
|
+
/* ---------------- Parse Logic ---------------- */
|
|
153
155
|
parseTimeValue(timeStr) {
|
|
154
|
-
const str = timeStr ?? this.value ?? '';
|
|
155
|
-
if (str
|
|
156
|
+
const str = timeStr ?? this._modelValue ?? this.value ?? '';
|
|
157
|
+
if (!str) {
|
|
156
158
|
this._modelValue = null;
|
|
157
159
|
this.setDefaultsForDropdown();
|
|
158
160
|
return;
|
|
@@ -164,103 +166,63 @@ class BkTimePicker {
|
|
|
164
166
|
this.currentSecond = parsed.second;
|
|
165
167
|
this.currentAMPM = parsed.ampm;
|
|
166
168
|
}
|
|
167
|
-
getHours() {
|
|
168
|
-
// 12-hour: 1-12, 24-hour: 0-23
|
|
169
|
-
if (this.timeFormat === 24) {
|
|
170
|
-
return Array.from({ length: 24 }, (_, i) => i);
|
|
171
|
-
}
|
|
172
|
-
return Array.from({ length: 12 }, (_, i) => i + 1);
|
|
173
|
-
}
|
|
174
|
-
getMinutes() {
|
|
175
|
-
return Array.from({ length: 60 }, (_, i) => i);
|
|
176
|
-
}
|
|
177
|
-
getSeconds() {
|
|
178
|
-
return Array.from({ length: 60 }, (_, i) => i);
|
|
179
|
-
}
|
|
180
|
-
getAMPMOptions() {
|
|
181
|
-
return ['AM', 'PM'];
|
|
182
|
-
}
|
|
183
169
|
parseTimeStringToComponents(timeStr) {
|
|
184
|
-
// Supports:
|
|
185
|
-
// - "H:MM AM/PM"
|
|
186
|
-
// - "H:MM:SS AM/PM"
|
|
187
|
-
// - "HH:MM" (24h)
|
|
188
|
-
// - "HH:MM:SS" (24h)
|
|
189
|
-
if (!timeStr) {
|
|
190
|
-
return {
|
|
191
|
-
hour: this.timeFormat === 24 ? 0 : 12,
|
|
192
|
-
minute: 0,
|
|
193
|
-
second: 0,
|
|
194
|
-
ampm: this.timeFormat === 24 ? '' : 'PM'
|
|
195
|
-
};
|
|
196
|
-
}
|
|
197
170
|
const parts = timeStr.trim().split(' ');
|
|
198
|
-
const timePart = parts[0]
|
|
171
|
+
const timePart = parts[0];
|
|
199
172
|
let ampm = (parts[1] || '').toUpperCase();
|
|
200
|
-
const [
|
|
201
|
-
let hour = parseInt(
|
|
202
|
-
const minute = parseInt(
|
|
203
|
-
const second = parseInt(
|
|
173
|
+
const [h, m, s] = timePart.split(':');
|
|
174
|
+
let hour = parseInt(h || '0', 10);
|
|
175
|
+
const minute = parseInt(m || '0', 10);
|
|
176
|
+
const second = parseInt(s || '0', 10);
|
|
204
177
|
if (this.timeFormat === 24) {
|
|
205
|
-
// In 24-hour mode we ignore AM/PM and keep hour as 0-23
|
|
206
178
|
return {
|
|
207
|
-
hour:
|
|
208
|
-
minute:
|
|
209
|
-
second:
|
|
179
|
+
hour: Math.min(Math.max(hour, 0), 23),
|
|
180
|
+
minute: Math.min(Math.max(minute, 0), 59),
|
|
181
|
+
second: Math.min(Math.max(second, 0), 59),
|
|
210
182
|
ampm: ''
|
|
211
183
|
};
|
|
212
184
|
}
|
|
213
|
-
|
|
214
|
-
let ampmValue = ampm === 'PM' || ampm === 'AM' ? ampm : '';
|
|
215
|
-
if (!ampmValue) {
|
|
216
|
-
// No AM/PM provided -> interpret as 24-hour and convert to 12-hour with AM/PM
|
|
185
|
+
if (!ampm) {
|
|
217
186
|
if (hour >= 12) {
|
|
218
|
-
|
|
187
|
+
ampm = 'PM';
|
|
219
188
|
if (hour > 12)
|
|
220
189
|
hour -= 12;
|
|
221
190
|
}
|
|
222
191
|
else {
|
|
223
|
-
|
|
192
|
+
ampm = 'AM';
|
|
224
193
|
if (hour === 0)
|
|
225
194
|
hour = 12;
|
|
226
195
|
}
|
|
227
196
|
}
|
|
228
|
-
// Clamp to 1-12 range
|
|
229
197
|
if (hour < 1)
|
|
230
198
|
hour = 1;
|
|
231
199
|
if (hour > 12)
|
|
232
200
|
hour = 12;
|
|
233
201
|
return {
|
|
234
202
|
hour,
|
|
235
|
-
minute
|
|
236
|
-
second
|
|
237
|
-
ampm
|
|
203
|
+
minute,
|
|
204
|
+
second,
|
|
205
|
+
ampm
|
|
238
206
|
};
|
|
239
207
|
}
|
|
240
208
|
formatTimeFromComponents(hour, minute, second, ampm) {
|
|
241
209
|
const hStr = hour.toString().padStart(2, '0');
|
|
242
|
-
const
|
|
243
|
-
const
|
|
210
|
+
const mStr = minute.toString().padStart(2, '0');
|
|
211
|
+
const sStr = second.toString().padStart(2, '0');
|
|
244
212
|
if (this.timeFormat === 24) {
|
|
245
|
-
|
|
246
|
-
return this.showSeconds
|
|
247
|
-
? `${hStr}:${minuteStr}:${secondStr}`
|
|
248
|
-
: `${hStr}:${minuteStr}`;
|
|
213
|
+
return this.showSeconds ? `${hStr}:${mStr}:${sStr}` : `${hStr}:${mStr}`;
|
|
249
214
|
}
|
|
250
|
-
// 12-hour: "H:MM" or "H:MM:SS" with AM/PM
|
|
251
|
-
const displayHour = hour; // already 1-12
|
|
252
215
|
return this.showSeconds
|
|
253
|
-
? `${
|
|
254
|
-
: `${
|
|
216
|
+
? `${hour}:${mStr}:${sStr} ${ampm}`
|
|
217
|
+
: `${hour}:${mStr} ${ampm}`;
|
|
255
218
|
}
|
|
219
|
+
/* ---------------- Picker ---------------- */
|
|
256
220
|
togglePicker() {
|
|
257
221
|
if (!this.showPicker) {
|
|
258
222
|
this.showPicker = true;
|
|
259
|
-
this.parseTimeValue();
|
|
223
|
+
this.parseTimeValue(this._modelValue);
|
|
260
224
|
this.pickerOpened.emit(this.pickerId);
|
|
261
|
-
setTimeout(() =>
|
|
262
|
-
this.scrollToSelectedTimes();
|
|
263
|
-
}, 100);
|
|
225
|
+
setTimeout(() => this.scrollToSelectedTimes(), 100);
|
|
264
226
|
}
|
|
265
227
|
else {
|
|
266
228
|
this.showPicker = false;
|
|
@@ -268,33 +230,22 @@ class BkTimePicker {
|
|
|
268
230
|
this.pickerClosed.emit(this.pickerId);
|
|
269
231
|
}
|
|
270
232
|
}
|
|
233
|
+
/* ---------------- Change handlers ---------------- */
|
|
271
234
|
onHourChange(hour) {
|
|
272
235
|
this.currentHour = hour;
|
|
273
236
|
this.updateTime();
|
|
274
|
-
setTimeout(() => {
|
|
275
|
-
this.scrollToSelectedTimes();
|
|
276
|
-
}, 50);
|
|
277
237
|
}
|
|
278
238
|
onMinuteChange(minute) {
|
|
279
239
|
this.currentMinute = minute;
|
|
280
240
|
this.updateTime();
|
|
281
|
-
setTimeout(() => {
|
|
282
|
-
this.scrollToSelectedTimes();
|
|
283
|
-
}, 50);
|
|
284
241
|
}
|
|
285
242
|
onSecondChange(second) {
|
|
286
243
|
this.currentSecond = second;
|
|
287
244
|
this.updateTime();
|
|
288
|
-
setTimeout(() => {
|
|
289
|
-
this.scrollToSelectedTimes();
|
|
290
|
-
}, 50);
|
|
291
245
|
}
|
|
292
246
|
onAMPMChange(ampm) {
|
|
293
247
|
this.currentAMPM = ampm;
|
|
294
248
|
this.updateTime();
|
|
295
|
-
setTimeout(() => {
|
|
296
|
-
this.scrollToSelectedTimes();
|
|
297
|
-
}, 50);
|
|
298
249
|
}
|
|
299
250
|
updateTime() {
|
|
300
251
|
const newTime = this.formatTimeFromComponents(this.currentHour, this.currentMinute, this.currentSecond, this.currentAMPM);
|
|
@@ -304,38 +255,57 @@ class BkTimePicker {
|
|
|
304
255
|
this.change.emit(newTime);
|
|
305
256
|
this.timeChange.emit(newTime);
|
|
306
257
|
}
|
|
258
|
+
/* ---------------- Scroll ---------------- */
|
|
307
259
|
scrollToSelectedTimes() {
|
|
308
|
-
this.timeScrollElements.forEach((
|
|
309
|
-
const element =
|
|
310
|
-
const
|
|
311
|
-
if (
|
|
312
|
-
|
|
313
|
-
|
|
260
|
+
this.timeScrollElements.forEach((elRef) => {
|
|
261
|
+
const element = elRef.nativeElement;
|
|
262
|
+
const selected = element.querySelector('.time-item.selected');
|
|
263
|
+
if (selected) {
|
|
264
|
+
element.scrollTop =
|
|
265
|
+
selected.offsetTop -
|
|
266
|
+
element.offsetHeight / 2 +
|
|
267
|
+
selected.offsetHeight / 2;
|
|
314
268
|
}
|
|
315
269
|
});
|
|
316
270
|
this.initMinuteWheelScroll();
|
|
317
271
|
if (this.showSeconds)
|
|
318
272
|
this.initSecondWheelScroll();
|
|
319
273
|
}
|
|
320
|
-
/** Position wheel so the selected value is at the top of the viewport. */
|
|
321
274
|
initMinuteWheelScroll() {
|
|
322
|
-
const
|
|
323
|
-
if (!
|
|
275
|
+
const el = this.minuteScrollElements?.first?.nativeElement;
|
|
276
|
+
if (!el)
|
|
324
277
|
return;
|
|
325
|
-
|
|
326
|
-
const scrollTop = this.MIDDLE_OFFSET + this.currentMinute * this.ITEM_HEIGHT;
|
|
327
|
-
el.scrollTop = Math.max(0, scrollTop);
|
|
278
|
+
el.scrollTop = this.MIDDLE_OFFSET + this.currentMinute * this.ITEM_HEIGHT;
|
|
328
279
|
}
|
|
329
280
|
initSecondWheelScroll() {
|
|
330
|
-
const
|
|
331
|
-
if (!
|
|
281
|
+
const el = this.secondScrollElements?.first?.nativeElement;
|
|
282
|
+
if (!el)
|
|
332
283
|
return;
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
284
|
+
el.scrollTop = this.MIDDLE_OFFSET + this.currentSecond * this.ITEM_HEIGHT;
|
|
285
|
+
}
|
|
286
|
+
/* ---------------- Outside click ---------------- */
|
|
287
|
+
onDocumentClick(event) {
|
|
288
|
+
const target = event.target;
|
|
289
|
+
if (!target.closest('.time-picker-wrapper') && this.showPicker) {
|
|
290
|
+
this.showPicker = false;
|
|
291
|
+
this.markAsTouched();
|
|
292
|
+
this.pickerClosed.emit(this.pickerId);
|
|
293
|
+
}
|
|
336
294
|
}
|
|
337
|
-
|
|
338
|
-
|
|
295
|
+
previousCloseCounter = 0;
|
|
296
|
+
getHours() {
|
|
297
|
+
if (this.timeFormat === 24) {
|
|
298
|
+
return Array.from({ length: 24 }, (_, i) => i);
|
|
299
|
+
}
|
|
300
|
+
return Array.from({ length: 12 }, (_, i) => i + 1);
|
|
301
|
+
}
|
|
302
|
+
getAMPMOptions() {
|
|
303
|
+
return ['PM', 'AM'];
|
|
304
|
+
}
|
|
305
|
+
onMinuteWheelScroll() {
|
|
306
|
+
const el = this.minuteScrollElements?.first?.nativeElement;
|
|
307
|
+
if (!el)
|
|
308
|
+
return;
|
|
339
309
|
let scrollTop = el.scrollTop;
|
|
340
310
|
const maxScroll = this.MIDDLE_OFFSET * 2 - 50;
|
|
341
311
|
if (scrollTop < this.MIDDLE_OFFSET - 100) {
|
|
@@ -348,90 +318,40 @@ class BkTimePicker {
|
|
|
348
318
|
}
|
|
349
319
|
const index = Math.round(scrollTop / this.ITEM_HEIGHT);
|
|
350
320
|
const value = ((index % this.WHEEL_CYCLE) + this.WHEEL_CYCLE) % this.WHEEL_CYCLE;
|
|
351
|
-
if (value !==
|
|
352
|
-
|
|
321
|
+
if (value !== this.currentMinute) {
|
|
322
|
+
this.currentMinute = value;
|
|
353
323
|
this.updateTime();
|
|
354
324
|
}
|
|
355
325
|
}
|
|
356
|
-
onMinuteWheelScroll() {
|
|
357
|
-
const list = this.minuteScrollElements?.toArray();
|
|
358
|
-
if (!list?.length)
|
|
359
|
-
return;
|
|
360
|
-
this.wheelScrollToValue(list[0].nativeElement, this.currentMinute, (v) => this.currentMinute = v);
|
|
361
|
-
}
|
|
362
326
|
onSecondWheelScroll() {
|
|
363
|
-
const
|
|
364
|
-
if (!
|
|
365
|
-
return;
|
|
366
|
-
this.wheelScrollToValue(list[0].nativeElement, this.currentSecond, (v) => this.currentSecond = v);
|
|
367
|
-
}
|
|
368
|
-
onDocumentClick(event) {
|
|
369
|
-
const target = event.target;
|
|
370
|
-
if (!target.closest('.time-picker-wrapper') && this.showPicker) {
|
|
371
|
-
this.showPicker = false;
|
|
372
|
-
this.markAsTouched();
|
|
373
|
-
this.pickerClosed.emit(this.pickerId);
|
|
374
|
-
}
|
|
375
|
-
}
|
|
376
|
-
previousCloseCounter = 0;
|
|
377
|
-
ngOnChanges(changes) {
|
|
378
|
-
if (changes['value']) {
|
|
379
|
-
this.parseTimeValue(this.value ?? '');
|
|
380
|
-
}
|
|
381
|
-
if (changes['closePicker'] && this.showPicker) {
|
|
382
|
-
const newCounter = changes['closePicker'].currentValue;
|
|
383
|
-
// If counter increased, close the picker
|
|
384
|
-
if (newCounter > this.previousCloseCounter) {
|
|
385
|
-
this.showPicker = false;
|
|
386
|
-
this.markAsTouched();
|
|
387
|
-
this.pickerClosed.emit(this.pickerId);
|
|
388
|
-
this.previousCloseCounter = newCounter;
|
|
389
|
-
}
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
// Basic keyboard support on the input (combobox behavior)
|
|
393
|
-
onInputKeydown(event) {
|
|
394
|
-
const key = event.key;
|
|
395
|
-
if (key === 'Enter' || key === ' ') {
|
|
396
|
-
event.preventDefault();
|
|
397
|
-
this.togglePicker();
|
|
327
|
+
const el = this.secondScrollElements?.first?.nativeElement;
|
|
328
|
+
if (!el)
|
|
398
329
|
return;
|
|
330
|
+
let scrollTop = el.scrollTop;
|
|
331
|
+
const maxScroll = this.MIDDLE_OFFSET * 2 - 50;
|
|
332
|
+
if (scrollTop < this.MIDDLE_OFFSET - 100) {
|
|
333
|
+
scrollTop += this.MIDDLE_OFFSET;
|
|
334
|
+
el.scrollTop = scrollTop;
|
|
399
335
|
}
|
|
400
|
-
if (
|
|
401
|
-
this.
|
|
402
|
-
|
|
403
|
-
return;
|
|
336
|
+
else if (scrollTop > maxScroll) {
|
|
337
|
+
scrollTop -= this.MIDDLE_OFFSET;
|
|
338
|
+
el.scrollTop = scrollTop;
|
|
404
339
|
}
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
if (key === 'ArrowUp') {
|
|
410
|
-
this.currentHour = (this.currentHour + 1) % 24;
|
|
411
|
-
}
|
|
412
|
-
else {
|
|
413
|
-
this.currentHour = this.currentHour <= 0 ? 23 : this.currentHour - 1;
|
|
414
|
-
}
|
|
415
|
-
}
|
|
416
|
-
else {
|
|
417
|
-
if (key === 'ArrowUp') {
|
|
418
|
-
this.currentHour = this.currentHour >= 12 ? 1 : this.currentHour + 1;
|
|
419
|
-
}
|
|
420
|
-
else {
|
|
421
|
-
this.currentHour = this.currentHour <= 1 ? 12 : this.currentHour - 1;
|
|
422
|
-
}
|
|
423
|
-
}
|
|
340
|
+
const index = Math.round(scrollTop / this.ITEM_HEIGHT);
|
|
341
|
+
const value = ((index % this.WHEEL_CYCLE) + this.WHEEL_CYCLE) % this.WHEEL_CYCLE;
|
|
342
|
+
if (value !== this.currentSecond) {
|
|
343
|
+
this.currentSecond = value;
|
|
424
344
|
this.updateTime();
|
|
425
345
|
}
|
|
426
346
|
}
|
|
427
347
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkTimePicker, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
428
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: BkTimePicker, isStandalone: true, selector: "bk-time-picker", inputs: { required: "required", value: "value", label: "label", placeholder: "placeholder", clearable: "clearable", position: "position", pickerId: "pickerId", closePicker: "closePicker", timeFormat: "timeFormat", showSeconds: "showSeconds" }, outputs: { change: "change", timeChange: "timeChange", pickerOpened: "pickerOpened", pickerClosed: "pickerClosed" }, host: { listeners: { "document:click": "onDocumentClick($event)" } }, providers: [
|
|
348
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: BkTimePicker, isStandalone: true, selector: "bk-time-picker", inputs: { required: "required", value: "value", label: "label", placeholder: "placeholder", clearable: "clearable", position: "position", pickerId: "pickerId", closePicker: "closePicker", timeFormat: "timeFormat", showSeconds: "showSeconds", disabled: "disabled" }, outputs: { change: "change", timeChange: "timeChange", pickerOpened: "pickerOpened", pickerClosed: "pickerClosed" }, host: { listeners: { "document:click": "onDocumentClick($event)" } }, providers: [
|
|
429
349
|
{
|
|
430
350
|
provide: NG_VALUE_ACCESSOR,
|
|
431
351
|
useExisting: forwardRef(() => BkTimePicker),
|
|
432
352
|
multi: true,
|
|
433
353
|
},
|
|
434
|
-
], viewQueries: [{ propertyName: "timeScrollElements", predicate: ["timeScroll"], descendants: true }, { propertyName: "minuteScrollElements", predicate: ["minuteScroll"], descendants: true }, { propertyName: "secondScrollElements", predicate: ["secondScroll"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"time-picker-wrapper\">\
|
|
354
|
+
], viewQueries: [{ propertyName: "timeScrollElements", predicate: ["timeScroll"], descendants: true }, { propertyName: "minuteScrollElements", predicate: ["minuteScroll"], descendants: true }, { propertyName: "secondScrollElements", predicate: ["secondScroll"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"time-picker-wrapper\">\n <div class=\"time-input-group\">\n @if(label){\n <label>{{ label }}</label>\n }\n <div class=\"time-input-wrapper\" [class.has-value]=\"hasValue\">\n <input\n type=\"text\"\n class=\"time-input\"\n [value]=\"getDisplayValue()\"\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled ? true : null\"\n readonly\n (click)=\"!disabled && togglePicker()\"\n (blur)=\"markAsTouched()\">\n <span class=\"time-icon\">\n <img alt=\"timer\" class=\"timer-icon\" [src]='brickclayIcons.timerIcon'/>\n </span>\n <button\n type=\"button\"\n class=\"time-clear-btn\"\n *ngIf=\"clearable && hasValue && !disabled\"\n (click)=\"clear(); $event.stopPropagation()\"\n title=\"Clear time\"\n aria-label=\"Clear time\">\u00D7</button>\n <div class=\"custom-time-picker-dropdown\" *ngIf=\"showPicker\">\n <div class=\"custom-time-picker\" [ngClass]=\"{\n 'left-position': position === 'left',\n 'right-position': position === 'right',\n 'format-24': timeFormat === 24\n }\">\n <!-- Hours Column -->\n <div class=\"time-column\">\n <div class=\"time-scroll\" #timeScroll>\n <div\n *ngFor=\"let h of getHours()\"\n class=\"time-item\"\n [class.selected]=\"currentHour === h\"\n (click)=\"onHourChange(h)\">\n {{ h.toString().padStart(2, '0') }}\n </div>\n </div>\n </div>\n <span class=\"time-separator\">:</span>\n <!-- Minutes Column (cyclic wheel: 59 -> 00) -->\n <div class=\"time-column\">\n <div class=\"time-scroll time-wheel\" #minuteScroll (scroll)=\"onMinuteWheelScroll()\">\n <div\n *ngFor=\"let m of wheelMinutes\"\n class=\"time-item\"\n [class.selected]=\"currentMinute === m\"\n (click)=\"onMinuteChange(m)\">\n {{ m.toString().padStart(2, '0') }}\n </div>\n </div>\n </div>\n @if (showSeconds) {\n <span class=\"time-separator\">:</span>\n <!-- Seconds Column (cyclic wheel: 59 -> 00) -->\n <div class=\"time-column\">\n <div class=\"time-scroll time-wheel\" #secondScroll (scroll)=\"onSecondWheelScroll()\">\n <div\n *ngFor=\"let s of wheelSeconds\"\n class=\"time-item\"\n [class.selected]=\"currentSecond === s\"\n (click)=\"onSecondChange(s)\">\n {{ s.toString().padStart(2, '0') }}\n </div>\n </div>\n </div>\n }\n <!-- AM/PM Column (only in 12-hour format) -->\n @if (timeFormat === 12) {\n <span class=\"time-separator\">:</span>\n <div class=\"time-column ampm-column\">\n <div class=\"time-scroll\" #timeScroll>\n <div\n *ngFor=\"let ap of getAMPMOptions()\"\n class=\"time-item\"\n [class.selected]=\"currentAMPM === ap\"\n (click)=\"onAMPMChange(ap)\">\n {{ ap }}\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n</div>\n\n", styles: [".time-picker-wrapper{width:100%;font-family:Inter,sans-serif}.time-input-group{display:flex;flex-direction:column;gap:4px}.time-input-group label{font-size:11px;font-weight:500;color:#15191e;text-transform:uppercase;letter-spacing:-.28px}.time-input-wrapper{position:relative;display:flex;align-items:center}.time-input-wrapper.has-value .time-input{padding-right:56px}.time-input{padding:8px 40px 8px 12px;border:1px solid #d1d5db;border-radius:4px;font-size:12px;font-family:Inter,sans-serif;color:#6f737b;background:#fff;transition:all .2s;width:100%;box-sizing:border-box;cursor:pointer}.time-input:focus{outline:none;border-color:#111827;box-shadow:0 0 0 3px #1118271a}.time-input:hover{border-color:#9ca3af}.time-clear-btn{position:absolute;right:26px;background:none;border:none;font-size:18px;color:#9ca3af;cursor:pointer;padding:0;width:20px;height:20px;display:flex;align-items:center;justify-content:center;line-height:1;top:7px}.time-clear-btn:hover{color:#374151}.time-icon{position:absolute;right:12px;font-size:16px;pointer-events:none;color:#9ca3af;cursor:pointer}.custom-time-picker-wrapper{width:100%;display:flex;justify-content:center}.custom-time-picker{display:flex;align-items:flex-start;gap:8px;background:#fff;border:1px solid #e5e7eb;border-radius:8px;padding:10px;box-shadow:0 4px 12px #00000026;width:182px;position:absolute;top:calc(100% + 4px);z-index:1000}.custom-time-picker.format-24{width:124px}.custom-time-picker.left-position{left:0}.custom-time-picker.right-position{right:0}.time-column{display:flex;flex-direction:column;position:relative}.time-scroll{display:flex;flex-direction:column;max-height:95px;overflow-y:auto;overflow-x:hidden;scrollbar-width:thin;scrollbar-color:#cbd5e1 transparent;scrollbar-width:none;-ms-overflow-style:none}.time-scroll::-webkit-scrollbar{display:none}.time-scroll::-webkit-scrollbar-track{background:transparent}.time-scroll::-webkit-scrollbar-thumb{background:#cbd5e1;border-radius:2px}.time-scroll::-webkit-scrollbar-thumb:hover{background:#94a3b8}.time-item{min-width:40px;width:40px;height:32px;min-height:32px;display:flex;align-items:center;justify-content:center;font-size:14px;font-weight:400;color:#374151;cursor:pointer;border-radius:4px;transition:all .15s ease;-webkit-user-select:none;user-select:none;font-family:Inter,sans-serif}.time-item:hover{background:#f3f4f6}.time-item.selected{background:#111827;color:#fff;font-weight:500;box-shadow:0 1px 2px #2563eb4d}.ampm-column .time-item{min-width:40px;width:40px}.time-separator{font-size:16px;font-weight:600;color:#6b7280;margin:5px 0 0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }] });
|
|
435
355
|
}
|
|
436
356
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkTimePicker, decorators: [{
|
|
437
357
|
type: Component,
|
|
@@ -441,7 +361,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
441
361
|
useExisting: forwardRef(() => BkTimePicker),
|
|
442
362
|
multi: true,
|
|
443
363
|
},
|
|
444
|
-
], template: "<div class=\"time-picker-wrapper\">\
|
|
364
|
+
], template: "<div class=\"time-picker-wrapper\">\n <div class=\"time-input-group\">\n @if(label){\n <label>{{ label }}</label>\n }\n <div class=\"time-input-wrapper\" [class.has-value]=\"hasValue\">\n <input\n type=\"text\"\n class=\"time-input\"\n [value]=\"getDisplayValue()\"\n [placeholder]=\"placeholder\"\n [disabled]=\"disabled ? true : null\"\n readonly\n (click)=\"!disabled && togglePicker()\"\n (blur)=\"markAsTouched()\">\n <span class=\"time-icon\">\n <img alt=\"timer\" class=\"timer-icon\" [src]='brickclayIcons.timerIcon'/>\n </span>\n <button\n type=\"button\"\n class=\"time-clear-btn\"\n *ngIf=\"clearable && hasValue && !disabled\"\n (click)=\"clear(); $event.stopPropagation()\"\n title=\"Clear time\"\n aria-label=\"Clear time\">\u00D7</button>\n <div class=\"custom-time-picker-dropdown\" *ngIf=\"showPicker\">\n <div class=\"custom-time-picker\" [ngClass]=\"{\n 'left-position': position === 'left',\n 'right-position': position === 'right',\n 'format-24': timeFormat === 24\n }\">\n <!-- Hours Column -->\n <div class=\"time-column\">\n <div class=\"time-scroll\" #timeScroll>\n <div\n *ngFor=\"let h of getHours()\"\n class=\"time-item\"\n [class.selected]=\"currentHour === h\"\n (click)=\"onHourChange(h)\">\n {{ h.toString().padStart(2, '0') }}\n </div>\n </div>\n </div>\n <span class=\"time-separator\">:</span>\n <!-- Minutes Column (cyclic wheel: 59 -> 00) -->\n <div class=\"time-column\">\n <div class=\"time-scroll time-wheel\" #minuteScroll (scroll)=\"onMinuteWheelScroll()\">\n <div\n *ngFor=\"let m of wheelMinutes\"\n class=\"time-item\"\n [class.selected]=\"currentMinute === m\"\n (click)=\"onMinuteChange(m)\">\n {{ m.toString().padStart(2, '0') }}\n </div>\n </div>\n </div>\n @if (showSeconds) {\n <span class=\"time-separator\">:</span>\n <!-- Seconds Column (cyclic wheel: 59 -> 00) -->\n <div class=\"time-column\">\n <div class=\"time-scroll time-wheel\" #secondScroll (scroll)=\"onSecondWheelScroll()\">\n <div\n *ngFor=\"let s of wheelSeconds\"\n class=\"time-item\"\n [class.selected]=\"currentSecond === s\"\n (click)=\"onSecondChange(s)\">\n {{ s.toString().padStart(2, '0') }}\n </div>\n </div>\n </div>\n }\n <!-- AM/PM Column (only in 12-hour format) -->\n @if (timeFormat === 12) {\n <span class=\"time-separator\">:</span>\n <div class=\"time-column ampm-column\">\n <div class=\"time-scroll\" #timeScroll>\n <div\n *ngFor=\"let ap of getAMPMOptions()\"\n class=\"time-item\"\n [class.selected]=\"currentAMPM === ap\"\n (click)=\"onAMPMChange(ap)\">\n {{ ap }}\n </div>\n </div>\n </div>\n }\n </div>\n </div>\n </div>\n </div>\n</div>\n\n", styles: [".time-picker-wrapper{width:100%;font-family:Inter,sans-serif}.time-input-group{display:flex;flex-direction:column;gap:4px}.time-input-group label{font-size:11px;font-weight:500;color:#15191e;text-transform:uppercase;letter-spacing:-.28px}.time-input-wrapper{position:relative;display:flex;align-items:center}.time-input-wrapper.has-value .time-input{padding-right:56px}.time-input{padding:8px 40px 8px 12px;border:1px solid #d1d5db;border-radius:4px;font-size:12px;font-family:Inter,sans-serif;color:#6f737b;background:#fff;transition:all .2s;width:100%;box-sizing:border-box;cursor:pointer}.time-input:focus{outline:none;border-color:#111827;box-shadow:0 0 0 3px #1118271a}.time-input:hover{border-color:#9ca3af}.time-clear-btn{position:absolute;right:26px;background:none;border:none;font-size:18px;color:#9ca3af;cursor:pointer;padding:0;width:20px;height:20px;display:flex;align-items:center;justify-content:center;line-height:1;top:7px}.time-clear-btn:hover{color:#374151}.time-icon{position:absolute;right:12px;font-size:16px;pointer-events:none;color:#9ca3af;cursor:pointer}.custom-time-picker-wrapper{width:100%;display:flex;justify-content:center}.custom-time-picker{display:flex;align-items:flex-start;gap:8px;background:#fff;border:1px solid #e5e7eb;border-radius:8px;padding:10px;box-shadow:0 4px 12px #00000026;width:182px;position:absolute;top:calc(100% + 4px);z-index:1000}.custom-time-picker.format-24{width:124px}.custom-time-picker.left-position{left:0}.custom-time-picker.right-position{right:0}.time-column{display:flex;flex-direction:column;position:relative}.time-scroll{display:flex;flex-direction:column;max-height:95px;overflow-y:auto;overflow-x:hidden;scrollbar-width:thin;scrollbar-color:#cbd5e1 transparent;scrollbar-width:none;-ms-overflow-style:none}.time-scroll::-webkit-scrollbar{display:none}.time-scroll::-webkit-scrollbar-track{background:transparent}.time-scroll::-webkit-scrollbar-thumb{background:#cbd5e1;border-radius:2px}.time-scroll::-webkit-scrollbar-thumb:hover{background:#94a3b8}.time-item{min-width:40px;width:40px;height:32px;min-height:32px;display:flex;align-items:center;justify-content:center;font-size:14px;font-weight:400;color:#374151;cursor:pointer;border-radius:4px;transition:all .15s ease;-webkit-user-select:none;user-select:none;font-family:Inter,sans-serif}.time-item:hover{background:#f3f4f6}.time-item.selected{background:#111827;color:#fff;font-weight:500;box-shadow:0 1px 2px #2563eb4d}.ampm-column .time-item{min-width:40px;width:40px}.time-separator{font-size:16px;font-weight:600;color:#6b7280;margin:5px 0 0}\n"] }]
|
|
445
365
|
}], propDecorators: { required: [{
|
|
446
366
|
type: Input
|
|
447
367
|
}], value: [{
|
|
@@ -470,6 +390,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
470
390
|
type: Output
|
|
471
391
|
}], pickerClosed: [{
|
|
472
392
|
type: Output
|
|
393
|
+
}], disabled: [{
|
|
394
|
+
type: Input
|
|
473
395
|
}], timeScrollElements: [{
|
|
474
396
|
type: ViewChildren,
|
|
475
397
|
args: ['timeScroll']
|
|
@@ -2356,7 +2278,7 @@ class BkCustomCalendar {
|
|
|
2356
2278
|
useExisting: forwardRef(() => BkCustomCalendar),
|
|
2357
2279
|
multi: true,
|
|
2358
2280
|
},
|
|
2359
|
-
], viewQueries: [{ propertyName: "inputWrapper", first: true, predicate: ["inputWrapper"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"calendar-container relative\" [class.open]=\"show\" [class.inline-mode]=\"inline\" [class.disabled]=\"disabled\">\r\n <!-- Input field -->\r\n <div #inputWrapper class=\"input-wrapper\" *ngIf=\"!inline\">\r\n <input\r\n type=\"text\"\r\n (click)=\"!disabled && toggle()\"\r\n (blur)=\"markAsTouched()\"\r\n readonly\r\n [value]=\"getDisplayValue()\"\r\n [placeholder]=\"placeholder\"\r\n [attr.disabled]=\"disabled ? true : null\"\r\n [class.hasError]=\"hasError\"\r\n class=\"calendar-input\">\r\n <!-- *ngIf=\"!getDisplayValue()\" -->\r\n\r\n <span class=\"calendar-icon\" >\r\n <img alt=\"calendar\" class=\"calendar-icon-img\" [src]='brickclayIcons.calenderIcon'/>\r\n </span>\r\n <button class=\"clear-btn\" *ngIf=\"getDisplayValue() && isDisplayCrossIcon\" (click)=\"clear(); $event.stopPropagation()\" title=\"Clear\">\u00D7</button>\r\n </div>\r\n\r\n <!-- Calendar Popup / Inline -->\r\n <div class=\"calendar-popup\"\r\n [class.inline-calendar]=\"inline\"\r\n [class.append-to-body]=\"appendToBody && !inline\"\r\n [style.position]=\"appendToBody && !inline ? 'fixed' : null\"\r\n [style.top]=\"appendToBody && !inline && drop !== 'up' ? dropdownStyle.top : null\"\r\n [style.bottom]=\"appendToBody && !inline && drop === 'up' ? dropdownStyle.bottom : null\"\r\n [style.left]=\"appendToBody && !inline ? dropdownStyle.left : null\"\r\n [ngClass]=\"{\r\n 'position-right': !inline && !appendToBody && opens === 'right',\r\n 'position-center': !inline && !appendToBody && opens === 'center',\r\n 'drop-up': !inline && drop === 'up',\r\n 'has-ranges': showRanges && customRanges,\r\n 'dual-calendar-mode': dualCalendar\r\n }\"\r\n *ngIf=\"inline || show\">\r\n\r\n <!-- RANGES -->\r\n <div class=\"ranges\" *ngIf=\"showRanges && customRanges\">\r\n <button\r\n *ngFor=\"let rangeKey of rangeOrder\"\r\n (click)=\"chooseRange(rangeKey)\"\r\n [class.active]=\"activeRange === rangeKey\"\r\n [class.custom-range]=\"rangeKey === 'Custom Range'\"\r\n class=\"range-btn\"\r\n [disabled]=\"rangeKey === 'Custom Range'\">\r\n {{ rangeKey }}\r\n </button>\r\n </div>\r\n<div class=\"\" [ngClass]=\"showRanges ? 'w-100 flex-grow-1' : ''\">\r\n\r\n\r\n <!-- SINGLE CALENDAR -->\r\n <div *ngIf=\"!dualCalendar\" class=\"calendar-wrapper\">\r\n <div class=\"header\">\r\n <!-- <button (click)=\"prevMonth()\" class=\"nav-btn\" type=\"button\">\r\n <img src=\"assets/calender/pagination-left-gray.svg\" alt=\"arrow-left\" class=\"arrow-left\">\r\n </button> -->\r\n <button class=\"nav-btn\" type=\"button\" (click)=\"prevMonth()\" matTooltip=\"Prev month\"\r\n >\r\n <img alt=\"prev\" class=\"h-3 w-3\" [src]=\"brickclayIcons.arrowleft\"/>\r\n </button>\r\n <span class=\"month-year\">{{ getMonthName(month) }} {{ year }}</span>\r\n <!-- <button (click)=\"nextMonth()\" class=\"nav-btn\" type=\"button\">\r\n <img src=\"assets/calender/pagination-right-gray.svg\" alt=\"arrow-right\" class=\"arrow-right\">\r\n </button> -->\r\n <button class=\"nav-btn\" type=\"button\" (click)=\"nextMonth()\" matTooltip=\"Next month\"\r\n >\r\n <img alt=\"next\" class=\"h-3 w-3\" [src]='brickclayIcons.arrowRight'/>\r\n <!--<img src=\"assets/calender/pagination-right-gray.svg\" alt=\"next\" class=\"h-3 w-3\" /> -->\r\n </button>\r\n </div>\r\n\r\n <table class=\"calendar-table\">\r\n <thead>\r\n <tr>\r\n <th *ngFor=\"let d of ['Mo','Tu','We','Th','Fr','Sa','Su']\" class=\"weekday-header\">{{ d }}</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let week of calendar\">\r\n <td\r\n *ngFor=\"let dayObj of week\"\r\n (click)=\"dayObj.currentMonth && !isDateDisabled(year, month, dayObj.day) && selectDate(dayObj.day)\"\r\n (mouseenter)=\"dayObj.currentMonth && !isDateDisabled(year, month, dayObj.day) && onDateHover(dayObj.day, false)\"\r\n (mouseleave)=\"onDateLeave()\"\r\n [class.active]=\"dayObj.currentMonth && isDateSelected(year, month, dayObj.day)\"\r\n [class.in-range]=\"dayObj.currentMonth && isDateInRange(year, month, dayObj.day)\"\r\n [class.other-month]=\"!dayObj.currentMonth\"\r\n [class.disabled]=\"isDateDisabled(year, month, dayObj.day)\"\r\n [class.multi-selected]=\"multiDateSelection && isDateInMultiSelection(year, month, dayObj.day)\"\r\n [class.today]=\"dayObj.currentMonth && isToday(year, month, dayObj.day)\"\r\n class=\"calendar-day\">\r\n {{ dayObj.day }}\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n\r\n <!-- Single Calendar Time Picker -->\r\n <div *ngIf=\"enableTimepicker\" class=\"timepicker-section\">\r\n <div class=\"timepicker-label\">Time</div>\r\n <div class=\"timepicker-controls\">\r\n <bk-time-picker\r\n pickerId=\"single-time\"\r\n [timeFormat]=\"timeFormat\"\r\n [clearable]=\"clearableTime\"\r\n [label]=\"''\"\r\n [ngModel]=\"singleTimeModel\"\r\n (ngModelChange)=\"onSingleTimePickerChange($event); singleTimeModel=$event\"\r\n [closePicker]=\"shouldClosePicker('single-time')\"\r\n (pickerOpened)=\"onTimePickerOpened($event)\"\r\n (pickerClosed)=\"onTimePickerClosed($event)\">\r\n </bk-time-picker>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- DUAL CALENDAR -->\r\n <div class=\"dual-calendar\" *ngIf=\"dualCalendar\">\r\n <!-- LEFT CALENDAR -->\r\n <div class=\"calendar-left\">\r\n <div class=\"header\">\r\n <button (click)=\"prevLeftMonth()\" class=\"nav-btn\" type=\"button\">\r\n <img alt=\"arrow-left\" class=\"arrow-left\" [src]=\"brickclayIcons.arrowleft\"/>\r\n </button>\r\n <span class=\"month-year\">{{ getMonthName(leftMonth) }} {{ leftYear }}</span>\r\n <button (click)=\"nextLeftMonth()\" class=\"nav-btn\" type=\"button\">\r\n <img alt=\"arrow-right\" class=\"arrow-right\" [src]='brickclayIcons.arrowRight'/>\r\n </button>\r\n </div>\r\n <table class=\"calendar-table\">\r\n <thead>\r\n <tr>\r\n <th *ngFor=\"let d of ['Mo','Tu','We','Th','Fr','Sa','Su']\" class=\"weekday-header\">{{ d }}</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let week of leftCalendar\">\r\n <td\r\n *ngFor=\"let dayObj of week\"\r\n (click)=\"dayObj.currentMonth && !isDateDisabled(leftYear, leftMonth, dayObj.day) && selectDate(dayObj.day, false)\"\r\n (mouseenter)=\"dayObj.currentMonth && !isDateDisabled(leftYear, leftMonth, dayObj.day) && onDateHover(dayObj.day, false)\"\r\n (mouseleave)=\"onDateLeave()\"\r\n [class.active]=\"dayObj.currentMonth && isDateSelected(leftYear, leftMonth, dayObj.day)\"\r\n [class.in-range]=\"dayObj.currentMonth && isDateInRange(leftYear, leftMonth, dayObj.day)\"\r\n [class.other-month]=\"!dayObj.currentMonth\"\r\n [class.disabled]=\"isDateDisabled(leftYear, leftMonth, dayObj.day)\"\r\n [class.multi-selected]=\"multiDateSelection && isDateInMultiSelection(leftYear, leftMonth, dayObj.day)\"\r\n [class.today]=\"dayObj.currentMonth && isToday(leftYear, leftMonth, dayObj.day)\"\r\n class=\"calendar-day\">\r\n {{ dayObj.day }}\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n\r\n <!-- Start Time Picker for Dual Calendar -->\r\n <div *ngIf=\"enableTimepicker\" class=\"timepicker-section\">\r\n <div class=\"timepicker-label\">Start Time</div>\r\n <div class=\"timepicker-controls\">\r\n <bk-time-picker\r\n pickerId=\"dual-start\"\r\n [timeFormat]=\"timeFormat\"\r\n [clearable]=\"clearableTime\"\r\n [label]=\"''\"\r\n [ngModel]=\"startTimeModel\"\r\n (ngModelChange)=\"onDualTimePickerChange($event, true); startTimeModel=$event\"\r\n [closePicker]=\"shouldClosePicker('dual-start')\"\r\n (pickerOpened)=\"onTimePickerOpened($event)\"\r\n (pickerClosed)=\"onTimePickerClosed($event)\">\r\n </bk-time-picker>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- RIGHT CALENDAR -->\r\n <div class=\"calendar-right\">\r\n <div class=\"header\">\r\n <button (click)=\"prevRightMonth()\" class=\"nav-btn\" type=\"button\">\r\n <img alt=\"arrow-left\" class=\"arrow-left\" [src]=\"brickclayIcons.arrowleft\"/>\r\n </button>\r\n <span class=\"month-year\">{{ getMonthName(rightMonth) }} {{ rightYear }}</span>\r\n <button (click)=\"nextRightMonth()\" class=\"nav-btn\" type=\"button\">\r\n <img alt=\"arrow-right\" class=\"arrow-right\" [src]='brickclayIcons.arrowRight'/>\r\n </button>\r\n </div>\r\n <table class=\"calendar-table\">\r\n <thead>\r\n <tr>\r\n <th *ngFor=\"let d of ['Mo','Tu','We','Th','Fr','Sa','Su']\" class=\"weekday-header\">{{ d }}</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let week of rightCalendar\">\r\n <td\r\n *ngFor=\"let dayObj of week\"\r\n (click)=\"dayObj.currentMonth && !isDateDisabled(rightYear, rightMonth, dayObj.day) && selectDate(dayObj.day, true)\"\r\n (mouseenter)=\"dayObj.currentMonth && !isDateDisabled(rightYear, rightMonth, dayObj.day) && onDateHover(dayObj.day, true)\"\r\n (mouseleave)=\"onDateLeave()\"\r\n [class.active]=\"dayObj.currentMonth && isDateSelected(rightYear, rightMonth, dayObj.day)\"\r\n [class.in-range]=\"dayObj.currentMonth && isDateInRange(rightYear, rightMonth, dayObj.day)\"\r\n [class.other-month]=\"!dayObj.currentMonth\"\r\n [class.disabled]=\"isDateDisabled(rightYear, rightMonth, dayObj.day)\"\r\n [class.multi-selected]=\"multiDateSelection && isDateInMultiSelection(rightYear, rightMonth, dayObj.day)\"\r\n [class.today]=\"dayObj.currentMonth && isToday(rightYear, rightMonth, dayObj.day)\"\r\n class=\"calendar-day\">\r\n {{ dayObj.day }}\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n\r\n <!-- End Time Picker for Dual Calendar -->\r\n <div *ngIf=\"enableTimepicker\" class=\"timepicker-section\">\r\n <div class=\"timepicker-label\">End Time</div>\r\n <div class=\"timepicker-controls\">\r\n <bk-time-picker\r\n pickerId=\"dual-end\"\r\n [timeFormat]=\"timeFormat\"\r\n [clearable]=\"clearableTime\"\r\n [label]=\"''\"\r\n [ngModel]=\"endTimeModel\"\r\n (ngModelChange)=\"onDualTimePickerChange($event, false); endTimeModel=$event\"\r\n [closePicker]=\"shouldClosePicker('dual-end')\"\r\n (pickerOpened)=\"onTimePickerOpened($event)\"\r\n (pickerClosed)=\"onTimePickerClosed($event)\">\r\n </bk-time-picker>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- FOOTER -->\r\n <div class=\"footer\" *ngIf=\"!inline && showCancelApply\">\r\n <button *ngIf=\"showCancel\" (click)=\"cancel()\" class=\"btn-cancel\" type=\"button\">Cancel</button>\r\n <button (click)=\"apply()\" class=\"btn-apply\" type=\"button\">Apply</button>\r\n </div>\r\n\r\n </div>\r\n\r\n </div>\r\n</div>\r\n\r\n@if (hasError){\r\n<p class=\"calender-error\">{{errorMessage}}</p>\r\n}\r\n", styles: [".calendar-container,.calendar-container *{font-family:Inter,sans-serif!important}.calendar-container{position:relative;display:inline-block;width:100%}.input-wrapper{position:relative;display:flex;align-items:center}.calendar-input{width:100%;padding:9px 12px 9px 36px;border:1px solid #E3E3E7;border-radius:4px;font-size:14px;line-height:20px;cursor:pointer;background:#fff;transition:all .2s}.calendar-input::placeholder{color:#6b7080}.calendar-input.hasError{border-color:#f34050}.calendar-input:focus{outline:none;border-color:#999}.calendar-icon{position:absolute;left:12px;pointer-events:none;font-size:18px}.clear-btn{position:absolute;right:9px;background:none;border:none;font-size:20px;color:#999;cursor:pointer;padding:0;width:20px;height:20px;display:flex;align-items:center;justify-content:center;line-height:1;transition:color .2s;top:8px}.clear-btn:hover{color:#333}.calendar-popup{position:absolute;top:110%;left:0;width:320px;background:#fff;border-radius:12px;box-shadow:0 10px 40px #00000026;z-index:1000;animation:slideDown .2s ease-out}.calendar-popup.inline-calendar{position:relative;top:0;left:0;width:100%;margin-top:0;animation:none;box-shadow:0 2px 8px #0000001a}.calendar-container.inline-mode{display:block;width:100%}.calendar-popup.dual-calendar-mode{width:600px}.calendar-popup.dual-calendar-mode.has-ranges{width:730px}.calendar-popup.has-ranges{width:450px}.calendar-popup.dual-calendar-mode.has-ranges .dual-calendar{border-left:1px solid #eee}.calendar-popup.drop-up{top:auto;bottom:110%;animation:slideUp .2s ease-out}.calendar-popup.position-right{left:auto;right:0}.calendar-popup.position-center{left:50%;transform:translate(-50%)}.calendar-popup.append-to-body{z-index:10000}@keyframes slideDown{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}@keyframes slideUp{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.ranges{display:flex;flex-direction:column;gap:4px;margin-bottom:16px;padding-bottom:16px;border-bottom:1px solid #eee;min-width:150px;padding-right:8px}.range-btn{padding:7px 10px;border:1px solid transparent;background:transparent;border-radius:4px;cursor:pointer;text-align:left;font-size:14px;transition:all .2s;color:#838383;font-weight:500}.range-btn:hover{background:#f5f5f5;color:#000}.range-btn.active{background:#f0f0f0;color:#000;font-weight:500}.calendar-wrapper{padding:0 12px 12px;border-left:1px solid #eee}.header{display:flex;justify-content:space-between;align-items:center;padding:12px 0}.month-year{font-size:15px;font-weight:500;color:#333;flex:1;text-align:center;text-transform:capitalize}.nav-btn{background:none;border:none;font-size:24px;cursor:pointer;padding:11.5px 14px;color:#666;border-radius:4px;transition:all .2s;line-height:1;height:30px;width:30px;display:flex;justify-content:center;align-items:center}.nav-btn:hover{background:#f0f0f0;color:#000}.nav-btn img{width:auto;max-width:none!important}.calendar-table{width:100%;border-collapse:collapse;text-align:center}.weekday-header{font-size:12px;color:#7e7e7e;font-weight:600;padding:8px 4px;letter-spacing:.3px}.calendar-day{padding:8px 4px;font-size:14px;cursor:pointer;border-radius:6px;transition:all .2s;position:relative;color:#333;font-weight:500;line-height:1.5}.calendar-day:hover:not(.disabled):not(.other-month){background:#efefef;color:#000}.calendar-day.other-month{color:#ccc;cursor:default}.calendar-day.disabled{color:#ddd;cursor:not-allowed;opacity:.5}.calendar-day.active{background:#000!important;color:#fff!important;font-weight:600}.calendar-day.today{font-weight:600}.calendar-day.today:not(.active){background:#e5e4e4}.calendar-day.active:hover{background:#000!important}.calendar-day.in-range{background:#f5f5f5;color:#333;border-radius:0;position:relative}.calendar-day.in-range:hover{background:#e8e8e8}.calendar-day.in-range:before{content:\"\";position:absolute;inset:0;background:#f5f5f5;z-index:-1}.calendar-day.in-range:hover:before{background:#e8e8e8}.calendar-day.multi-selected{background:#4caf50;color:#fff;font-weight:600;border-radius:6px}.calendar-day.multi-selected:hover{background:#45a049}.dual-calendar{display:flex;width:100%;border-left:1px solid #eee}.calendar-left,.calendar-right{flex:1;min-width:0;padding:0 12px 12px}.calendar-popup.has-ranges{display:flex;flex-direction:row}.calendar-popup.has-ranges .ranges{margin-bottom:0;border-bottom:none;padding:10px}.calendar-popup.has-ranges .dual-calendar,.calendar-popup.has-ranges .calendar-wrapper{flex:1}.calendar-right .header{justify-content:space-between}.calendar-right .header .month-year{text-align:center;flex:1}.timepicker-section{margin-top:12px;padding-top:12px;border-top:1px solid #eee}.timepicker-label{font-size:12px;font-weight:500;color:#000;margin-bottom:4px;letter-spacing:-.28px}.custom-time-picker{display:flex;flex-direction:column;gap:8px;align-items:start}.time-input-group{display:flex;align-items:center;justify-content:center;gap:8px;background:#f8f9fa;padding:12px;border-radius:8px;border:1px solid #e0e0e0}.time-control{display:flex;flex-direction:column;align-items:center}.time-btn{background:#fff;border:1px solid #ddd;width:28px;height:20px;cursor:pointer;font-size:10px;color:#666;border-radius:4px;transition:all .2s;display:flex;align-items:center;justify-content:center;padding:0;line-height:1}.time-btn:hover{background:#e4e4e4;color:#fff;border-color:#e4e4e4}.time-btn.up{border-bottom-left-radius:0;border-bottom-right-radius:0;border-bottom:none}.time-btn.down{border-top-left-radius:0;border-top-right-radius:0;border-top:none}.time-input{width:40px;height:32px;text-align:center;border:1px solid #ddd;border-radius:4px;font-size:16px;font-weight:600;background:#fff;color:#333}.time-separator{font-size:18px;font-weight:600;color:#666;margin:0 2px}.ampm-control{display:flex;flex-direction:column;gap:4px;margin-left:8px}.ampm-btn{padding:6px 12px;border:1px solid #ddd;background:#fff;border-radius:4px;cursor:pointer;font-size:12px;font-weight:600;color:#666;transition:all .2s;min-width:45px}.ampm-btn:hover{background:#f0f0f0}.ampm-btn.active{background:#000;color:#fff;border-color:#000}.html5-time-input{margin-top:8px;padding:8px;border:1px solid #ddd;border-radius:6px;font-size:14px;width:100%;max-width:120px}.footer{padding:12px;display:flex;justify-content:flex-end;gap:8px;border-top:1px solid #eee}.btn-cancel,.btn-apply{padding:8px 16px;border:none;border-radius:4px;font-size:14px;font-weight:500;cursor:pointer;transition:all .2s;min-width:80px}.btn-cancel{background:#fff;color:#666;border:1px solid #ddd}.btn-cancel:hover{background:#f5f5f5;border-color:#bbb}.btn-apply{background:#000;color:#fff}.btn-apply:hover{background:#333}.btn-apply:active{transform:translateY(0)}@media (max-width: 768px){.calendar-popup{width:100%;max-width:320px}.calendar-popup.dual-calendar-mode{width:100%;max-width:100%}.calendar-popup.has-ranges{flex-direction:column}.calendar-popup.has-ranges .ranges{border-right:none;border-bottom:1px solid #eee;padding-right:0;margin-right:0;padding-bottom:16px;margin-bottom:16px}.dual-calendar{flex-direction:column}.time-input-group{flex-wrap:wrap;justify-content:center}}.ranges::-webkit-scrollbar{width:6px}.ranges::-webkit-scrollbar-track{background:#f1f1f1;border-radius:3px}.ranges::-webkit-scrollbar-thumb{background:#888;border-radius:3px}.ranges::-webkit-scrollbar-thumb:hover{background:#555}.w-100{width:100%}.flex-grow-1{flex-grow:1}.calender-error{margin-top:6px;color:#f34050;font-size:14px;line-height:20px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: BkTimePicker, selector: "bk-time-picker", inputs: ["required", "value", "label", "placeholder", "clearable", "position", "pickerId", "closePicker", "timeFormat", "showSeconds"], outputs: ["change", "timeChange", "pickerOpened", "pickerClosed"] }] });
|
|
2281
|
+
], viewQueries: [{ propertyName: "inputWrapper", first: true, predicate: ["inputWrapper"], descendants: true }], usesOnChanges: true, ngImport: i0, template: "<div class=\"calendar-container relative\" [class.open]=\"show\" [class.inline-mode]=\"inline\" [class.disabled]=\"disabled\">\r\n <!-- Input field -->\r\n <div #inputWrapper class=\"input-wrapper\" *ngIf=\"!inline\">\r\n <input\r\n type=\"text\"\r\n (click)=\"!disabled && toggle()\"\r\n (blur)=\"markAsTouched()\"\r\n readonly\r\n [value]=\"getDisplayValue()\"\r\n [placeholder]=\"placeholder\"\r\n [attr.disabled]=\"disabled ? true : null\"\r\n [class.hasError]=\"hasError\"\r\n class=\"calendar-input\">\r\n <!-- *ngIf=\"!getDisplayValue()\" -->\r\n\r\n <span class=\"calendar-icon\" >\r\n <img alt=\"calendar\" class=\"calendar-icon-img\" [src]='brickclayIcons.calenderIcon'/>\r\n </span>\r\n <button class=\"clear-btn\" *ngIf=\"getDisplayValue() && isDisplayCrossIcon\" (click)=\"clear(); $event.stopPropagation()\" title=\"Clear\">\u00D7</button>\r\n </div>\r\n\r\n <!-- Calendar Popup / Inline -->\r\n <div class=\"calendar-popup\"\r\n [class.inline-calendar]=\"inline\"\r\n [class.append-to-body]=\"appendToBody && !inline\"\r\n [style.position]=\"appendToBody && !inline ? 'fixed' : null\"\r\n [style.top]=\"appendToBody && !inline && drop !== 'up' ? dropdownStyle.top : null\"\r\n [style.bottom]=\"appendToBody && !inline && drop === 'up' ? dropdownStyle.bottom : null\"\r\n [style.left]=\"appendToBody && !inline ? dropdownStyle.left : null\"\r\n [ngClass]=\"{\r\n 'position-right': !inline && !appendToBody && opens === 'right',\r\n 'position-center': !inline && !appendToBody && opens === 'center',\r\n 'drop-up': !inline && drop === 'up',\r\n 'has-ranges': showRanges && customRanges,\r\n 'dual-calendar-mode': dualCalendar\r\n }\"\r\n *ngIf=\"inline || show\">\r\n\r\n <!-- RANGES -->\r\n <div class=\"ranges\" *ngIf=\"showRanges && customRanges\">\r\n <button\r\n *ngFor=\"let rangeKey of rangeOrder\"\r\n (click)=\"chooseRange(rangeKey)\"\r\n [class.active]=\"activeRange === rangeKey\"\r\n [class.custom-range]=\"rangeKey === 'Custom Range'\"\r\n class=\"range-btn\"\r\n [disabled]=\"rangeKey === 'Custom Range'\">\r\n {{ rangeKey }}\r\n </button>\r\n </div>\r\n<div class=\"\" [ngClass]=\"showRanges ? 'w-100 flex-grow-1' : ''\">\r\n\r\n\r\n <!-- SINGLE CALENDAR -->\r\n <div *ngIf=\"!dualCalendar\" class=\"calendar-wrapper\">\r\n <div class=\"header\">\r\n <!-- <button (click)=\"prevMonth()\" class=\"nav-btn\" type=\"button\">\r\n <img src=\"assets/calender/pagination-left-gray.svg\" alt=\"arrow-left\" class=\"arrow-left\">\r\n </button> -->\r\n <button class=\"nav-btn\" type=\"button\" (click)=\"prevMonth()\" matTooltip=\"Prev month\"\r\n >\r\n <img alt=\"prev\" class=\"h-3 w-3\" [src]=\"brickclayIcons.arrowleft\"/>\r\n </button>\r\n <span class=\"month-year\">{{ getMonthName(month) }} {{ year }}</span>\r\n <!-- <button (click)=\"nextMonth()\" class=\"nav-btn\" type=\"button\">\r\n <img src=\"assets/calender/pagination-right-gray.svg\" alt=\"arrow-right\" class=\"arrow-right\">\r\n </button> -->\r\n <button class=\"nav-btn\" type=\"button\" (click)=\"nextMonth()\" matTooltip=\"Next month\"\r\n >\r\n <img alt=\"next\" class=\"h-3 w-3\" [src]='brickclayIcons.arrowRight'/>\r\n <!--<img src=\"assets/calender/pagination-right-gray.svg\" alt=\"next\" class=\"h-3 w-3\" /> -->\r\n </button>\r\n </div>\r\n\r\n <table class=\"calendar-table\">\r\n <thead>\r\n <tr>\r\n <th *ngFor=\"let d of ['Mo','Tu','We','Th','Fr','Sa','Su']\" class=\"weekday-header\">{{ d }}</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let week of calendar\">\r\n <td\r\n *ngFor=\"let dayObj of week\"\r\n (click)=\"dayObj.currentMonth && !isDateDisabled(year, month, dayObj.day) && selectDate(dayObj.day)\"\r\n (mouseenter)=\"dayObj.currentMonth && !isDateDisabled(year, month, dayObj.day) && onDateHover(dayObj.day, false)\"\r\n (mouseleave)=\"onDateLeave()\"\r\n [class.active]=\"dayObj.currentMonth && isDateSelected(year, month, dayObj.day)\"\r\n [class.in-range]=\"dayObj.currentMonth && isDateInRange(year, month, dayObj.day)\"\r\n [class.other-month]=\"!dayObj.currentMonth\"\r\n [class.disabled]=\"isDateDisabled(year, month, dayObj.day)\"\r\n [class.multi-selected]=\"multiDateSelection && isDateInMultiSelection(year, month, dayObj.day)\"\r\n [class.today]=\"dayObj.currentMonth && isToday(year, month, dayObj.day)\"\r\n class=\"calendar-day\">\r\n {{ dayObj.day }}\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n\r\n <!-- Single Calendar Time Picker -->\r\n <div *ngIf=\"enableTimepicker\" class=\"timepicker-section\">\r\n <div class=\"timepicker-label\">Time</div>\r\n <div class=\"timepicker-controls\">\r\n <bk-time-picker\r\n pickerId=\"single-time\"\r\n [timeFormat]=\"timeFormat\"\r\n [clearable]=\"clearableTime\"\r\n [label]=\"''\"\r\n [ngModel]=\"singleTimeModel\"\r\n (ngModelChange)=\"onSingleTimePickerChange($event); singleTimeModel=$event\"\r\n [closePicker]=\"shouldClosePicker('single-time')\"\r\n (pickerOpened)=\"onTimePickerOpened($event)\"\r\n (pickerClosed)=\"onTimePickerClosed($event)\">\r\n </bk-time-picker>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- DUAL CALENDAR -->\r\n <div class=\"dual-calendar\" *ngIf=\"dualCalendar\">\r\n <!-- LEFT CALENDAR -->\r\n <div class=\"calendar-left\">\r\n <div class=\"header\">\r\n <button (click)=\"prevLeftMonth()\" class=\"nav-btn\" type=\"button\">\r\n <img alt=\"arrow-left\" class=\"arrow-left\" [src]=\"brickclayIcons.arrowleft\"/>\r\n </button>\r\n <span class=\"month-year\">{{ getMonthName(leftMonth) }} {{ leftYear }}</span>\r\n <button (click)=\"nextLeftMonth()\" class=\"nav-btn\" type=\"button\">\r\n <img alt=\"arrow-right\" class=\"arrow-right\" [src]='brickclayIcons.arrowRight'/>\r\n </button>\r\n </div>\r\n <table class=\"calendar-table\">\r\n <thead>\r\n <tr>\r\n <th *ngFor=\"let d of ['Mo','Tu','We','Th','Fr','Sa','Su']\" class=\"weekday-header\">{{ d }}</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let week of leftCalendar\">\r\n <td\r\n *ngFor=\"let dayObj of week\"\r\n (click)=\"dayObj.currentMonth && !isDateDisabled(leftYear, leftMonth, dayObj.day) && selectDate(dayObj.day, false)\"\r\n (mouseenter)=\"dayObj.currentMonth && !isDateDisabled(leftYear, leftMonth, dayObj.day) && onDateHover(dayObj.day, false)\"\r\n (mouseleave)=\"onDateLeave()\"\r\n [class.active]=\"dayObj.currentMonth && isDateSelected(leftYear, leftMonth, dayObj.day)\"\r\n [class.in-range]=\"dayObj.currentMonth && isDateInRange(leftYear, leftMonth, dayObj.day)\"\r\n [class.other-month]=\"!dayObj.currentMonth\"\r\n [class.disabled]=\"isDateDisabled(leftYear, leftMonth, dayObj.day)\"\r\n [class.multi-selected]=\"multiDateSelection && isDateInMultiSelection(leftYear, leftMonth, dayObj.day)\"\r\n [class.today]=\"dayObj.currentMonth && isToday(leftYear, leftMonth, dayObj.day)\"\r\n class=\"calendar-day\">\r\n {{ dayObj.day }}\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n\r\n <!-- Start Time Picker for Dual Calendar -->\r\n <div *ngIf=\"enableTimepicker\" class=\"timepicker-section\">\r\n <div class=\"timepicker-label\">Start Time</div>\r\n <div class=\"timepicker-controls\">\r\n <bk-time-picker\r\n pickerId=\"dual-start\"\r\n [timeFormat]=\"timeFormat\"\r\n [clearable]=\"clearableTime\"\r\n [label]=\"''\"\r\n [ngModel]=\"startTimeModel\"\r\n (ngModelChange)=\"onDualTimePickerChange($event, true); startTimeModel=$event\"\r\n [closePicker]=\"shouldClosePicker('dual-start')\"\r\n (pickerOpened)=\"onTimePickerOpened($event)\"\r\n (pickerClosed)=\"onTimePickerClosed($event)\">\r\n </bk-time-picker>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- RIGHT CALENDAR -->\r\n <div class=\"calendar-right\">\r\n <div class=\"header\">\r\n <button (click)=\"prevRightMonth()\" class=\"nav-btn\" type=\"button\">\r\n <img alt=\"arrow-left\" class=\"arrow-left\" [src]=\"brickclayIcons.arrowleft\"/>\r\n </button>\r\n <span class=\"month-year\">{{ getMonthName(rightMonth) }} {{ rightYear }}</span>\r\n <button (click)=\"nextRightMonth()\" class=\"nav-btn\" type=\"button\">\r\n <img alt=\"arrow-right\" class=\"arrow-right\" [src]='brickclayIcons.arrowRight'/>\r\n </button>\r\n </div>\r\n <table class=\"calendar-table\">\r\n <thead>\r\n <tr>\r\n <th *ngFor=\"let d of ['Mo','Tu','We','Th','Fr','Sa','Su']\" class=\"weekday-header\">{{ d }}</th>\r\n </tr>\r\n </thead>\r\n <tbody>\r\n <tr *ngFor=\"let week of rightCalendar\">\r\n <td\r\n *ngFor=\"let dayObj of week\"\r\n (click)=\"dayObj.currentMonth && !isDateDisabled(rightYear, rightMonth, dayObj.day) && selectDate(dayObj.day, true)\"\r\n (mouseenter)=\"dayObj.currentMonth && !isDateDisabled(rightYear, rightMonth, dayObj.day) && onDateHover(dayObj.day, true)\"\r\n (mouseleave)=\"onDateLeave()\"\r\n [class.active]=\"dayObj.currentMonth && isDateSelected(rightYear, rightMonth, dayObj.day)\"\r\n [class.in-range]=\"dayObj.currentMonth && isDateInRange(rightYear, rightMonth, dayObj.day)\"\r\n [class.other-month]=\"!dayObj.currentMonth\"\r\n [class.disabled]=\"isDateDisabled(rightYear, rightMonth, dayObj.day)\"\r\n [class.multi-selected]=\"multiDateSelection && isDateInMultiSelection(rightYear, rightMonth, dayObj.day)\"\r\n [class.today]=\"dayObj.currentMonth && isToday(rightYear, rightMonth, dayObj.day)\"\r\n class=\"calendar-day\">\r\n {{ dayObj.day }}\r\n </td>\r\n </tr>\r\n </tbody>\r\n </table>\r\n\r\n <!-- End Time Picker for Dual Calendar -->\r\n <div *ngIf=\"enableTimepicker\" class=\"timepicker-section\">\r\n <div class=\"timepicker-label\">End Time</div>\r\n <div class=\"timepicker-controls\">\r\n <bk-time-picker\r\n pickerId=\"dual-end\"\r\n [timeFormat]=\"timeFormat\"\r\n [clearable]=\"clearableTime\"\r\n [label]=\"''\"\r\n [ngModel]=\"endTimeModel\"\r\n (ngModelChange)=\"onDualTimePickerChange($event, false); endTimeModel=$event\"\r\n [closePicker]=\"shouldClosePicker('dual-end')\"\r\n (pickerOpened)=\"onTimePickerOpened($event)\"\r\n (pickerClosed)=\"onTimePickerClosed($event)\">\r\n </bk-time-picker>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- FOOTER -->\r\n <div class=\"footer\" *ngIf=\"!inline && showCancelApply\">\r\n <button *ngIf=\"showCancel\" (click)=\"cancel()\" class=\"btn-cancel\" type=\"button\">Cancel</button>\r\n <button (click)=\"apply()\" class=\"btn-apply\" type=\"button\">Apply</button>\r\n </div>\r\n\r\n </div>\r\n\r\n </div>\r\n</div>\r\n\r\n@if (hasError){\r\n<p class=\"calender-error\">{{errorMessage}}</p>\r\n}\r\n", styles: [".calendar-container,.calendar-container *{font-family:Inter,sans-serif!important}.calendar-container{position:relative;display:inline-block;width:100%}.input-wrapper{position:relative;display:flex;align-items:center}.calendar-input{width:100%;padding:9px 12px 9px 36px;border:1px solid #E3E3E7;border-radius:4px;font-size:14px;line-height:20px;cursor:pointer;background:#fff;transition:all .2s}.calendar-input::placeholder{color:#6b7080}.calendar-input.hasError{border-color:#f34050}.calendar-input:focus{outline:none;border-color:#999}.calendar-icon{position:absolute;left:12px;pointer-events:none;font-size:18px}.clear-btn{position:absolute;right:9px;background:none;border:none;font-size:20px;color:#999;cursor:pointer;padding:0;width:20px;height:20px;display:flex;align-items:center;justify-content:center;line-height:1;transition:color .2s;top:8px}.clear-btn:hover{color:#333}.calendar-popup{position:absolute;top:110%;left:0;width:320px;background:#fff;border-radius:12px;box-shadow:0 10px 40px #00000026;z-index:1000;animation:slideDown .2s ease-out}.calendar-popup.inline-calendar{position:relative;top:0;left:0;width:100%;margin-top:0;animation:none;box-shadow:0 2px 8px #0000001a}.calendar-container.inline-mode{display:block;width:100%}.calendar-popup.dual-calendar-mode{width:600px}.calendar-popup.dual-calendar-mode.has-ranges{width:730px}.calendar-popup.has-ranges{width:450px}.calendar-popup.dual-calendar-mode.has-ranges .dual-calendar{border-left:1px solid #eee}.calendar-popup.drop-up{top:auto;bottom:110%;animation:slideUp .2s ease-out}.calendar-popup.position-right{left:auto;right:0}.calendar-popup.position-center{left:50%;transform:translate(-50%)}.calendar-popup.append-to-body{z-index:10000}@keyframes slideDown{0%{opacity:0;transform:translateY(-10px)}to{opacity:1;transform:translateY(0)}}@keyframes slideUp{0%{opacity:0;transform:translateY(10px)}to{opacity:1;transform:translateY(0)}}.ranges{display:flex;flex-direction:column;gap:4px;margin-bottom:16px;padding-bottom:16px;border-bottom:1px solid #eee;min-width:150px;padding-right:8px}.range-btn{padding:7px 10px;border:1px solid transparent;background:transparent;border-radius:4px;cursor:pointer;text-align:left;font-size:14px;transition:all .2s;color:#838383;font-weight:500}.range-btn:hover{background:#f5f5f5;color:#000}.range-btn.active{background:#f0f0f0;color:#000;font-weight:500}.calendar-wrapper{padding:0 12px 12px;border-left:1px solid #eee}.header{display:flex;justify-content:space-between;align-items:center;padding:12px 0}.month-year{font-size:15px;font-weight:500;color:#333;flex:1;text-align:center;text-transform:capitalize}.nav-btn{background:none;border:none;font-size:24px;cursor:pointer;padding:11.5px 14px;color:#666;border-radius:4px;transition:all .2s;line-height:1;height:30px;width:30px;display:flex;justify-content:center;align-items:center}.nav-btn:hover{background:#f0f0f0;color:#000}.nav-btn img{width:auto;max-width:none!important}.calendar-table{width:100%;border-collapse:collapse;text-align:center}.weekday-header{font-size:12px;color:#7e7e7e;font-weight:600;padding:8px 4px;letter-spacing:.3px}.calendar-day{padding:8px 4px;font-size:14px;cursor:pointer;border-radius:6px;transition:all .2s;position:relative;color:#333;font-weight:500;line-height:1.5}.calendar-day:hover:not(.disabled):not(.other-month){background:#efefef;color:#000}.calendar-day.other-month{color:#ccc;cursor:default}.calendar-day.disabled{color:#ddd;cursor:not-allowed;opacity:.5}.calendar-day.active{background:#000!important;color:#fff!important;font-weight:600}.calendar-day.today{font-weight:600}.calendar-day.today:not(.active){background:#e5e4e4}.calendar-day.active:hover{background:#000!important}.calendar-day.in-range{background:#f5f5f5;color:#333;border-radius:0;position:relative}.calendar-day.in-range:hover{background:#e8e8e8}.calendar-day.in-range:before{content:\"\";position:absolute;inset:0;background:#f5f5f5;z-index:-1}.calendar-day.in-range:hover:before{background:#e8e8e8}.calendar-day.multi-selected{background:#4caf50;color:#fff;font-weight:600;border-radius:6px}.calendar-day.multi-selected:hover{background:#45a049}.dual-calendar{display:flex;width:100%;border-left:1px solid #eee}.calendar-left,.calendar-right{flex:1;min-width:0;padding:0 12px 12px}.calendar-popup.has-ranges{display:flex;flex-direction:row}.calendar-popup.has-ranges .ranges{margin-bottom:0;border-bottom:none;padding:10px}.calendar-popup.has-ranges .dual-calendar,.calendar-popup.has-ranges .calendar-wrapper{flex:1}.calendar-right .header{justify-content:space-between}.calendar-right .header .month-year{text-align:center;flex:1}.timepicker-section{margin-top:12px;padding-top:12px;border-top:1px solid #eee}.timepicker-label{font-size:12px;font-weight:500;color:#000;margin-bottom:4px;letter-spacing:-.28px}.custom-time-picker{display:flex;flex-direction:column;gap:8px;align-items:start}.time-input-group{display:flex;align-items:center;justify-content:center;gap:8px;background:#f8f9fa;padding:12px;border-radius:8px;border:1px solid #e0e0e0}.time-control{display:flex;flex-direction:column;align-items:center}.time-btn{background:#fff;border:1px solid #ddd;width:28px;height:20px;cursor:pointer;font-size:10px;color:#666;border-radius:4px;transition:all .2s;display:flex;align-items:center;justify-content:center;padding:0;line-height:1}.time-btn:hover{background:#e4e4e4;color:#fff;border-color:#e4e4e4}.time-btn.up{border-bottom-left-radius:0;border-bottom-right-radius:0;border-bottom:none}.time-btn.down{border-top-left-radius:0;border-top-right-radius:0;border-top:none}.time-input{width:40px;height:32px;text-align:center;border:1px solid #ddd;border-radius:4px;font-size:16px;font-weight:600;background:#fff;color:#333}.time-separator{font-size:18px;font-weight:600;color:#666;margin:0 2px}.ampm-control{display:flex;flex-direction:column;gap:4px;margin-left:8px}.ampm-btn{padding:6px 12px;border:1px solid #ddd;background:#fff;border-radius:4px;cursor:pointer;font-size:12px;font-weight:600;color:#666;transition:all .2s;min-width:45px}.ampm-btn:hover{background:#f0f0f0}.ampm-btn.active{background:#000;color:#fff;border-color:#000}.html5-time-input{margin-top:8px;padding:8px;border:1px solid #ddd;border-radius:6px;font-size:14px;width:100%;max-width:120px}.footer{padding:12px;display:flex;justify-content:flex-end;gap:8px;border-top:1px solid #eee}.btn-cancel,.btn-apply{padding:8px 16px;border:none;border-radius:4px;font-size:14px;font-weight:500;cursor:pointer;transition:all .2s;min-width:80px}.btn-cancel{background:#fff;color:#666;border:1px solid #ddd}.btn-cancel:hover{background:#f5f5f5;border-color:#bbb}.btn-apply{background:#000;color:#fff}.btn-apply:hover{background:#333}.btn-apply:active{transform:translateY(0)}@media (max-width: 768px){.calendar-popup{width:100%;max-width:320px}.calendar-popup.dual-calendar-mode{width:100%;max-width:100%}.calendar-popup.has-ranges{flex-direction:column}.calendar-popup.has-ranges .ranges{border-right:none;border-bottom:1px solid #eee;padding-right:0;margin-right:0;padding-bottom:16px;margin-bottom:16px}.dual-calendar{flex-direction:column}.time-input-group{flex-wrap:wrap;justify-content:center}}.ranges::-webkit-scrollbar{width:6px}.ranges::-webkit-scrollbar-track{background:#f1f1f1;border-radius:3px}.ranges::-webkit-scrollbar-thumb{background:#888;border-radius:3px}.ranges::-webkit-scrollbar-thumb:hover{background:#555}.w-100{width:100%}.flex-grow-1{flex-grow:1}.calender-error{margin-top:6px;color:#f34050;font-size:14px;line-height:20px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "component", type: BkTimePicker, selector: "bk-time-picker", inputs: ["required", "value", "label", "placeholder", "clearable", "position", "pickerId", "closePicker", "timeFormat", "showSeconds", "disabled"], outputs: ["change", "timeChange", "pickerOpened", "pickerClosed"] }] });
|
|
2360
2282
|
}
|
|
2361
2283
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkCustomCalendar, decorators: [{
|
|
2362
2284
|
type: Component,
|
|
@@ -2759,7 +2681,7 @@ class BkScheduledDatePicker {
|
|
|
2759
2681
|
this.emitScheduled();
|
|
2760
2682
|
}
|
|
2761
2683
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkScheduledDatePicker, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
2762
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: BkScheduledDatePicker, isStandalone: true, selector: "bk-scheduled-date-picker", inputs: { timeFormat: "timeFormat", enableSeconds: "enableSeconds" }, outputs: { scheduled: "scheduled", cleared: "cleared" }, ngImport: i0, template: "<div class=\"scheduled-date-picker-container\">\r\n <!-- Header with Tabs -->\r\n\r\n\r\n <!-- Main Content Area -->\r\n\r\n <div class=\"scheduled-content\">\r\n <!-- Left Side: Calendar -->\r\n <div class=\"calendar-section\">\r\n <h2 class=\"scheduled-title\">Scheduled Dates</h2>\r\n <div class=\"tabs\">\r\n <button\r\n class=\"tab-button\"\r\n [class.active]=\"activeTab === 'single'\"\r\n (click)=\"onTabChange('single')\">\r\n Single Date\r\n </button>\r\n <button\r\n class=\"tab-button\"\r\n [class.active]=\"activeTab === 'multiple'\"\r\n (click)=\"onTabChange('multiple')\">\r\n Multiple Dates\r\n </button>\r\n <button\r\n class=\"tab-button\"\r\n [class.active]=\"activeTab === 'range'\"\r\n (click)=\"onTabChange('range')\">\r\n Date Range\r\n </button>\r\n </div>\r\n <!-- Single Date Calendar -->\r\n <div *ngIf=\"activeTab === 'single'\" class=\"calendar-wrapper-inline\">\r\n <bk-custom-calendar\r\n [inline]=\"true\"\r\n [dualCalendar]=\"false\"\r\n [singleDatePicker]=\"true\"\r\n [showRanges]=\"false\"\r\n [enableTimepicker]=\"false\"\r\n [showCancel]=\"false\"\r\n placeholder=\"Select a date\"\r\n (selected)=\"onSingleDateSelected($event)\">\r\n </bk-custom-calendar>\r\n </div>\r\n\r\n <!-- Multiple Dates Calendar -->\r\n <div *ngIf=\"activeTab === 'multiple'\" class=\"calendar-wrapper-inline\">\r\n <bk-custom-calendar\r\n [inline]=\"true\"\r\n [dualCalendar]=\"false\"\r\n [singleDatePicker]=\"false\"\r\n [showRanges]=\"false\"\r\n [enableTimepicker]=\"false\"\r\n [multiDateSelection]=\"true\"\r\n [showCancel]=\"false\"\r\n placeholder=\"Select multiple dates\"\r\n (selected)=\"onMultipleDatesSelected($event)\">\r\n </bk-custom-calendar>\r\n </div>\r\n\r\n <!-- Date Range Calendar -->\r\n <div *ngIf=\"activeTab === 'range'\" class=\"calendar-wrapper-inline\">\r\n <bk-custom-calendar\r\n [inline]=\"true\"\r\n [dualCalendar]=\"false\"\r\n [singleDatePicker]=\"false\"\r\n [showRanges]=\"false\"\r\n [enableTimepicker]=\"false\"\r\n [showCancel]=\"false\"\r\n placeholder=\"Select date range\"\r\n (selected)=\"onRangeSelected($event)\">\r\n </bk-custom-calendar>\r\n </div>\r\n </div>\r\n\r\n <!-- Right Side: Time Configuration -->\r\n <div class=\"time-config-section\">\r\n <h3 class=\"time-config-title\">Time Configuration</h3>\r\n\r\n <!-- Single Date Time Configuration -->\r\n <div *ngIf=\"activeTab === 'single'\">\r\n <div *ngIf=\"singleDate\" class=\"time-config-item\">\r\n <div class=\"time-config-header\">\r\n <span class=\"date-label\">{{ formatDate(singleDate) }}</span>\r\n <label class=\"all-day-toggle\">\r\n <span class=\"toggle-label\">All Day</span>\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"singleAllDay\"\r\n (change)=\"onSingleAllDayChange()\">\r\n </label>\r\n </div>\r\n <div *ngIf=\"!singleAllDay\" class=\"time-inputs\">\r\n <bk-time-picker\r\n pickerId=\"single-start\"\r\n label=\"Start Time\"\r\n [value]=\"singleStartTime\"\r\n [position]=\"'left'\"\r\n [closePicker]=\"shouldClosePicker('single-start')\"\r\n (change)=\"onSingleStartTimeChange($event)\"\r\n (pickerOpened)=\"onTimePickerOpened($event)\"\r\n (pickerClosed)=\"onTimePickerClosed($event)\">\r\n </bk-time-picker>\r\n <bk-time-picker\r\n pickerId=\"single-end\"\r\n label=\"End Time\"\r\n [value]=\"singleEndTime\"\r\n [position]=\"'right'\"\r\n [closePicker]=\"shouldClosePicker('single-end')\"\r\n (change)=\"onSingleEndTimeChange($event)\"\r\n (pickerOpened)=\"onTimePickerOpened($event)\"\r\n (pickerClosed)=\"onTimePickerClosed($event)\">\r\n </bk-time-picker>\r\n </div>\r\n </div>\r\n <div *ngIf=\"!singleDate\" class=\"no-selection\">\r\n <p>No date selected. Select a date from the calendar.</p>\r\n </div>\r\n </div>\r\n\r\n <!-- Multiple Dates Time Configuration -->\r\n <div *ngIf=\"activeTab === 'multiple'\" class=\"time-config-list\">\r\n <div\r\n *ngFor=\"let dateConfig of multipleDates; let i = index\"\r\n class=\"time-config-item\">\r\n <div class=\"time-config-header\">\r\n <span class=\"date-label\">{{ formatDate(dateConfig.date) }}</span>\r\n <label class=\"all-day-toggle\">\r\n <span class=\"toggle-label\">All Day</span>\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"dateConfig.allDay\"\r\n (change)=\"onMultipleDateAllDayChange(i)\">\r\n </label>\r\n </div>\r\n <div *ngIf=\"!dateConfig.allDay\" class=\"time-inputs\">\r\n <bk-time-picker\r\n [pickerId]=\"'multiple-' + i + '-start'\"\r\n label=\"Start Time\"\r\n [value]=\"dateConfig.startTime\"\r\n [position]=\"'left'\"\r\n [closePicker]=\"shouldClosePicker('multiple-' + i + '-start')\"\r\n (change)=\"onMultipleDateStartTimeChange(i, $event)\"\r\n (pickerOpened)=\"onTimePickerOpened($event)\"\r\n (pickerClosed)=\"onTimePickerClosed($event)\">\r\n </bk-time-picker>\r\n <bk-time-picker\r\n [pickerId]=\"'multiple-' + i + '-end'\"\r\n label=\"End Time\"\r\n [value]=\"dateConfig.endTime\"\r\n [position]=\"'right'\"\r\n [closePicker]=\"shouldClosePicker('multiple-' + i + '-end')\"\r\n (change)=\"onMultipleDateEndTimeChange(i, $event)\"\r\n (pickerOpened)=\"onTimePickerOpened($event)\"\r\n (pickerClosed)=\"onTimePickerClosed($event)\">\r\n </bk-time-picker>\r\n </div>\r\n </div>\r\n <div *ngIf=\"multipleDates.length === 0\" class=\"no-selection\">\r\n <p>No dates selected. Select dates from the calendar.</p>\r\n </div>\r\n </div>\r\n\r\n <!-- Date Range Time Configuration -->\r\n <div *ngIf=\"activeTab === 'range' && rangeStartDate && rangeEndDate\" class=\"time-config-item\">\r\n <div class=\"time-config-header\">\r\n <span class=\"date-label\">{{ formatDate(rangeStartDate) }} - {{ formatDate(rangeEndDate) }}</span>\r\n <label class=\"all-day-toggle\">\r\n <span class=\"toggle-label\">All Day</span>\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"rangeAllDay\"\r\n (change)=\"onRangeAllDayChange()\">\r\n </label>\r\n </div>\r\n <div *ngIf=\"!rangeAllDay\" class=\"time-inputs\">\r\n <bk-time-picker\r\n pickerId=\"range-start\"\r\n label=\"Start Time\"\r\n [value]=\"rangeStartTime\"\r\n [position]=\"'left'\"\r\n [closePicker]=\"shouldClosePicker('range-start')\"\r\n (change)=\"onRangeStartTimeChange($event)\"\r\n (pickerOpened)=\"onTimePickerOpened($event)\"\r\n (pickerClosed)=\"onTimePickerClosed($event)\">\r\n </bk-time-picker>\r\n <bk-time-picker\r\n pickerId=\"range-end\"\r\n label=\"End Time\"\r\n [value]=\"rangeEndTime\"\r\n [position]=\"'right'\"\r\n [closePicker]=\"shouldClosePicker('range-end')\"\r\n (change)=\"onRangeEndTimeChange($event)\"\r\n (pickerOpened)=\"onTimePickerOpened($event)\"\r\n (pickerClosed)=\"onTimePickerClosed($event)\">\r\n </bk-time-picker>\r\n </div>\r\n </div>\r\n <div *ngIf=\"activeTab === 'range' && (!rangeStartDate || !rangeEndDate)\" class=\"no-selection\">\r\n <p>No date range selected. Select a date range from the calendar.</p>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Action Buttons -->\r\n <div class=\"action-buttons\">\r\n <button class=\"btn-clear\" (click)=\"clear()\">Clear</button>\r\n <button class=\"btn-apply\" (click)=\"apply()\">Apply</button>\r\n </div>\r\n</div>\r\n\r\n", styles: [".scheduled-date-picker-container{font-family:Inter,sans-serif;background:#fff;border-radius:12px;padding:0;box-shadow:0 2px 8px #0000001a;overflow:hidden;width:100%;max-width:100%;box-sizing:border-box}.scheduled-header{padding:24px 24px 16px;border-bottom:1px solid #e5e7eb;background:#fff}.scheduled-title{font-size:18px;font-weight:500;line-height:26px;color:#111827;letter-spacing:-.28px;margin:0 0 16px}.tabs{display:flex;margin-bottom:16px;border-radius:6px;padding:3px;background-color:#54578e12}.tab-button{padding:5px 11px;border:none;background:transparent;color:#6b7080;font-size:11px;font-weight:500;cursor:pointer;border:1px solid transparent;transition:all .2s;font-family:Inter,sans-serif;flex:1;border-radius:4px}.tab-button.active{color:#15191e;border-color:#42578a26;background:#fff}.scheduled-content{display:flex;gap:0;align-items:stretch}.calendar-section{flex:0 0 55%;max-width:55%;padding:12px;border-right:1px solid #e5e7eb;background:#fff;box-sizing:border-box}.calendar-wrapper-inline{width:100%}.calendar-wrapper-inline app-custom-calendar{width:100%}.time-config-section{flex:0 0 45%;max-width:45%;padding:12px;background:#fff;overflow-y:auto;max-height:600px;box-sizing:border-box}.time-config-title{font-size:16px;font-weight:600;color:#111827;margin:17px 0 14px}.time-config-item{padding:14px;border:1px solid #e5e7eb;border-radius:8px;background:#fff}.time-config-header{display:flex;justify-content:space-between;align-items:center}.date-label{font-size:12px;font-weight:500;color:#15191e;letter-spacing:-.28px}.all-day-toggle{display:flex;align-items:center;gap:5px;cursor:pointer;-webkit-user-select:none;user-select:none}.all-day-toggle input[type=checkbox]{width:28px;height:16px;appearance:none;background:#bbbdc5;border-radius:10px;position:relative;cursor:pointer;transition:background .2s;margin:0}.all-day-toggle input[type=checkbox]:checked{background:#22973f}.all-day-toggle input[type=checkbox]:before{content:\"\";position:absolute;width:12px;height:12px;border-radius:50%;background:#fff;top:1.5px;left:2.5px;transition:transform .2s;box-shadow:0 1px 3px #0003}.all-day-toggle input[type=checkbox]:checked:before{transform:translate(12px)}.toggle-label{font-size:12px;font-weight:500;color:#111827}.all-day-toggle input[type=checkbox]:checked+.toggle-label{color:#111827}.time-inputs{display:flex;gap:14px;margin-top:12px}.time-config-list{display:flex;flex-direction:column;gap:14px;max-height:350px;overflow-y:auto;padding-right:4px}.time-config-list::-webkit-scrollbar{width:6px;height:6px}.time-config-list::-webkit-scrollbar-track{background:#f1f1f1;border-radius:3px}.time-config-list::-webkit-scrollbar-thumb{background:#b4b4b4;border-radius:3px}.time-config-list::-webkit-scrollbar-thumb:hover{background:#9b9b9b}.no-selection{padding:24px;text-align:center;color:#9ca3af;font-size:14px}.action-buttons{display:flex;justify-content:flex-end;gap:12px;padding:12px;border-top:1px solid #e5e7eb;background:#fff}.btn-clear,.btn-apply{padding:10px 20px;border:none;border-radius:6px;font-size:14px;font-weight:500;cursor:pointer;transition:all .2s;font-family:Inter,sans-serif;min-width:80px}.btn-clear{background:#fff;color:#6b7280;border:1px solid #d1d5db}.btn-clear:hover{background:#f9fafb;border-color:#9ca3af}.btn-apply{background:#111827;color:#fff}.btn-apply:hover{background:#374151}@media (max-width: 1200px){.calendar-section{flex:0 0 52%;max-width:52%}.time-config-section{flex:0 0 48%;max-width:48%}}@media (max-width: 1024px){.scheduled-content{flex-direction:column}.calendar-section{flex:1 1 auto;max-width:100%;border-right:none;border-bottom:1px solid #e5e7eb}.time-config-section{flex:1 1 auto;max-width:100%;max-height:none}.time-config-list{max-height:320px}}@media (max-width: 768px){.scheduled-date-picker-container{border-radius:0}.scheduled-header{padding:16px}.calendar-section,.time-config-section{padding:12px 16px}.tabs{overflow-x:auto}.tab-button{white-space:nowrap;font-size:12px;padding:6px 10px}.time-inputs{flex-direction:column}.time-config-item{padding:12px}.action-buttons{padding:10px}}@media (max-width: 480px){.scheduled-title{font-size:16px}.time-config-title{font-size:14px}.date-label{font-size:11px}.time-config-list{max-height:260px}.btn-clear,.btn-apply{padding:8px 14px;font-size:13px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: BkCustomCalendar, selector: "bk-custom-calendar", inputs: ["enableTimepicker", "autoApply", "closeOnAutoApply", "showCancel", "linkedCalendars", "singleDatePicker", "showWeekNumbers", "showISOWeekNumbers", "customRangeDirection", "lockStartDate", "position", "drop", "dualCalendar", "showRanges", "timeFormat", "clearableTime", "enableSeconds", "customRanges", "multiDateSelection", "maxDate", "minDate", "placeholder", "opens", "inline", "appendToBody", "isDisplayCrossIcon", "hasError", "errorMessage", "showCancelApply", "selectedValue", "displayFormat", "required"], outputs: ["selected", "opened", "closed"] }, { kind: "component", type: BkTimePicker, selector: "bk-time-picker", inputs: ["required", "value", "label", "placeholder", "clearable", "position", "pickerId", "closePicker", "timeFormat", "showSeconds"], outputs: ["change", "timeChange", "pickerOpened", "pickerClosed"] }] });
|
|
2684
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: BkScheduledDatePicker, isStandalone: true, selector: "bk-scheduled-date-picker", inputs: { timeFormat: "timeFormat", enableSeconds: "enableSeconds" }, outputs: { scheduled: "scheduled", cleared: "cleared" }, ngImport: i0, template: "<div class=\"scheduled-date-picker-container\">\r\n <!-- Header with Tabs -->\r\n\r\n\r\n <!-- Main Content Area -->\r\n\r\n <div class=\"scheduled-content\">\r\n <!-- Left Side: Calendar -->\r\n <div class=\"calendar-section\">\r\n <h2 class=\"scheduled-title\">Scheduled Dates</h2>\r\n <div class=\"tabs\">\r\n <button\r\n class=\"tab-button\"\r\n [class.active]=\"activeTab === 'single'\"\r\n (click)=\"onTabChange('single')\">\r\n Single Date\r\n </button>\r\n <button\r\n class=\"tab-button\"\r\n [class.active]=\"activeTab === 'multiple'\"\r\n (click)=\"onTabChange('multiple')\">\r\n Multiple Dates\r\n </button>\r\n <button\r\n class=\"tab-button\"\r\n [class.active]=\"activeTab === 'range'\"\r\n (click)=\"onTabChange('range')\">\r\n Date Range\r\n </button>\r\n </div>\r\n <!-- Single Date Calendar -->\r\n <div *ngIf=\"activeTab === 'single'\" class=\"calendar-wrapper-inline\">\r\n <bk-custom-calendar\r\n [inline]=\"true\"\r\n [dualCalendar]=\"false\"\r\n [singleDatePicker]=\"true\"\r\n [showRanges]=\"false\"\r\n [enableTimepicker]=\"false\"\r\n [showCancel]=\"false\"\r\n placeholder=\"Select a date\"\r\n (selected)=\"onSingleDateSelected($event)\">\r\n </bk-custom-calendar>\r\n </div>\r\n\r\n <!-- Multiple Dates Calendar -->\r\n <div *ngIf=\"activeTab === 'multiple'\" class=\"calendar-wrapper-inline\">\r\n <bk-custom-calendar\r\n [inline]=\"true\"\r\n [dualCalendar]=\"false\"\r\n [singleDatePicker]=\"false\"\r\n [showRanges]=\"false\"\r\n [enableTimepicker]=\"false\"\r\n [multiDateSelection]=\"true\"\r\n [showCancel]=\"false\"\r\n placeholder=\"Select multiple dates\"\r\n (selected)=\"onMultipleDatesSelected($event)\">\r\n </bk-custom-calendar>\r\n </div>\r\n\r\n <!-- Date Range Calendar -->\r\n <div *ngIf=\"activeTab === 'range'\" class=\"calendar-wrapper-inline\">\r\n <bk-custom-calendar\r\n [inline]=\"true\"\r\n [dualCalendar]=\"false\"\r\n [singleDatePicker]=\"false\"\r\n [showRanges]=\"false\"\r\n [enableTimepicker]=\"false\"\r\n [showCancel]=\"false\"\r\n placeholder=\"Select date range\"\r\n (selected)=\"onRangeSelected($event)\">\r\n </bk-custom-calendar>\r\n </div>\r\n </div>\r\n\r\n <!-- Right Side: Time Configuration -->\r\n <div class=\"time-config-section\">\r\n <h3 class=\"time-config-title\">Time Configuration</h3>\r\n\r\n <!-- Single Date Time Configuration -->\r\n <div *ngIf=\"activeTab === 'single'\">\r\n <div *ngIf=\"singleDate\" class=\"time-config-item\">\r\n <div class=\"time-config-header\">\r\n <span class=\"date-label\">{{ formatDate(singleDate) }}</span>\r\n <label class=\"all-day-toggle\">\r\n <span class=\"toggle-label\">All Day</span>\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"singleAllDay\"\r\n (change)=\"onSingleAllDayChange()\">\r\n </label>\r\n </div>\r\n <div *ngIf=\"!singleAllDay\" class=\"time-inputs\">\r\n <bk-time-picker\r\n pickerId=\"single-start\"\r\n label=\"Start Time\"\r\n [value]=\"singleStartTime\"\r\n [position]=\"'left'\"\r\n [closePicker]=\"shouldClosePicker('single-start')\"\r\n (change)=\"onSingleStartTimeChange($event)\"\r\n (pickerOpened)=\"onTimePickerOpened($event)\"\r\n (pickerClosed)=\"onTimePickerClosed($event)\">\r\n </bk-time-picker>\r\n <bk-time-picker\r\n pickerId=\"single-end\"\r\n label=\"End Time\"\r\n [value]=\"singleEndTime\"\r\n [position]=\"'right'\"\r\n [closePicker]=\"shouldClosePicker('single-end')\"\r\n (change)=\"onSingleEndTimeChange($event)\"\r\n (pickerOpened)=\"onTimePickerOpened($event)\"\r\n (pickerClosed)=\"onTimePickerClosed($event)\">\r\n </bk-time-picker>\r\n </div>\r\n </div>\r\n <div *ngIf=\"!singleDate\" class=\"no-selection\">\r\n <p>No date selected. Select a date from the calendar.</p>\r\n </div>\r\n </div>\r\n\r\n <!-- Multiple Dates Time Configuration -->\r\n <div *ngIf=\"activeTab === 'multiple'\" class=\"time-config-list\">\r\n <div\r\n *ngFor=\"let dateConfig of multipleDates; let i = index\"\r\n class=\"time-config-item\">\r\n <div class=\"time-config-header\">\r\n <span class=\"date-label\">{{ formatDate(dateConfig.date) }}</span>\r\n <label class=\"all-day-toggle\">\r\n <span class=\"toggle-label\">All Day</span>\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"dateConfig.allDay\"\r\n (change)=\"onMultipleDateAllDayChange(i)\">\r\n </label>\r\n </div>\r\n <div *ngIf=\"!dateConfig.allDay\" class=\"time-inputs\">\r\n <bk-time-picker\r\n [pickerId]=\"'multiple-' + i + '-start'\"\r\n label=\"Start Time\"\r\n [value]=\"dateConfig.startTime\"\r\n [position]=\"'left'\"\r\n [closePicker]=\"shouldClosePicker('multiple-' + i + '-start')\"\r\n (change)=\"onMultipleDateStartTimeChange(i, $event)\"\r\n (pickerOpened)=\"onTimePickerOpened($event)\"\r\n (pickerClosed)=\"onTimePickerClosed($event)\">\r\n </bk-time-picker>\r\n <bk-time-picker\r\n [pickerId]=\"'multiple-' + i + '-end'\"\r\n label=\"End Time\"\r\n [value]=\"dateConfig.endTime\"\r\n [position]=\"'right'\"\r\n [closePicker]=\"shouldClosePicker('multiple-' + i + '-end')\"\r\n (change)=\"onMultipleDateEndTimeChange(i, $event)\"\r\n (pickerOpened)=\"onTimePickerOpened($event)\"\r\n (pickerClosed)=\"onTimePickerClosed($event)\">\r\n </bk-time-picker>\r\n </div>\r\n </div>\r\n <div *ngIf=\"multipleDates.length === 0\" class=\"no-selection\">\r\n <p>No dates selected. Select dates from the calendar.</p>\r\n </div>\r\n </div>\r\n\r\n <!-- Date Range Time Configuration -->\r\n <div *ngIf=\"activeTab === 'range' && rangeStartDate && rangeEndDate\" class=\"time-config-item\">\r\n <div class=\"time-config-header\">\r\n <span class=\"date-label\">{{ formatDate(rangeStartDate) }} - {{ formatDate(rangeEndDate) }}</span>\r\n <label class=\"all-day-toggle\">\r\n <span class=\"toggle-label\">All Day</span>\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"rangeAllDay\"\r\n (change)=\"onRangeAllDayChange()\">\r\n </label>\r\n </div>\r\n <div *ngIf=\"!rangeAllDay\" class=\"time-inputs\">\r\n <bk-time-picker\r\n pickerId=\"range-start\"\r\n label=\"Start Time\"\r\n [value]=\"rangeStartTime\"\r\n [position]=\"'left'\"\r\n [closePicker]=\"shouldClosePicker('range-start')\"\r\n (change)=\"onRangeStartTimeChange($event)\"\r\n (pickerOpened)=\"onTimePickerOpened($event)\"\r\n (pickerClosed)=\"onTimePickerClosed($event)\">\r\n </bk-time-picker>\r\n <bk-time-picker\r\n pickerId=\"range-end\"\r\n label=\"End Time\"\r\n [value]=\"rangeEndTime\"\r\n [position]=\"'right'\"\r\n [closePicker]=\"shouldClosePicker('range-end')\"\r\n (change)=\"onRangeEndTimeChange($event)\"\r\n (pickerOpened)=\"onTimePickerOpened($event)\"\r\n (pickerClosed)=\"onTimePickerClosed($event)\">\r\n </bk-time-picker>\r\n </div>\r\n </div>\r\n <div *ngIf=\"activeTab === 'range' && (!rangeStartDate || !rangeEndDate)\" class=\"no-selection\">\r\n <p>No date range selected. Select a date range from the calendar.</p>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Action Buttons -->\r\n <div class=\"action-buttons\">\r\n <button class=\"btn-clear\" (click)=\"clear()\">Clear</button>\r\n <button class=\"btn-apply\" (click)=\"apply()\">Apply</button>\r\n </div>\r\n</div>\r\n\r\n", styles: [".scheduled-date-picker-container{font-family:Inter,sans-serif;background:#fff;border-radius:12px;padding:0;box-shadow:0 2px 8px #0000001a;overflow:hidden;width:100%;max-width:100%;box-sizing:border-box}.scheduled-header{padding:24px 24px 16px;border-bottom:1px solid #e5e7eb;background:#fff}.scheduled-title{font-size:18px;font-weight:500;line-height:26px;color:#111827;letter-spacing:-.28px;margin:0 0 16px}.tabs{display:flex;margin-bottom:16px;border-radius:6px;padding:3px;background-color:#54578e12}.tab-button{padding:5px 11px;border:none;background:transparent;color:#6b7080;font-size:11px;font-weight:500;cursor:pointer;border:1px solid transparent;transition:all .2s;font-family:Inter,sans-serif;flex:1;border-radius:4px}.tab-button.active{color:#15191e;border-color:#42578a26;background:#fff}.scheduled-content{display:flex;gap:0;align-items:stretch}.calendar-section{flex:0 0 55%;max-width:55%;padding:12px;border-right:1px solid #e5e7eb;background:#fff;box-sizing:border-box}.calendar-wrapper-inline{width:100%}.calendar-wrapper-inline app-custom-calendar{width:100%}.time-config-section{flex:0 0 45%;max-width:45%;padding:12px;background:#fff;overflow-y:auto;max-height:600px;box-sizing:border-box}.time-config-title{font-size:16px;font-weight:600;color:#111827;margin:17px 0 14px}.time-config-item{padding:14px;border:1px solid #e5e7eb;border-radius:8px;background:#fff}.time-config-header{display:flex;justify-content:space-between;align-items:center}.date-label{font-size:12px;font-weight:500;color:#15191e;letter-spacing:-.28px}.all-day-toggle{display:flex;align-items:center;gap:5px;cursor:pointer;-webkit-user-select:none;user-select:none}.all-day-toggle input[type=checkbox]{width:28px;height:16px;appearance:none;background:#bbbdc5;border-radius:10px;position:relative;cursor:pointer;transition:background .2s;margin:0}.all-day-toggle input[type=checkbox]:checked{background:#22973f}.all-day-toggle input[type=checkbox]:before{content:\"\";position:absolute;width:12px;height:12px;border-radius:50%;background:#fff;top:1.5px;left:2.5px;transition:transform .2s;box-shadow:0 1px 3px #0003}.all-day-toggle input[type=checkbox]:checked:before{transform:translate(12px)}.toggle-label{font-size:12px;font-weight:500;color:#111827}.all-day-toggle input[type=checkbox]:checked+.toggle-label{color:#111827}.time-inputs{display:flex;gap:14px;margin-top:12px}.time-config-list{display:flex;flex-direction:column;gap:14px;max-height:350px;overflow-y:auto;padding-right:4px}.time-config-list::-webkit-scrollbar{width:6px;height:6px}.time-config-list::-webkit-scrollbar-track{background:#f1f1f1;border-radius:3px}.time-config-list::-webkit-scrollbar-thumb{background:#b4b4b4;border-radius:3px}.time-config-list::-webkit-scrollbar-thumb:hover{background:#9b9b9b}.no-selection{padding:24px;text-align:center;color:#9ca3af;font-size:14px}.action-buttons{display:flex;justify-content:flex-end;gap:12px;padding:12px;border-top:1px solid #e5e7eb;background:#fff}.btn-clear,.btn-apply{padding:10px 20px;border:none;border-radius:6px;font-size:14px;font-weight:500;cursor:pointer;transition:all .2s;font-family:Inter,sans-serif;min-width:80px}.btn-clear{background:#fff;color:#6b7280;border:1px solid #d1d5db}.btn-clear:hover{background:#f9fafb;border-color:#9ca3af}.btn-apply{background:#111827;color:#fff}.btn-apply:hover{background:#374151}@media (max-width: 1200px){.calendar-section{flex:0 0 52%;max-width:52%}.time-config-section{flex:0 0 48%;max-width:48%}}@media (max-width: 1024px){.scheduled-content{flex-direction:column}.calendar-section{flex:1 1 auto;max-width:100%;border-right:none;border-bottom:1px solid #e5e7eb}.time-config-section{flex:1 1 auto;max-width:100%;max-height:none}.time-config-list{max-height:320px}}@media (max-width: 768px){.scheduled-date-picker-container{border-radius:0}.scheduled-header{padding:16px}.calendar-section,.time-config-section{padding:12px 16px}.tabs{overflow-x:auto}.tab-button{white-space:nowrap;font-size:12px;padding:6px 10px}.time-inputs{flex-direction:column}.time-config-item{padding:12px}.action-buttons{padding:10px}}@media (max-width: 480px){.scheduled-title{font-size:16px}.time-config-title{font-size:14px}.date-label{font-size:11px}.time-config-list{max-height:260px}.btn-clear,.btn-apply{padding:8px 14px;font-size:13px}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: FormsModule }, { kind: "component", type: BkCustomCalendar, selector: "bk-custom-calendar", inputs: ["enableTimepicker", "autoApply", "closeOnAutoApply", "showCancel", "linkedCalendars", "singleDatePicker", "showWeekNumbers", "showISOWeekNumbers", "customRangeDirection", "lockStartDate", "position", "drop", "dualCalendar", "showRanges", "timeFormat", "clearableTime", "enableSeconds", "customRanges", "multiDateSelection", "maxDate", "minDate", "placeholder", "opens", "inline", "appendToBody", "isDisplayCrossIcon", "hasError", "errorMessage", "showCancelApply", "selectedValue", "displayFormat", "required"], outputs: ["selected", "opened", "closed"] }, { kind: "component", type: BkTimePicker, selector: "bk-time-picker", inputs: ["required", "value", "label", "placeholder", "clearable", "position", "pickerId", "closePicker", "timeFormat", "showSeconds", "disabled"], outputs: ["change", "timeChange", "pickerOpened", "pickerClosed"] }] });
|
|
2763
2685
|
}
|
|
2764
2686
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: BkScheduledDatePicker, decorators: [{
|
|
2765
2687
|
type: Component,
|