@atlaskit/datetime-picker 12.7.6 → 12.7.8

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 CHANGED
@@ -1,5 +1,17 @@
1
1
  # @atlaskit/datetime-picker
2
2
 
3
+ ## 12.7.8
4
+
5
+ ### Patch Changes
6
+
7
+ - [`e8bb91da805`](https://bitbucket.org/atlassian/atlassian-frontend/commits/e8bb91da805) - [ux] Ensure menu doesn't close when focus moves within it. Makes future keyboard accessibility possible.
8
+
9
+ ## 12.7.7
10
+
11
+ ### Patch Changes
12
+
13
+ - [`ba50169844e`](https://bitbucket.org/atlassian/atlassian-frontend/commits/ba50169844e) - Remove lookahead and lookbehind in format util to support browsers without that functionality.
14
+
3
15
  ## 12.7.6
4
16
 
5
17
  ### Patch Changes
@@ -37,7 +37,7 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
37
37
  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
38
  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; } } /* eslint-disable @repo/internal/react/use-noop */ /** @jsx jsx */ // eslint-disable-next-line no-restricted-imports
39
39
  var packageName = "@atlaskit/datetime-picker";
40
- var packageVersion = "12.7.6";
40
+ var packageVersion = "12.7.8";
41
41
 
42
42
  /* eslint-disable react/no-unused-prop-types */
43
43
 
@@ -168,12 +168,16 @@ var DatePicker = /*#__PURE__*/function (_Component) {
168
168
  }
169
169
  });
170
170
  (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "onSelectBlur", function (event) {
171
+ var _this$containerRef;
172
+ var newlyFocusedElement = event.relatedTarget;
171
173
  if (_this.getSafeState().clearingFromIcon) {
172
174
  // Don't close menu if blurring after the user has clicked clear
173
175
  _this.setState({
174
176
  clearingFromIcon: false
175
177
  });
176
- } else {
178
+ } else if (!((_this$containerRef = _this.containerRef) !== null && _this$containerRef !== void 0 && _this$containerRef.contains(newlyFocusedElement))) {
179
+ // Don't close menu if focus is staying within the date picker's
180
+ // container. Makes keyboard accessibility of calendar possible
177
181
  _this.setState({
178
182
  isOpen: false,
179
183
  isFocused: false
@@ -471,56 +475,60 @@ var DatePicker = /*#__PURE__*/function (_Component) {
471
475
  nextMonthLabel: nextMonthLabel,
472
476
  previousMonthLabel: previousMonthLabel
473
477
  };
474
- return (0, _react2.jsx)("div", (0, _extends2.default)({}, innerProps, {
475
- role: "presentation",
476
- onClick: this.onInputClick,
477
- onInput: this.onTextInput,
478
- onKeyDown: this.onInputKeyDown,
479
- ref: this.getContainerRef,
480
- "data-testid": testId && "".concat(testId, "--container")
481
- }), (0, _react2.jsx)("input", {
482
- name: name,
483
- type: "hidden",
484
- value: value,
485
- "data-testid": testId && "".concat(testId, "--input")
486
- }), (0, _react2.jsx)(_select.default, (0, _extends2.default)({
487
- appearance: this.props.appearance,
488
- enableAnimation: false,
489
- menuIsOpen: menuIsOpen,
490
- closeMenuOnSelect: true,
491
- autoFocus: autoFocus,
492
- instanceId: id,
493
- isDisabled: isDisabled,
494
- onBlur: this.onSelectBlur,
495
- onFocus: this.onSelectFocus,
496
- inputValue: actualSelectInputValue,
497
- onInputChange: this.handleSelectInputChange,
498
- components: selectComponents,
499
- onChange: this.onSelectChange,
500
- styles: (0, _select.mergeStyles)(selectStyles, {
501
- control: function control(base) {
502
- return _objectSpread(_objectSpread({}, base), disabledStyle);
503
- },
504
- indicatorsContainer: function indicatorsContainer(base) {
505
- return _objectSpread(_objectSpread({}, base), {}, {
506
- paddingLeft: "var(--ds-space-025, 2px)",
507
- // ICON_PADDING = 2
508
- paddingRight: "var(--ds-space-075, 6px)" // 8 - ICON_PADDING = 6
509
- });
510
- }
511
- }),
478
+ return (
479
+ // TODO: Remove role="presentation", since div's have no semantics anyway
480
+ // (DSP-11587)
481
+ (0, _react2.jsx)("div", (0, _extends2.default)({}, innerProps, {
482
+ role: "presentation",
483
+ onClick: this.onInputClick,
484
+ onInput: this.onTextInput,
485
+ onKeyDown: this.onInputKeyDown,
486
+ ref: this.getContainerRef,
487
+ "data-testid": testId && "".concat(testId, "--container")
488
+ }), (0, _react2.jsx)("input", {
489
+ name: name,
490
+ type: "hidden",
491
+ value: value,
492
+ "data-testid": testId && "".concat(testId, "--input")
493
+ }), (0, _react2.jsx)(_select.default, (0, _extends2.default)({
494
+ appearance: this.props.appearance,
495
+ enableAnimation: false,
496
+ menuIsOpen: menuIsOpen,
497
+ closeMenuOnSelect: true,
498
+ autoFocus: autoFocus,
499
+ instanceId: id,
500
+ isDisabled: isDisabled,
501
+ onBlur: this.onSelectBlur,
502
+ onFocus: this.onSelectFocus,
503
+ inputValue: actualSelectInputValue,
504
+ onInputChange: this.handleSelectInputChange,
505
+ components: selectComponents,
506
+ onChange: this.onSelectChange,
507
+ styles: (0, _select.mergeStyles)(selectStyles, {
508
+ control: function control(base) {
509
+ return _objectSpread(_objectSpread({}, base), disabledStyle);
510
+ },
511
+ indicatorsContainer: function indicatorsContainer(base) {
512
+ return _objectSpread(_objectSpread({}, base), {}, {
513
+ paddingLeft: "var(--ds-space-025, 2px)",
514
+ // ICON_PADDING = 2
515
+ paddingRight: "var(--ds-space-075, 6px)" // 8 - ICON_PADDING = 6
516
+ });
517
+ }
518
+ }),
512
519
 
513
- placeholder: this.getPlaceholder(),
514
- value: value && {
515
- label: this.formatDate(value),
516
- value: value
517
- }
518
- }, selectProps, calendarProps, {
519
- isClearable: true,
520
- spacing: spacing,
521
- isInvalid: isInvalid,
522
- testId: testId
523
- })));
520
+ placeholder: this.getPlaceholder(),
521
+ value: value && {
522
+ label: this.formatDate(value),
523
+ value: value
524
+ }
525
+ }, selectProps, calendarProps, {
526
+ isClearable: true,
527
+ spacing: spacing,
528
+ isInvalid: isInvalid,
529
+ testId: testId
530
+ })))
531
+ );
524
532
  }
525
533
  }]);
526
534
  return DatePicker;
@@ -31,7 +31,7 @@ function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Re
31
31
  function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); enumerableOnly && (symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; })), keys.push.apply(keys, symbols); } return keys; }
32
32
  function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = null != arguments[i] ? arguments[i] : {}; i % 2 ? ownKeys(Object(source), !0).forEach(function (key) { (0, _defineProperty2.default)(target, key, source[key]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)) : ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } return target; } /* eslint-disable @repo/internal/react/use-noop */ /** @jsx jsx */ // eslint-disable-next-line no-restricted-imports
33
33
  var packageName = "@atlaskit/datetime-picker";
34
- var packageVersion = "12.7.6";
34
+ var packageVersion = "12.7.8";
35
35
 
36
36
  /* eslint-disable react/no-unused-prop-types */
37
37
 
@@ -38,7 +38,7 @@ function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { va
38
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); }; }
39
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; } }
40
40
  var packageName = "@atlaskit/datetime-picker";
41
- var packageVersion = "12.7.6";
41
+ var packageVersion = "12.7.8";
42
42
 
43
43
  /* eslint-disable react/no-unused-prop-types */
44
44
 
@@ -56,34 +56,51 @@ var tokensMap = {
56
56
  x: 'T'
57
57
  };
58
58
  var v1tokens = Object.keys(tokensMap).sort().reverse();
59
- var tokensRegExp = new RegExp('(\\[[^\\[]*\\])|(\\\\)?' + '(' + v1tokens.join('|') + '|.)', 'g');
59
+ var tokensRegExp = new RegExp(
60
+ // v1 escape string (unsure the purpose of post-pipe capture group)
61
+ '(\\[[^\\[]*\\])|(\\\\)?' +
62
+ // v2 escape string
63
+ "('.+'|" +
64
+ // All v1 tokens
65
+ v1tokens.join('|') + '|.)', 'g');
60
66
  function convertTokens(format) {
61
67
  var tokensCaptures = format.match(tokensRegExp);
62
- if (tokensCaptures) {
63
- return tokensCaptures.reduce(function (acc, tokenString, index) {
64
- var v2token = tokensMap[tokenString];
65
- if (!v2token) {
66
- var escapedCaptures = tokenString.match(/^\[(.+)\]$/);
67
- if (escapedCaptures) {
68
- acc.textBuffer.push(escapedCaptures[1]);
69
- } else {
70
- acc.textBuffer.push(tokenString);
71
- }
72
- }
73
- var endOfString = index === tokensCaptures.length - 1;
74
- if (acc.textBuffer.length && (v2token || endOfString)) {
75
- acc.formatBuffer.push("'".concat(acc.textBuffer.join(''), "'"));
76
- acc.textBuffer = [];
77
- }
78
- if (v2token) {
79
- acc.formatBuffer.push(v2token);
80
- }
81
- return acc;
82
- }, {
83
- formatBuffer: [],
84
- textBuffer: []
85
- }).formatBuffer.join('');
86
- } else {
68
+ if (!tokensCaptures) {
87
69
  return format;
88
70
  }
71
+ return tokensCaptures.reduce(function (parsed, tokenString, index) {
72
+ var v2token = tokensMap[tokenString];
73
+ if (!v2token) {
74
+ var escapedCaptures = tokenString.match(/^\[(.+)\]$/);
75
+ if (escapedCaptures) {
76
+ parsed.escapedTextBuffer.push(escapedCaptures[1]);
77
+ } else {
78
+ parsed.escapedTextBuffer.push(tokenString);
79
+ }
80
+ }
81
+ var endOfString = index === tokensCaptures.length - 1;
82
+ if (parsed.escapedTextBuffer.length && (v2token || endOfString)) {
83
+ // This allows double parentheses to be rendered correctly
84
+ // according to date-fns's spec.
85
+ // https://date-fns.org/v2.29.3/docs/format
86
+ //
87
+ // We have to keep the single quote and then remove it because
88
+ // browser support for lookahead/behind is low and causes breaking
89
+ // errors (HOT-104152)
90
+ var filteredEscapedTextBuffer = parsed.escapedTextBuffer.map(function (token) {
91
+ return token[0] === "'" && token.slice(-1) === "'" ? token.slice(1, -1) : token;
92
+ }).filter(function (token) {
93
+ return token !== "'";
94
+ }).join('');
95
+ parsed.formatBuffer.push("'".concat(filteredEscapedTextBuffer, "'"));
96
+ parsed.escapedTextBuffer = [];
97
+ }
98
+ if (v2token) {
99
+ parsed.formatBuffer.push(v2token);
100
+ }
101
+ return parsed;
102
+ }, {
103
+ formatBuffer: [],
104
+ escapedTextBuffer: []
105
+ }).formatBuffer.join('');
89
106
  }
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/datetime-picker",
3
- "version": "12.7.6",
3
+ "version": "12.7.8",
4
4
  "sideEffects": false
5
5
  }
@@ -19,7 +19,7 @@ import { defaultDateFormat, EmptyComponent, padToTwo, placeholderDatetime } from
19
19
  import FixedLayer from '../internal/fixed-layer';
20
20
  import { convertTokens } from './utils';
21
21
  const packageName = "@atlaskit/datetime-picker";
22
- const packageVersion = "12.7.6";
22
+ const packageVersion = "12.7.8";
23
23
 
24
24
  /* eslint-disable react/no-unused-prop-types */
25
25
 
@@ -146,12 +146,16 @@ class DatePicker extends Component {
146
146
  }
147
147
  });
148
148
  _defineProperty(this, "onSelectBlur", event => {
149
+ var _this$containerRef;
150
+ const newlyFocusedElement = event.relatedTarget;
149
151
  if (this.getSafeState().clearingFromIcon) {
150
152
  // Don't close menu if blurring after the user has clicked clear
151
153
  this.setState({
152
154
  clearingFromIcon: false
153
155
  });
154
- } else {
156
+ } else if (!((_this$containerRef = this.containerRef) !== null && _this$containerRef !== void 0 && _this$containerRef.contains(newlyFocusedElement))) {
157
+ // Don't close menu if focus is staying within the date picker's
158
+ // container. Makes keyboard accessibility of calendar possible
155
159
  this.setState({
156
160
  isOpen: false,
157
161
  isFocused: false
@@ -461,56 +465,60 @@ class DatePicker extends Component {
461
465
  nextMonthLabel,
462
466
  previousMonthLabel
463
467
  };
464
- return jsx("div", _extends({}, innerProps, {
465
- role: "presentation",
466
- onClick: this.onInputClick,
467
- onInput: this.onTextInput,
468
- onKeyDown: this.onInputKeyDown,
469
- ref: this.getContainerRef,
470
- "data-testid": testId && `${testId}--container`
471
- }), jsx("input", {
472
- name: name,
473
- type: "hidden",
474
- value: value,
475
- "data-testid": testId && `${testId}--input`
476
- }), jsx(Select, _extends({
477
- appearance: this.props.appearance,
478
- enableAnimation: false,
479
- menuIsOpen: menuIsOpen,
480
- closeMenuOnSelect: true,
481
- autoFocus: autoFocus,
482
- instanceId: id,
483
- isDisabled: isDisabled,
484
- onBlur: this.onSelectBlur,
485
- onFocus: this.onSelectFocus,
486
- inputValue: actualSelectInputValue,
487
- onInputChange: this.handleSelectInputChange,
488
- components: selectComponents,
489
- onChange: this.onSelectChange,
490
- styles: mergeStyles(selectStyles, {
491
- control: base => ({
492
- ...base,
493
- ...disabledStyle
468
+ return (
469
+ // TODO: Remove role="presentation", since div's have no semantics anyway
470
+ // (DSP-11587)
471
+ jsx("div", _extends({}, innerProps, {
472
+ role: "presentation",
473
+ onClick: this.onInputClick,
474
+ onInput: this.onTextInput,
475
+ onKeyDown: this.onInputKeyDown,
476
+ ref: this.getContainerRef,
477
+ "data-testid": testId && `${testId}--container`
478
+ }), jsx("input", {
479
+ name: name,
480
+ type: "hidden",
481
+ value: value,
482
+ "data-testid": testId && `${testId}--input`
483
+ }), jsx(Select, _extends({
484
+ appearance: this.props.appearance,
485
+ enableAnimation: false,
486
+ menuIsOpen: menuIsOpen,
487
+ closeMenuOnSelect: true,
488
+ autoFocus: autoFocus,
489
+ instanceId: id,
490
+ isDisabled: isDisabled,
491
+ onBlur: this.onSelectBlur,
492
+ onFocus: this.onSelectFocus,
493
+ inputValue: actualSelectInputValue,
494
+ onInputChange: this.handleSelectInputChange,
495
+ components: selectComponents,
496
+ onChange: this.onSelectChange,
497
+ styles: mergeStyles(selectStyles, {
498
+ control: base => ({
499
+ ...base,
500
+ ...disabledStyle
501
+ }),
502
+ indicatorsContainer: base => ({
503
+ ...base,
504
+ paddingLeft: "var(--ds-space-025, 2px)",
505
+ // ICON_PADDING = 2
506
+ paddingRight: "var(--ds-space-075, 6px)" // 8 - ICON_PADDING = 6
507
+ })
494
508
  }),
495
- indicatorsContainer: base => ({
496
- ...base,
497
- paddingLeft: "var(--ds-space-025, 2px)",
498
- // ICON_PADDING = 2
499
- paddingRight: "var(--ds-space-075, 6px)" // 8 - ICON_PADDING = 6
500
- })
501
- }),
502
509
 
503
- placeholder: this.getPlaceholder(),
504
- value: value && {
505
- label: this.formatDate(value),
506
- value
507
- }
508
- }, selectProps, calendarProps, {
509
- isClearable: true,
510
- spacing: spacing,
511
- isInvalid: isInvalid,
512
- testId: testId
513
- })));
510
+ placeholder: this.getPlaceholder(),
511
+ value: value && {
512
+ label: this.formatDate(value),
513
+ value
514
+ }
515
+ }, selectProps, calendarProps, {
516
+ isClearable: true,
517
+ spacing: spacing,
518
+ isInvalid: isInvalid,
519
+ testId: testId
520
+ })))
521
+ );
514
522
  }
515
523
  }
516
524
  _defineProperty(DatePicker, "defaultProps", datePickerDefaultProps);
@@ -17,7 +17,7 @@ import DatePicker from './date-picker';
17
17
  import TimePicker from './time-picker';
18
18
  import { convertTokens } from './utils';
19
19
  const packageName = "@atlaskit/datetime-picker";
20
- const packageVersion = "12.7.6";
20
+ const packageVersion = "12.7.8";
21
21
 
22
22
  /* eslint-disable react/no-unused-prop-types */
23
23
 
@@ -16,7 +16,7 @@ import FixedLayer from '../internal/fixed-layer';
16
16
  import parseTime from '../internal/parse-time';
17
17
  import { convertTokens } from './utils';
18
18
  const packageName = "@atlaskit/datetime-picker";
19
- const packageVersion = "12.7.6";
19
+ const packageVersion = "12.7.8";
20
20
 
21
21
  /* eslint-disable react/no-unused-prop-types */
22
22
 
@@ -50,34 +50,47 @@ const tokensMap = {
50
50
  x: 'T'
51
51
  };
52
52
  const v1tokens = Object.keys(tokensMap).sort().reverse();
53
- const tokensRegExp = new RegExp('(\\[[^\\[]*\\])|(\\\\)?' + '(' + v1tokens.join('|') + '|.)', 'g');
53
+ const tokensRegExp = new RegExp(
54
+ // v1 escape string (unsure the purpose of post-pipe capture group)
55
+ '(\\[[^\\[]*\\])|(\\\\)?' +
56
+ // v2 escape string
57
+ "('.+'|" +
58
+ // All v1 tokens
59
+ v1tokens.join('|') + '|.)', 'g');
54
60
  export function convertTokens(format) {
55
61
  const tokensCaptures = format.match(tokensRegExp);
56
- if (tokensCaptures) {
57
- return tokensCaptures.reduce((acc, tokenString, index) => {
58
- const v2token = tokensMap[tokenString];
59
- if (!v2token) {
60
- const escapedCaptures = tokenString.match(/^\[(.+)\]$/);
61
- if (escapedCaptures) {
62
- acc.textBuffer.push(escapedCaptures[1]);
63
- } else {
64
- acc.textBuffer.push(tokenString);
65
- }
66
- }
67
- const endOfString = index === tokensCaptures.length - 1;
68
- if (acc.textBuffer.length && (v2token || endOfString)) {
69
- acc.formatBuffer.push(`'${acc.textBuffer.join('')}'`);
70
- acc.textBuffer = [];
71
- }
72
- if (v2token) {
73
- acc.formatBuffer.push(v2token);
74
- }
75
- return acc;
76
- }, {
77
- formatBuffer: [],
78
- textBuffer: []
79
- }).formatBuffer.join('');
80
- } else {
62
+ if (!tokensCaptures) {
81
63
  return format;
82
64
  }
65
+ return tokensCaptures.reduce((parsed, tokenString, index) => {
66
+ const v2token = tokensMap[tokenString];
67
+ if (!v2token) {
68
+ const escapedCaptures = tokenString.match(/^\[(.+)\]$/);
69
+ if (escapedCaptures) {
70
+ parsed.escapedTextBuffer.push(escapedCaptures[1]);
71
+ } else {
72
+ parsed.escapedTextBuffer.push(tokenString);
73
+ }
74
+ }
75
+ const endOfString = index === tokensCaptures.length - 1;
76
+ if (parsed.escapedTextBuffer.length && (v2token || endOfString)) {
77
+ // This allows double parentheses to be rendered correctly
78
+ // according to date-fns's spec.
79
+ // https://date-fns.org/v2.29.3/docs/format
80
+ //
81
+ // We have to keep the single quote and then remove it because
82
+ // browser support for lookahead/behind is low and causes breaking
83
+ // errors (HOT-104152)
84
+ const filteredEscapedTextBuffer = parsed.escapedTextBuffer.map(token => token[0] === "'" && token.slice(-1) === "'" ? token.slice(1, -1) : token).filter(token => token !== "'").join('');
85
+ parsed.formatBuffer.push(`'${filteredEscapedTextBuffer}'`);
86
+ parsed.escapedTextBuffer = [];
87
+ }
88
+ if (v2token) {
89
+ parsed.formatBuffer.push(v2token);
90
+ }
91
+ return parsed;
92
+ }, {
93
+ formatBuffer: [],
94
+ escapedTextBuffer: []
95
+ }).formatBuffer.join('');
83
96
  }
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/datetime-picker",
3
- "version": "12.7.6",
3
+ "version": "12.7.8",
4
4
  "sideEffects": false
5
5
  }
@@ -30,7 +30,7 @@ import { defaultDateFormat, EmptyComponent, padToTwo, placeholderDatetime } from
30
30
  import FixedLayer from '../internal/fixed-layer';
31
31
  import { convertTokens } from './utils';
32
32
  var packageName = "@atlaskit/datetime-picker";
33
- var packageVersion = "12.7.6";
33
+ var packageVersion = "12.7.8";
34
34
 
35
35
  /* eslint-disable react/no-unused-prop-types */
36
36
 
@@ -161,12 +161,16 @@ var DatePicker = /*#__PURE__*/function (_Component) {
161
161
  }
162
162
  });
163
163
  _defineProperty(_assertThisInitialized(_this), "onSelectBlur", function (event) {
164
+ var _this$containerRef;
165
+ var newlyFocusedElement = event.relatedTarget;
164
166
  if (_this.getSafeState().clearingFromIcon) {
165
167
  // Don't close menu if blurring after the user has clicked clear
166
168
  _this.setState({
167
169
  clearingFromIcon: false
168
170
  });
169
- } else {
171
+ } else if (!((_this$containerRef = _this.containerRef) !== null && _this$containerRef !== void 0 && _this$containerRef.contains(newlyFocusedElement))) {
172
+ // Don't close menu if focus is staying within the date picker's
173
+ // container. Makes keyboard accessibility of calendar possible
170
174
  _this.setState({
171
175
  isOpen: false,
172
176
  isFocused: false
@@ -464,56 +468,60 @@ var DatePicker = /*#__PURE__*/function (_Component) {
464
468
  nextMonthLabel: nextMonthLabel,
465
469
  previousMonthLabel: previousMonthLabel
466
470
  };
467
- return jsx("div", _extends({}, innerProps, {
468
- role: "presentation",
469
- onClick: this.onInputClick,
470
- onInput: this.onTextInput,
471
- onKeyDown: this.onInputKeyDown,
472
- ref: this.getContainerRef,
473
- "data-testid": testId && "".concat(testId, "--container")
474
- }), jsx("input", {
475
- name: name,
476
- type: "hidden",
477
- value: value,
478
- "data-testid": testId && "".concat(testId, "--input")
479
- }), jsx(Select, _extends({
480
- appearance: this.props.appearance,
481
- enableAnimation: false,
482
- menuIsOpen: menuIsOpen,
483
- closeMenuOnSelect: true,
484
- autoFocus: autoFocus,
485
- instanceId: id,
486
- isDisabled: isDisabled,
487
- onBlur: this.onSelectBlur,
488
- onFocus: this.onSelectFocus,
489
- inputValue: actualSelectInputValue,
490
- onInputChange: this.handleSelectInputChange,
491
- components: selectComponents,
492
- onChange: this.onSelectChange,
493
- styles: mergeStyles(selectStyles, {
494
- control: function control(base) {
495
- return _objectSpread(_objectSpread({}, base), disabledStyle);
496
- },
497
- indicatorsContainer: function indicatorsContainer(base) {
498
- return _objectSpread(_objectSpread({}, base), {}, {
499
- paddingLeft: "var(--ds-space-025, 2px)",
500
- // ICON_PADDING = 2
501
- paddingRight: "var(--ds-space-075, 6px)" // 8 - ICON_PADDING = 6
502
- });
503
- }
504
- }),
471
+ return (
472
+ // TODO: Remove role="presentation", since div's have no semantics anyway
473
+ // (DSP-11587)
474
+ jsx("div", _extends({}, innerProps, {
475
+ role: "presentation",
476
+ onClick: this.onInputClick,
477
+ onInput: this.onTextInput,
478
+ onKeyDown: this.onInputKeyDown,
479
+ ref: this.getContainerRef,
480
+ "data-testid": testId && "".concat(testId, "--container")
481
+ }), jsx("input", {
482
+ name: name,
483
+ type: "hidden",
484
+ value: value,
485
+ "data-testid": testId && "".concat(testId, "--input")
486
+ }), jsx(Select, _extends({
487
+ appearance: this.props.appearance,
488
+ enableAnimation: false,
489
+ menuIsOpen: menuIsOpen,
490
+ closeMenuOnSelect: true,
491
+ autoFocus: autoFocus,
492
+ instanceId: id,
493
+ isDisabled: isDisabled,
494
+ onBlur: this.onSelectBlur,
495
+ onFocus: this.onSelectFocus,
496
+ inputValue: actualSelectInputValue,
497
+ onInputChange: this.handleSelectInputChange,
498
+ components: selectComponents,
499
+ onChange: this.onSelectChange,
500
+ styles: mergeStyles(selectStyles, {
501
+ control: function control(base) {
502
+ return _objectSpread(_objectSpread({}, base), disabledStyle);
503
+ },
504
+ indicatorsContainer: function indicatorsContainer(base) {
505
+ return _objectSpread(_objectSpread({}, base), {}, {
506
+ paddingLeft: "var(--ds-space-025, 2px)",
507
+ // ICON_PADDING = 2
508
+ paddingRight: "var(--ds-space-075, 6px)" // 8 - ICON_PADDING = 6
509
+ });
510
+ }
511
+ }),
505
512
 
506
- placeholder: this.getPlaceholder(),
507
- value: value && {
508
- label: this.formatDate(value),
509
- value: value
510
- }
511
- }, selectProps, calendarProps, {
512
- isClearable: true,
513
- spacing: spacing,
514
- isInvalid: isInvalid,
515
- testId: testId
516
- })));
513
+ placeholder: this.getPlaceholder(),
514
+ value: value && {
515
+ label: this.formatDate(value),
516
+ value: value
517
+ }
518
+ }, selectProps, calendarProps, {
519
+ isClearable: true,
520
+ spacing: spacing,
521
+ isInvalid: isInvalid,
522
+ testId: testId
523
+ })))
524
+ );
517
525
  }
518
526
  }]);
519
527
  return DatePicker;
@@ -27,7 +27,7 @@ import DatePicker from './date-picker';
27
27
  import TimePicker from './time-picker';
28
28
  import { convertTokens } from './utils';
29
29
  var packageName = "@atlaskit/datetime-picker";
30
- var packageVersion = "12.7.6";
30
+ var packageVersion = "12.7.8";
31
31
 
32
32
  /* eslint-disable react/no-unused-prop-types */
33
33
 
@@ -29,7 +29,7 @@ import FixedLayer from '../internal/fixed-layer';
29
29
  import parseTime from '../internal/parse-time';
30
30
  import { convertTokens } from './utils';
31
31
  var packageName = "@atlaskit/datetime-picker";
32
- var packageVersion = "12.7.6";
32
+ var packageVersion = "12.7.8";
33
33
 
34
34
  /* eslint-disable react/no-unused-prop-types */
35
35
 
@@ -50,34 +50,51 @@ var tokensMap = {
50
50
  x: 'T'
51
51
  };
52
52
  var v1tokens = Object.keys(tokensMap).sort().reverse();
53
- var tokensRegExp = new RegExp('(\\[[^\\[]*\\])|(\\\\)?' + '(' + v1tokens.join('|') + '|.)', 'g');
53
+ var tokensRegExp = new RegExp(
54
+ // v1 escape string (unsure the purpose of post-pipe capture group)
55
+ '(\\[[^\\[]*\\])|(\\\\)?' +
56
+ // v2 escape string
57
+ "('.+'|" +
58
+ // All v1 tokens
59
+ v1tokens.join('|') + '|.)', 'g');
54
60
  export function convertTokens(format) {
55
61
  var tokensCaptures = format.match(tokensRegExp);
56
- if (tokensCaptures) {
57
- return tokensCaptures.reduce(function (acc, tokenString, index) {
58
- var v2token = tokensMap[tokenString];
59
- if (!v2token) {
60
- var escapedCaptures = tokenString.match(/^\[(.+)\]$/);
61
- if (escapedCaptures) {
62
- acc.textBuffer.push(escapedCaptures[1]);
63
- } else {
64
- acc.textBuffer.push(tokenString);
65
- }
66
- }
67
- var endOfString = index === tokensCaptures.length - 1;
68
- if (acc.textBuffer.length && (v2token || endOfString)) {
69
- acc.formatBuffer.push("'".concat(acc.textBuffer.join(''), "'"));
70
- acc.textBuffer = [];
71
- }
72
- if (v2token) {
73
- acc.formatBuffer.push(v2token);
74
- }
75
- return acc;
76
- }, {
77
- formatBuffer: [],
78
- textBuffer: []
79
- }).formatBuffer.join('');
80
- } else {
62
+ if (!tokensCaptures) {
81
63
  return format;
82
64
  }
65
+ return tokensCaptures.reduce(function (parsed, tokenString, index) {
66
+ var v2token = tokensMap[tokenString];
67
+ if (!v2token) {
68
+ var escapedCaptures = tokenString.match(/^\[(.+)\]$/);
69
+ if (escapedCaptures) {
70
+ parsed.escapedTextBuffer.push(escapedCaptures[1]);
71
+ } else {
72
+ parsed.escapedTextBuffer.push(tokenString);
73
+ }
74
+ }
75
+ var endOfString = index === tokensCaptures.length - 1;
76
+ if (parsed.escapedTextBuffer.length && (v2token || endOfString)) {
77
+ // This allows double parentheses to be rendered correctly
78
+ // according to date-fns's spec.
79
+ // https://date-fns.org/v2.29.3/docs/format
80
+ //
81
+ // We have to keep the single quote and then remove it because
82
+ // browser support for lookahead/behind is low and causes breaking
83
+ // errors (HOT-104152)
84
+ var filteredEscapedTextBuffer = parsed.escapedTextBuffer.map(function (token) {
85
+ return token[0] === "'" && token.slice(-1) === "'" ? token.slice(1, -1) : token;
86
+ }).filter(function (token) {
87
+ return token !== "'";
88
+ }).join('');
89
+ parsed.formatBuffer.push("'".concat(filteredEscapedTextBuffer, "'"));
90
+ parsed.escapedTextBuffer = [];
91
+ }
92
+ if (v2token) {
93
+ parsed.formatBuffer.push(v2token);
94
+ }
95
+ return parsed;
96
+ }, {
97
+ formatBuffer: [],
98
+ escapedTextBuffer: []
99
+ }).formatBuffer.join('');
83
100
  }
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "name": "@atlaskit/datetime-picker",
3
- "version": "12.7.6",
3
+ "version": "12.7.8",
4
4
  "sideEffects": false
5
5
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/datetime-picker",
3
- "version": "12.7.6",
3
+ "version": "12.7.8",
4
4
  "description": "A date time picker allows the user to select an associated date and time.",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -41,7 +41,7 @@
41
41
  "@atlaskit/popper": "^5.5.0",
42
42
  "@atlaskit/select": "^16.5.0",
43
43
  "@atlaskit/theme": "^12.5.0",
44
- "@atlaskit/tokens": "^1.11.0",
44
+ "@atlaskit/tokens": "^1.13.0",
45
45
  "@babel/runtime": "^7.0.0",
46
46
  "@emotion/react": "^11.7.1",
47
47
  "date-fns": "^2.17.0",
@@ -52,11 +52,12 @@
52
52
  "react": "^16.8.0"
53
53
  },
54
54
  "devDependencies": {
55
+ "@af/accessibility-testing": "*",
55
56
  "@atlaskit/button": "^16.8.0",
56
57
  "@atlaskit/docs": "*",
57
58
  "@atlaskit/form": "^8.11.0",
58
59
  "@atlaskit/modal-dialog": "^12.6.0",
59
- "@atlaskit/popup": "^1.8.0",
60
+ "@atlaskit/popup": "^1.9.0",
60
61
  "@atlaskit/range": "^7.1.0",
61
62
  "@atlaskit/section-message": "^6.4.0",
62
63
  "@atlaskit/ssr": "*",