@atlaskit/datetime-picker 12.10.6 → 13.0.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.
Files changed (32) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/dist/cjs/components/date-picker.js +6 -3
  3. package/dist/cjs/components/date-time-picker.js +9 -11
  4. package/dist/cjs/components/time-picker.js +9 -4
  5. package/dist/cjs/internal/clear-button.js +47 -0
  6. package/dist/cjs/internal/clear-indicator.js +37 -0
  7. package/dist/cjs/internal/parse-time.js +30 -12
  8. package/dist/es2019/components/date-picker.js +6 -3
  9. package/dist/es2019/components/date-time-picker.js +9 -11
  10. package/dist/es2019/components/time-picker.js +9 -4
  11. package/dist/es2019/internal/clear-button.js +38 -0
  12. package/dist/es2019/internal/clear-indicator.js +31 -0
  13. package/dist/es2019/internal/parse-time.js +29 -11
  14. package/dist/esm/components/date-picker.js +6 -3
  15. package/dist/esm/components/date-time-picker.js +9 -11
  16. package/dist/esm/components/time-picker.js +9 -4
  17. package/dist/esm/internal/clear-button.js +39 -0
  18. package/dist/esm/internal/clear-indicator.js +32 -0
  19. package/dist/esm/internal/parse-time.js +29 -11
  20. package/dist/types/components/date-picker.d.ts +4 -5
  21. package/dist/types/components/date-time-picker.d.ts +3 -4
  22. package/dist/types/components/time-picker.d.ts +4 -3
  23. package/dist/types/internal/clear-button.d.ts +17 -0
  24. package/dist/types/internal/clear-indicator.d.ts +10 -0
  25. package/dist/types/internal/parse-time.d.ts +9 -9
  26. package/dist/types-ts4.5/components/date-picker.d.ts +4 -5
  27. package/dist/types-ts4.5/components/date-time-picker.d.ts +3 -4
  28. package/dist/types-ts4.5/components/time-picker.d.ts +4 -3
  29. package/dist/types-ts4.5/internal/clear-button.d.ts +17 -0
  30. package/dist/types-ts4.5/internal/clear-indicator.d.ts +10 -0
  31. package/dist/types-ts4.5/internal/parse-time.d.ts +9 -9
  32. package/package.json +4 -4
package/CHANGELOG.md CHANGED
@@ -1,5 +1,26 @@
1
1
  # @atlaskit/datetime-picker
2
2
 
3
+ ## 13.0.1
4
+
5
+ ### Patch Changes
6
+
7
+ - [#40391](https://bitbucket.org/atlassian/atlassian-frontend/pull-requests/40391) [`4300c9d6f18`](https://bitbucket.org/atlassian/atlassian-frontend/commits/4300c9d6f18) - Associate the label with the `Date` / `Time` picker and the clear button.
8
+ Add hidden span to the Label component.
9
+ This allows to associate a label with a clear button.
10
+ Unit tests update.
11
+
12
+ ## 13.0.0
13
+
14
+ ### Major Changes
15
+
16
+ - [#43269](https://bitbucket.org/atlassian/atlassian-frontend/pull-requests/43269) [`c7ab5b9501c`](https://bitbucket.org/atlassian/atlassian-frontend/commits/c7ab5b9501c) - This fixes it so that `<TimePicker timeEditable timeFormat="hh:mm:ss">` will return seconds when the timeformat includes seconds whereas previously it would strictly return `HH:mm` and not account for the `timeFormat`. It is still not flexible and does not return time in your `timeFormat` to avoid causing unexpected breaking changes as that `HH:mm` format has been there for so long.
17
+
18
+ There's a theoretical risk that `HH:mm` formats are expected back when `HH:mm:ss` format are used and unsed improperly, but any typical parsing of datetime should handle this change perfectly fine, with zero breaking change expected.
19
+
20
+ ### Patch Changes
21
+
22
+ - Updated dependencies
23
+
3
24
  ## 12.10.6
4
25
 
5
26
  ### Patch Changes
@@ -29,6 +29,7 @@ var _select = _interopRequireWildcard(require("@atlaskit/select"));
29
29
  var _colors = require("@atlaskit/theme/colors");
30
30
  var _constants = require("@atlaskit/theme/constants");
31
31
  var _internal = require("../internal");
32
+ var _clearIndicator = _interopRequireDefault(require("../internal/clear-indicator"));
32
33
  var _fixedLayer = _interopRequireDefault(require("../internal/fixed-layer"));
33
34
  var _singleValue = require("../internal/single-value");
34
35
  var _utils = require("./utils");
@@ -39,7 +40,7 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
39
40
  function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
40
41
  function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } /** @jsx jsx */
41
42
  var packageName = "@atlaskit/datetime-picker";
42
- var packageVersion = "12.10.6";
43
+ var packageVersion = "13.0.1";
43
44
  function getValidDate(iso) {
44
45
  var date = (0, _dateFns.parseISO)(iso);
45
46
  return (0, _dateFns.isValid)(date) ? {
@@ -439,7 +440,9 @@ var DatePicker = exports.DatePickerWithoutAnalytics = /*#__PURE__*/function (_Co
439
440
  DropdownIndicator: dropDownIcon,
440
441
  Menu: Menu,
441
442
  SingleValue: SingleValue
442
- }, !showClearIndicator && {
443
+ }, showClearIndicator ? {
444
+ ClearIndicator: _clearIndicator.default
445
+ } : {
443
446
  ClearIndicator: _internal.EmptyComponent
444
447
  });
445
448
  var _selectProps$styles = selectProps.styles,
@@ -486,7 +489,7 @@ var DatePicker = exports.DatePickerWithoutAnalytics = /*#__PURE__*/function (_Co
486
489
  menuIsOpen: menuIsOpen,
487
490
  closeMenuOnSelect: true,
488
491
  autoFocus: autoFocus,
489
- instanceId: id,
492
+ inputId: id,
490
493
  isDisabled: isDisabled,
491
494
  onBlur: this.onSelectBlur,
492
495
  onFocus: this.onSelectFocus,
@@ -18,11 +18,11 @@ var _react2 = require("@emotion/react");
18
18
  var _dateFns = require("date-fns");
19
19
  var _pick = _interopRequireDefault(require("lodash/pick"));
20
20
  var _analyticsNext = require("@atlaskit/analytics-next");
21
- var _selectClear = _interopRequireDefault(require("@atlaskit/icon/glyph/select-clear"));
22
21
  var _platformFeatureFlags = require("@atlaskit/platform-feature-flags");
23
22
  var _select = require("@atlaskit/select");
24
23
  var _colors = require("@atlaskit/theme/colors");
25
24
  var _internal = require("../internal");
25
+ var _clearButton = _interopRequireDefault(require("../internal/clear-button"));
26
26
  var _datePicker = _interopRequireDefault(require("./date-picker"));
27
27
  var _timePicker = _interopRequireDefault(require("./time-picker"));
28
28
  var _utils = require("./utils");
@@ -31,7 +31,7 @@ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Re
31
31
  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; }
32
32
  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; } /** @jsx jsx */
33
33
  var packageName = "@atlaskit/datetime-picker";
34
- var packageVersion = "12.10.6";
34
+ var packageVersion = "13.0.1";
35
35
  var isInvalidBorderStyles = (0, _react2.css)({
36
36
  borderColor: "var(--ds-border-danger, ".concat(_colors.R400, ")")
37
37
  });
@@ -305,9 +305,11 @@ var DateTimePicker = exports.DateTimePickerWithoutAnalytics = /*#__PURE__*/funct
305
305
  // Don't use Date or TimePicker's because they can't be customised
306
306
  var isClearable = Boolean(dateValue || timeValue);
307
307
  var notFocusedOrIsDisabled = !(isFocused || isDisabled);
308
+ var ariaLabelledbyId = id && "label--".concat(id);
308
309
  return (0, _react2.jsx)("div", (0, _extends2.default)({
309
310
  css: [baseContainerStyles, isDisabled && isDisabledStyles, isFocused && isFocusedStyles, bothProps.appearance === 'subtle' && (isFocused ? subtleFocusedBgStyles : subtleBgStyles), isFocused && isFocusedBorderStyles, bothProps.isInvalid && isInvalidBorderStyles, notFocusedOrIsDisabled && (bothProps.isInvalid ? isInvalidHoverStyles : hoverStyles), bothProps.appearance === 'none' && noBgStyles]
310
311
  }, innerProps, {
312
+ "aria-labelledby": innerProps['aria-labelledby'] || ariaLabelledbyId,
311
313
  "data-testid": testId
312
314
  }), (0, _react2.jsx)("input", {
313
315
  name: name,
@@ -338,17 +340,13 @@ var DateTimePicker = exports.DateTimePickerWithoutAnalytics = /*#__PURE__*/funct
338
340
  timeFormat: timeFormat,
339
341
  locale: locale,
340
342
  testId: testId && "".concat(testId, "--timepicker")
341
- }, timePickerProps))), isClearable && !isDisabled ? (0, _react2.jsx)("button", {
342
- css: iconContainerStyles,
343
+ }, timePickerProps))), isClearable && !isDisabled ? (0, _react2.jsx)(_clearButton.default, {
344
+ inputId: id,
345
+ buttonStyles: iconContainerStyles,
343
346
  onClick: this.onClear,
344
347
  "data-testid": testId && "".concat(testId, "--icon--container"),
345
- tabIndex: -1,
346
- type: "button"
347
- }, (0, _react2.jsx)(_selectClear.default, {
348
- size: "small",
349
- primaryColor: "inherit",
350
- label: "clear"
351
- })) : null);
348
+ primaryColor: "inherit"
349
+ }) : null);
352
350
  }
353
351
  }]);
354
352
  return DateTimePicker;
@@ -23,6 +23,7 @@ var _locale = require("@atlaskit/locale");
23
23
  var _select = _interopRequireWildcard(require("@atlaskit/select"));
24
24
  var _constants = require("@atlaskit/theme/constants");
25
25
  var _internal = require("../internal");
26
+ var _clearIndicator = _interopRequireDefault(require("../internal/clear-indicator"));
26
27
  var _fixedLayer = _interopRequireDefault(require("../internal/fixed-layer"));
27
28
  var _parseTime = _interopRequireDefault(require("../internal/parse-time"));
28
29
  var _singleValue = require("../internal/single-value");
@@ -37,7 +38,7 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
37
38
  function _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; }
38
39
  function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } }
39
40
  var packageName = "@atlaskit/datetime-picker";
40
- var packageVersion = "12.10.6";
41
+ var packageVersion = "13.0.1";
41
42
  var menuStyles = {
42
43
  /* Need to remove default absolute positioning as that causes issues with position fixed */
43
44
  position: 'static',
@@ -138,7 +139,9 @@ var TimePicker = exports.TimePickerWithoutAnalytics = /*#__PURE__*/function (_Re
138
139
  return; // do nothing, the main validation should happen in the form
139
140
  }
140
141
 
141
- var formattedValue = (0, _dateFns.format)(sanitizedInput, 'HH:mm') || '';
142
+ var includesSeconds = !!(_timeFormat2 && /[:.]?(s|ss)/.test(_timeFormat2));
143
+ var formatFormat = includesSeconds ? 'HH:mm:ss' : 'HH:mm';
144
+ var formattedValue = (0, _dateFns.format)(sanitizedInput, formatFormat) || '';
142
145
  _this.setState({
143
146
  value: formattedValue
144
147
  });
@@ -277,8 +280,10 @@ var TimePicker = exports.TimePickerWithoutAnalytics = /*#__PURE__*/function (_Re
277
280
  DropdownIndicator: _internal.EmptyComponent,
278
281
  Menu: FixedLayerMenu,
279
282
  SingleValue: SingleValue
280
- }, hideIcon && {
283
+ }, hideIcon ? {
281
284
  ClearIndicator: _internal.EmptyComponent
285
+ } : {
286
+ ClearIndicator: _clearIndicator.default
282
287
  });
283
288
  var renderIconContainer = Boolean(!hideIcon && value);
284
289
  var mergedStyles = (0, _select.mergeStyles)(selectStyles, {
@@ -312,7 +317,7 @@ var TimePicker = exports.TimePickerWithoutAnalytics = /*#__PURE__*/function (_Re
312
317
  appearance: appearance,
313
318
  autoFocus: autoFocus,
314
319
  components: selectComponents,
315
- instanceId: id,
320
+ inputId: id,
316
321
  isClearable: true,
317
322
  isDisabled: isDisabled,
318
323
  menuIsOpen: isOpen && !isDisabled,
@@ -0,0 +1,47 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.default = void 0;
8
+ var _react = require("@emotion/react");
9
+ var _selectClear = _interopRequireDefault(require("@atlaskit/icon/glyph/select-clear"));
10
+ /** @jsx jsx */
11
+
12
+ /**
13
+ * __Clear button__
14
+ */
15
+ var ClearButton = function ClearButton(_ref) {
16
+ var inputId = _ref.inputId,
17
+ _ref$iconSize = _ref.iconSize,
18
+ iconSize = _ref$iconSize === void 0 ? 'small' : _ref$iconSize,
19
+ _ref$label = _ref.label,
20
+ label = _ref$label === void 0 ? 'Clear' : _ref$label,
21
+ primaryColor = _ref.primaryColor,
22
+ buttonStyles = _ref.buttonStyles,
23
+ dataTestId = _ref.dataTestId,
24
+ onClick = _ref.onClick;
25
+ var labelId = inputId && "label--".concat(inputId);
26
+ var clearButtonId = inputId && "clear-btn--".concat(inputId);
27
+ return (0, _react.jsx)("button", {
28
+ css: buttonStyles,
29
+ type: "button",
30
+ tabIndex: -1,
31
+ "data-testid": "".concat(dataTestId, "--clear--btn"),
32
+ onClick: onClick
33
+ }, (0, _react.jsx)("span", {
34
+ hidden: true,
35
+ id: clearButtonId
36
+ }, "Clear"), (0, _react.jsx)("span", {
37
+ style: {
38
+ display: 'flex'
39
+ },
40
+ "aria-labelledby": inputId ? "".concat(clearButtonId, " ").concat(labelId) : "".concat(clearButtonId)
41
+ }, (0, _react.jsx)(_selectClear.default, {
42
+ size: iconSize,
43
+ label: inputId ? '' : label,
44
+ primaryColor: primaryColor
45
+ })));
46
+ };
47
+ var _default = exports.default = ClearButton;
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.default = void 0;
8
+ var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
9
+ var _react = require("@emotion/react");
10
+ var _select = require("@atlaskit/select");
11
+ var _clearButton = _interopRequireDefault(require("./clear-button"));
12
+ 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; }
13
+ 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; } /** @jsx jsx */
14
+ var buttonStyles = (0, _react.css)({
15
+ display: 'flex',
16
+ alignItems: 'center',
17
+ all: 'unset',
18
+ outline: 'revert'
19
+ });
20
+
21
+ /**
22
+ * __Clear indicator__
23
+ * Overwrites the default `ClearIndicator` button with custom styles and attributes
24
+ *
25
+ */
26
+ var ClearIndicator = function ClearIndicator(props) {
27
+ return (0, _react.jsx)(_select.components.ClearIndicator, _objectSpread(_objectSpread({}, props), {}, {
28
+ innerProps: _objectSpread(_objectSpread({}, props.innerProps), {}, {
29
+ 'aria-hidden': 'false'
30
+ })
31
+ }), (0, _react.jsx)(_clearButton.default, {
32
+ buttonStyles: buttonStyles,
33
+ inputId: props.selectProps.inputId,
34
+ dataTestId: props.selectProps.testId
35
+ }));
36
+ };
37
+ var _default = exports.default = ClearIndicator;
@@ -5,7 +5,7 @@ Object.defineProperty(exports, "__esModule", {
5
5
  });
6
6
  exports.assignToDate = assignToDate;
7
7
  exports.checkHour = checkHour;
8
- exports.checkMinute = checkMinute;
8
+ exports.checkMinuteSecond = checkMinuteSecond;
9
9
  exports.convertTo24hrTime = convertTo24hrTime;
10
10
  exports.default = _default;
11
11
  exports.formatSemi24 = formatSemi24;
@@ -26,16 +26,31 @@ var map24 = {
26
26
  '11': '23'
27
27
  };
28
28
  function isValid(timeString) {
29
- var time = timeString.trim().match(/(\d+)(?::(\d\d))?\s*(a|p)?/i);
30
- var time24hr = timeString.trim().match(/(\d\d)[:.]?(\d\d)/);
29
+ /**
30
+ * Regex match for `12:34`, `12:34:56`, `1:23:56 p`, `1:23:56PM`, and a bit more…
31
+ */
32
+ var time = timeString.trim().match(/([012]?[\d])(?::([0-5][\d]))?(?::([0-5][\d]))?\s*([ap]m?)?/i);
33
+
34
+ /**
35
+ * Regex match for `1234`, `12:34`, `12.34`, `123456`, `12:34:56`, `12.34.56`
36
+ */
37
+ var time24hr = timeString.trim().match(/([012][\d])[:.]?([0-5][\d])([:.]?([0-5][\d]))?/);
38
+
39
+ /**
40
+ * Convert `2:34:56 pm` down to `23456`
41
+ */
31
42
  var num = timeString.replace(/[^0-9]/g, '');
43
+ var includesSeconds = time && time[1] !== undefined && time[2] !== undefined && time[3] !== undefined || time24hr && time24hr[1] !== undefined && time24hr[2] !== undefined && time24hr[4] !== undefined;
32
44
  if (!time && !time24hr) {
33
45
  return false;
34
46
  }
35
47
  if (time && !time[1]) {
36
48
  return false;
37
49
  }
38
- if (num.length > 4) {
50
+ if (num.length > 6) {
51
+ return false;
52
+ }
53
+ if (num.length > 4 && !includesSeconds) {
39
54
  return false;
40
55
  }
41
56
  if (num.length === 2 && parseInt(num, 10) > 12) {
@@ -44,7 +59,7 @@ function isValid(timeString) {
44
59
  return true;
45
60
  }
46
61
  function removeSpacer(time) {
47
- return time.replace(/[:.]/, '');
62
+ return time.replace(/[:.]/g, '');
48
63
  }
49
64
  function formatSemi24(time) {
50
65
  if (time.length === 1) {
@@ -53,7 +68,7 @@ function formatSemi24(time) {
53
68
  if (time.length === 2) {
54
69
  return "".concat(time, "00");
55
70
  }
56
- if (time.length === 3) {
71
+ if (time.length === 3 || time.length === 5) {
57
72
  return "0".concat(time);
58
73
  }
59
74
  return time;
@@ -70,31 +85,34 @@ function checkHour(hour, meridiem) {
70
85
  }
71
86
  return hour;
72
87
  }
73
- function checkMinute(minute) {
74
- if (minute > '59') {
88
+ function checkMinuteSecond(value) {
89
+ if (value > '59') {
75
90
  return null;
76
91
  }
77
- return minute;
92
+ return value;
78
93
  }
79
94
  function convertTo24hrTime(time) {
80
95
  var timeArray = time.toLowerCase().split(/(p|a)/i);
81
96
  var meridiem = timeArray[1];
82
97
  var semi24 = formatSemi24(timeArray[0].trim());
83
98
  var hour = checkHour(semi24.substring(0, 2), meridiem);
84
- var minute = checkMinute(semi24.substring(2, 4));
99
+ var minute = checkMinuteSecond(semi24.substring(2, 4));
100
+ var seconds = semi24.length === 6 && checkMinuteSecond(semi24.substring(4, 6));
85
101
  if (!hour || !minute) {
86
102
  return null;
87
103
  }
88
104
  return {
89
105
  hour: parseInt(hour, 10),
90
- minute: parseInt(minute, 10)
106
+ minute: parseInt(minute, 10),
107
+ seconds: parseInt(seconds || '0', 10) || 0
91
108
  };
92
109
  }
93
110
  function assignToDate(time) {
94
111
  var dateTime = new Date();
95
112
  dateTime.setHours(time.hour);
96
113
  dateTime.setMinutes(time.minute);
97
- dateTime.setSeconds(0, 0);
114
+ // milliseconds is not supported
115
+ dateTime.setSeconds(time.seconds || 0, 0);
98
116
  return dateTime;
99
117
  }
100
118
  function _default(time) {
@@ -15,11 +15,12 @@ import Select, { mergeStyles } from '@atlaskit/select';
15
15
  import { N0, N50A, N60A } from '@atlaskit/theme/colors';
16
16
  import { layers } from '@atlaskit/theme/constants';
17
17
  import { defaultDateFormat, EmptyComponent, padToTwo, placeholderDatetime } from '../internal';
18
+ import ClearIndicator from '../internal/clear-indicator';
18
19
  import FixedLayer from '../internal/fixed-layer';
19
20
  import { makeSingleValue } from '../internal/single-value';
20
21
  import { convertTokens } from './utils';
21
22
  const packageName = "@atlaskit/datetime-picker";
22
- const packageVersion = "12.10.6";
23
+ const packageVersion = "13.0.1";
23
24
  function getValidDate(iso) {
24
25
  const date = parseISO(iso);
25
26
  return isValid(date) ? {
@@ -437,7 +438,9 @@ class DatePicker extends Component {
437
438
  DropdownIndicator: dropDownIcon,
438
439
  Menu,
439
440
  SingleValue,
440
- ...(!showClearIndicator && {
441
+ ...(showClearIndicator ? {
442
+ ClearIndicator: ClearIndicator
443
+ } : {
441
444
  ClearIndicator: EmptyComponent
442
445
  })
443
446
  };
@@ -486,7 +489,7 @@ class DatePicker extends Component {
486
489
  menuIsOpen: menuIsOpen,
487
490
  closeMenuOnSelect: true,
488
491
  autoFocus: autoFocus,
489
- instanceId: id,
492
+ inputId: id,
490
493
  isDisabled: isDisabled,
491
494
  onBlur: this.onSelectBlur,
492
495
  onFocus: this.onSelectFocus,
@@ -6,16 +6,16 @@ import { css, jsx } from '@emotion/react';
6
6
  import { format, isValid, parseISO } from 'date-fns';
7
7
  import pick from 'lodash/pick';
8
8
  import { createAndFireEvent, withAnalyticsContext, withAnalyticsEvents } from '@atlaskit/analytics-next';
9
- import SelectClearIcon from '@atlaskit/icon/glyph/select-clear';
10
9
  import { getBooleanFF } from '@atlaskit/platform-feature-flags';
11
10
  import { mergeStyles } from '@atlaskit/select';
12
11
  import { B100, N0, N100, N20, N30, N500, N70, R400 } from '@atlaskit/theme/colors';
13
12
  import { defaultTimes, formatDateTimeZoneIntoIso } from '../internal';
13
+ import ClearButton from '../internal/clear-button';
14
14
  import DatePicker from './date-picker';
15
15
  import TimePicker from './time-picker';
16
16
  import { convertTokens } from './utils';
17
17
  const packageName = "@atlaskit/datetime-picker";
18
- const packageVersion = "12.10.6";
18
+ const packageVersion = "13.0.1";
19
19
  const isInvalidBorderStyles = css({
20
20
  borderColor: `var(--ds-border-danger, ${R400})`
21
21
  });
@@ -291,9 +291,11 @@ class DateTimePicker extends React.Component {
291
291
  // Don't use Date or TimePicker's because they can't be customised
292
292
  const isClearable = Boolean(dateValue || timeValue);
293
293
  const notFocusedOrIsDisabled = !(isFocused || isDisabled);
294
+ const ariaLabelledbyId = id && `label--${id}`;
294
295
  return jsx("div", _extends({
295
296
  css: [baseContainerStyles, isDisabled && isDisabledStyles, isFocused && isFocusedStyles, bothProps.appearance === 'subtle' && (isFocused ? subtleFocusedBgStyles : subtleBgStyles), isFocused && isFocusedBorderStyles, bothProps.isInvalid && isInvalidBorderStyles, notFocusedOrIsDisabled && (bothProps.isInvalid ? isInvalidHoverStyles : hoverStyles), bothProps.appearance === 'none' && noBgStyles]
296
297
  }, innerProps, {
298
+ "aria-labelledby": innerProps['aria-labelledby'] || ariaLabelledbyId,
297
299
  "data-testid": testId
298
300
  }), jsx("input", {
299
301
  name: name,
@@ -324,17 +326,13 @@ class DateTimePicker extends React.Component {
324
326
  timeFormat: timeFormat,
325
327
  locale: locale,
326
328
  testId: testId && `${testId}--timepicker`
327
- }, timePickerProps))), isClearable && !isDisabled ? jsx("button", {
328
- css: iconContainerStyles,
329
+ }, timePickerProps))), isClearable && !isDisabled ? jsx(ClearButton, {
330
+ inputId: id,
331
+ buttonStyles: iconContainerStyles,
329
332
  onClick: this.onClear,
330
333
  "data-testid": testId && `${testId}--icon--container`,
331
- tabIndex: -1,
332
- type: "button"
333
- }, jsx(SelectClearIcon, {
334
- size: "small",
335
- primaryColor: "inherit",
336
- label: "clear"
337
- })) : null);
334
+ primaryColor: "inherit"
335
+ }) : null);
338
336
  }
339
337
  }
340
338
  _defineProperty(DateTimePicker, "defaultProps", dateTimePickerDefaultProps);
@@ -11,12 +11,13 @@ import Select, { components, CreatableSelect, mergeStyles } from '@atlaskit/sele
11
11
  // eslint-disable-next-line @atlaskit/design-system/no-deprecated-imports
12
12
  import { gridSize } from '@atlaskit/theme/constants';
13
13
  import { defaultTimeFormat, defaultTimes, EmptyComponent, placeholderDatetime } from '../internal';
14
+ import ClearIndicator from '../internal/clear-indicator';
14
15
  import FixedLayer from '../internal/fixed-layer';
15
16
  import parseTime from '../internal/parse-time';
16
17
  import { makeSingleValue } from '../internal/single-value';
17
18
  import { convertTokens } from './utils';
18
19
  const packageName = "@atlaskit/datetime-picker";
19
- const packageVersion = "12.10.6";
20
+ const packageVersion = "13.0.1";
20
21
  const menuStyles = {
21
22
  /* Need to remove default absolute positioning as that causes issues with position fixed */
22
23
  position: 'static',
@@ -113,7 +114,9 @@ class TimePicker extends React.Component {
113
114
  return; // do nothing, the main validation should happen in the form
114
115
  }
115
116
 
116
- const formattedValue = format(sanitizedInput, 'HH:mm') || '';
117
+ const includesSeconds = !!(timeFormat && /[:.]?(s|ss)/.test(timeFormat));
118
+ const formatFormat = includesSeconds ? 'HH:mm:ss' : 'HH:mm';
119
+ const formattedValue = format(sanitizedInput, formatFormat) || '';
117
120
  this.setState({
118
121
  value: formattedValue
119
122
  });
@@ -252,8 +255,10 @@ class TimePicker extends React.Component {
252
255
  DropdownIndicator: EmptyComponent,
253
256
  Menu: FixedLayerMenu,
254
257
  SingleValue,
255
- ...(hideIcon && {
258
+ ...(hideIcon ? {
256
259
  ClearIndicator: EmptyComponent
260
+ } : {
261
+ ClearIndicator: ClearIndicator
257
262
  })
258
263
  };
259
264
  const renderIconContainer = Boolean(!hideIcon && value);
@@ -287,7 +292,7 @@ class TimePicker extends React.Component {
287
292
  appearance: appearance,
288
293
  autoFocus: autoFocus,
289
294
  components: selectComponents,
290
- instanceId: id,
295
+ inputId: id,
291
296
  isClearable: true,
292
297
  isDisabled: isDisabled,
293
298
  menuIsOpen: isOpen && !isDisabled,
@@ -0,0 +1,38 @@
1
+ /** @jsx jsx */
2
+ import { jsx } from '@emotion/react';
3
+ import SelectClearIcon from '@atlaskit/icon/glyph/select-clear';
4
+ /**
5
+ * __Clear button__
6
+ */
7
+ const ClearButton = ({
8
+ inputId,
9
+ iconSize = 'small',
10
+ label = 'Clear',
11
+ primaryColor,
12
+ buttonStyles,
13
+ dataTestId,
14
+ onClick
15
+ }) => {
16
+ const labelId = inputId && `label--${inputId}`;
17
+ const clearButtonId = inputId && `clear-btn--${inputId}`;
18
+ return jsx("button", {
19
+ css: buttonStyles,
20
+ type: "button",
21
+ tabIndex: -1,
22
+ "data-testid": `${dataTestId}--clear--btn`,
23
+ onClick: onClick
24
+ }, jsx("span", {
25
+ hidden: true,
26
+ id: clearButtonId
27
+ }, "Clear"), jsx("span", {
28
+ style: {
29
+ display: 'flex'
30
+ },
31
+ "aria-labelledby": inputId ? `${clearButtonId} ${labelId}` : `${clearButtonId}`
32
+ }, jsx(SelectClearIcon, {
33
+ size: iconSize,
34
+ label: inputId ? '' : label,
35
+ primaryColor: primaryColor
36
+ })));
37
+ };
38
+ export default ClearButton;
@@ -0,0 +1,31 @@
1
+ import _extends from "@babel/runtime/helpers/extends";
2
+ /** @jsx jsx */
3
+
4
+ import { css, jsx } from '@emotion/react';
5
+ import { components } from '@atlaskit/select';
6
+ import ClearButton from './clear-button';
7
+ const buttonStyles = css({
8
+ display: 'flex',
9
+ alignItems: 'center',
10
+ all: 'unset',
11
+ outline: 'revert'
12
+ });
13
+
14
+ /**
15
+ * __Clear indicator__
16
+ * Overwrites the default `ClearIndicator` button with custom styles and attributes
17
+ *
18
+ */
19
+ const ClearIndicator = props => {
20
+ return jsx(components.ClearIndicator, _extends({}, props, {
21
+ innerProps: {
22
+ ...props.innerProps,
23
+ 'aria-hidden': 'false'
24
+ }
25
+ }), jsx(ClearButton, {
26
+ buttonStyles: buttonStyles,
27
+ inputId: props.selectProps.inputId,
28
+ dataTestId: props.selectProps.testId
29
+ }));
30
+ };
31
+ export default ClearIndicator;
@@ -13,16 +13,31 @@ const map24 = {
13
13
  '11': '23'
14
14
  };
15
15
  export function isValid(timeString) {
16
- const time = timeString.trim().match(/(\d+)(?::(\d\d))?\s*(a|p)?/i);
17
- const time24hr = timeString.trim().match(/(\d\d)[:.]?(\d\d)/);
16
+ /**
17
+ * Regex match for `12:34`, `12:34:56`, `1:23:56 p`, `1:23:56PM`, and a bit more…
18
+ */
19
+ const time = timeString.trim().match(/([012]?[\d])(?::([0-5][\d]))?(?::([0-5][\d]))?\s*([ap]m?)?/i);
20
+
21
+ /**
22
+ * Regex match for `1234`, `12:34`, `12.34`, `123456`, `12:34:56`, `12.34.56`
23
+ */
24
+ const time24hr = timeString.trim().match(/([012][\d])[:.]?([0-5][\d])([:.]?([0-5][\d]))?/);
25
+
26
+ /**
27
+ * Convert `2:34:56 pm` down to `23456`
28
+ */
18
29
  const num = timeString.replace(/[^0-9]/g, '');
30
+ const includesSeconds = time && time[1] !== undefined && time[2] !== undefined && time[3] !== undefined || time24hr && time24hr[1] !== undefined && time24hr[2] !== undefined && time24hr[4] !== undefined;
19
31
  if (!time && !time24hr) {
20
32
  return false;
21
33
  }
22
34
  if (time && !time[1]) {
23
35
  return false;
24
36
  }
25
- if (num.length > 4) {
37
+ if (num.length > 6) {
38
+ return false;
39
+ }
40
+ if (num.length > 4 && !includesSeconds) {
26
41
  return false;
27
42
  }
28
43
  if (num.length === 2 && parseInt(num, 10) > 12) {
@@ -31,7 +46,7 @@ export function isValid(timeString) {
31
46
  return true;
32
47
  }
33
48
  export function removeSpacer(time) {
34
- return time.replace(/[:.]/, '');
49
+ return time.replace(/[:.]/g, '');
35
50
  }
36
51
  export function formatSemi24(time) {
37
52
  if (time.length === 1) {
@@ -40,7 +55,7 @@ export function formatSemi24(time) {
40
55
  if (time.length === 2) {
41
56
  return `${time}00`;
42
57
  }
43
- if (time.length === 3) {
58
+ if (time.length === 3 || time.length === 5) {
44
59
  return `0${time}`;
45
60
  }
46
61
  return time;
@@ -57,31 +72,34 @@ export function checkHour(hour, meridiem) {
57
72
  }
58
73
  return hour;
59
74
  }
60
- export function checkMinute(minute) {
61
- if (minute > '59') {
75
+ export function checkMinuteSecond(value) {
76
+ if (value > '59') {
62
77
  return null;
63
78
  }
64
- return minute;
79
+ return value;
65
80
  }
66
81
  export function convertTo24hrTime(time) {
67
82
  const timeArray = time.toLowerCase().split(/(p|a)/i);
68
83
  const meridiem = timeArray[1];
69
84
  const semi24 = formatSemi24(timeArray[0].trim());
70
85
  const hour = checkHour(semi24.substring(0, 2), meridiem);
71
- const minute = checkMinute(semi24.substring(2, 4));
86
+ const minute = checkMinuteSecond(semi24.substring(2, 4));
87
+ const seconds = semi24.length === 6 && checkMinuteSecond(semi24.substring(4, 6));
72
88
  if (!hour || !minute) {
73
89
  return null;
74
90
  }
75
91
  return {
76
92
  hour: parseInt(hour, 10),
77
- minute: parseInt(minute, 10)
93
+ minute: parseInt(minute, 10),
94
+ seconds: parseInt(seconds || '0', 10) || 0
78
95
  };
79
96
  }
80
97
  export function assignToDate(time) {
81
98
  const dateTime = new Date();
82
99
  dateTime.setHours(time.hour);
83
100
  dateTime.setMinutes(time.minute);
84
- dateTime.setSeconds(0, 0);
101
+ // milliseconds is not supported
102
+ dateTime.setSeconds(time.seconds || 0, 0);
85
103
  return dateTime;
86
104
  }
87
105
  export default function (time) {