@rolldate/mcp 1.1.0 → 1.3.1
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/AGENTS.md +12 -3
- package/README.md +39 -12
- package/package.json +6 -3
- package/src/catalog-events.js +241 -0
- package/src/catalog.js +11 -10
- package/src/index.js +121 -97
- package/src/products.js +73 -0
- package/templates/AGENTS.md +12 -3
- package/templates/rolldate-mcp.mdc +17 -4
- package/vendor/rolldate/rolldate.css +297 -134
- package/vendor/rolldate/rolldate.js +311 -112
- package/vendor/rolldate/rolldate.min.css +1 -1
- package/vendor/rolldate/rolldate.min.js +1 -1
- package/vendor/rolldate-events/rolldate-events.css +1 -0
- package/vendor/rolldate-events/rolldate-events.mjs +2 -0
|
@@ -454,49 +454,55 @@ var RollDate = (function () {
|
|
|
454
454
|
? options.weekDays
|
|
455
455
|
: ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
|
|
456
456
|
this.enableTime = Boolean(options.enableTime);
|
|
457
|
-
this.hasFooter = Boolean(options.
|
|
457
|
+
this.hasFooter = Boolean(options.footerButtons && options.footerButtons.length);
|
|
458
458
|
|
|
459
459
|
this.init();
|
|
460
460
|
}
|
|
461
461
|
|
|
462
462
|
init() {
|
|
463
|
+
const timePanelHtml = this.enableTime
|
|
464
|
+
? '<div class="RollDate__time-separator" aria-hidden="true"></div><div class="RollDate__time-panel"><div class="RollDate__time"></div></div>'
|
|
465
|
+
: '';
|
|
466
|
+
|
|
463
467
|
const footerHtml = this.hasFooter ? `
|
|
464
468
|
<div class="RollDate__footer">
|
|
465
|
-
${this.enableTime ? '<div class="RollDate__time"></div>' : ''}
|
|
466
469
|
<div class="RollDate__footer__buttons"></div>
|
|
467
470
|
</div>
|
|
468
471
|
` : '';
|
|
469
472
|
|
|
470
473
|
this.$container.innerHTML = `
|
|
471
|
-
<div class="
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
<div class="
|
|
474
|
+
<div class="RollDate__content">
|
|
475
|
+
<div class="RollDate__calendar">
|
|
476
|
+
<div class="RollDate__header">
|
|
477
|
+
<div class="RollDate__calendar__switcher">
|
|
478
|
+
<div class="RollDate__header__year"></div>
|
|
479
|
+
<div class="RollDate__header__month"></div>
|
|
480
|
+
</div>
|
|
481
|
+
<div class="RollDate__calendar__buttons">
|
|
482
|
+
<button class="RollDate__calendar__button" data-direction="prev">
|
|
483
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 61 55" width="55" height="50">
|
|
484
|
+
<path id="Форма 2" fill-rule="evenodd" class="s0" d="m52.76 54.67l-44.73 0.12c-6.16 0.02-10.02-6.64-6.96-11.98l22.26-38.79c3.07-5.35 10.76-5.37 13.86-0.04l22.47 38.67c3.09 5.33-0.74 12.01-6.9 12.02z"/>
|
|
485
|
+
</svg>
|
|
486
|
+
</button>
|
|
487
|
+
<button class="RollDate__calendar__button" data-direction="next">
|
|
488
|
+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 61 55" width="55" height="50">
|
|
489
|
+
<path id="Форма 2" fill-rule="evenodd" class="s0" d="m52.76 54.67l-44.73 0.12c-6.16 0.02-10.02-6.64-6.96-11.98l22.26-38.79c3.07-5.35 10.76-5.37 13.86-0.04l22.47 38.67c3.09 5.33-0.74 12.01-6.9 12.02z" />
|
|
490
|
+
</svg>
|
|
491
|
+
</button>
|
|
492
|
+
</div>
|
|
475
493
|
</div>
|
|
476
|
-
<div class="
|
|
477
|
-
|
|
478
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 61 55" width="55" height="50">
|
|
479
|
-
<path id="Форма 2" fill-rule="evenodd" class="s0" d="m52.76 54.67l-44.73 0.12c-6.16 0.02-10.02-6.64-6.96-11.98l22.26-38.79c3.07-5.35 10.76-5.37 13.86-0.04l22.47 38.67c3.09 5.33-0.74 12.01-6.9 12.02z"/>
|
|
480
|
-
</svg>
|
|
481
|
-
</button>
|
|
482
|
-
<button class="RollDate__calendar__button" data-direction="next">
|
|
483
|
-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 61 55" width="55" height="50">
|
|
484
|
-
<path id="Форма 2" fill-rule="evenodd" class="s0" d="m52.76 54.67l-44.73 0.12c-6.16 0.02-10.02-6.64-6.96-11.98l22.26-38.79c3.07-5.35 10.76-5.37 13.86-0.04l22.47 38.67c3.09 5.33-0.74 12.01-6.9 12.02z" />
|
|
485
|
-
</svg>
|
|
486
|
-
</button>
|
|
494
|
+
<div class="RollDate__calendar__header">
|
|
495
|
+
${this.#dayHeaders()}
|
|
487
496
|
</div>
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
<div class="RollDate__calendar__scrollblock">
|
|
495
|
-
<div class="RollDate__calendar__days"></div>
|
|
496
|
-
<div class="RollDate__calendar__months"></div>
|
|
497
|
-
<div class="RollDate__calendar__years"></div>
|
|
497
|
+
<div class="RollDate__calendar__body">
|
|
498
|
+
<div class="RollDate__calendar__scrollblock">
|
|
499
|
+
<div class="RollDate__calendar__days"></div>
|
|
500
|
+
<div class="RollDate__calendar__months"></div>
|
|
501
|
+
<div class="RollDate__calendar__years"></div>
|
|
502
|
+
</div>
|
|
498
503
|
</div>
|
|
499
504
|
</div>
|
|
505
|
+
${timePanelHtml}
|
|
500
506
|
</div>
|
|
501
507
|
${footerHtml}
|
|
502
508
|
`;
|
|
@@ -655,6 +661,10 @@ var RollDate = (function () {
|
|
|
655
661
|
#lastEdgeTriggerAt = 0
|
|
656
662
|
#isTouchDragging = false
|
|
657
663
|
#touchLastY = 0
|
|
664
|
+
#touchLastTime = 0
|
|
665
|
+
#touchVelocity = 0
|
|
666
|
+
#momentumId = 0
|
|
667
|
+
#animId = 0
|
|
658
668
|
|
|
659
669
|
constructor(body, methods = {
|
|
660
670
|
dominant: () => console.error('Function "dominant" is not found'),
|
|
@@ -684,6 +694,7 @@ var RollDate = (function () {
|
|
|
684
694
|
wheelHandler(e) {
|
|
685
695
|
e.preventDefault();
|
|
686
696
|
e.stopPropagation();
|
|
697
|
+
this.#cancelMomentum();
|
|
687
698
|
|
|
688
699
|
const rawDelta = e.deltaY * 0.85;
|
|
689
700
|
const steps = Math.abs(rawDelta) > 50 ? 20 : 1;
|
|
@@ -715,8 +726,11 @@ var RollDate = (function () {
|
|
|
715
726
|
|
|
716
727
|
touchStartHandler(e) {
|
|
717
728
|
if (!e.touches || e.touches.length !== 1) return
|
|
729
|
+
this.#cancelMomentum();
|
|
718
730
|
this.#isTouchDragging = true;
|
|
719
731
|
this.#touchLastY = e.touches[0].clientY;
|
|
732
|
+
this.#touchLastTime = performance.now();
|
|
733
|
+
this.#touchVelocity = 0;
|
|
720
734
|
this.#edgeTriggeredInCurrentWheel = false;
|
|
721
735
|
}
|
|
722
736
|
|
|
@@ -726,7 +740,13 @@ var RollDate = (function () {
|
|
|
726
740
|
|
|
727
741
|
const currentY = e.touches[0].clientY;
|
|
728
742
|
const deltaY = currentY - this.#touchLastY;
|
|
743
|
+
const now = performance.now();
|
|
744
|
+
const dt = now - this.#touchLastTime;
|
|
745
|
+
if (dt > 0 && dt < 120) {
|
|
746
|
+
this.#touchVelocity = this.#touchVelocity * 0.65 + (deltaY / dt) * 0.35;
|
|
747
|
+
}
|
|
729
748
|
this.#touchLastY = currentY;
|
|
749
|
+
this.#touchLastTime = now;
|
|
730
750
|
|
|
731
751
|
if (Math.abs(deltaY) < 1) return
|
|
732
752
|
|
|
@@ -740,6 +760,86 @@ var RollDate = (function () {
|
|
|
740
760
|
touchEndHandler() {
|
|
741
761
|
this.#isTouchDragging = false;
|
|
742
762
|
this.#edgeTriggeredInCurrentWheel = false;
|
|
763
|
+
|
|
764
|
+
const v = this.#touchVelocity * 16;
|
|
765
|
+
if (Math.abs(v) < 0.4) return
|
|
766
|
+
|
|
767
|
+
let velocity = v;
|
|
768
|
+
const step = () => {
|
|
769
|
+
if (Math.abs(velocity) < 0.35) {
|
|
770
|
+
this.#momentumId = 0;
|
|
771
|
+
return
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
const prevOffset = this.#offset;
|
|
775
|
+
this.offset += velocity;
|
|
776
|
+
if (this.#offset === prevOffset) {
|
|
777
|
+
this.#momentumId = 0;
|
|
778
|
+
return
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
this.dominant();
|
|
782
|
+
const direction = velocity < 0 ? 'down' : 'up';
|
|
783
|
+
this.checkEdge(direction);
|
|
784
|
+
|
|
785
|
+
velocity *= 0.92;
|
|
786
|
+
this.#momentumId = requestAnimationFrame(step);
|
|
787
|
+
};
|
|
788
|
+
this.#momentumId = requestAnimationFrame(step);
|
|
789
|
+
}
|
|
790
|
+
|
|
791
|
+
#cancelMomentum() {
|
|
792
|
+
if (!this.#momentumId) return
|
|
793
|
+
cancelAnimationFrame(this.#momentumId);
|
|
794
|
+
this.#momentumId = 0;
|
|
795
|
+
}
|
|
796
|
+
|
|
797
|
+
#cancelAnimate() {
|
|
798
|
+
if (!this.#animId) return
|
|
799
|
+
cancelAnimationFrame(this.#animId);
|
|
800
|
+
this.#animId = 0;
|
|
801
|
+
this.blocked = false;
|
|
802
|
+
}
|
|
803
|
+
|
|
804
|
+
animateTo(targetOffset, opts = {}) {
|
|
805
|
+
this.#cancelMomentum();
|
|
806
|
+
this.#cancelAnimate();
|
|
807
|
+
|
|
808
|
+
const duration = opts.duration ?? 220;
|
|
809
|
+
const start = this.#offset;
|
|
810
|
+
const min = this.minScroll;
|
|
811
|
+
const target = Math.max(Math.min(targetOffset, 0), min);
|
|
812
|
+
|
|
813
|
+
if (Math.abs(target - start) < 1) {
|
|
814
|
+
this.offset = target;
|
|
815
|
+
this.dominant();
|
|
816
|
+
opts.onComplete?.();
|
|
817
|
+
return Promise.resolve()
|
|
818
|
+
}
|
|
819
|
+
|
|
820
|
+
this.blocked = true;
|
|
821
|
+
const startTime = performance.now();
|
|
822
|
+
|
|
823
|
+
return new Promise(resolve => {
|
|
824
|
+
const step = (now) => {
|
|
825
|
+
const t = Math.min(1, (now - startTime) / duration);
|
|
826
|
+
const eased = 1 - Math.pow(1 - t, 3);
|
|
827
|
+
this.offset = start + (target - start) * eased;
|
|
828
|
+
|
|
829
|
+
if (t < 1) {
|
|
830
|
+
this.#animId = requestAnimationFrame(step);
|
|
831
|
+
return
|
|
832
|
+
}
|
|
833
|
+
|
|
834
|
+
this.offset = target;
|
|
835
|
+
this.blocked = false;
|
|
836
|
+
this.dominant();
|
|
837
|
+
this.#animId = 0;
|
|
838
|
+
opts.onComplete?.();
|
|
839
|
+
resolve();
|
|
840
|
+
};
|
|
841
|
+
this.#animId = requestAnimationFrame(step);
|
|
842
|
+
})
|
|
743
843
|
}
|
|
744
844
|
|
|
745
845
|
apply() {
|
|
@@ -810,6 +910,8 @@ var RollDate = (function () {
|
|
|
810
910
|
}
|
|
811
911
|
|
|
812
912
|
destroy() {
|
|
913
|
+
this.#cancelMomentum();
|
|
914
|
+
this.#cancelAnimate();
|
|
813
915
|
if (this.#boundWheelHandler) {
|
|
814
916
|
this.$body.removeEventListener('wheel', this.#boundWheelHandler);
|
|
815
917
|
}
|
|
@@ -1066,11 +1168,8 @@ var RollDate = (function () {
|
|
|
1066
1168
|
}
|
|
1067
1169
|
}
|
|
1068
1170
|
|
|
1069
|
-
const
|
|
1070
|
-
|
|
1071
|
-
const ARROW_SVG = `<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 61 55" width="55" height="50" aria-hidden="true">
|
|
1072
|
-
<path fill-rule="evenodd" d="m52.76 54.67l-44.73 0.12c-6.16 0.02-10.02-6.64-6.96-11.98l22.26-38.79c3.07-5.35 10.76-5.37 13.86-0.04l22.47 38.67c3.09 5.33-0.74 12.01-6.9 12.02z"/>
|
|
1073
|
-
</svg>`;
|
|
1171
|
+
const DEFAULT_ITEM_HEIGHT = 28;
|
|
1172
|
+
const DEFAULT_VISIBLE = 3;
|
|
1074
1173
|
|
|
1075
1174
|
class TimePicker {
|
|
1076
1175
|
#hours = 0
|
|
@@ -1079,7 +1178,6 @@ var RollDate = (function () {
|
|
|
1079
1178
|
#period = 'AM'
|
|
1080
1179
|
#minuteStep = 1
|
|
1081
1180
|
#columns = []
|
|
1082
|
-
#displayEl = null
|
|
1083
1181
|
|
|
1084
1182
|
constructor(root, options = {}) {
|
|
1085
1183
|
this.root = root;
|
|
@@ -1113,7 +1211,83 @@ var RollDate = (function () {
|
|
|
1113
1211
|
return Math.min(59, Math.max(0, Number.isNaN(m) ? 0 : m))
|
|
1114
1212
|
}
|
|
1115
1213
|
|
|
1214
|
+
#readMetrics(viewport) {
|
|
1215
|
+
const container = viewport.closest('.RollDate__container');
|
|
1216
|
+
const cs = container ? getComputedStyle(container) : getComputedStyle(viewport);
|
|
1217
|
+
const itemH = parseFloat(cs.getPropertyValue('--rd-time-item-h')) || DEFAULT_ITEM_HEIGHT;
|
|
1218
|
+
const visible = parseInt(cs.getPropertyValue('--rd-time-visible'), 10) || DEFAULT_VISIBLE;
|
|
1219
|
+
const pad = Math.floor((visible - 1) / 2) * itemH;
|
|
1220
|
+
return { itemH, visible, pad }
|
|
1221
|
+
}
|
|
1222
|
+
|
|
1116
1223
|
#build() {
|
|
1224
|
+
this.root.innerHTML = `
|
|
1225
|
+
<div class="RollDate__time__picker"></div>
|
|
1226
|
+
<div class="RollDate__time__period">
|
|
1227
|
+
<div class="RollDate__time__segmented RollDate__time__segmented--period" data-role="period">
|
|
1228
|
+
<button type="button" class="RollDate__time__segment-btn" data-period="AM">AM</button>
|
|
1229
|
+
<button type="button" class="RollDate__time__segment-btn" data-period="PM">PM</button>
|
|
1230
|
+
</div>
|
|
1231
|
+
</div>
|
|
1232
|
+
`;
|
|
1233
|
+
|
|
1234
|
+
if (this.#use12Hour) {
|
|
1235
|
+
this.root.classList.add('RollDate__time--12h');
|
|
1236
|
+
}
|
|
1237
|
+
this.#bindToolbar();
|
|
1238
|
+
this.#buildPickerColumns();
|
|
1239
|
+
this.#syncToolbar();
|
|
1240
|
+
}
|
|
1241
|
+
|
|
1242
|
+
#bindToolbar() {
|
|
1243
|
+
this.root.querySelector('[data-role="period"]')?.addEventListener('click', (e) => {
|
|
1244
|
+
const btn = e.target.closest('[data-period]');
|
|
1245
|
+
if (!btn || !this.#use12Hour) return
|
|
1246
|
+
this.#setPeriod(btn.dataset.period);
|
|
1247
|
+
});
|
|
1248
|
+
}
|
|
1249
|
+
|
|
1250
|
+
#setPeriod(period) {
|
|
1251
|
+
if (period !== 'AM' && period !== 'PM') return
|
|
1252
|
+
if (this.#period === period) return
|
|
1253
|
+
|
|
1254
|
+
this.#readColumns();
|
|
1255
|
+
const was = this.#period;
|
|
1256
|
+
this.#period = period;
|
|
1257
|
+
|
|
1258
|
+
if (was === 'AM' && period === 'PM' && this.#hours < 12) {
|
|
1259
|
+
this.#hours += 12;
|
|
1260
|
+
} else if (was === 'PM' && period === 'AM' && this.#hours >= 12) {
|
|
1261
|
+
this.#hours -= 12;
|
|
1262
|
+
}
|
|
1263
|
+
|
|
1264
|
+
this.#columns.find(c => c.unit === 'hour')?.scrollToValue(this.#displayHour(), true);
|
|
1265
|
+
this.#syncToolbar();
|
|
1266
|
+
hapticTick(this.hapticFeedback);
|
|
1267
|
+
this.#commitTime();
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1270
|
+
#syncToolbar() {
|
|
1271
|
+
this.root.classList.toggle('RollDate__time--12h', this.#use12Hour);
|
|
1272
|
+
|
|
1273
|
+
this.root.querySelectorAll('[data-period]').forEach((btn) => {
|
|
1274
|
+
const active = btn.dataset.period === this.#period;
|
|
1275
|
+
btn.classList.toggle('RollDate__time__segment-btn--active', active);
|
|
1276
|
+
btn.setAttribute('aria-pressed', active ? 'true' : 'false');
|
|
1277
|
+
});
|
|
1278
|
+
}
|
|
1279
|
+
|
|
1280
|
+
#destroyColumns() {
|
|
1281
|
+
this.#columns.forEach((column) => column._resizeObserver?.disconnect());
|
|
1282
|
+
this.#columns = [];
|
|
1283
|
+
}
|
|
1284
|
+
|
|
1285
|
+
#buildPickerColumns() {
|
|
1286
|
+
this.#destroyColumns();
|
|
1287
|
+
|
|
1288
|
+
const picker = this.root.querySelector('.RollDate__time__picker');
|
|
1289
|
+
if (!picker) return
|
|
1290
|
+
|
|
1117
1291
|
const hourValues = this.#use12Hour
|
|
1118
1292
|
? Array.from({ length: 12 }, (_, i) => i + 1)
|
|
1119
1293
|
: Array.from({ length: 24 }, (_, i) => i);
|
|
@@ -1123,76 +1297,38 @@ var RollDate = (function () {
|
|
|
1123
1297
|
minuteValues.push(m);
|
|
1124
1298
|
}
|
|
1125
1299
|
|
|
1126
|
-
|
|
1127
|
-
<div class="RollDate__time__picker">
|
|
1300
|
+
picker.innerHTML = `
|
|
1128
1301
|
<div class="RollDate__time__field" data-unit="hour">
|
|
1129
1302
|
<div class="RollDate__time__column">
|
|
1130
|
-
<button type="button" class="RollDate__time__arrow RollDate__time__arrow--prev" data-dir="prev" aria-label="Earlier hour">${ARROW_SVG}</button>
|
|
1131
1303
|
<div class="RollDate__time__viewport">
|
|
1132
1304
|
<div class="RollDate__time__list"></div>
|
|
1133
1305
|
</div>
|
|
1134
|
-
<button type="button" class="RollDate__time__arrow RollDate__time__arrow--next" data-dir="next" aria-label="Later hour">${ARROW_SVG}</button>
|
|
1135
1306
|
</div>
|
|
1136
1307
|
</div>
|
|
1137
1308
|
<span class="RollDate__time__sep">:</span>
|
|
1138
1309
|
<div class="RollDate__time__field" data-unit="minute">
|
|
1139
1310
|
<div class="RollDate__time__column">
|
|
1140
|
-
<button type="button" class="RollDate__time__arrow RollDate__time__arrow--prev" data-dir="prev" aria-label="Earlier minute">${ARROW_SVG}</button>
|
|
1141
1311
|
<div class="RollDate__time__viewport">
|
|
1142
1312
|
<div class="RollDate__time__list"></div>
|
|
1143
1313
|
</div>
|
|
1144
|
-
<button type="button" class="RollDate__time__arrow RollDate__time__arrow--next" data-dir="next" aria-label="Later minute">${ARROW_SVG}</button>
|
|
1145
1314
|
</div>
|
|
1146
1315
|
</div>
|
|
1147
|
-
${this.#use12Hour ? `
|
|
1148
|
-
<div class="RollDate__time__field RollDate__time__field--period" data-unit="period">
|
|
1149
|
-
<div class="RollDate__time__column">
|
|
1150
|
-
<button type="button" class="RollDate__time__arrow RollDate__time__arrow--prev" data-dir="prev" aria-label="Earlier period">${ARROW_SVG}</button>
|
|
1151
|
-
<div class="RollDate__time__viewport">
|
|
1152
|
-
<div class="RollDate__time__list"></div>
|
|
1153
|
-
</div>
|
|
1154
|
-
<button type="button" class="RollDate__time__arrow RollDate__time__arrow--next" data-dir="next" aria-label="Later period">${ARROW_SVG}</button>
|
|
1155
|
-
</div>
|
|
1156
|
-
</div>` : ''}
|
|
1157
|
-
</div>
|
|
1158
|
-
<div class="RollDate__time__display" aria-live="polite"></div>
|
|
1159
1316
|
`;
|
|
1160
1317
|
|
|
1161
|
-
this.#
|
|
1162
|
-
if (this.#use12Hour) {
|
|
1163
|
-
this.root.classList.add('RollDate__time--12h');
|
|
1164
|
-
}
|
|
1165
|
-
|
|
1166
|
-
this.#columns.push(this.#createColumn('hour', hourValues, this.#displayHour()));
|
|
1318
|
+
this.#columns.push(this.#createColumn('hour', hourValues, this.#use12Hour ? this.#displayHour() : this.#hours));
|
|
1167
1319
|
this.#columns.push(this.#createColumn('minute', minuteValues, this.#minutes));
|
|
1168
|
-
if (this.#use12Hour) {
|
|
1169
|
-
this.#columns.push(this.#createColumn('period', ['AM', 'PM'], this.#period));
|
|
1170
|
-
}
|
|
1171
|
-
|
|
1172
|
-
this.#updateDisplay();
|
|
1173
|
-
}
|
|
1174
|
-
|
|
1175
|
-
#formatDisplay() {
|
|
1176
|
-
const hours = String(this.#hours).padStart(2, '0');
|
|
1177
|
-
const minutes = String(this.#minutes).padStart(2, '0');
|
|
1178
|
-
if (this.#use12Hour) {
|
|
1179
|
-
return `${String(this.#displayHour()).padStart(2, '0')}:${minutes} ${this.#period}`
|
|
1180
|
-
}
|
|
1181
|
-
return `${hours}:${minutes}`
|
|
1182
|
-
}
|
|
1183
|
-
|
|
1184
|
-
#updateDisplay() {
|
|
1185
|
-
if (this.#displayEl) {
|
|
1186
|
-
this.#displayEl.textContent = this.#formatDisplay();
|
|
1187
|
-
}
|
|
1188
1320
|
}
|
|
1189
1321
|
|
|
1190
1322
|
#commitTime() {
|
|
1191
1323
|
this.#readColumns();
|
|
1192
|
-
this.#updateDisplay();
|
|
1193
1324
|
this.onChange(this.getTime());
|
|
1194
1325
|
}
|
|
1195
1326
|
|
|
1327
|
+
#parseItemValue(unit, raw) {
|
|
1328
|
+
if (unit === 'period') return raw
|
|
1329
|
+
return Number(raw)
|
|
1330
|
+
}
|
|
1331
|
+
|
|
1196
1332
|
#createColumn(unit, values, initial) {
|
|
1197
1333
|
const field = this.root.querySelector(`[data-unit="${unit}"]`);
|
|
1198
1334
|
const viewport = field.querySelector('.RollDate__time__viewport');
|
|
@@ -1205,17 +1341,22 @@ var RollDate = (function () {
|
|
|
1205
1341
|
return `<div class="RollDate__time__item" data-value="${value}">${label}</div>`
|
|
1206
1342
|
}).join('');
|
|
1207
1343
|
|
|
1208
|
-
list.style.paddingTop = `${ITEM_HEIGHT}px`;
|
|
1209
|
-
list.style.paddingBottom = `${ITEM_HEIGHT}px`;
|
|
1210
|
-
|
|
1211
1344
|
const column = {
|
|
1212
1345
|
unit,
|
|
1213
1346
|
viewport,
|
|
1214
1347
|
list,
|
|
1215
1348
|
values,
|
|
1216
|
-
offset: 0
|
|
1349
|
+
offset: 0,
|
|
1350
|
+
getMetrics: () => this.#readMetrics(viewport)
|
|
1217
1351
|
};
|
|
1218
1352
|
|
|
1353
|
+
const applyPadding = () => {
|
|
1354
|
+
const { pad } = column.getMetrics();
|
|
1355
|
+
list.style.paddingTop = `${pad}px`;
|
|
1356
|
+
list.style.paddingBottom = `${pad}px`;
|
|
1357
|
+
};
|
|
1358
|
+
applyPadding();
|
|
1359
|
+
|
|
1219
1360
|
column.updateActive = () => {
|
|
1220
1361
|
const index = column.indexFromOffset();
|
|
1221
1362
|
if (column._lastIndex !== index) {
|
|
@@ -1231,7 +1372,8 @@ var RollDate = (function () {
|
|
|
1231
1372
|
};
|
|
1232
1373
|
|
|
1233
1374
|
column.indexFromOffset = () => {
|
|
1234
|
-
const
|
|
1375
|
+
const { itemH } = column.getMetrics();
|
|
1376
|
+
const raw = Math.round(-column.offset / itemH);
|
|
1235
1377
|
return Math.min(values.length - 1, Math.max(0, raw))
|
|
1236
1378
|
};
|
|
1237
1379
|
|
|
@@ -1244,42 +1386,51 @@ var RollDate = (function () {
|
|
|
1244
1386
|
};
|
|
1245
1387
|
|
|
1246
1388
|
column.snap = () => {
|
|
1389
|
+
const { itemH } = column.getMetrics();
|
|
1247
1390
|
const index = column.indexFromOffset();
|
|
1248
|
-
column.offset = -index *
|
|
1391
|
+
column.offset = -index * itemH;
|
|
1249
1392
|
column._lastIndex = index;
|
|
1250
1393
|
column.apply(true);
|
|
1251
1394
|
this.#commitTime();
|
|
1252
1395
|
};
|
|
1253
1396
|
|
|
1254
1397
|
column.scrollToValue = (value, animate = true) => {
|
|
1398
|
+
const { itemH } = column.getMetrics();
|
|
1255
1399
|
const index = values.indexOf(value);
|
|
1256
1400
|
if (index < 0) return
|
|
1257
|
-
column.offset = -index *
|
|
1401
|
+
column.offset = -index * itemH;
|
|
1402
|
+
column._lastIndex = index;
|
|
1258
1403
|
column.apply(animate);
|
|
1259
1404
|
};
|
|
1260
1405
|
|
|
1261
|
-
column.
|
|
1262
|
-
const
|
|
1263
|
-
|
|
1264
|
-
column.
|
|
1406
|
+
column.scrollToIndex = (index, animate = true) => {
|
|
1407
|
+
const { itemH } = column.getMetrics();
|
|
1408
|
+
const clamped = Math.min(values.length - 1, Math.max(0, index));
|
|
1409
|
+
column.offset = -clamped * itemH;
|
|
1410
|
+
column._lastIndex = clamped;
|
|
1411
|
+
column.apply(animate);
|
|
1265
1412
|
};
|
|
1266
1413
|
|
|
1267
1414
|
column.scrollToValue(initial, false);
|
|
1268
1415
|
this.#bindWheel(column);
|
|
1269
1416
|
this.#bindTouch(column);
|
|
1270
|
-
this.#
|
|
1417
|
+
this.#bindItemClick(column);
|
|
1418
|
+
column._resizeObserver = new ResizeObserver(() => {
|
|
1419
|
+
applyPadding();
|
|
1420
|
+
column.scrollToIndex(column.indexFromOffset(), false);
|
|
1421
|
+
});
|
|
1422
|
+
column._resizeObserver.observe(viewport);
|
|
1271
1423
|
|
|
1272
1424
|
return column
|
|
1273
1425
|
}
|
|
1274
1426
|
|
|
1275
|
-
#
|
|
1276
|
-
|
|
1277
|
-
e.
|
|
1278
|
-
|
|
1279
|
-
|
|
1280
|
-
|
|
1281
|
-
|
|
1282
|
-
column.stepBy(1);
|
|
1427
|
+
#bindItemClick(column) {
|
|
1428
|
+
column.list.addEventListener('click', (e) => {
|
|
1429
|
+
const item = e.target.closest('.RollDate__time__item');
|
|
1430
|
+
if (!item) return
|
|
1431
|
+
const value = this.#parseItemValue(column.unit, item.dataset.value);
|
|
1432
|
+
column.scrollToValue(value, true);
|
|
1433
|
+
this.#commitTime();
|
|
1283
1434
|
});
|
|
1284
1435
|
}
|
|
1285
1436
|
|
|
@@ -1287,9 +1438,10 @@ var RollDate = (function () {
|
|
|
1287
1438
|
column.viewport.addEventListener('wheel', (e) => {
|
|
1288
1439
|
e.preventDefault();
|
|
1289
1440
|
e.stopPropagation();
|
|
1441
|
+
const { itemH } = column.getMetrics();
|
|
1290
1442
|
column.list.style.transition = 'none';
|
|
1291
1443
|
column.offset -= e.deltaY * 0.35;
|
|
1292
|
-
const min = -(column.values.length - 1) *
|
|
1444
|
+
const min = -(column.values.length - 1) * itemH;
|
|
1293
1445
|
column.offset = Math.max(min, Math.min(0, column.offset));
|
|
1294
1446
|
column.list.style.transform = `translateY(${column.offset}px)`;
|
|
1295
1447
|
column.updateActive();
|
|
@@ -1312,8 +1464,9 @@ var RollDate = (function () {
|
|
|
1312
1464
|
column.viewport.addEventListener('touchmove', (e) => {
|
|
1313
1465
|
if (!e.touches || e.touches.length !== 1) return
|
|
1314
1466
|
e.preventDefault();
|
|
1467
|
+
const { itemH } = column.getMetrics();
|
|
1315
1468
|
column.offset = startOffset + (e.touches[0].clientY - startY);
|
|
1316
|
-
const min = -(column.values.length - 1) *
|
|
1469
|
+
const min = -(column.values.length - 1) * itemH;
|
|
1317
1470
|
column.offset = Math.max(min, Math.min(0, column.offset));
|
|
1318
1471
|
column.list.style.transform = `translateY(${column.offset}px)`;
|
|
1319
1472
|
column.updateActive();
|
|
@@ -1325,13 +1478,12 @@ var RollDate = (function () {
|
|
|
1325
1478
|
#readColumns() {
|
|
1326
1479
|
const hourCol = this.#columns.find(c => c.unit === 'hour');
|
|
1327
1480
|
const minuteCol = this.#columns.find(c => c.unit === 'minute');
|
|
1328
|
-
|
|
1481
|
+
if (!hourCol || !minuteCol) return
|
|
1329
1482
|
|
|
1330
1483
|
const hourValue = hourCol.getValue();
|
|
1331
1484
|
this.#minutes = minuteCol.getValue();
|
|
1332
1485
|
|
|
1333
|
-
if (this.#use12Hour
|
|
1334
|
-
this.#period = periodCol.getValue();
|
|
1486
|
+
if (this.#use12Hour) {
|
|
1335
1487
|
if (this.#period === 'AM') {
|
|
1336
1488
|
this.#hours = hourValue === 12 ? 0 : hourValue;
|
|
1337
1489
|
} else {
|
|
@@ -1352,16 +1504,15 @@ var RollDate = (function () {
|
|
|
1352
1504
|
if (this.#use12Hour) {
|
|
1353
1505
|
this.#period = this.#hours >= 12 ? 'PM' : 'AM';
|
|
1354
1506
|
this.#columns.find(c => c.unit === 'hour')?.scrollToValue(this.#displayHour());
|
|
1355
|
-
this.#columns.find(c => c.unit === 'period')?.scrollToValue(this.#period);
|
|
1356
1507
|
} else {
|
|
1357
1508
|
this.#columns.find(c => c.unit === 'hour')?.scrollToValue(this.#hours);
|
|
1358
1509
|
}
|
|
1359
1510
|
this.#columns.find(c => c.unit === 'minute')?.scrollToValue(this.#minutes);
|
|
1360
|
-
this.#
|
|
1511
|
+
this.#syncToolbar();
|
|
1361
1512
|
}
|
|
1362
1513
|
|
|
1363
1514
|
destroy() {
|
|
1364
|
-
this.#
|
|
1515
|
+
this.#destroyColumns();
|
|
1365
1516
|
this.root.innerHTML = '';
|
|
1366
1517
|
}
|
|
1367
1518
|
}
|
|
@@ -1371,6 +1522,7 @@ var RollDate = (function () {
|
|
|
1371
1522
|
|
|
1372
1523
|
#wheelHandler
|
|
1373
1524
|
#viewNumber = 0
|
|
1525
|
+
#arrowAnimating = false
|
|
1374
1526
|
#viewPeriodNames = ['day', 'month', 'year']
|
|
1375
1527
|
#selectedDates = []
|
|
1376
1528
|
#firstOpen = true
|
|
@@ -1581,6 +1733,11 @@ var RollDate = (function () {
|
|
|
1581
1733
|
const btn = document.createElement('button');
|
|
1582
1734
|
btn.type = 'button';
|
|
1583
1735
|
btn.className = 'RollDate__footer__button';
|
|
1736
|
+
if (cfg.variant === 'primary') {
|
|
1737
|
+
btn.classList.add('RollDate__footer__button--primary');
|
|
1738
|
+
} else if (cfg.variant === 'secondary') {
|
|
1739
|
+
btn.classList.add('RollDate__footer__button--secondary');
|
|
1740
|
+
}
|
|
1584
1741
|
btn.textContent = cfg.text;
|
|
1585
1742
|
btn.addEventListener('click', (e) => {
|
|
1586
1743
|
e.preventDefault();
|
|
@@ -1712,7 +1869,7 @@ var RollDate = (function () {
|
|
|
1712
1869
|
|
|
1713
1870
|
const baseOptions = {
|
|
1714
1871
|
mode: 'auto',
|
|
1715
|
-
theme: '
|
|
1872
|
+
theme: 'main',
|
|
1716
1873
|
startWeekFromMonday: true,
|
|
1717
1874
|
selectType: 'single',
|
|
1718
1875
|
monthsNames: ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
|
|
@@ -1729,6 +1886,7 @@ var RollDate = (function () {
|
|
|
1729
1886
|
enableTime: false,
|
|
1730
1887
|
use12Hour: false,
|
|
1731
1888
|
timeStep: 1,
|
|
1889
|
+
timePosition: 'right',
|
|
1732
1890
|
footerButtons: [],
|
|
1733
1891
|
rangePresets: [],
|
|
1734
1892
|
hapticFeedback: true,
|
|
@@ -1736,7 +1894,7 @@ var RollDate = (function () {
|
|
|
1736
1894
|
};
|
|
1737
1895
|
|
|
1738
1896
|
if (baseOptions.theme === 'default') {
|
|
1739
|
-
baseOptions.theme = '
|
|
1897
|
+
baseOptions.theme = 'main';
|
|
1740
1898
|
}
|
|
1741
1899
|
|
|
1742
1900
|
const resolvedLocale = baseOptions.locale ||
|
|
@@ -1816,8 +1974,10 @@ var RollDate = (function () {
|
|
|
1816
1974
|
|
|
1817
1975
|
if (this.options.enableTime) {
|
|
1818
1976
|
this.$container.classList.add('RollDate__has-time');
|
|
1977
|
+
const timePosition = this.options.timePosition === 'bottom' ? 'bottom' : 'right';
|
|
1978
|
+
this.$container.classList.add(`RollDate__time-position_${timePosition}`);
|
|
1819
1979
|
}
|
|
1820
|
-
if (this.options.footerButtons?.length
|
|
1980
|
+
if (this.options.footerButtons?.length) {
|
|
1821
1981
|
this.$container.classList.add('RollDate__has-footer');
|
|
1822
1982
|
}
|
|
1823
1983
|
|
|
@@ -1923,6 +2083,13 @@ var RollDate = (function () {
|
|
|
1923
2083
|
|
|
1924
2084
|
const preserveScroll = options.preserveScroll === true;
|
|
1925
2085
|
const savedOffset = preserveScroll ? this.scroll.offset : null;
|
|
2086
|
+
const animateScroll = options.animate === true && Number(options.shift);
|
|
2087
|
+
const onScrollComplete = typeof options.onScrollComplete === 'function'
|
|
2088
|
+
? options.onScrollComplete
|
|
2089
|
+
: null;
|
|
2090
|
+
const finishScroll = () => {
|
|
2091
|
+
onScrollComplete?.();
|
|
2092
|
+
};
|
|
1926
2093
|
|
|
1927
2094
|
this.#updateHeader();
|
|
1928
2095
|
this.scroll.blocked = false;
|
|
@@ -1953,6 +2120,7 @@ var RollDate = (function () {
|
|
|
1953
2120
|
if (blockHeight <= bodyHeight) {
|
|
1954
2121
|
this.scroll.setBaseOffset(bodyHeight - blockHeight);
|
|
1955
2122
|
this.scroll.offset = 0;
|
|
2123
|
+
finishScroll();
|
|
1956
2124
|
return
|
|
1957
2125
|
}
|
|
1958
2126
|
|
|
@@ -1961,6 +2129,7 @@ var RollDate = (function () {
|
|
|
1961
2129
|
|
|
1962
2130
|
if (preserveScroll && savedOffset != null) {
|
|
1963
2131
|
this.scroll.offset = Math.max(savedOffset, this.scroll.minScroll);
|
|
2132
|
+
finishScroll();
|
|
1964
2133
|
return
|
|
1965
2134
|
}
|
|
1966
2135
|
|
|
@@ -1979,12 +2148,29 @@ var RollDate = (function () {
|
|
|
1979
2148
|
$firstEl = this.$container.querySelector(fallbacks[this.period]);
|
|
1980
2149
|
}
|
|
1981
2150
|
|
|
1982
|
-
if (!$firstEl)
|
|
2151
|
+
if (!$firstEl) {
|
|
2152
|
+
finishScroll();
|
|
2153
|
+
return
|
|
2154
|
+
}
|
|
1983
2155
|
|
|
1984
2156
|
const containerRect = $scrollBlock.getBoundingClientRect();
|
|
1985
2157
|
const firstRect = $firstEl.getBoundingClientRect();
|
|
1986
2158
|
const firstRectOffset = -(firstRect.top - containerRect.top);
|
|
1987
|
-
|
|
2159
|
+
const targetOffset = Math.max(firstRectOffset, this.scroll.minScroll);
|
|
2160
|
+
|
|
2161
|
+
if (animateScroll) {
|
|
2162
|
+
const slide = Math.min(bodyHeight * 0.38, 140);
|
|
2163
|
+
const startOffset = Math.max(
|
|
2164
|
+
Math.min(targetOffset + (options.shift > 0 ? slide : -slide), 0),
|
|
2165
|
+
this.scroll.minScroll
|
|
2166
|
+
);
|
|
2167
|
+
this.scroll.offset = startOffset;
|
|
2168
|
+
this.scroll.animateTo(targetOffset, { onComplete: finishScroll });
|
|
2169
|
+
return
|
|
2170
|
+
}
|
|
2171
|
+
|
|
2172
|
+
this.scroll.offset = targetOffset;
|
|
2173
|
+
finishScroll();
|
|
1988
2174
|
};
|
|
1989
2175
|
|
|
1990
2176
|
setTimeout(applyScroll, 0);
|
|
@@ -2245,6 +2431,8 @@ var RollDate = (function () {
|
|
|
2245
2431
|
e.preventDefault();
|
|
2246
2432
|
e.stopPropagation();
|
|
2247
2433
|
|
|
2434
|
+
if (this.#arrowAnimating) return
|
|
2435
|
+
|
|
2248
2436
|
const direction = e.currentTarget?.dataset?.direction;
|
|
2249
2437
|
if (direction !== 'prev' && direction !== 'next') return
|
|
2250
2438
|
const shift = direction === 'prev' ? -1 : 1;
|
|
@@ -2281,8 +2469,15 @@ var RollDate = (function () {
|
|
|
2281
2469
|
this.data.current_decade = targetDecade;
|
|
2282
2470
|
}
|
|
2283
2471
|
|
|
2472
|
+
this.#arrowAnimating = true;
|
|
2284
2473
|
hapticTick(this.options.hapticFeedback !== false);
|
|
2285
|
-
this.#updateView(this.#viewNumber
|
|
2474
|
+
this.#updateView(this.#viewNumber, {
|
|
2475
|
+
animate: true,
|
|
2476
|
+
shift,
|
|
2477
|
+
onScrollComplete: () => {
|
|
2478
|
+
this.#arrowAnimating = false;
|
|
2479
|
+
}
|
|
2480
|
+
});
|
|
2286
2481
|
});
|
|
2287
2482
|
});
|
|
2288
2483
|
}
|
|
@@ -2807,6 +3002,10 @@ var RollDate = (function () {
|
|
|
2807
3002
|
this.data.current_month = now.getMonth();
|
|
2808
3003
|
this.data.current_decade = getDecade(now.getFullYear());
|
|
2809
3004
|
|
|
3005
|
+
if (this.options.enableTime && this.timePicker) {
|
|
3006
|
+
this.timePicker.setTime(now.getHours(), now.getMinutes());
|
|
3007
|
+
}
|
|
3008
|
+
|
|
2810
3009
|
const selected = this.#applyTimeToDate(now);
|
|
2811
3010
|
|
|
2812
3011
|
if (this.options.selectType === 'single') {
|