@atlaskit/datetime-picker 19.3.1 → 19.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -0
- package/dist/cjs/components/date-picker.js +1 -1
- package/dist/cjs/components/date-time-picker.js +1 -1
- package/dist/cjs/components/time-picker.js +13 -11
- package/dist/cjs/internal/is-valid.js +2 -2
- package/dist/cjs/internal/parse-time.js +180 -2
- package/dist/es2019/components/date-picker.js +1 -1
- package/dist/es2019/components/date-time-picker.js +1 -1
- package/dist/es2019/components/time-picker.js +11 -7
- package/dist/es2019/internal/is-valid.js +2 -2
- package/dist/es2019/internal/parse-time.js +135 -2
- package/dist/esm/components/date-picker.js +1 -1
- package/dist/esm/components/date-time-picker.js +1 -1
- package/dist/esm/components/time-picker.js +14 -12
- package/dist/esm/internal/is-valid.js +2 -2
- package/dist/esm/internal/parse-time.js +179 -2
- package/dist/types/internal/parse-time.d.ts +2 -1
- package/package.json +13 -9
- package/dist/cjs/internal/fixed-layer-menu-top-layer.js +0 -118
- package/dist/es2019/internal/fixed-layer-menu-top-layer.js +0 -109
- package/dist/esm/internal/fixed-layer-menu-top-layer.js +0 -111
- package/dist/types/internal/fixed-layer-menu-top-layer.d.ts +0 -12
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
# @atlaskit/datetime-picker
|
|
2
2
|
|
|
3
|
+
## 19.4.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`cf5cda7218d8e`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/cf5cda7218d8e) -
|
|
8
|
+
Behind the `platform-dst-locale-aware-time-parsing` feature gate, parse localized editable time
|
|
9
|
+
input while retaining ISO output and legacy English forms.
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- Updated dependencies
|
|
14
|
+
|
|
15
|
+
## 19.3.2
|
|
16
|
+
|
|
17
|
+
### Patch Changes
|
|
18
|
+
|
|
19
|
+
- [`45ba618a887fd`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/45ba618a887fd) -
|
|
20
|
+
When `platform-dst-top-layer` is enabled, keep select menus within the viewport by sizing the
|
|
21
|
+
anchored host to the menu and constraining the scrolling list to available space.
|
|
22
|
+
|
|
23
|
+
When `platform-dst-top-layer` is enabled, use Select's top-layer menu positioning for TimePicker
|
|
24
|
+
instead of nesting a second popover.
|
|
25
|
+
|
|
26
|
+
- Updated dependencies
|
|
27
|
+
|
|
3
28
|
## 19.3.1
|
|
4
29
|
|
|
5
30
|
### Patch Changes
|
|
@@ -47,7 +47,7 @@ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r
|
|
|
47
47
|
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; }
|
|
48
48
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(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; }
|
|
49
49
|
var packageName = "@atlaskit/datetime-picker";
|
|
50
|
-
var packageVersion = "19.3.
|
|
50
|
+
var packageVersion = "19.3.2";
|
|
51
51
|
var styles = {
|
|
52
52
|
pickerContainerStyle: "_kqswh2mm",
|
|
53
53
|
dropdownIndicatorStyles: "_1ul91k8s _1tke1k8s _1e0c1txw _4cvr1h6o _1bah1h6o",
|
|
@@ -35,7 +35,7 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
|
|
|
35
35
|
// for typing `process`
|
|
36
36
|
// oxlint-disable-next-line @atlassian/no-restricted-imports
|
|
37
37
|
var packageName = "@atlaskit/datetime-picker";
|
|
38
|
-
var packageVersion = "19.3.
|
|
38
|
+
var packageVersion = "19.3.2";
|
|
39
39
|
var analyticsAttributes = {
|
|
40
40
|
componentName: 'dateTimePicker',
|
|
41
41
|
packageName: packageName,
|
|
@@ -19,6 +19,7 @@ var _usePlatformLeafEventHandler = require("@atlaskit/analytics-next/usePlatform
|
|
|
19
19
|
var _button = _interopRequireDefault(require("@atlaskit/button/icon/button"));
|
|
20
20
|
var _noop = _interopRequireDefault(require("@atlaskit/ds-lib/noop"));
|
|
21
21
|
var _clock = _interopRequireDefault(require("@atlaskit/icon/core/clock"));
|
|
22
|
+
var _getTimeFormat = require("@atlaskit/locale/get-time-format");
|
|
22
23
|
var _localizationProvider = require("@atlaskit/locale/localization-provider");
|
|
23
24
|
var _fg = require("@atlaskit/platform-feature-flags/fg");
|
|
24
25
|
var _styles = require("@atlaskit/react-select/styles");
|
|
@@ -27,7 +28,6 @@ var _default2 = _interopRequireDefault(require("@atlaskit/select/default"));
|
|
|
27
28
|
var _defaultTimes = require("../internal/default-times");
|
|
28
29
|
var _emptyComponent = require("../internal/empty-component");
|
|
29
30
|
var _fixedLayerMenu = require("../internal/fixed-layer-menu");
|
|
30
|
-
var _fixedLayerMenuTopLayer = require("../internal/fixed-layer-menu-top-layer");
|
|
31
31
|
var _parseTime = _interopRequireDefault(require("../internal/parse-time"));
|
|
32
32
|
var _parseTokens = require("../internal/parse-tokens");
|
|
33
33
|
var _pickerButtonContainer = require("../internal/picker-button-container");
|
|
@@ -38,7 +38,7 @@ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r
|
|
|
38
38
|
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; }
|
|
39
39
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(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; } // oxlint-disable-next-line @atlassian/no-restricted-imports
|
|
40
40
|
var packageName = "@atlaskit/datetime-picker";
|
|
41
|
-
var packageVersion = "19.3.
|
|
41
|
+
var packageVersion = "19.3.2";
|
|
42
42
|
var defaultTimeFormat = 'h:mma';
|
|
43
43
|
var menuStyles = {
|
|
44
44
|
/* Need to remove default absolute positioning as that causes issues with position fixed */
|
|
@@ -106,10 +106,7 @@ var TimePicker = /*#__PURE__*/(0, _react.forwardRef)(function (_ref2, _ref) {
|
|
|
106
106
|
providedOnChange = _ref2$onChange === void 0 ? _noop.default : _ref2$onChange,
|
|
107
107
|
_ref2$onFocus = _ref2.onFocus,
|
|
108
108
|
providedOnFocus = _ref2$onFocus === void 0 ? _noop.default : _ref2$onFocus,
|
|
109
|
-
|
|
110
|
-
parseInputValue = _ref2$parseInputValue === void 0 ? function (time, _timeFormat) {
|
|
111
|
-
return (0, _parseTime.default)(time);
|
|
112
|
-
} : _ref2$parseInputValue,
|
|
109
|
+
parseInputValue = _ref2.parseInputValue,
|
|
113
110
|
placeholder = _ref2.placeholder,
|
|
114
111
|
_ref2$selectProps = _ref2.selectProps,
|
|
115
112
|
selectProps = _ref2$selectProps === void 0 ? {} : _ref2$selectProps,
|
|
@@ -154,6 +151,10 @@ var TimePicker = /*#__PURE__*/(0, _react.forwardRef)(function (_ref2, _ref) {
|
|
|
154
151
|
_useState10 = (0, _slicedToArray2.default)(_useState1, 2),
|
|
155
152
|
value = _useState10[0],
|
|
156
153
|
setValue = _useState10[1];
|
|
154
|
+
var l10n = (0, _localizationProvider.createLocalizationProvider)(locale);
|
|
155
|
+
var localeTimeFormat = (0, _react.useMemo)(function () {
|
|
156
|
+
return (0, _fg.fg)('platform-dst-locale-aware-time-parsing') ? (0, _getTimeFormat.getTimeFormat)(locale) : undefined;
|
|
157
|
+
}, [locale]);
|
|
157
158
|
|
|
158
159
|
// Hack to force update: https://legacy.reactjs.org/docs/hooks-faq.html#is-there-something-like-forceupdate
|
|
159
160
|
var _useReducer = (0, _react.useReducer)(function (x) {
|
|
@@ -200,7 +201,7 @@ var TimePicker = /*#__PURE__*/(0, _react.forwardRef)(function (_ref2, _ref) {
|
|
|
200
201
|
if (timeIsEditable) {
|
|
201
202
|
var sanitizedInput;
|
|
202
203
|
try {
|
|
203
|
-
sanitizedInput = parseInputValue(inputValue, timeFormat || defaultTimeFormat);
|
|
204
|
+
sanitizedInput = parseInputValue ? parseInputValue(inputValue, timeFormat || defaultTimeFormat) : (0, _parseTime.default)(inputValue, localeTimeFormat);
|
|
204
205
|
} catch (_unused) {
|
|
205
206
|
return; // do nothing, the main validation should happen in the form
|
|
206
207
|
}
|
|
@@ -273,7 +274,6 @@ var TimePicker = /*#__PURE__*/(0, _react.forwardRef)(function (_ref2, _ref) {
|
|
|
273
274
|
};
|
|
274
275
|
var ICON_PADDING = 2;
|
|
275
276
|
var GRID_SIZE = 8;
|
|
276
|
-
var l10n = (0, _localizationProvider.createLocalizationProvider)(locale);
|
|
277
277
|
var _selectProps$styles = selectProps.styles,
|
|
278
278
|
selectStyles = _selectProps$styles === void 0 ? {} : _selectProps$styles,
|
|
279
279
|
otherSelectProps = (0, _objectWithoutProperties2.default)(selectProps, _excluded);
|
|
@@ -338,9 +338,11 @@ var TimePicker = /*#__PURE__*/(0, _react.forwardRef)(function (_ref2, _ref) {
|
|
|
338
338
|
id: valueId,
|
|
339
339
|
lang: locale
|
|
340
340
|
});
|
|
341
|
-
var selectComponents = _objectSpread({
|
|
342
|
-
DropdownIndicator: _emptyComponent.EmptyComponent
|
|
343
|
-
|
|
341
|
+
var selectComponents = _objectSpread(_objectSpread({
|
|
342
|
+
DropdownIndicator: _emptyComponent.EmptyComponent
|
|
343
|
+
}, !(0, _fg.fg)('platform-dst-top-layer') && {
|
|
344
|
+
Menu: _fixedLayerMenu.FixedLayerMenu
|
|
345
|
+
}), {}, {
|
|
344
346
|
SingleValue: SingleValue
|
|
345
347
|
}, hideIcon && {
|
|
346
348
|
ClearIndicator: _emptyComponent.EmptyComponent
|
|
@@ -8,12 +8,12 @@ function isValid(timeString) {
|
|
|
8
8
|
/**
|
|
9
9
|
* Regex match for `12:34`, `12:34:56`, `1:23:56 p`, `1:23:56PM`, and a bit more…
|
|
10
10
|
*/
|
|
11
|
-
var time = timeString.trim().match(
|
|
11
|
+
var time = timeString.trim().match(/^([012]?[\d])(?:[:.]?([0-5][\d]))?(?:[:.]?([0-5][\d]))?\s*([ap](?:\s*\.?\s*m\.?)?)?$/i);
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* Regex match for `1234`, `12:34`, `12.34`, `123456`, `12:34:56`, `12.34.56`
|
|
15
15
|
*/
|
|
16
|
-
var time24hr = timeString.trim().match(
|
|
16
|
+
var time24hr = timeString.trim().match(/^([012][\d])[:.]?([0-5][\d])([:.]?([0-5][\d]))?$/);
|
|
17
17
|
|
|
18
18
|
/**
|
|
19
19
|
* Convert `2:34:56 pm` down to `23456`
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
|
|
3
4
|
Object.defineProperty(exports, "__esModule", {
|
|
4
5
|
value: true
|
|
5
6
|
});
|
|
6
7
|
exports.default = parseTime;
|
|
8
|
+
var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
|
|
9
|
+
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
7
10
|
var _convertTo24hrTime = require("./convert-to24hr-time");
|
|
8
11
|
var _isValid = require("./is-valid");
|
|
9
12
|
var _removeSpacer = require("./remove-spacer");
|
|
13
|
+
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; }
|
|
14
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { (0, _defineProperty2.default)(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; }
|
|
10
15
|
function assignToDate(time) {
|
|
11
16
|
var dateTime = new Date();
|
|
12
17
|
dateTime.setHours(time.hour);
|
|
@@ -15,8 +20,26 @@ function assignToDate(time) {
|
|
|
15
20
|
dateTime.setSeconds(time.seconds || 0, 0);
|
|
16
21
|
return dateTime;
|
|
17
22
|
}
|
|
18
|
-
function
|
|
23
|
+
function parseLegacyTime(time) {
|
|
24
|
+
var allowCompactTime = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
|
|
19
25
|
var trimmedTime = time.toString().trim();
|
|
26
|
+
var compactTime = allowCompactTime ? trimmedTime.match(/^\d{5}$/) : null;
|
|
27
|
+
if (compactTime) {
|
|
28
|
+
var normalizedTime = "0".concat(compactTime[0]);
|
|
29
|
+
var hour = Number(normalizedTime.slice(0, 2));
|
|
30
|
+
var minute = Number(normalizedTime.slice(2, 4));
|
|
31
|
+
var seconds = Number(normalizedTime.slice(4, 6));
|
|
32
|
+
if (minute <= 59 && seconds <= 59) {
|
|
33
|
+
return assignToDate({
|
|
34
|
+
hour: hour,
|
|
35
|
+
minute: minute,
|
|
36
|
+
seconds: seconds
|
|
37
|
+
});
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
if (/^\d{5}$/.test(trimmedTime)) {
|
|
41
|
+
throw RangeError('invalid time format');
|
|
42
|
+
}
|
|
20
43
|
if (!(0, _isValid.isValid)(trimmedTime)) {
|
|
21
44
|
throw RangeError('invalid time format');
|
|
22
45
|
}
|
|
@@ -25,5 +48,160 @@ function parseTime(time) {
|
|
|
25
48
|
if (!time2) {
|
|
26
49
|
throw RangeError('invalid time format');
|
|
27
50
|
}
|
|
28
|
-
return assignToDate(time2)
|
|
51
|
+
return assignToDate(_objectSpread(_objectSpread({}, time2), {}, {
|
|
52
|
+
hour: time2.hour === 24 ? 0 : time2.hour
|
|
53
|
+
}));
|
|
54
|
+
}
|
|
55
|
+
var escapeRegExp = function escapeRegExp(value) {
|
|
56
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
57
|
+
};
|
|
58
|
+
var normalizeDigits = function normalizeDigits(time, timeFormat) {
|
|
59
|
+
return Array.from(time, function (character) {
|
|
60
|
+
return timeFormat.digits[character] || character;
|
|
61
|
+
}).join('');
|
|
62
|
+
};
|
|
63
|
+
var isValidHourForCycle = function isValidHourForCycle(hour, hourCycle) {
|
|
64
|
+
return hourCycle === 'h11' ? hour <= 11 : hourCycle === 'h12' ? hour >= 1 && hour <= 12 : hour <= 24;
|
|
65
|
+
};
|
|
66
|
+
function parseExactLocalizedTime(time, timeFormat) {
|
|
67
|
+
if (!timeFormat.timeParts) {
|
|
68
|
+
return undefined;
|
|
69
|
+
}
|
|
70
|
+
var dayPeriods = Object.entries(timeFormat.dayPeriods).filter(function (_ref) {
|
|
71
|
+
var _ref2 = (0, _slicedToArray2.default)(_ref, 2),
|
|
72
|
+
value = _ref2[1];
|
|
73
|
+
return value;
|
|
74
|
+
});
|
|
75
|
+
var groupTypes = [];
|
|
76
|
+
var patternParts = timeFormat.timeParts.map(function (part) {
|
|
77
|
+
if (part.type === 'hour' || part.type === 'minute' || part.type === 'second') {
|
|
78
|
+
groupTypes.push(part.type);
|
|
79
|
+
return part.type === 'hour' ? '(\\d{1,2})' : '(\\d{2})';
|
|
80
|
+
}
|
|
81
|
+
if (part.type === 'dayPeriod') {
|
|
82
|
+
if (dayPeriods.length === 0) {
|
|
83
|
+
return null;
|
|
84
|
+
}
|
|
85
|
+
groupTypes.push('dayPeriod');
|
|
86
|
+
return "(".concat(dayPeriods.map(function (_ref3) {
|
|
87
|
+
var _ref4 = (0, _slicedToArray2.default)(_ref3, 2),
|
|
88
|
+
value = _ref4[1];
|
|
89
|
+
return escapeRegExp(value);
|
|
90
|
+
}).join('|'), ")");
|
|
91
|
+
}
|
|
92
|
+
if (part.type === 'literal') {
|
|
93
|
+
return escapeRegExp(part.value);
|
|
94
|
+
}
|
|
95
|
+
return null;
|
|
96
|
+
});
|
|
97
|
+
if (patternParts.some(function (part) {
|
|
98
|
+
return part === null;
|
|
99
|
+
})) {
|
|
100
|
+
return undefined;
|
|
101
|
+
}
|
|
102
|
+
var match = time.match(new RegExp("^".concat(patternParts.join(''), "$"), 'u'));
|
|
103
|
+
if (!match) {
|
|
104
|
+
return undefined;
|
|
105
|
+
}
|
|
106
|
+
var values = Object.fromEntries(groupTypes.map(function (type, index) {
|
|
107
|
+
return [type, match[index + 1]];
|
|
108
|
+
}));
|
|
109
|
+
if (!values.hour || !values.minute) {
|
|
110
|
+
return undefined;
|
|
111
|
+
}
|
|
112
|
+
var hour = Number(values.hour);
|
|
113
|
+
var minute = Number(values.minute);
|
|
114
|
+
var seconds = Number(values.second || '0');
|
|
115
|
+
if (minute > 59 || seconds > 59) {
|
|
116
|
+
return null;
|
|
117
|
+
}
|
|
118
|
+
if (values.dayPeriod) {
|
|
119
|
+
var _dayPeriods$find;
|
|
120
|
+
var period = (_dayPeriods$find = dayPeriods.find(function (_ref5) {
|
|
121
|
+
var _ref6 = (0, _slicedToArray2.default)(_ref5, 2),
|
|
122
|
+
value = _ref6[1];
|
|
123
|
+
return value === values.dayPeriod;
|
|
124
|
+
})) === null || _dayPeriods$find === void 0 ? void 0 : _dayPeriods$find[0];
|
|
125
|
+
if (!period || !isValidHourForCycle(hour, timeFormat.hourCycle)) {
|
|
126
|
+
return null;
|
|
127
|
+
}
|
|
128
|
+
return assignToDate({
|
|
129
|
+
hour: period === 'pm' ? hour % 12 + 12 : hour % 12,
|
|
130
|
+
minute: minute,
|
|
131
|
+
seconds: seconds
|
|
132
|
+
});
|
|
133
|
+
}
|
|
134
|
+
if (hour > 24) {
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
return assignToDate({
|
|
138
|
+
hour: hour === 24 ? 0 : hour,
|
|
139
|
+
minute: minute,
|
|
140
|
+
seconds: seconds
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
function parseLocalizedTime(normalizedTime, timeFormat) {
|
|
144
|
+
var dayPeriods = Object.entries(timeFormat.dayPeriods).filter(function (_ref7) {
|
|
145
|
+
var _ref8 = (0, _slicedToArray2.default)(_ref7, 2),
|
|
146
|
+
value = _ref8[1];
|
|
147
|
+
return value;
|
|
148
|
+
});
|
|
149
|
+
var markers = dayPeriods.filter(function (_ref9) {
|
|
150
|
+
var _ref0 = (0, _slicedToArray2.default)(_ref9, 2),
|
|
151
|
+
value = _ref0[1];
|
|
152
|
+
return new RegExp(escapeRegExp(value), 'u').test(normalizedTime);
|
|
153
|
+
});
|
|
154
|
+
if (markers.length === 0) {
|
|
155
|
+
return undefined;
|
|
156
|
+
}
|
|
157
|
+
if (markers.length !== 1) {
|
|
158
|
+
return null;
|
|
159
|
+
}
|
|
160
|
+
var _markers = (0, _slicedToArray2.default)(markers, 1),
|
|
161
|
+
_markers$ = (0, _slicedToArray2.default)(_markers[0], 2),
|
|
162
|
+
period = _markers$[0],
|
|
163
|
+
marker = _markers$[1];
|
|
164
|
+
var numericTime = normalizedTime.replace(new RegExp(escapeRegExp(marker), 'u'), '').trim();
|
|
165
|
+
var match = numericTime.match(/^(\d{1,2})(?:[:.](\d{2}))?(?:[:.](\d{2}))?$/);
|
|
166
|
+
if (!match) {
|
|
167
|
+
return null;
|
|
168
|
+
}
|
|
169
|
+
var _match = (0, _slicedToArray2.default)(match, 4),
|
|
170
|
+
hourValue = _match[1],
|
|
171
|
+
_match$ = _match[2],
|
|
172
|
+
minuteValue = _match$ === void 0 ? '0' : _match$,
|
|
173
|
+
_match$2 = _match[3],
|
|
174
|
+
secondValue = _match$2 === void 0 ? '0' : _match$2;
|
|
175
|
+
var hour = Number(hourValue);
|
|
176
|
+
var minute = Number(minuteValue);
|
|
177
|
+
var seconds = Number(secondValue);
|
|
178
|
+
if (!isValidHourForCycle(hour, timeFormat.hourCycle) || minute > 59 || seconds > 59) {
|
|
179
|
+
return null;
|
|
180
|
+
}
|
|
181
|
+
return assignToDate({
|
|
182
|
+
hour: period === 'pm' ? hour % 12 + 12 : hour % 12,
|
|
183
|
+
minute: minute,
|
|
184
|
+
seconds: seconds
|
|
185
|
+
});
|
|
186
|
+
}
|
|
187
|
+
function parseTime(time, timeFormat) {
|
|
188
|
+
if (timeFormat) {
|
|
189
|
+
var normalizedTime = normalizeDigits(time, timeFormat);
|
|
190
|
+
var exactLocalizedTime = parseExactLocalizedTime(normalizedTime, timeFormat);
|
|
191
|
+
if (exactLocalizedTime instanceof Date) {
|
|
192
|
+
return exactLocalizedTime;
|
|
193
|
+
}
|
|
194
|
+
if (exactLocalizedTime === null) {
|
|
195
|
+
throw RangeError('invalid time format');
|
|
196
|
+
}
|
|
197
|
+
var localizedTime = parseLocalizedTime(normalizedTime, timeFormat);
|
|
198
|
+
if (localizedTime instanceof Date) {
|
|
199
|
+
return localizedTime;
|
|
200
|
+
}
|
|
201
|
+
if (localizedTime === null) {
|
|
202
|
+
throw RangeError('invalid time format');
|
|
203
|
+
}
|
|
204
|
+
return parseLegacyTime(normalizedTime, true);
|
|
205
|
+
}
|
|
206
|
+
return parseLegacyTime(time);
|
|
29
207
|
}
|
|
@@ -32,7 +32,7 @@ import { parseDate } from '../internal/parse-date';
|
|
|
32
32
|
import { PickerButtonContainer } from '../internal/picker-button-container';
|
|
33
33
|
import { makeSingleValue } from '../internal/single-value';
|
|
34
34
|
const packageName = "@atlaskit/datetime-picker";
|
|
35
|
-
const packageVersion = "19.3.
|
|
35
|
+
const packageVersion = "19.3.2";
|
|
36
36
|
const styles = {
|
|
37
37
|
pickerContainerStyle: "_kqswh2mm",
|
|
38
38
|
dropdownIndicatorStyles: "_1ul91k8s _1tke1k8s _1e0c1txw _4cvr1h6o _1bah1h6o",
|
|
@@ -22,7 +22,7 @@ import { convertTokens } from '../internal/parse-tokens';
|
|
|
22
22
|
import DatePicker from './date-picker';
|
|
23
23
|
import TimePicker from './time-picker';
|
|
24
24
|
const packageName = "@atlaskit/datetime-picker";
|
|
25
|
-
const packageVersion = "19.3.
|
|
25
|
+
const packageVersion = "19.3.2";
|
|
26
26
|
const analyticsAttributes = {
|
|
27
27
|
componentName: 'dateTimePicker',
|
|
28
28
|
packageName,
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
import _extends from "@babel/runtime/helpers/extends";
|
|
3
3
|
import "./time-picker.compiled.css";
|
|
4
4
|
import { ax, ix } from "@compiled/react/runtime";
|
|
5
|
-
import React, { forwardRef, useCallback, useEffect, useId, useReducer, useState } from 'react';
|
|
5
|
+
import React, { forwardRef, useCallback, useEffect, useId, useMemo, useReducer, useState } from 'react';
|
|
6
6
|
|
|
7
7
|
// oxlint-disable-next-line @atlassian/no-restricted-imports
|
|
8
8
|
import { format, isValid } from 'date-fns';
|
|
@@ -10,6 +10,7 @@ import { usePlatformLeafEventHandler } from '@atlaskit/analytics-next/usePlatfor
|
|
|
10
10
|
import IconButton from '@atlaskit/button/icon/button';
|
|
11
11
|
import __noop from '@atlaskit/ds-lib/noop';
|
|
12
12
|
import ClockIcon from '@atlaskit/icon/core/clock';
|
|
13
|
+
import { getTimeFormat } from '@atlaskit/locale/get-time-format';
|
|
13
14
|
import { createLocalizationProvider } from '@atlaskit/locale/localization-provider';
|
|
14
15
|
import { fg } from '@atlaskit/platform-feature-flags/fg';
|
|
15
16
|
import { mergeStyles } from '@atlaskit/react-select/styles';
|
|
@@ -18,14 +19,13 @@ import Select from '@atlaskit/select/default';
|
|
|
18
19
|
import { defaultTimes } from '../internal/default-times';
|
|
19
20
|
import { EmptyComponent } from '../internal/empty-component';
|
|
20
21
|
import { FixedLayerMenu } from '../internal/fixed-layer-menu';
|
|
21
|
-
import { FixedLayerMenuTopLayer } from '../internal/fixed-layer-menu-top-layer';
|
|
22
22
|
import parseTime from '../internal/parse-time';
|
|
23
23
|
import { convertTokens } from '../internal/parse-tokens';
|
|
24
24
|
import { PickerButtonContainer } from '../internal/picker-button-container';
|
|
25
25
|
import { placeholderDatetime } from '../internal/placeholder-date-time';
|
|
26
26
|
import { makeSingleValue } from '../internal/single-value';
|
|
27
27
|
const packageName = "@atlaskit/datetime-picker";
|
|
28
|
-
const packageVersion = "19.3.
|
|
28
|
+
const packageVersion = "19.3.2";
|
|
29
29
|
const defaultTimeFormat = 'h:mma';
|
|
30
30
|
const menuStyles = {
|
|
31
31
|
/* Need to remove default absolute positioning as that causes issues with position fixed */
|
|
@@ -75,7 +75,7 @@ const TimePicker = /*#__PURE__*/forwardRef(({
|
|
|
75
75
|
onBlur: providedOnBlur = __noop,
|
|
76
76
|
onChange: providedOnChange = __noop,
|
|
77
77
|
onFocus: providedOnFocus = __noop,
|
|
78
|
-
parseInputValue
|
|
78
|
+
parseInputValue,
|
|
79
79
|
placeholder,
|
|
80
80
|
selectProps = {},
|
|
81
81
|
shouldShowTimeButton = false,
|
|
@@ -98,6 +98,8 @@ const TimePicker = /*#__PURE__*/forwardRef(({
|
|
|
98
98
|
const [isOpen, setIsOpen] = useState(defaultIsOpen);
|
|
99
99
|
const [shouldFocusTimeInput, setShouldFocusTimeInput] = useState(false);
|
|
100
100
|
const [value, setValue] = useState(defaultValue);
|
|
101
|
+
const l10n = createLocalizationProvider(locale);
|
|
102
|
+
const localeTimeFormat = useMemo(() => fg('platform-dst-locale-aware-time-parsing') ? getTimeFormat(locale) : undefined, [locale]);
|
|
101
103
|
|
|
102
104
|
// Hack to force update: https://legacy.reactjs.org/docs/hooks-faq.html#is-there-something-like-forceupdate
|
|
103
105
|
const [, forceUpdate] = useReducer(x => x + 1, 0);
|
|
@@ -141,7 +143,7 @@ const TimePicker = /*#__PURE__*/forwardRef(({
|
|
|
141
143
|
if (timeIsEditable) {
|
|
142
144
|
let sanitizedInput;
|
|
143
145
|
try {
|
|
144
|
-
sanitizedInput = parseInputValue(inputValue, timeFormat || defaultTimeFormat);
|
|
146
|
+
sanitizedInput = parseInputValue ? parseInputValue(inputValue, timeFormat || defaultTimeFormat) : parseTime(inputValue, localeTimeFormat);
|
|
145
147
|
} catch {
|
|
146
148
|
return; // do nothing, the main validation should happen in the form
|
|
147
149
|
}
|
|
@@ -216,7 +218,6 @@ const TimePicker = /*#__PURE__*/forwardRef(({
|
|
|
216
218
|
};
|
|
217
219
|
const ICON_PADDING = 2;
|
|
218
220
|
const GRID_SIZE = 8;
|
|
219
|
-
const l10n = createLocalizationProvider(locale);
|
|
220
221
|
const {
|
|
221
222
|
styles: selectStyles = {},
|
|
222
223
|
...otherSelectProps
|
|
@@ -284,7 +285,10 @@ const TimePicker = /*#__PURE__*/forwardRef(({
|
|
|
284
285
|
});
|
|
285
286
|
const selectComponents = {
|
|
286
287
|
DropdownIndicator: EmptyComponent,
|
|
287
|
-
|
|
288
|
+
// Select owns top-layer positioning; only the legacy path needs a separate wrapper.
|
|
289
|
+
...(!fg('platform-dst-top-layer') && {
|
|
290
|
+
Menu: FixedLayerMenu
|
|
291
|
+
}),
|
|
288
292
|
SingleValue,
|
|
289
293
|
...(hideIcon && {
|
|
290
294
|
ClearIndicator: EmptyComponent
|
|
@@ -2,12 +2,12 @@ export function isValid(timeString) {
|
|
|
2
2
|
/**
|
|
3
3
|
* Regex match for `12:34`, `12:34:56`, `1:23:56 p`, `1:23:56PM`, and a bit more…
|
|
4
4
|
*/
|
|
5
|
-
const time = timeString.trim().match(
|
|
5
|
+
const time = timeString.trim().match(/^([012]?[\d])(?:[:.]?([0-5][\d]))?(?:[:.]?([0-5][\d]))?\s*([ap](?:\s*\.?\s*m\.?)?)?$/i);
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* Regex match for `1234`, `12:34`, `12.34`, `123456`, `12:34:56`, `12.34.56`
|
|
9
9
|
*/
|
|
10
|
-
const time24hr = timeString.trim().match(
|
|
10
|
+
const time24hr = timeString.trim().match(/^([012][\d])[:.]?([0-5][\d])([:.]?([0-5][\d]))?$/);
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* Convert `2:34:56 pm` down to `23456`
|
|
@@ -9,8 +9,25 @@ function assignToDate(time) {
|
|
|
9
9
|
dateTime.setSeconds(time.seconds || 0, 0);
|
|
10
10
|
return dateTime;
|
|
11
11
|
}
|
|
12
|
-
|
|
12
|
+
function parseLegacyTime(time, allowCompactTime = false) {
|
|
13
13
|
const trimmedTime = time.toString().trim();
|
|
14
|
+
const compactTime = allowCompactTime ? trimmedTime.match(/^\d{5}$/) : null;
|
|
15
|
+
if (compactTime) {
|
|
16
|
+
const normalizedTime = `0${compactTime[0]}`;
|
|
17
|
+
const hour = Number(normalizedTime.slice(0, 2));
|
|
18
|
+
const minute = Number(normalizedTime.slice(2, 4));
|
|
19
|
+
const seconds = Number(normalizedTime.slice(4, 6));
|
|
20
|
+
if (minute <= 59 && seconds <= 59) {
|
|
21
|
+
return assignToDate({
|
|
22
|
+
hour,
|
|
23
|
+
minute,
|
|
24
|
+
seconds
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
if (/^\d{5}$/.test(trimmedTime)) {
|
|
29
|
+
throw RangeError('invalid time format');
|
|
30
|
+
}
|
|
14
31
|
if (!isValid(trimmedTime)) {
|
|
15
32
|
throw RangeError('invalid time format');
|
|
16
33
|
}
|
|
@@ -19,5 +36,121 @@ export default function parseTime(time) {
|
|
|
19
36
|
if (!time2) {
|
|
20
37
|
throw RangeError('invalid time format');
|
|
21
38
|
}
|
|
22
|
-
return assignToDate(
|
|
39
|
+
return assignToDate({
|
|
40
|
+
...time2,
|
|
41
|
+
hour: time2.hour === 24 ? 0 : time2.hour
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
const escapeRegExp = value => value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
45
|
+
const normalizeDigits = (time, timeFormat) => Array.from(time, character => timeFormat.digits[character] || character).join('');
|
|
46
|
+
const isValidHourForCycle = (hour, hourCycle) => hourCycle === 'h11' ? hour <= 11 : hourCycle === 'h12' ? hour >= 1 && hour <= 12 : hour <= 24;
|
|
47
|
+
function parseExactLocalizedTime(time, timeFormat) {
|
|
48
|
+
if (!timeFormat.timeParts) {
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
51
|
+
const dayPeriods = Object.entries(timeFormat.dayPeriods).filter(([, value]) => value);
|
|
52
|
+
const groupTypes = [];
|
|
53
|
+
const patternParts = timeFormat.timeParts.map(part => {
|
|
54
|
+
if (part.type === 'hour' || part.type === 'minute' || part.type === 'second') {
|
|
55
|
+
groupTypes.push(part.type);
|
|
56
|
+
return part.type === 'hour' ? '(\\d{1,2})' : '(\\d{2})';
|
|
57
|
+
}
|
|
58
|
+
if (part.type === 'dayPeriod') {
|
|
59
|
+
if (dayPeriods.length === 0) {
|
|
60
|
+
return null;
|
|
61
|
+
}
|
|
62
|
+
groupTypes.push('dayPeriod');
|
|
63
|
+
return `(${dayPeriods.map(([, value]) => escapeRegExp(value)).join('|')})`;
|
|
64
|
+
}
|
|
65
|
+
if (part.type === 'literal') {
|
|
66
|
+
return escapeRegExp(part.value);
|
|
67
|
+
}
|
|
68
|
+
return null;
|
|
69
|
+
});
|
|
70
|
+
if (patternParts.some(part => part === null)) {
|
|
71
|
+
return undefined;
|
|
72
|
+
}
|
|
73
|
+
const match = time.match(new RegExp(`^${patternParts.join('')}$`, 'u'));
|
|
74
|
+
if (!match) {
|
|
75
|
+
return undefined;
|
|
76
|
+
}
|
|
77
|
+
const values = Object.fromEntries(groupTypes.map((type, index) => [type, match[index + 1]]));
|
|
78
|
+
if (!values.hour || !values.minute) {
|
|
79
|
+
return undefined;
|
|
80
|
+
}
|
|
81
|
+
const hour = Number(values.hour);
|
|
82
|
+
const minute = Number(values.minute);
|
|
83
|
+
const seconds = Number(values.second || '0');
|
|
84
|
+
if (minute > 59 || seconds > 59) {
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
if (values.dayPeriod) {
|
|
88
|
+
var _dayPeriods$find;
|
|
89
|
+
const period = (_dayPeriods$find = dayPeriods.find(([, value]) => value === values.dayPeriod)) === null || _dayPeriods$find === void 0 ? void 0 : _dayPeriods$find[0];
|
|
90
|
+
if (!period || !isValidHourForCycle(hour, timeFormat.hourCycle)) {
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
return assignToDate({
|
|
94
|
+
hour: period === 'pm' ? hour % 12 + 12 : hour % 12,
|
|
95
|
+
minute,
|
|
96
|
+
seconds
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
if (hour > 24) {
|
|
100
|
+
return null;
|
|
101
|
+
}
|
|
102
|
+
return assignToDate({
|
|
103
|
+
hour: hour === 24 ? 0 : hour,
|
|
104
|
+
minute,
|
|
105
|
+
seconds
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
function parseLocalizedTime(normalizedTime, timeFormat) {
|
|
109
|
+
const dayPeriods = Object.entries(timeFormat.dayPeriods).filter(([, value]) => value);
|
|
110
|
+
const markers = dayPeriods.filter(([, value]) => new RegExp(escapeRegExp(value), 'u').test(normalizedTime));
|
|
111
|
+
if (markers.length === 0) {
|
|
112
|
+
return undefined;
|
|
113
|
+
}
|
|
114
|
+
if (markers.length !== 1) {
|
|
115
|
+
return null;
|
|
116
|
+
}
|
|
117
|
+
const [[period, marker]] = markers;
|
|
118
|
+
const numericTime = normalizedTime.replace(new RegExp(escapeRegExp(marker), 'u'), '').trim();
|
|
119
|
+
const match = numericTime.match(/^(\d{1,2})(?:[:.](\d{2}))?(?:[:.](\d{2}))?$/);
|
|
120
|
+
if (!match) {
|
|
121
|
+
return null;
|
|
122
|
+
}
|
|
123
|
+
const [, hourValue, minuteValue = '0', secondValue = '0'] = match;
|
|
124
|
+
const hour = Number(hourValue);
|
|
125
|
+
const minute = Number(minuteValue);
|
|
126
|
+
const seconds = Number(secondValue);
|
|
127
|
+
if (!isValidHourForCycle(hour, timeFormat.hourCycle) || minute > 59 || seconds > 59) {
|
|
128
|
+
return null;
|
|
129
|
+
}
|
|
130
|
+
return assignToDate({
|
|
131
|
+
hour: period === 'pm' ? hour % 12 + 12 : hour % 12,
|
|
132
|
+
minute,
|
|
133
|
+
seconds
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
export default function parseTime(time, timeFormat) {
|
|
137
|
+
if (timeFormat) {
|
|
138
|
+
const normalizedTime = normalizeDigits(time, timeFormat);
|
|
139
|
+
const exactLocalizedTime = parseExactLocalizedTime(normalizedTime, timeFormat);
|
|
140
|
+
if (exactLocalizedTime instanceof Date) {
|
|
141
|
+
return exactLocalizedTime;
|
|
142
|
+
}
|
|
143
|
+
if (exactLocalizedTime === null) {
|
|
144
|
+
throw RangeError('invalid time format');
|
|
145
|
+
}
|
|
146
|
+
const localizedTime = parseLocalizedTime(normalizedTime, timeFormat);
|
|
147
|
+
if (localizedTime instanceof Date) {
|
|
148
|
+
return localizedTime;
|
|
149
|
+
}
|
|
150
|
+
if (localizedTime === null) {
|
|
151
|
+
throw RangeError('invalid time format');
|
|
152
|
+
}
|
|
153
|
+
return parseLegacyTime(normalizedTime, true);
|
|
154
|
+
}
|
|
155
|
+
return parseLegacyTime(time);
|
|
23
156
|
}
|
|
@@ -40,7 +40,7 @@ import { parseDate } from '../internal/parse-date';
|
|
|
40
40
|
import { PickerButtonContainer } from '../internal/picker-button-container';
|
|
41
41
|
import { makeSingleValue } from '../internal/single-value';
|
|
42
42
|
var packageName = "@atlaskit/datetime-picker";
|
|
43
|
-
var packageVersion = "19.3.
|
|
43
|
+
var packageVersion = "19.3.2";
|
|
44
44
|
var styles = {
|
|
45
45
|
pickerContainerStyle: "_kqswh2mm",
|
|
46
46
|
dropdownIndicatorStyles: "_1ul91k8s _1tke1k8s _1e0c1txw _4cvr1h6o _1bah1h6o",
|
|
@@ -29,7 +29,7 @@ import { convertTokens } from '../internal/parse-tokens';
|
|
|
29
29
|
import DatePicker from './date-picker';
|
|
30
30
|
import TimePicker from './time-picker';
|
|
31
31
|
var packageName = "@atlaskit/datetime-picker";
|
|
32
|
-
var packageVersion = "19.3.
|
|
32
|
+
var packageVersion = "19.3.2";
|
|
33
33
|
var analyticsAttributes = {
|
|
34
34
|
componentName: 'dateTimePicker',
|
|
35
35
|
packageName: packageName,
|