@brickclay-org/ui 0.1.25 → 0.1.27
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 +99 -52
- package/fesm2022/brickclay-org-ui.mjs.map +1 -1
- package/index.d.ts +11 -0
- package/package.json +1 -1
|
@@ -657,6 +657,32 @@ class BkCustomCalendar {
|
|
|
657
657
|
return false;
|
|
658
658
|
return !this.startDate || !this.endDate;
|
|
659
659
|
}
|
|
660
|
+
/**
|
|
661
|
+
* Popup single-date with manual Apply: do not push to ngModel / (selected) until Apply.
|
|
662
|
+
* Inline calendars have no Apply footer, so they always commit immediately.
|
|
663
|
+
*/
|
|
664
|
+
shouldDeferSingleDateCommit() {
|
|
665
|
+
return this.singleDatePicker && !this.autoApply && !this.inline;
|
|
666
|
+
}
|
|
667
|
+
emitSelectionUnlessSingleDateDeferred() {
|
|
668
|
+
if (this.shouldDeferSingleDateCommit())
|
|
669
|
+
return;
|
|
670
|
+
this.emitSelection();
|
|
671
|
+
}
|
|
672
|
+
/** Discard in-popup draft and restore last committed value from {@link selectedValue}. */
|
|
673
|
+
revertSingleDateDraftIfNeeded() {
|
|
674
|
+
if (this.shouldDeferSingleDateCommit()) {
|
|
675
|
+
this.applyValueToState(this.selectedValue ?? null);
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
finishPopupDismissal() {
|
|
679
|
+
if (this.inline)
|
|
680
|
+
return;
|
|
681
|
+
this.revertSingleDateDraftIfNeeded();
|
|
682
|
+
this.show = false;
|
|
683
|
+
this.onTouched();
|
|
684
|
+
this.closed.emit();
|
|
685
|
+
}
|
|
660
686
|
/** User preference before viewport adjustment (legacy `drop` still applies when `popupPosition` is `bottom`). */
|
|
661
687
|
preferPopupAbove() {
|
|
662
688
|
return this.popupPosition === 'top' || (this.popupPosition === 'bottom' && this.drop === 'up');
|
|
@@ -730,6 +756,29 @@ class BkCustomCalendar {
|
|
|
730
756
|
markAsTouched() {
|
|
731
757
|
this.onTouched();
|
|
732
758
|
}
|
|
759
|
+
/** Clears embedded time picker ngModels, spinner state, raw minute typing, and forces dropdowns closed. */
|
|
760
|
+
resetEmbeddedTimePickerUiState() {
|
|
761
|
+
this.singleTimeModel = null;
|
|
762
|
+
this.startTimeModel = null;
|
|
763
|
+
this.endTimeModel = null;
|
|
764
|
+
this.selectedHour = 1;
|
|
765
|
+
this.selectedMinute = 0;
|
|
766
|
+
this.selectedSecond = 0;
|
|
767
|
+
this.selectedAMPM = 'AM';
|
|
768
|
+
this.startHour = 1;
|
|
769
|
+
this.startMinute = 0;
|
|
770
|
+
this.startSecond = 0;
|
|
771
|
+
this.startAMPM = 'AM';
|
|
772
|
+
this.endHour = 2;
|
|
773
|
+
this.endMinute = 0;
|
|
774
|
+
this.endSecond = 0;
|
|
775
|
+
this.endAMPM = 'AM';
|
|
776
|
+
this.minuteInputValues = {};
|
|
777
|
+
this.openTimePickerId = null;
|
|
778
|
+
for (const id of ['single-time', 'dual-start', 'dual-end']) {
|
|
779
|
+
this.closePickerCounter[id] = (this.closePickerCounter[id] || 0) + 1;
|
|
780
|
+
}
|
|
781
|
+
}
|
|
733
782
|
/** Apply CalendarSelection to internal state (startDate, endDate, startTime, endTime, selectedDates, calendar view). */
|
|
734
783
|
applyValueToState(value) {
|
|
735
784
|
if (!value) {
|
|
@@ -738,9 +787,8 @@ class BkCustomCalendar {
|
|
|
738
787
|
this.startTime = null;
|
|
739
788
|
this.endTime = null;
|
|
740
789
|
this.selectedDates = [];
|
|
741
|
-
this.
|
|
742
|
-
this.
|
|
743
|
-
this.endTimeModel = null;
|
|
790
|
+
this.activeRange = null;
|
|
791
|
+
this.resetEmbeddedTimePickerUiState();
|
|
744
792
|
this.month = this.today.getMonth();
|
|
745
793
|
this.year = this.today.getFullYear();
|
|
746
794
|
this.generateCalendar();
|
|
@@ -817,8 +865,13 @@ class BkCustomCalendar {
|
|
|
817
865
|
this.selectedAMPM = this.startAMPM;
|
|
818
866
|
}
|
|
819
867
|
else if (this.startDate) {
|
|
868
|
+
// Date-only committed value: keep startTime null; sync spinners for UX only (not emitted until user sets time).
|
|
820
869
|
this.initializeTimeFromDate(this.startDate, true);
|
|
821
|
-
|
|
870
|
+
if (!this.dualCalendar) {
|
|
871
|
+
this.selectedHour = this.startHour;
|
|
872
|
+
this.selectedMinute = this.startMinute;
|
|
873
|
+
this.selectedAMPM = this.startAMPM;
|
|
874
|
+
}
|
|
822
875
|
}
|
|
823
876
|
if (this.endTime) {
|
|
824
877
|
const endParsed = this.parsePickerTimeString(this.endTime);
|
|
@@ -836,7 +889,6 @@ class BkCustomCalendar {
|
|
|
836
889
|
}
|
|
837
890
|
else if (this.endDate) {
|
|
838
891
|
this.initializeTimeFromDate(this.endDate, false);
|
|
839
|
-
this.endTime = this.formatTimeToAmPm(this.endHour, this.endMinute, this.endAMPM);
|
|
840
892
|
}
|
|
841
893
|
if (this.startDate && this.endDate) {
|
|
842
894
|
this.checkAndSetActiveRange();
|
|
@@ -880,9 +932,14 @@ class BkCustomCalendar {
|
|
|
880
932
|
this.initializeDual();
|
|
881
933
|
else
|
|
882
934
|
this.generateCalendar();
|
|
883
|
-
// Initialize
|
|
935
|
+
// Initialize spinner state from existing dates (does not set startTime/endTime — those stay null until user picks time).
|
|
884
936
|
if (this.startDate) {
|
|
885
937
|
this.initializeTimeFromDate(this.startDate, true);
|
|
938
|
+
if (!this.dualCalendar) {
|
|
939
|
+
this.selectedHour = this.startHour;
|
|
940
|
+
this.selectedMinute = this.startMinute;
|
|
941
|
+
this.selectedAMPM = this.startAMPM;
|
|
942
|
+
}
|
|
886
943
|
}
|
|
887
944
|
if (this.endDate) {
|
|
888
945
|
this.initializeTimeFromDate(this.endDate, false);
|
|
@@ -1025,7 +1082,7 @@ class BkCustomCalendar {
|
|
|
1025
1082
|
this.opened.emit();
|
|
1026
1083
|
}
|
|
1027
1084
|
else {
|
|
1028
|
-
this.
|
|
1085
|
+
this.finishPopupDismissal();
|
|
1029
1086
|
}
|
|
1030
1087
|
}
|
|
1031
1088
|
/** Update popup position when appendToBody is true (fixed positioning relative to viewport). */
|
|
@@ -1247,13 +1304,10 @@ class BkCustomCalendar {
|
|
|
1247
1304
|
}
|
|
1248
1305
|
}
|
|
1249
1306
|
close() {
|
|
1250
|
-
// Don't close if inline mode is enabled
|
|
1251
1307
|
if (this.inline) {
|
|
1252
1308
|
return;
|
|
1253
1309
|
}
|
|
1254
|
-
this.
|
|
1255
|
-
this.onTouched();
|
|
1256
|
-
this.closed.emit();
|
|
1310
|
+
this.finishPopupDismissal();
|
|
1257
1311
|
}
|
|
1258
1312
|
onDateHover(day, fromRight = false) {
|
|
1259
1313
|
if (!day || this.singleDatePicker || this.multiDateSelection) {
|
|
@@ -1339,8 +1393,7 @@ class BkCustomCalendar {
|
|
|
1339
1393
|
this.close();
|
|
1340
1394
|
}
|
|
1341
1395
|
else {
|
|
1342
|
-
|
|
1343
|
-
this.emitSelection();
|
|
1396
|
+
this.emitSelectionUnlessSingleDateDeferred();
|
|
1344
1397
|
}
|
|
1345
1398
|
return;
|
|
1346
1399
|
}
|
|
@@ -1477,23 +1530,21 @@ class BkCustomCalendar {
|
|
|
1477
1530
|
return;
|
|
1478
1531
|
// Format minute inputs to 2 digits before applying
|
|
1479
1532
|
this.formatAllMinuteInputs();
|
|
1480
|
-
// Apply time
|
|
1533
|
+
// Apply time only when the user has an explicit time string (avoids inventing "12:00 AM" from picker defaults).
|
|
1481
1534
|
if (this.enableTimepicker) {
|
|
1482
1535
|
if (this.dualCalendar) {
|
|
1483
|
-
|
|
1484
|
-
if (this.startDate) {
|
|
1536
|
+
if (this.startDate && this.startTime != null) {
|
|
1485
1537
|
this.applyTimeToDate(this.startDate, true);
|
|
1486
1538
|
}
|
|
1487
|
-
if (this.endDate) {
|
|
1539
|
+
if (this.endDate && this.endTime != null) {
|
|
1488
1540
|
this.applyTimeToDate(this.endDate, false);
|
|
1489
1541
|
}
|
|
1490
1542
|
}
|
|
1491
1543
|
else {
|
|
1492
|
-
|
|
1493
|
-
if (this.startDate) {
|
|
1544
|
+
if (this.startDate && this.startTime != null) {
|
|
1494
1545
|
this.applyTimeToDate(this.startDate, true);
|
|
1495
1546
|
}
|
|
1496
|
-
if (this.endDate && !this.singleDatePicker) {
|
|
1547
|
+
if (this.endDate && !this.singleDatePicker && this.startTime != null) {
|
|
1497
1548
|
this.applyTimeToDate(this.endDate, true);
|
|
1498
1549
|
}
|
|
1499
1550
|
}
|
|
@@ -1508,10 +1559,14 @@ class BkCustomCalendar {
|
|
|
1508
1559
|
cancel() {
|
|
1509
1560
|
if (this.disabled)
|
|
1510
1561
|
return;
|
|
1511
|
-
this.
|
|
1512
|
-
this.
|
|
1513
|
-
|
|
1514
|
-
|
|
1562
|
+
// if (this.shouldDeferSingleDateCommit()) {
|
|
1563
|
+
// this.finishPopupDismissal();
|
|
1564
|
+
// return;
|
|
1565
|
+
// }
|
|
1566
|
+
// this.startDate = null;
|
|
1567
|
+
// this.endDate = null;
|
|
1568
|
+
// this.selectedDates = [];
|
|
1569
|
+
// this.resetCalendarFocusAfterClear();
|
|
1515
1570
|
this.close();
|
|
1516
1571
|
}
|
|
1517
1572
|
clear() {
|
|
@@ -1521,22 +1576,9 @@ class BkCustomCalendar {
|
|
|
1521
1576
|
this.endDate = null;
|
|
1522
1577
|
this.startTime = null;
|
|
1523
1578
|
this.endTime = null;
|
|
1524
|
-
// Time picker for single calendar (12-hour format: 1-12)
|
|
1525
|
-
this.selectedHour = 1;
|
|
1526
|
-
this.selectedMinute = 0;
|
|
1527
|
-
this.selectedSecond = 0;
|
|
1528
|
-
this.selectedAMPM = 'AM';
|
|
1529
|
-
// NEW: Separate time pickers for dual calendar (12-hour format: 1-12)
|
|
1530
|
-
this.startHour = 1;
|
|
1531
|
-
this.startMinute = 0;
|
|
1532
|
-
this.startSecond = 0;
|
|
1533
|
-
this.startAMPM = 'AM';
|
|
1534
|
-
this.endHour = 2;
|
|
1535
|
-
this.endMinute = 0;
|
|
1536
|
-
this.endSecond = 0;
|
|
1537
|
-
this.endAMPM = 'AM';
|
|
1538
1579
|
this.selectedDates = [];
|
|
1539
|
-
this.activeRange = null;
|
|
1580
|
+
this.activeRange = null;
|
|
1581
|
+
this.resetEmbeddedTimePickerUiState();
|
|
1540
1582
|
this.resetCalendarFocusAfterClear();
|
|
1541
1583
|
this.emitSelection();
|
|
1542
1584
|
}
|
|
@@ -1616,8 +1658,13 @@ class BkCustomCalendar {
|
|
|
1616
1658
|
else if (this.startDate) {
|
|
1617
1659
|
this.keyboardFocusDate = new Date(this.startDate.getFullYear(), this.startDate.getMonth(), this.startDate.getDate());
|
|
1618
1660
|
}
|
|
1619
|
-
this.
|
|
1620
|
-
if (this.
|
|
1661
|
+
this.emitSelectionUnlessSingleDateDeferred();
|
|
1662
|
+
if (this.shouldDeferSingleDateCommit()) {
|
|
1663
|
+
if (this.autoApply) {
|
|
1664
|
+
this.apply();
|
|
1665
|
+
}
|
|
1666
|
+
}
|
|
1667
|
+
else if (this.autoApply || this.closeOnAutoApply) {
|
|
1621
1668
|
this.close();
|
|
1622
1669
|
}
|
|
1623
1670
|
}
|
|
@@ -1981,7 +2028,7 @@ class BkCustomCalendar {
|
|
|
1981
2028
|
if (this.startDate) {
|
|
1982
2029
|
this.startDate.setHours(0, 0, this.selectedSecond);
|
|
1983
2030
|
}
|
|
1984
|
-
this.
|
|
2031
|
+
this.emitSelectionUnlessSingleDateDeferred();
|
|
1985
2032
|
return;
|
|
1986
2033
|
}
|
|
1987
2034
|
const { hour12, minute, ampm } = this.parsePickerTimeString(time);
|
|
@@ -1998,7 +2045,7 @@ class BkCustomCalendar {
|
|
|
1998
2045
|
h24 = 0;
|
|
1999
2046
|
this.startDate.setHours(h24, minute, this.selectedSecond);
|
|
2000
2047
|
}
|
|
2001
|
-
this.
|
|
2048
|
+
this.emitSelectionUnlessSingleDateDeferred();
|
|
2002
2049
|
}
|
|
2003
2050
|
// NEW: Handle BkTimePicker change for dual calendar
|
|
2004
2051
|
onDualTimePickerChange(time, isStart = true) {
|
|
@@ -2079,7 +2126,7 @@ class BkCustomCalendar {
|
|
|
2079
2126
|
this.selectedMinute = m;
|
|
2080
2127
|
if (this.startDate) {
|
|
2081
2128
|
this.startDate.setHours(h, m, this.selectedSecond);
|
|
2082
|
-
this.
|
|
2129
|
+
this.emitSelectionUnlessSingleDateDeferred();
|
|
2083
2130
|
}
|
|
2084
2131
|
}
|
|
2085
2132
|
// Custom time picker controls
|
|
@@ -2240,7 +2287,7 @@ class BkCustomCalendar {
|
|
|
2240
2287
|
if (this.selectedAMPM === 'AM' && h === 12)
|
|
2241
2288
|
h = 0;
|
|
2242
2289
|
this.startDate.setHours(h, this.selectedMinute, this.selectedSecond);
|
|
2243
|
-
this.
|
|
2290
|
+
this.emitSelectionUnlessSingleDateDeferred();
|
|
2244
2291
|
}
|
|
2245
2292
|
}
|
|
2246
2293
|
decrementSingleHour() {
|
|
@@ -2256,7 +2303,7 @@ class BkCustomCalendar {
|
|
|
2256
2303
|
if (this.selectedAMPM === 'AM' && h === 12)
|
|
2257
2304
|
h = 0;
|
|
2258
2305
|
this.startDate.setHours(h, this.selectedMinute, this.selectedSecond);
|
|
2259
|
-
this.
|
|
2306
|
+
this.emitSelectionUnlessSingleDateDeferred();
|
|
2260
2307
|
}
|
|
2261
2308
|
}
|
|
2262
2309
|
incrementSingleMinute() {
|
|
@@ -2268,7 +2315,7 @@ class BkCustomCalendar {
|
|
|
2268
2315
|
if (this.selectedAMPM === 'AM' && h === 12)
|
|
2269
2316
|
h = 0;
|
|
2270
2317
|
this.startDate.setHours(h, this.selectedMinute, this.selectedSecond);
|
|
2271
|
-
this.
|
|
2318
|
+
this.emitSelectionUnlessSingleDateDeferred();
|
|
2272
2319
|
}
|
|
2273
2320
|
}
|
|
2274
2321
|
decrementSingleMinute() {
|
|
@@ -2280,7 +2327,7 @@ class BkCustomCalendar {
|
|
|
2280
2327
|
if (this.selectedAMPM === 'AM' && h === 12)
|
|
2281
2328
|
h = 0;
|
|
2282
2329
|
this.startDate.setHours(h, this.selectedMinute, this.selectedSecond);
|
|
2283
|
-
this.
|
|
2330
|
+
this.emitSelectionUnlessSingleDateDeferred();
|
|
2284
2331
|
}
|
|
2285
2332
|
}
|
|
2286
2333
|
toggleSingleAMPM() {
|
|
@@ -2292,7 +2339,7 @@ class BkCustomCalendar {
|
|
|
2292
2339
|
if (this.selectedAMPM === 'AM' && h === 12)
|
|
2293
2340
|
h = 0;
|
|
2294
2341
|
this.startDate.setHours(h, this.selectedMinute, this.selectedSecond);
|
|
2295
|
-
this.
|
|
2342
|
+
this.emitSelectionUnlessSingleDateDeferred();
|
|
2296
2343
|
}
|
|
2297
2344
|
}
|
|
2298
2345
|
getMonthName(month) {
|
|
@@ -2321,7 +2368,7 @@ class BkCustomCalendar {
|
|
|
2321
2368
|
if (this.selectedAMPM === 'AM' && h === 12)
|
|
2322
2369
|
h = 0;
|
|
2323
2370
|
this.startDate.setHours(h, this.selectedMinute, this.selectedSecond);
|
|
2324
|
-
this.
|
|
2371
|
+
this.emitSelectionUnlessSingleDateDeferred();
|
|
2325
2372
|
}
|
|
2326
2373
|
}
|
|
2327
2374
|
else if (isStart) {
|
|
@@ -2376,7 +2423,7 @@ class BkCustomCalendar {
|
|
|
2376
2423
|
if (this.selectedAMPM === 'AM' && h === 12)
|
|
2377
2424
|
h = 0;
|
|
2378
2425
|
this.startDate.setHours(h, this.selectedMinute, this.selectedSecond);
|
|
2379
|
-
this.
|
|
2426
|
+
this.emitSelectionUnlessSingleDateDeferred();
|
|
2380
2427
|
}
|
|
2381
2428
|
}
|
|
2382
2429
|
else if (isStart) {
|
|
@@ -2470,7 +2517,7 @@ class BkCustomCalendar {
|
|
|
2470
2517
|
if (this.selectedAMPM === 'AM' && h === 12)
|
|
2471
2518
|
h = 0;
|
|
2472
2519
|
this.startDate.setHours(h, this.selectedMinute, this.selectedSecond);
|
|
2473
|
-
this.
|
|
2520
|
+
this.emitSelectionUnlessSingleDateDeferred();
|
|
2474
2521
|
}
|
|
2475
2522
|
}
|
|
2476
2523
|
else if (isStart) {
|