@digitransit-component/digitransit-component-datetimepicker 7.1.1 → 9.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/index.cjs +1 -1
- package/lib/index.cjs.map +1 -1
- package/lib/index.development.cjs +592 -524
- package/lib/index.js +564 -494
- package/lib/index.js.map +1 -1
- package/package.json +12 -16
package/lib/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import PropTypes from 'prop-types';
|
|
2
|
-
import
|
|
2
|
+
import { useState, useEffect, useRef, useMemo } from 'react';
|
|
3
3
|
import { useTranslation, I18nextProvider } from 'react-i18next';
|
|
4
4
|
import { DateTime, Settings } from 'luxon';
|
|
5
5
|
import debounce from 'lodash/debounce';
|
|
@@ -7,6 +7,7 @@ import uniqueId from 'lodash/uniqueId';
|
|
|
7
7
|
import Icon from '@digitransit-component/digitransit-component-icon';
|
|
8
8
|
import Select from 'react-select';
|
|
9
9
|
import cx from 'classnames';
|
|
10
|
+
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
10
11
|
import Modal from 'react-modal';
|
|
11
12
|
import { useSelect } from 'downshift';
|
|
12
13
|
import { createInstance } from 'i18next';
|
|
@@ -260,144 +261,146 @@ function DesktopDatetimepicker({
|
|
|
260
261
|
return isValidHour ? option.label.split(':')[0] === comp.split(':')[0] : true;
|
|
261
262
|
};
|
|
262
263
|
const ariaError = t('invalid-input', translationSettings);
|
|
263
|
-
return /*#__PURE__*/
|
|
264
|
+
return /*#__PURE__*/jsxs("label", {
|
|
264
265
|
className: styles['combobox-container'],
|
|
265
|
-
htmlFor: inputId
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
266
|
+
htmlFor: inputId,
|
|
267
|
+
children: [/*#__PURE__*/jsxs("span", {
|
|
268
|
+
className: styles['sr-only'],
|
|
269
|
+
id: labelId,
|
|
270
|
+
children: [label, " ", displayValue]
|
|
271
|
+
}), icon, /*#__PURE__*/jsx(Select, {
|
|
272
|
+
"aria-labelledby": labelId,
|
|
273
|
+
ariaLiveMessages: {
|
|
274
|
+
guidance: context => {
|
|
275
|
+
// When user types invalid value, isDisabled becomes undefined instead of false
|
|
276
|
+
if (context.isDisabled === undefined && invalidInput) {
|
|
277
|
+
return ariaError;
|
|
278
|
+
}
|
|
279
|
+
return '.'; // this can't be empty for some reason
|
|
280
|
+
},
|
|
281
|
+
onChange: () => {
|
|
282
|
+
return '';
|
|
283
|
+
},
|
|
284
|
+
onFilter: () => {
|
|
285
|
+
return '';
|
|
286
|
+
},
|
|
287
|
+
onFocus: ({
|
|
288
|
+
context,
|
|
289
|
+
label: itemLabel
|
|
290
|
+
}) => {
|
|
291
|
+
if (context === 'menu') {
|
|
292
|
+
return itemLabel;
|
|
293
|
+
}
|
|
294
|
+
return '';
|
|
276
295
|
}
|
|
277
|
-
return '.'; // this can't be empty for some reason
|
|
278
296
|
},
|
|
279
|
-
|
|
280
|
-
|
|
297
|
+
options: options,
|
|
298
|
+
inputId: inputId,
|
|
299
|
+
onChange: time => {
|
|
300
|
+
const currentTime = DateTime.fromMillis(value).toFormat('HH:mm');
|
|
301
|
+
const ts = getTs(displayValue, value);
|
|
302
|
+
if (typing) {
|
|
303
|
+
if (ts !== null) {
|
|
304
|
+
if (currentTime !== displayValue && time.value === value) {
|
|
305
|
+
handleTimestamp(ts);
|
|
306
|
+
} else {
|
|
307
|
+
handleTimestamp(time.value);
|
|
308
|
+
}
|
|
309
|
+
setTyping(false);
|
|
310
|
+
} else {
|
|
311
|
+
if (time.value !== value) {
|
|
312
|
+
handleTimestamp(time.value);
|
|
313
|
+
} else {
|
|
314
|
+
// reset value
|
|
315
|
+
changeDisplayValue(getDisplay(value));
|
|
316
|
+
}
|
|
317
|
+
setTyping(false);
|
|
318
|
+
}
|
|
319
|
+
if (!datePicker) {
|
|
320
|
+
setinvalidInput(false);
|
|
321
|
+
}
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
if (!datePicker) {
|
|
325
|
+
setinvalidInput(false);
|
|
326
|
+
}
|
|
327
|
+
handleTimestamp(time.value);
|
|
281
328
|
},
|
|
282
|
-
|
|
329
|
+
components: {
|
|
330
|
+
IndicatorsContainer: () => null
|
|
331
|
+
},
|
|
332
|
+
className: cx(styles['datetimepicker-select-container'], invalidInput && 'datetimepicker-invalid-input'),
|
|
333
|
+
classNamePrefix: "datetimepicker-select",
|
|
334
|
+
onInputChange: onInputChange,
|
|
335
|
+
inputValue: !disableTyping && displayValue,
|
|
336
|
+
value: closestOption,
|
|
337
|
+
noOptionsMessage: () => {
|
|
283
338
|
return '';
|
|
284
339
|
},
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
}) => {
|
|
289
|
-
if (context === 'menu') {
|
|
290
|
-
return itemLabel;
|
|
340
|
+
filterOption: (option, input) => {
|
|
341
|
+
if (datePicker) {
|
|
342
|
+
return true;
|
|
291
343
|
}
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
344
|
+
const completeInput = input.length === 5 || input.length === 4 && input.split(':')[0].length === 1;
|
|
345
|
+
const isMod15 = option.label.split(':')[1] % 15 === 0;
|
|
346
|
+
const minuteInput = input.split(':')[1]?.length === 1;
|
|
347
|
+
if (showAllOptions && isMod15) {
|
|
348
|
+
return true;
|
|
349
|
+
}
|
|
350
|
+
if (minuteInput) {
|
|
351
|
+
const inputH = input.split(':')[0].length === 1 ? '0'.concat(input.split(':')[0]) : input.split(':')[0];
|
|
352
|
+
const inputM = input.split(':')[1];
|
|
353
|
+
const optH = option.label.split(':')[0];
|
|
354
|
+
const optM = option.label.split(':')[1];
|
|
355
|
+
if (inputH === optH) {
|
|
356
|
+
const time = Number(inputM) * 10;
|
|
357
|
+
const total = Number(optM) - time;
|
|
358
|
+
if (total >= 0 && total <= 9) {
|
|
359
|
+
return true;
|
|
360
|
+
}
|
|
361
|
+
return false;
|
|
306
362
|
}
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
363
|
+
}
|
|
364
|
+
if (completeInput && !showAllOptions) {
|
|
365
|
+
return input.length === 4 ? '0'.concat(input) === option.label : input === option.label;
|
|
366
|
+
}
|
|
367
|
+
if (isMod15) {
|
|
368
|
+
return filterOptions(option, input);
|
|
369
|
+
}
|
|
370
|
+
return false;
|
|
371
|
+
},
|
|
372
|
+
controlShouldRenderValue: disableTyping,
|
|
373
|
+
tabSelectsValue: false,
|
|
374
|
+
placeholder: "",
|
|
375
|
+
onFocus: e => {
|
|
376
|
+
if (!disableTyping) {
|
|
377
|
+
e.target.select();
|
|
378
|
+
}
|
|
379
|
+
},
|
|
380
|
+
onBlur: () => {
|
|
381
|
+
// removing focus also locks in value
|
|
382
|
+
if (typing) {
|
|
383
|
+
const validated = getTs(displayValue, value);
|
|
384
|
+
if (validated !== null) {
|
|
385
|
+
handleTimestamp(validated);
|
|
386
|
+
setTyping(false);
|
|
311
387
|
} else {
|
|
312
|
-
// reset value
|
|
313
388
|
changeDisplayValue(getDisplay(value));
|
|
389
|
+
setTyping(false);
|
|
314
390
|
}
|
|
315
|
-
setTyping(false);
|
|
316
391
|
}
|
|
317
392
|
if (!datePicker) {
|
|
318
393
|
setinvalidInput(false);
|
|
319
394
|
}
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
setinvalidInput(false);
|
|
324
|
-
}
|
|
325
|
-
handleTimestamp(time.value);
|
|
326
|
-
},
|
|
327
|
-
components: {
|
|
328
|
-
IndicatorsContainer: () => null
|
|
329
|
-
},
|
|
330
|
-
className: cx(styles['datetimepicker-select-container'], invalidInput && 'datetimepicker-invalid-input'),
|
|
331
|
-
classNamePrefix: "datetimepicker-select",
|
|
332
|
-
onInputChange: onInputChange,
|
|
333
|
-
inputValue: !disableTyping && displayValue,
|
|
334
|
-
value: closestOption,
|
|
335
|
-
noOptionsMessage: () => {
|
|
336
|
-
return '';
|
|
337
|
-
},
|
|
338
|
-
filterOption: (option, input) => {
|
|
339
|
-
if (datePicker) {
|
|
340
|
-
return true;
|
|
341
|
-
}
|
|
342
|
-
const completeInput = input.length === 5 || input.length === 4 && input.split(':')[0].length === 1;
|
|
343
|
-
const isMod15 = option.label.split(':')[1] % 15 === 0;
|
|
344
|
-
const minuteInput = input.split(':')[1]?.length === 1;
|
|
345
|
-
if (showAllOptions && isMod15) {
|
|
346
|
-
return true;
|
|
347
|
-
}
|
|
348
|
-
if (minuteInput) {
|
|
349
|
-
const inputH = input.split(':')[0].length === 1 ? '0'.concat(input.split(':')[0]) : input.split(':')[0];
|
|
350
|
-
const inputM = input.split(':')[1];
|
|
351
|
-
const optH = option.label.split(':')[0];
|
|
352
|
-
const optM = option.label.split(':')[1];
|
|
353
|
-
if (inputH === optH) {
|
|
354
|
-
const time = Number(inputM) * 10;
|
|
355
|
-
const total = Number(optM) - time;
|
|
356
|
-
if (total >= 0 && total <= 9) {
|
|
357
|
-
return true;
|
|
358
|
-
}
|
|
359
|
-
return false;
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
if (completeInput && !showAllOptions) {
|
|
363
|
-
return input.length === 4 ? '0'.concat(input) === option.label : input === option.label;
|
|
364
|
-
}
|
|
365
|
-
if (isMod15) {
|
|
366
|
-
return filterOptions(option, input);
|
|
367
|
-
}
|
|
368
|
-
return false;
|
|
369
|
-
},
|
|
370
|
-
controlShouldRenderValue: disableTyping,
|
|
371
|
-
tabSelectsValue: false,
|
|
372
|
-
placeholder: "",
|
|
373
|
-
onFocus: e => {
|
|
374
|
-
if (!disableTyping) {
|
|
375
|
-
e.target.select();
|
|
376
|
-
}
|
|
377
|
-
},
|
|
378
|
-
onBlur: () => {
|
|
379
|
-
// removing focus also locks in value
|
|
380
|
-
if (typing) {
|
|
381
|
-
const validated = getTs(displayValue, value);
|
|
382
|
-
if (validated !== null) {
|
|
383
|
-
handleTimestamp(validated);
|
|
384
|
-
setTyping(false);
|
|
385
|
-
} else {
|
|
386
|
-
changeDisplayValue(getDisplay(value));
|
|
395
|
+
},
|
|
396
|
+
onKeyDown: e => {
|
|
397
|
+
if (['ArrowDown', 'ArrowUp'].includes(e.key)) {
|
|
387
398
|
setTyping(false);
|
|
388
399
|
}
|
|
389
|
-
}
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
},
|
|
394
|
-
onKeyDown: e => {
|
|
395
|
-
if (['ArrowDown', 'ArrowUp'].includes(e.key)) {
|
|
396
|
-
setTyping(false);
|
|
397
|
-
}
|
|
398
|
-
},
|
|
399
|
-
isSearchable: !disableTyping
|
|
400
|
-
}));
|
|
400
|
+
},
|
|
401
|
+
isSearchable: !disableTyping
|
|
402
|
+
})]
|
|
403
|
+
});
|
|
401
404
|
}
|
|
402
405
|
process.env.NODE_ENV !== "production" ? DesktopDatetimepicker.propTypes = {
|
|
403
406
|
value: PropTypes.number.isRequired,
|
|
@@ -455,6 +458,43 @@ function dateTimeInputIsSupported() {
|
|
|
455
458
|
return true;
|
|
456
459
|
}
|
|
457
460
|
|
|
461
|
+
function _typeof(o) {
|
|
462
|
+
"@babel/helpers - typeof";
|
|
463
|
+
|
|
464
|
+
return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) {
|
|
465
|
+
return typeof o;
|
|
466
|
+
} : function (o) {
|
|
467
|
+
return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o;
|
|
468
|
+
}, _typeof(o);
|
|
469
|
+
}
|
|
470
|
+
|
|
471
|
+
function toPrimitive(t, r) {
|
|
472
|
+
if ("object" != _typeof(t) || !t) return t;
|
|
473
|
+
var e = t[Symbol.toPrimitive];
|
|
474
|
+
if (void 0 !== e) {
|
|
475
|
+
var i = e.call(t, r);
|
|
476
|
+
if ("object" != _typeof(i)) return i;
|
|
477
|
+
throw new TypeError("@@toPrimitive must return a primitive value.");
|
|
478
|
+
}
|
|
479
|
+
return ("string" === r ? String : Number)(t);
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
function toPropertyKey(t) {
|
|
483
|
+
var i = toPrimitive(t, "string");
|
|
484
|
+
return "symbol" == _typeof(i) ? i : i + "";
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
function _defineProperty(e, r, t) {
|
|
488
|
+
return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, {
|
|
489
|
+
value: t,
|
|
490
|
+
enumerable: true,
|
|
491
|
+
configurable: true,
|
|
492
|
+
writable: true
|
|
493
|
+
}) : e[r] = t, e;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
497
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), true).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
458
498
|
const AndroidSelect = ({
|
|
459
499
|
value,
|
|
460
500
|
dateChoices,
|
|
@@ -488,21 +528,31 @@ const AndroidSelect = ({
|
|
|
488
528
|
},
|
|
489
529
|
id
|
|
490
530
|
});
|
|
491
|
-
return /*#__PURE__*/
|
|
492
|
-
className: styles.container
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
531
|
+
return /*#__PURE__*/jsxs("div", {
|
|
532
|
+
className: styles.container,
|
|
533
|
+
children: [/*#__PURE__*/jsx("div", _objectSpread(_objectSpread({}, getToggleButtonProps({
|
|
534
|
+
'aria-labelledby': labelId,
|
|
535
|
+
id: inputId
|
|
536
|
+
})), {}, {
|
|
537
|
+
children: /*#__PURE__*/jsx("div", {
|
|
538
|
+
className: styles.input,
|
|
539
|
+
children: selectedItem.label
|
|
540
|
+
})
|
|
541
|
+
})), /*#__PURE__*/jsx("div", {
|
|
542
|
+
className: cx(styles.suggestionsContainerOpen, !isOpen && 'hidden'),
|
|
543
|
+
children: /*#__PURE__*/jsx("ul", _objectSpread(_objectSpread({}, getMenuProps()), {}, {
|
|
544
|
+
children: isOpen && items.map((option, index) => /*#__PURE__*/jsx("li", _objectSpread(_objectSpread({
|
|
545
|
+
className: cx(styles.suggestion, index === highlightedIndex && styles.suggestionHighlighted)
|
|
546
|
+
}, getItemProps({
|
|
547
|
+
index
|
|
548
|
+
})), {}, {
|
|
549
|
+
children: /*#__PURE__*/jsx("span", {
|
|
550
|
+
children: option.label
|
|
551
|
+
})
|
|
552
|
+
}), option.value))
|
|
553
|
+
}))
|
|
554
|
+
})]
|
|
555
|
+
});
|
|
506
556
|
};
|
|
507
557
|
process.env.NODE_ENV !== "production" ? AndroidSelect.propTypes = {
|
|
508
558
|
value: PropTypes.number.isRequired,
|
|
@@ -535,31 +585,36 @@ function MobileDatepicker({
|
|
|
535
585
|
const nativeInput = !isAndroid();
|
|
536
586
|
const labelId = `${id}-label`;
|
|
537
587
|
const inputId = `${id}-input`;
|
|
538
|
-
return /*#__PURE__*/
|
|
588
|
+
return /*#__PURE__*/jsxs("label", {
|
|
539
589
|
className: styles['input-container'],
|
|
540
|
-
htmlFor: inputId
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
590
|
+
htmlFor: inputId,
|
|
591
|
+
children: [/*#__PURE__*/jsx("span", {
|
|
592
|
+
children: icon
|
|
593
|
+
}), /*#__PURE__*/jsx("span", {
|
|
594
|
+
className: styles['sr-only'],
|
|
595
|
+
id: labelId,
|
|
596
|
+
children: label
|
|
597
|
+
}), nativeInput ? /*#__PURE__*/jsx("select", {
|
|
598
|
+
id: inputId,
|
|
599
|
+
className: styles['mobile-input-display'],
|
|
600
|
+
onChange: e => onChange(Number(e.target.value)),
|
|
601
|
+
value: value,
|
|
602
|
+
children: dateChoices.map(date => {
|
|
603
|
+
return /*#__PURE__*/jsx("option", {
|
|
604
|
+
value: date,
|
|
605
|
+
children: getDisplay(date)
|
|
606
|
+
}, date);
|
|
607
|
+
})
|
|
608
|
+
}) : /*#__PURE__*/jsx(AndroidSelect, {
|
|
609
|
+
value,
|
|
610
|
+
dateChoices,
|
|
611
|
+
id,
|
|
612
|
+
getDisplay,
|
|
613
|
+
onChange,
|
|
614
|
+
labelId,
|
|
615
|
+
inputId
|
|
616
|
+
})]
|
|
617
|
+
});
|
|
563
618
|
}
|
|
564
619
|
process.env.NODE_ENV !== "production" ? MobileDatepicker.propTypes = {
|
|
565
620
|
value: PropTypes.number.isRequired,
|
|
@@ -573,9 +628,6 @@ process.env.NODE_ENV !== "production" ? MobileDatepicker.propTypes = {
|
|
|
573
628
|
timeZone: PropTypes.string
|
|
574
629
|
} : void 0;
|
|
575
630
|
|
|
576
|
-
/**
|
|
577
|
-
* Component to display a time input on mobile
|
|
578
|
-
*/
|
|
579
631
|
function MobileTimepicker({
|
|
580
632
|
value,
|
|
581
633
|
getDisplay,
|
|
@@ -591,42 +643,46 @@ function MobileTimepicker({
|
|
|
591
643
|
const inputId = `${id}-input`;
|
|
592
644
|
const labelId = `${id}-label`;
|
|
593
645
|
const showError = !isValidInput;
|
|
594
|
-
return /*#__PURE__*/
|
|
646
|
+
return /*#__PURE__*/jsxs("label", {
|
|
595
647
|
className: styles['input-container'],
|
|
596
|
-
htmlFor: inputId
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
648
|
+
htmlFor: inputId,
|
|
649
|
+
children: [/*#__PURE__*/jsx("span", {
|
|
650
|
+
children: icon
|
|
651
|
+
}), /*#__PURE__*/jsx("span", {
|
|
652
|
+
className: styles['sr-only'],
|
|
653
|
+
id: labelId,
|
|
654
|
+
children: label
|
|
655
|
+
}), /*#__PURE__*/jsx("input", {
|
|
656
|
+
id: inputId,
|
|
657
|
+
inputMode: "numeric",
|
|
658
|
+
type: "text",
|
|
659
|
+
maxLength: "6",
|
|
660
|
+
className: cx(styles['time-input-mobile'], showError && 'mobile-datetimepicker-invalid-input'),
|
|
661
|
+
value: inputValue,
|
|
662
|
+
onFocus: e => {
|
|
663
|
+
e.target.setSelectionRange(0, 0); // set caret to start of input
|
|
664
|
+
},
|
|
665
|
+
onChange: event => {
|
|
666
|
+
let newValue = event.target.value.replace('.', ':');
|
|
667
|
+
const valid = validateInput(newValue);
|
|
668
|
+
setValidInput(valid);
|
|
669
|
+
if (
|
|
670
|
+
// number typed as first char => clear rest of the input
|
|
671
|
+
newValue.match(/[0-9]{3}:[0-9]{2}/) && newValue.slice(1) === inputValue) {
|
|
672
|
+
newValue = newValue.charAt(0);
|
|
673
|
+
}
|
|
674
|
+
if (newValue.length > 5) {
|
|
675
|
+
return;
|
|
676
|
+
}
|
|
677
|
+
const actual = parseTypedTime(newValue);
|
|
678
|
+
changeInputValue(actual);
|
|
679
|
+
const timestamp = getTs(actual, value);
|
|
680
|
+
if (timestamp) {
|
|
681
|
+
onChange(timestamp);
|
|
682
|
+
}
|
|
627
683
|
}
|
|
628
|
-
}
|
|
629
|
-
})
|
|
684
|
+
})]
|
|
685
|
+
});
|
|
630
686
|
}
|
|
631
687
|
process.env.NODE_ENV !== "production" ? MobileTimepicker.propTypes = {
|
|
632
688
|
value: PropTypes.number.isRequired,
|
|
@@ -689,96 +745,110 @@ function MobilePickerModal({
|
|
|
689
745
|
hour: DateTime.fromMillis(displayTimestamp).hour,
|
|
690
746
|
minute: DateTime.fromMillis(displayTimestamp).minute
|
|
691
747
|
}).toMillis();
|
|
692
|
-
return /*#__PURE__*/
|
|
748
|
+
return /*#__PURE__*/jsx(Modal, {
|
|
693
749
|
appElement: document ? document.querySelector('#app') : undefined,
|
|
694
750
|
isOpen: true,
|
|
695
751
|
className: styles['mobile-modal-content'],
|
|
696
752
|
overlayClassName: styles['mobile-modal-overlay'],
|
|
697
|
-
onAfterClose: onAfterClose
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
753
|
+
onAfterClose: onAfterClose,
|
|
754
|
+
children: /*#__PURE__*/jsxs("div", {
|
|
755
|
+
id: "digitransit-mobile-datetime",
|
|
756
|
+
style: {
|
|
757
|
+
'--color': `${color}`
|
|
758
|
+
},
|
|
759
|
+
children: [/*#__PURE__*/jsxs("div", {
|
|
760
|
+
className: styles['top-row'],
|
|
761
|
+
children: [/*#__PURE__*/jsx("h3", {
|
|
762
|
+
className: styles['modal-title'],
|
|
763
|
+
children: t('choose-time', translationSettings)
|
|
764
|
+
}), /*#__PURE__*/jsx("button", {
|
|
765
|
+
type: "button",
|
|
766
|
+
className: styles['departure-now-button'],
|
|
767
|
+
onClick: onNowClick,
|
|
768
|
+
children: t('departure-now', translationSettings)
|
|
769
|
+
})]
|
|
770
|
+
}), /*#__PURE__*/jsxs("div", {
|
|
771
|
+
className: styles['tab-row'],
|
|
772
|
+
children: [/*#__PURE__*/jsxs("label", {
|
|
773
|
+
htmlFor: `${htmlId}-modal-departure`,
|
|
774
|
+
className: `${styles['radio-tab-label']}
|
|
775
|
+
${styles[departureOrArrivalCurrent === 'departure' ? 'active' : undefined]}`,
|
|
776
|
+
children: [t('departure', translationSettings), /*#__PURE__*/jsx("input", {
|
|
777
|
+
id: `${htmlId}-modal-departure`,
|
|
778
|
+
name: "departureOrArrival",
|
|
779
|
+
type: "radio",
|
|
780
|
+
value: "departure",
|
|
781
|
+
className: styles['radio-textbutton'],
|
|
782
|
+
onChange: () => {
|
|
783
|
+
onDepartureClick();
|
|
784
|
+
},
|
|
785
|
+
checked: departureOrArrivalCurrent === 'departure'
|
|
786
|
+
})]
|
|
787
|
+
}), /*#__PURE__*/jsxs("label", {
|
|
788
|
+
htmlFor: `${htmlId}-modal-arrival`,
|
|
789
|
+
className: `${styles['radio-tab-label']}
|
|
790
|
+
${styles[departureOrArrivalCurrent === 'arrival' ? 'active' : undefined]}`,
|
|
791
|
+
children: [t('arrival', translationSettings), /*#__PURE__*/jsx("input", {
|
|
792
|
+
id: `${htmlId}-modal-arrival`,
|
|
793
|
+
name: "departureOrArrival",
|
|
794
|
+
type: "radio",
|
|
795
|
+
value: "arrival",
|
|
796
|
+
className: styles['radio-textbutton'],
|
|
797
|
+
onChange: () => {
|
|
798
|
+
onArrivalClick();
|
|
799
|
+
},
|
|
800
|
+
checked: departureOrArrivalCurrent === 'arrival'
|
|
801
|
+
})]
|
|
802
|
+
})]
|
|
803
|
+
}), /*#__PURE__*/jsxs("div", {
|
|
804
|
+
className: styles['input-row'],
|
|
805
|
+
children: [/*#__PURE__*/jsx(MobileDatepicker, {
|
|
806
|
+
value: displayTimestamp,
|
|
807
|
+
getDisplay: getDateDisplay,
|
|
808
|
+
onChange: changeTimestamp,
|
|
809
|
+
itemCount: dateSelectItemCount,
|
|
810
|
+
startTime: dateSelectStartTime,
|
|
811
|
+
id: `${htmlId}-date`,
|
|
812
|
+
label: t('date', translationSettings),
|
|
813
|
+
icon: /*#__PURE__*/jsx("span", {
|
|
814
|
+
className: `${styles['combobox-icon']} ${styles['date-input-icon']}`,
|
|
815
|
+
children: /*#__PURE__*/jsx(Icon, {
|
|
816
|
+
img: "calendar",
|
|
817
|
+
color: color
|
|
818
|
+
})
|
|
819
|
+
}),
|
|
820
|
+
timeZone: timeZone
|
|
821
|
+
}), /*#__PURE__*/jsx(MobileTimepicker, {
|
|
822
|
+
value: displayTimestamp,
|
|
823
|
+
getDisplay: getTimeDisplay,
|
|
824
|
+
onChange: changeTimestamp,
|
|
825
|
+
id: `${htmlId}-time`,
|
|
826
|
+
label: t('time', translationSettings),
|
|
827
|
+
icon: /*#__PURE__*/jsx("span", {
|
|
828
|
+
className: `${styles['combobox-icon']} ${styles['time-input-icon']}`,
|
|
829
|
+
children: /*#__PURE__*/jsx(Icon, {
|
|
830
|
+
img: "time",
|
|
831
|
+
color: color
|
|
832
|
+
})
|
|
833
|
+
}),
|
|
834
|
+
timeZone: timeZone
|
|
835
|
+
})]
|
|
836
|
+
}), /*#__PURE__*/jsxs("div", {
|
|
837
|
+
className: styles['buttons-row'],
|
|
838
|
+
children: [/*#__PURE__*/jsx("button", {
|
|
839
|
+
type: "button",
|
|
840
|
+
className: styles['ready-button'],
|
|
841
|
+
onClick: () => onSubmit(displayTimestamp, departureOrArrivalCurrent),
|
|
842
|
+
children: t('ready', translationSettings)
|
|
843
|
+
}), /*#__PURE__*/jsx("button", {
|
|
844
|
+
type: "button",
|
|
845
|
+
className: styles['cancel-button'],
|
|
846
|
+
onClick: onCancel,
|
|
847
|
+
children: t('cancel', translationSettings)
|
|
848
|
+
})]
|
|
849
|
+
})]
|
|
850
|
+
})
|
|
851
|
+
});
|
|
782
852
|
}
|
|
783
853
|
process.env.NODE_ENV !== "production" ? MobilePickerModal.propTypes = {
|
|
784
854
|
timeZone: PropTypes.string,
|
|
@@ -1005,7 +1075,7 @@ function Datetimepicker({
|
|
|
1005
1075
|
};
|
|
1006
1076
|
function renderOpen() {
|
|
1007
1077
|
if (useMobileInputs) {
|
|
1008
|
-
return isOpen && /*#__PURE__*/
|
|
1078
|
+
return isOpen && /*#__PURE__*/jsx(MobilePickerModal, {
|
|
1009
1079
|
departureOrArrival: departureOrArrival,
|
|
1010
1080
|
onNowClick: handleNowClick,
|
|
1011
1081
|
lang: lang,
|
|
@@ -1027,114 +1097,134 @@ function Datetimepicker({
|
|
|
1027
1097
|
getDisplay: getTimeDisplay
|
|
1028
1098
|
});
|
|
1029
1099
|
}
|
|
1030
|
-
return /*#__PURE__*/
|
|
1031
|
-
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
|
|
1035
|
-
|
|
1036
|
-
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1042
|
-
|
|
1043
|
-
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
|
|
1112
|
-
|
|
1113
|
-
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1100
|
+
return /*#__PURE__*/jsxs(Fragment, {
|
|
1101
|
+
children: [/*#__PURE__*/jsxs("div", {
|
|
1102
|
+
className: `${styles['datetimepicker-open-container']} ${!isOpen ? styles.hidden : ''}`,
|
|
1103
|
+
children: [/*#__PURE__*/jsxs("div", {
|
|
1104
|
+
className: isOpen ? `${styles['top-row-container']} datetimepicker-top-row` : `${styles.hidden} datetimepicker-top-row`,
|
|
1105
|
+
children: [' ', /*#__PURE__*/jsx("span", {
|
|
1106
|
+
role: "alert",
|
|
1107
|
+
className: styles['sr-only'],
|
|
1108
|
+
ref: alertRef
|
|
1109
|
+
}), /*#__PURE__*/jsx("span", {}), /*#__PURE__*/jsxs("span", {
|
|
1110
|
+
className: styles['departure-or-arrival-container'],
|
|
1111
|
+
children: [/*#__PURE__*/jsxs("label", {
|
|
1112
|
+
htmlFor: `${htmlId}-departure`,
|
|
1113
|
+
className: `${styles['radio-textbutton-label']}
|
|
1114
|
+
${styles[departureOrArrival === 'departure' ? 'active' : undefined]}`,
|
|
1115
|
+
children: [t('departure', translationSettings), /*#__PURE__*/jsx("input", {
|
|
1116
|
+
id: `${htmlId}-departure`,
|
|
1117
|
+
name: "departureOrArrival",
|
|
1118
|
+
type: "radio",
|
|
1119
|
+
value: "departure",
|
|
1120
|
+
className: styles['radio-textbutton'],
|
|
1121
|
+
onChange: () => {
|
|
1122
|
+
onDepartureClick();
|
|
1123
|
+
},
|
|
1124
|
+
checked: departureOrArrival === 'departure'
|
|
1125
|
+
})]
|
|
1126
|
+
}), /*#__PURE__*/jsxs("label", {
|
|
1127
|
+
htmlFor: `${htmlId}-arrival`,
|
|
1128
|
+
className: `${styles['radio-textbutton-label']}
|
|
1129
|
+
${styles[departureOrArrival === 'arrival' ? 'active' : undefined]}`,
|
|
1130
|
+
children: [t('arrival', translationSettings), /*#__PURE__*/jsx("input", {
|
|
1131
|
+
id: `${htmlId}-arrival`,
|
|
1132
|
+
name: "departureOrArrival",
|
|
1133
|
+
type: "radio",
|
|
1134
|
+
value: "arrival",
|
|
1135
|
+
className: styles['radio-textbutton'],
|
|
1136
|
+
onChange: () => {
|
|
1137
|
+
onArrivalClick();
|
|
1138
|
+
},
|
|
1139
|
+
checked: departureOrArrival === 'arrival'
|
|
1140
|
+
})]
|
|
1141
|
+
})]
|
|
1142
|
+
}), /*#__PURE__*/jsx("button", {
|
|
1143
|
+
id: `${htmlId}-now`,
|
|
1144
|
+
type: "button",
|
|
1145
|
+
className: styles['departure-now-button'],
|
|
1146
|
+
onClick: handleNowClick,
|
|
1147
|
+
ref: inputRef,
|
|
1148
|
+
children: t('departure-now', translationSettings)
|
|
1149
|
+
}), /*#__PURE__*/jsx("span", {
|
|
1150
|
+
className: styles['right-edge'],
|
|
1151
|
+
children: /*#__PURE__*/jsxs("button", {
|
|
1152
|
+
type: "button",
|
|
1153
|
+
className: styles['close-button'],
|
|
1154
|
+
"aria-controls": `${htmlId}-root`,
|
|
1155
|
+
"aria-expanded": "true",
|
|
1156
|
+
onClick: handleClose,
|
|
1157
|
+
children: [/*#__PURE__*/jsx("span", {
|
|
1158
|
+
className: styles['close-icon'],
|
|
1159
|
+
children: /*#__PURE__*/jsx(Icon, {
|
|
1160
|
+
img: "close",
|
|
1161
|
+
color: color
|
|
1162
|
+
})
|
|
1163
|
+
}), /*#__PURE__*/jsx("span", {
|
|
1164
|
+
className: styles['sr-only'],
|
|
1165
|
+
children: t('accessible-close', translationSettings)
|
|
1166
|
+
})]
|
|
1167
|
+
})
|
|
1168
|
+
})]
|
|
1169
|
+
}), /*#__PURE__*/jsxs("div", {
|
|
1170
|
+
className: isOpen ? `${styles['picker-container']}` : `${styles.hidden} datetimepicker-top-row`,
|
|
1171
|
+
children: [/*#__PURE__*/jsx("span", {
|
|
1172
|
+
className: styles['combobox-left'],
|
|
1173
|
+
children: /*#__PURE__*/jsx(DesktopDatetimepicker, {
|
|
1174
|
+
value: displayTimestamp,
|
|
1175
|
+
onChange: newValue => {
|
|
1176
|
+
onDateChange(newValue);
|
|
1177
|
+
},
|
|
1178
|
+
getDisplay: getDateDisplay,
|
|
1179
|
+
timeChoices: dateChoices,
|
|
1180
|
+
validate: () => null,
|
|
1181
|
+
icon: /*#__PURE__*/jsx("span", {
|
|
1182
|
+
className: `${styles['combobox-icon']} ${styles['date-input-icon']}`,
|
|
1183
|
+
children: /*#__PURE__*/jsx(Icon, {
|
|
1184
|
+
img: "calendar",
|
|
1185
|
+
color: color
|
|
1186
|
+
})
|
|
1187
|
+
}),
|
|
1188
|
+
id: `${htmlId}-date`,
|
|
1189
|
+
label: t('date', translationSettings),
|
|
1190
|
+
disableTyping: true,
|
|
1191
|
+
timeZone: timeZone,
|
|
1192
|
+
datePicker: true
|
|
1193
|
+
})
|
|
1194
|
+
}), /*#__PURE__*/jsx("span", {
|
|
1195
|
+
className: styles['combobox-right'],
|
|
1196
|
+
children: /*#__PURE__*/jsx(DesktopDatetimepicker, {
|
|
1197
|
+
value: displayTimestamp,
|
|
1198
|
+
onChange: newValue => {
|
|
1199
|
+
onTimeChange(newValue);
|
|
1200
|
+
},
|
|
1201
|
+
getDisplay: getTimeDisplay,
|
|
1202
|
+
timeChoices: timeChoices,
|
|
1203
|
+
icon: /*#__PURE__*/jsx("span", {
|
|
1204
|
+
className: `${styles['combobox-icon']} ${styles['time-input-icon']}`,
|
|
1205
|
+
children: /*#__PURE__*/jsx(Icon, {
|
|
1206
|
+
img: "time",
|
|
1207
|
+
color: color
|
|
1208
|
+
})
|
|
1209
|
+
}),
|
|
1210
|
+
id: `${htmlId}-time`,
|
|
1211
|
+
label: t('time', translationSettings),
|
|
1212
|
+
timeZone: timeZone,
|
|
1213
|
+
translationSettings: translationSettings
|
|
1214
|
+
})
|
|
1215
|
+
})]
|
|
1216
|
+
})]
|
|
1217
|
+
}), /*#__PURE__*/jsx("span", {
|
|
1218
|
+
className: isOpen ? '' : styles.hidden,
|
|
1219
|
+
children: embedWhenOpen
|
|
1220
|
+
})]
|
|
1221
|
+
});
|
|
1134
1222
|
}
|
|
1135
1223
|
const formatToprowSummary = () => {
|
|
1136
1224
|
if (nowSelected && departureOrArrival === 'departure') {
|
|
1137
|
-
return /*#__PURE__*/
|
|
1225
|
+
return /*#__PURE__*/jsx("span", {
|
|
1226
|
+
children: t('departure-now', translationSettings)
|
|
1227
|
+
});
|
|
1138
1228
|
}
|
|
1139
1229
|
const dateDisplay = getDateDisplay(displayTimestamp);
|
|
1140
1230
|
const timeDisplay = getTimeDisplay(displayTimestamp);
|
|
@@ -1144,61 +1234,77 @@ function Datetimepicker({
|
|
|
1144
1234
|
days: 1
|
|
1145
1235
|
}).hasSame(DateTime.fromMillis(displayTimestamp), 'day');
|
|
1146
1236
|
if (isToday) {
|
|
1147
|
-
return /*#__PURE__*/
|
|
1237
|
+
return /*#__PURE__*/jsx("span", {
|
|
1238
|
+
children: `${summary} ${timeDisplay}`
|
|
1239
|
+
});
|
|
1148
1240
|
}
|
|
1149
1241
|
if (isTomorrow) {
|
|
1150
|
-
return /*#__PURE__*/
|
|
1242
|
+
return /*#__PURE__*/jsx("span", {
|
|
1243
|
+
children: `${summary} ${dateDisplay.toLowerCase()} ${timeDisplay}`
|
|
1244
|
+
});
|
|
1151
1245
|
}
|
|
1152
|
-
return /*#__PURE__*/
|
|
1246
|
+
return /*#__PURE__*/jsx("span", {
|
|
1247
|
+
children: `${summary} ${dateDisplay} ${timeDisplay}`
|
|
1248
|
+
});
|
|
1153
1249
|
};
|
|
1154
|
-
return /*#__PURE__*/
|
|
1250
|
+
return /*#__PURE__*/jsxs("fieldset", {
|
|
1155
1251
|
className: styles['dt-datetimepicker'],
|
|
1156
1252
|
id: `${htmlId}-root`,
|
|
1157
1253
|
style: {
|
|
1158
1254
|
'--color': `${color}`
|
|
1159
|
-
}
|
|
1160
|
-
}, /*#__PURE__*/React.createElement("legend", {
|
|
1161
|
-
className: styles['sr-only']
|
|
1162
|
-
}, t('accessible-title', translationSettings)), /*#__PURE__*/React.createElement("span", {
|
|
1163
|
-
className: styles['sr-only']
|
|
1164
|
-
}, t('accessible-update-instructions', translationSettings)), /*#__PURE__*/React.createElement("div", {
|
|
1165
|
-
className: !isOpen ? `${styles['top-row-container']} ${styles.closed} datetimepicker-top-row` : `${styles.hidden} datetimepicker-top-row`
|
|
1166
|
-
}, /*#__PURE__*/React.createElement("label", {
|
|
1167
|
-
className: styles['label-open'],
|
|
1168
|
-
htmlFor: `${htmlId}-open`
|
|
1169
|
-
}, /*#__PURE__*/React.createElement("span", {
|
|
1170
|
-
className: styles['time-icon']
|
|
1171
|
-
}, /*#__PURE__*/React.createElement(Icon, {
|
|
1172
|
-
img: "time",
|
|
1173
|
-
color: color
|
|
1174
|
-
})), /*#__PURE__*/React.createElement("span", {
|
|
1175
|
-
className: styles['sr-only']
|
|
1176
|
-
}, t('accessible-open', translationSettings)), /*#__PURE__*/React.createElement("span", {
|
|
1177
|
-
role: "alert",
|
|
1178
|
-
className: styles['sr-only'],
|
|
1179
|
-
ref: alertRef
|
|
1180
|
-
}), /*#__PURE__*/React.createElement("button", {
|
|
1181
|
-
id: `${htmlId}-open`,
|
|
1182
|
-
type: "button",
|
|
1183
|
-
className: `${styles.textbutton} ${styles.active} ${styles['open-button']}`,
|
|
1184
|
-
"aria-controls": `${htmlId}-root`,
|
|
1185
|
-
"aria-expanded": "false",
|
|
1186
|
-
onClick: () => {
|
|
1187
|
-
changeOpen(true);
|
|
1188
|
-
showScreenreaderOpenAlert();
|
|
1189
|
-
if (onOpen) {
|
|
1190
|
-
onOpen();
|
|
1191
|
-
}
|
|
1192
1255
|
},
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
|
|
1201
|
-
|
|
1256
|
+
children: [/*#__PURE__*/jsx("legend", {
|
|
1257
|
+
className: styles['sr-only'],
|
|
1258
|
+
children: t('accessible-title', translationSettings)
|
|
1259
|
+
}), /*#__PURE__*/jsx("span", {
|
|
1260
|
+
className: styles['sr-only'],
|
|
1261
|
+
children: t('accessible-update-instructions', translationSettings)
|
|
1262
|
+
}), /*#__PURE__*/jsxs("div", {
|
|
1263
|
+
className: !isOpen ? `${styles['top-row-container']} ${styles.closed} datetimepicker-top-row` : `${styles.hidden} datetimepicker-top-row`,
|
|
1264
|
+
children: [/*#__PURE__*/jsxs("label", {
|
|
1265
|
+
className: styles['label-open'],
|
|
1266
|
+
htmlFor: `${htmlId}-open`,
|
|
1267
|
+
children: [/*#__PURE__*/jsx("span", {
|
|
1268
|
+
className: styles['time-icon'],
|
|
1269
|
+
children: /*#__PURE__*/jsx(Icon, {
|
|
1270
|
+
img: "time",
|
|
1271
|
+
color: color
|
|
1272
|
+
})
|
|
1273
|
+
}), /*#__PURE__*/jsx("span", {
|
|
1274
|
+
className: styles['sr-only'],
|
|
1275
|
+
children: t('accessible-open', translationSettings)
|
|
1276
|
+
}), /*#__PURE__*/jsx("span", {
|
|
1277
|
+
role: "alert",
|
|
1278
|
+
className: styles['sr-only'],
|
|
1279
|
+
ref: alertRef
|
|
1280
|
+
}), /*#__PURE__*/jsxs("button", {
|
|
1281
|
+
id: `${htmlId}-open`,
|
|
1282
|
+
type: "button",
|
|
1283
|
+
className: `${styles.textbutton} ${styles.active} ${styles['open-button']}`,
|
|
1284
|
+
"aria-controls": `${htmlId}-root`,
|
|
1285
|
+
"aria-expanded": "false",
|
|
1286
|
+
onClick: () => {
|
|
1287
|
+
changeOpen(true);
|
|
1288
|
+
showScreenreaderOpenAlert();
|
|
1289
|
+
if (onOpen) {
|
|
1290
|
+
onOpen();
|
|
1291
|
+
}
|
|
1292
|
+
},
|
|
1293
|
+
ref: openPickerRef,
|
|
1294
|
+
children: [formatToprowSummary(), /*#__PURE__*/jsx("span", {
|
|
1295
|
+
className: styles['dropdown-icon'],
|
|
1296
|
+
children: /*#__PURE__*/jsx(Icon, {
|
|
1297
|
+
img: "arrow-dropdown",
|
|
1298
|
+
color: color
|
|
1299
|
+
})
|
|
1300
|
+
})]
|
|
1301
|
+
})]
|
|
1302
|
+
}), /*#__PURE__*/jsx("span", {
|
|
1303
|
+
className: styles['right-edge'],
|
|
1304
|
+
children: embedWhenClosed
|
|
1305
|
+
})]
|
|
1306
|
+
}), /*#__PURE__*/jsx("div", {}), renderOpen()]
|
|
1307
|
+
});
|
|
1202
1308
|
}
|
|
1203
1309
|
process.env.NODE_ENV !== "production" ? Datetimepicker.propTypes = {
|
|
1204
1310
|
timestamp: PropTypes.number,
|
|
@@ -1338,43 +1444,6 @@ const i18n = createInstance({
|
|
|
1338
1444
|
});
|
|
1339
1445
|
i18n.init();
|
|
1340
1446
|
|
|
1341
|
-
/**
|
|
1342
|
-
* This component renders an input to choose a date and time. Renders separate input fields for date and time selection. Values for timestamp and arriveBy correspond to Digitransit query params time and arriveBy. This component will display a native date input on mobile and a custom one for desktop. Mobile detection is done by parsing user agent.
|
|
1343
|
-
*
|
|
1344
|
-
* @alias Datetimepicker
|
|
1345
|
-
*
|
|
1346
|
-
* @param {Object} props
|
|
1347
|
-
*
|
|
1348
|
-
* @param {boolean} props.realtime Determine if selected time should be updated in realtime when 'now' is selected.
|
|
1349
|
-
* @param {Number} props.initialTimestamp Initial value for selected time. Unix timestamp in seconds. Updating this will change timepicker value but the correct value is kept in component state even if this is not updated.
|
|
1350
|
-
* @param {boolean} props.initialArriveBy Initial value for arriveBy. Determines if picker is in arrival mode (true) or departure mode (false). Correct value is kept in component state even if this is not updated. Changing this will also trigger change in the component.
|
|
1351
|
-
* @param {function} props.onTimeChange Called with (time, arriveBy) when time input changes. time is number timestamp in seconds, arriveBy is boolean
|
|
1352
|
-
* @param {function} props.onDateChange Called with (time, arriveBy) when date input changes. time is number timestamp in seconds, arriveBy is boolean
|
|
1353
|
-
* @param {function} props.onNowClick Called when "depart now" button is clicked. time is current input value in seconds
|
|
1354
|
-
* @param {function} props.onDepartureClick Called with (time) when "departure" button is clicked. time is current input value in seconds
|
|
1355
|
-
* @param {function} props.onArrivalClick Called with (time) when "arrival" button is clicked. time is current input value in seconds
|
|
1356
|
-
* @param {node} props.embedWhenClosed JSX element to render in the corner when input is closed
|
|
1357
|
-
* @param {node} props.embedWhenOpen JSX element to render when input is open
|
|
1358
|
-
* @param {string} props.lang Language selection. Default 'en'
|
|
1359
|
-
* @param {number} props.serviceTimeRange Determine number of days shown in timepicker. Optional. default is 30.
|
|
1360
|
-
* @param {function} props.onOpen Determine what to do when timepicker is open. Optional. no default implementation.
|
|
1361
|
-
* @param {function} props.onClose Determine what to do when timepicker is closed. Optional. no default implementation.
|
|
1362
|
-
* @param {function} props.openPicker Determine if timepicker should be open in intial render. Optional. Default is undefined.
|
|
1363
|
-
* @example
|
|
1364
|
-
* <Datetimepicker
|
|
1365
|
-
* realtime={true}
|
|
1366
|
-
* initialTimestamp={1590133823}
|
|
1367
|
-
* initialArriveBy={false}
|
|
1368
|
-
* onTimeChange={(time, arriveBy) => changeUrl(time, arriveBy)}
|
|
1369
|
-
* onDateChange={(time, arriveBy) => changeUrl(time, arriveBy)}
|
|
1370
|
-
* onNowClick={(time) => changeUrl(undefined, undefined)}
|
|
1371
|
-
* onDepartureClick={(time) => changeUrl(time, 'true')}
|
|
1372
|
-
* onArrivalClick={(time) => changeUrl(time, undefined)}
|
|
1373
|
-
* embedWhenClosed={<button />}
|
|
1374
|
-
* lang={'en'}
|
|
1375
|
-
* serviceTimeRange={15}
|
|
1376
|
-
* />
|
|
1377
|
-
*/
|
|
1378
1447
|
function DatetimepickerStateContainer({
|
|
1379
1448
|
realtime = false,
|
|
1380
1449
|
initialArriveBy,
|
|
@@ -1480,27 +1549,28 @@ function DatetimepickerStateContainer({
|
|
|
1480
1549
|
changeDepartureOrArrival(mode);
|
|
1481
1550
|
onTimeChange(Math.round(time / 1000), mode === 'arrival', true);
|
|
1482
1551
|
};
|
|
1483
|
-
return /*#__PURE__*/
|
|
1484
|
-
i18n: i18n
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1552
|
+
return /*#__PURE__*/jsx(I18nextProvider, {
|
|
1553
|
+
i18n: i18n,
|
|
1554
|
+
children: /*#__PURE__*/jsx(Datetimepicker, {
|
|
1555
|
+
timestamp: timestamp,
|
|
1556
|
+
onTimeChange: timeChanged,
|
|
1557
|
+
onDateChange: dateChanged,
|
|
1558
|
+
departureOrArrival: departureOrArrival,
|
|
1559
|
+
onNowClick: nowClicked,
|
|
1560
|
+
onDepartureClick: departureClicked,
|
|
1561
|
+
onArrivalClick: arrivalClicked,
|
|
1562
|
+
embedWhenClosed: embedWhenClosed,
|
|
1563
|
+
embedWhenOpen: embedWhenOpen,
|
|
1564
|
+
lang: lang,
|
|
1565
|
+
color: color,
|
|
1566
|
+
timeZone: timeZone,
|
|
1567
|
+
onModalSubmit: onModalSubmit,
|
|
1568
|
+
serviceTimeRange: serviceTimeRange,
|
|
1569
|
+
onOpen: onOpen,
|
|
1570
|
+
onClose: onClose,
|
|
1571
|
+
openPicker: openPicker
|
|
1572
|
+
})
|
|
1573
|
+
});
|
|
1504
1574
|
}
|
|
1505
1575
|
process.env.NODE_ENV !== "production" ? DatetimepickerStateContainer.propTypes = {
|
|
1506
1576
|
realtime: PropTypes.bool,
|