@atlaskit/datetime-picker 19.2.0 → 19.3.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 CHANGED
@@ -1,5 +1,15 @@
1
1
  # @atlaskit/datetime-picker
2
2
 
3
+ ## 19.3.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`07e6863319dbc`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/07e6863319dbc) -
8
+ Add an optional clock button for opening the time picker without opening its menu on keyboard
9
+ focus. Invoke consumer menu callbacks once per clock button activation, including in React Strict
10
+ Mode. Share the calendar and clock button positioning and spacing through an internal styling-only
11
+ wrapper.
12
+
3
13
  ## 19.2.0
4
14
 
5
15
  ### Minor Changes
@@ -1,15 +1,9 @@
1
- ._v564vrg3{transition:color .15s}._12l21b66{margin-inline-end:var(--ds-space-050,4px)}
2
- ._12l2xy5q{margin-inline-end:var(--ds-space-400,2pc)}
3
- ._152tze3t{inset-block-start:var(--ds-space-0,0)}
4
- ._1bah1h6o{justify-content:center}
1
+ ._v564vrg3{transition:color .15s}._1bah1h6o{justify-content:center}
5
2
  ._1e0c1txw{display:flex}
6
3
  ._1tke1k8s{min-height:1.5rem}
7
4
  ._1ul91k8s{min-width:1.5rem}
8
5
  ._4cvr1h6o{align-items:center}
9
- ._4t3i1osq{height:100%}
10
6
  ._i0dl1kw7{flex-basis:inherit}
11
7
  ._kqswh2mm{position:relative}
12
- ._kqswstnw{position:absolute}
13
- ._rjxpze3t{inset-inline-end:var(--ds-space-0,0)}
14
8
  ._syaz1rpy{color:var(--ds-text-subtlest,#6b6e76)}
15
9
  ._30l3azsu:hover{color:var(--ds-text-subtle,#505258)}
@@ -18,7 +18,6 @@ var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/h
18
18
  var _dateFns = require("date-fns");
19
19
  var _usePlatformLeafEventHandler = require("@atlaskit/analytics-next/usePlatformLeafEventHandler");
20
20
  var _button = _interopRequireDefault(require("@atlaskit/button/icon/button"));
21
- var _css = require("@atlaskit/css");
22
21
  var _useId = require("@atlaskit/ds-lib/use-id");
23
22
  var _calendar = _interopRequireDefault(require("@atlaskit/icon/core/calendar"));
24
23
  var _localizationProvider = require("@atlaskit/locale/localization-provider");
@@ -37,6 +36,7 @@ var _isDateDisabled = require("../internal/is-date-disabled");
37
36
  var _menu = require("../internal/menu");
38
37
  var _menuTopLayer = require("../internal/menu-top-layer");
39
38
  var _parseDate = require("../internal/parse-date");
39
+ var _pickerButtonContainer = require("../internal/picker-button-container");
40
40
  var _singleValue = require("../internal/single-value");
41
41
  var _excluded = ["appearance", "autoFocus", "clearControlLabel", "hideIcon", "openCalendarLabel", "defaultIsOpen", "defaultValue", "disabled", "disabledDateFilter", "icon", "id", "innerProps", "inputLabel", "inputLabelId", "isDisabled", "isInvalid", "isRequired", "label", "name", "onBlur", "onChange", "onFocus", "selectProps", "shouldShowCalendarButton", "spacing", "locale", "value", "isOpen", "maxDate", "minDate", "weekStartDay", "formatDisplayLabel", "testId", "aria-describedby", "calendarLabel", "placeholder", "nextMonthLabel", "previousMonthLabel"],
42
42
  _excluded2 = ["MenuPortal"],
@@ -47,13 +47,11 @@ 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.1.0";
50
+ var packageVersion = "19.2.0";
51
51
  var styles = {
52
52
  pickerContainerStyle: "_kqswh2mm",
53
53
  dropdownIndicatorStyles: "_1ul91k8s _1tke1k8s _1e0c1txw _4cvr1h6o _1bah1h6o",
54
- iconContainerStyles: "_v564vrg3 _1e0c1txw _4t3i1osq _kqswstnw _4cvr1h6o _i0dl1kw7 _syaz1rpy _152tze3t _rjxpze3t _30l3azsu",
55
- iconSpacingWithClearButtonStyles: "_12l2xy5q",
56
- iconSpacingWithoutClearButtonStyles: "_12l21b66"
54
+ iconContainerStyles: "_v564vrg3 _i0dl1kw7 _syaz1rpy _30l3azsu"
57
55
  };
58
56
  var analyticsAttributes = {
59
57
  componentName: 'datePicker',
@@ -676,8 +674,9 @@ var DatePicker = /*#__PURE__*/(0, _react.forwardRef)(function (props, _forwarded
676
674
  previousMonthLabel: previousMonthLabel,
677
675
  shouldSetFocusOnCurrentDay: calendarProps.shouldSetFocusOnCurrentDay,
678
676
  menuInnerWrapper: calendarProps.menuInnerWrapper
679
- })), shouldShowCalendarButton && !isDisabled ? /*#__PURE__*/React.createElement(_compiled.Box, {
680
- xcss: (0, _css.cx)(styles.iconContainerStyles, getterValue && !hideIcon ? styles.iconSpacingWithClearButtonStyles : styles.iconSpacingWithoutClearButtonStyles)
677
+ })), shouldShowCalendarButton && !isDisabled ? /*#__PURE__*/React.createElement(_pickerButtonContainer.PickerButtonContainer, {
678
+ hasClearIndicator: Boolean(getterValue && !hideIcon),
679
+ xcss: styles.iconContainerStyles
681
680
  }, /*#__PURE__*/React.createElement(_button.default, {
682
681
  appearance: "subtle",
683
682
  label: !inputLabelId ? fullopenCalendarLabel : openCalendarLabel,
@@ -34,7 +34,7 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
34
34
  // for typing `process`
35
35
  // oxlint-disable-next-line @atlassian/no-restricted-imports
36
36
  var packageName = "@atlaskit/datetime-picker";
37
- var packageVersion = "19.1.0";
37
+ var packageVersion = "19.2.0";
38
38
  var analyticsAttributes = {
39
39
  componentName: 'dateTimePicker',
40
40
  packageName: packageName,
@@ -509,12 +509,14 @@ var DateTimePicker = /*#__PURE__*/(0, _react.forwardRef)(function (_ref2, ref) {
509
509
  label: timePickerLabel,
510
510
  locale: timePickerProps.locale || locale,
511
511
  name: timePickerProps.name,
512
+ openTimeLabel: timePickerProps.openTimeLabel,
512
513
  onBlur: onTimeBlur,
513
514
  onChange: onTimeChange,
514
515
  onFocus: onTimeFocus,
515
516
  parseInputValue: timePickerProps.parseInputValue,
516
517
  placeholder: timePickerProps.placeholder,
517
518
  selectProps: mergedTimePickerSelectProps,
519
+ shouldShowTimeButton: timePickerProps.shouldShowTimeButton,
518
520
  spacing: timePickerProps.spacing || spacing,
519
521
  testId: timePickerProps.testId || testId && "".concat(testId, "--timepicker"),
520
522
  timeFormat: timePickerProps.timeFormat,
@@ -0,0 +1 @@
1
+ ._kqswh2mm{position:relative}
@@ -1,3 +1,4 @@
1
+ /* time-picker.tsx generated by @compiled/babel-plugin v3.0.2 */
1
2
  "use strict";
2
3
 
3
4
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
@@ -6,6 +7,8 @@ Object.defineProperty(exports, "__esModule", {
6
7
  value: true
7
8
  });
8
9
  exports.default = void 0;
10
+ require("./time-picker.compiled.css");
11
+ var _runtime = require("@compiled/react/runtime");
9
12
  var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
10
13
  var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties"));
11
14
  var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
@@ -13,7 +16,9 @@ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/sli
13
16
  var _react = _interopRequireWildcard(require("react"));
14
17
  var _dateFns = require("date-fns");
15
18
  var _usePlatformLeafEventHandler = require("@atlaskit/analytics-next/usePlatformLeafEventHandler");
19
+ var _button = _interopRequireDefault(require("@atlaskit/button/icon/button"));
16
20
  var _noop = _interopRequireDefault(require("@atlaskit/ds-lib/noop"));
21
+ var _clock = _interopRequireDefault(require("@atlaskit/icon/core/clock"));
17
22
  var _localizationProvider = require("@atlaskit/locale/localization-provider");
18
23
  var _fg = require("@atlaskit/platform-feature-flags/fg");
19
24
  var _styles = require("@atlaskit/react-select/styles");
@@ -25,6 +30,7 @@ var _fixedLayerMenu = require("../internal/fixed-layer-menu");
25
30
  var _fixedLayerMenuTopLayer = require("../internal/fixed-layer-menu-top-layer");
26
31
  var _parseTime = _interopRequireDefault(require("../internal/parse-time"));
27
32
  var _parseTokens = require("../internal/parse-tokens");
33
+ var _pickerButtonContainer = require("../internal/picker-button-container");
28
34
  var _placeholderDateTime = require("../internal/placeholder-date-time");
29
35
  var _singleValue = require("../internal/single-value");
30
36
  var _excluded = ["styles"];
@@ -32,7 +38,7 @@ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r
32
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; }
33
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
34
40
  var packageName = "@atlaskit/datetime-picker";
35
- var packageVersion = "19.1.0";
41
+ var packageVersion = "19.2.0";
36
42
  var defaultTimeFormat = 'h:mma';
37
43
  var menuStyles = {
38
44
  /* Need to remove default absolute positioning as that causes issues with position fixed */
@@ -42,6 +48,9 @@ var menuStyles = {
42
48
  /* React-Popper has already offset the menu so we need to reset the margin, otherwise the offset value is doubled */
43
49
  margin: 0
44
50
  };
51
+ var styles = {
52
+ pickerContainer: "_kqswh2mm"
53
+ };
45
54
  var analyticsAttributes = {
46
55
  componentName: 'timePicker',
47
56
  packageName: packageName,
@@ -89,6 +98,8 @@ var TimePicker = /*#__PURE__*/(0, _react.forwardRef)(function (_ref2, _ref) {
89
98
  locale = _ref2$locale === void 0 ? 'en-US' : _ref2$locale,
90
99
  _ref2$name = _ref2.name,
91
100
  name = _ref2$name === void 0 ? '' : _ref2$name,
101
+ _ref2$openTimeLabel = _ref2.openTimeLabel,
102
+ openTimeLabel = _ref2$openTimeLabel === void 0 ? 'Open time picker' : _ref2$openTimeLabel,
92
103
  _ref2$onBlur = _ref2.onBlur,
93
104
  providedOnBlur = _ref2$onBlur === void 0 ? _noop.default : _ref2$onBlur,
94
105
  _ref2$onChange = _ref2.onChange,
@@ -102,6 +113,8 @@ var TimePicker = /*#__PURE__*/(0, _react.forwardRef)(function (_ref2, _ref) {
102
113
  placeholder = _ref2.placeholder,
103
114
  _ref2$selectProps = _ref2.selectProps,
104
115
  selectProps = _ref2$selectProps === void 0 ? {} : _ref2$selectProps,
116
+ _ref2$shouldShowTimeB = _ref2.shouldShowTimeButton,
117
+ shouldShowTimeButton = _ref2$shouldShowTimeB === void 0 ? false : _ref2$shouldShowTimeB,
105
118
  _ref2$spacing = _ref2.spacing,
106
119
  spacing = _ref2$spacing === void 0 ? 'default' : _ref2$spacing,
107
120
  testId = _ref2.testId,
@@ -133,10 +146,14 @@ var TimePicker = /*#__PURE__*/(0, _react.forwardRef)(function (_ref2, _ref) {
133
146
  _useState8 = (0, _slicedToArray2.default)(_useState7, 2),
134
147
  isOpen = _useState8[0],
135
148
  setIsOpen = _useState8[1];
136
- var _useState9 = (0, _react.useState)(defaultValue),
149
+ var _useState9 = (0, _react.useState)(false),
137
150
  _useState0 = (0, _slicedToArray2.default)(_useState9, 2),
138
- value = _useState0[0],
139
- setValue = _useState0[1];
151
+ shouldFocusTimeInput = _useState0[0],
152
+ setShouldFocusTimeInput = _useState0[1];
153
+ var _useState1 = (0, _react.useState)(defaultValue),
154
+ _useState10 = (0, _slicedToArray2.default)(_useState1, 2),
155
+ value = _useState10[0],
156
+ setValue = _useState10[1];
140
157
 
141
158
  // Hack to force update: https://legacy.reactjs.org/docs/hooks-faq.html#is-there-something-like-forceupdate
142
159
  var _useReducer = (0, _react.useReducer)(function (x) {
@@ -158,6 +175,14 @@ var TimePicker = /*#__PURE__*/(0, _react.forwardRef)(function (_ref2, _ref) {
158
175
  setIsOpen(providedIsOpen);
159
176
  }
160
177
  }, [providedIsOpen]);
178
+ (0, _react.useEffect)(function () {
179
+ if (!isOpen || !shouldFocusTimeInput) {
180
+ return;
181
+ }
182
+ var innerCombobox = containerRef === null || containerRef === void 0 ? void 0 : containerRef.querySelector('[role="combobox"]');
183
+ innerCombobox === null || innerCombobox === void 0 || innerCombobox.focus();
184
+ setShouldFocusTimeInput(false);
185
+ }, [containerRef, isOpen, shouldFocusTimeInput]);
161
186
  var onChange = (0, _react.useCallback)(function (newValue, action) {
162
187
  var rawValue = newValue ? newValue.value || newValue : '';
163
188
  var finalValue = rawValue.toString();
@@ -229,6 +254,23 @@ var TimePicker = /*#__PURE__*/(0, _react.forwardRef)(function (_ref2, _ref) {
229
254
  setClearingFromIcon(false);
230
255
  }
231
256
  };
257
+ var onTimeButtonClick = function onTimeButtonClick(event) {
258
+ var nextIsOpen = !isOpen;
259
+ setIsOpen(nextIsOpen);
260
+ if (nextIsOpen) {
261
+ var _otherSelectProps$onM;
262
+ (_otherSelectProps$onM = otherSelectProps.onMenuOpen) === null || _otherSelectProps$onM === void 0 || _otherSelectProps$onM.call(otherSelectProps);
263
+ } else {
264
+ var _otherSelectProps$onM2;
265
+ (_otherSelectProps$onM2 = otherSelectProps.onMenuClose) === null || _otherSelectProps$onM2 === void 0 || _otherSelectProps$onM2.call(otherSelectProps);
266
+ }
267
+ event.stopPropagation();
268
+ };
269
+ var onTimeButtonKeyDown = function onTimeButtonKeyDown(event) {
270
+ if (!isOpen && (event.key === ' ' || event.key === 'Enter')) {
271
+ setShouldFocusTimeInput(true);
272
+ }
273
+ };
232
274
  var ICON_PADDING = 2;
233
275
  var GRID_SIZE = 8;
234
276
  var l10n = (0, _localizationProvider.createLocalizationProvider)(locale);
@@ -236,6 +278,17 @@ var TimePicker = /*#__PURE__*/(0, _react.forwardRef)(function (_ref2, _ref) {
236
278
  selectStyles = _selectProps$styles === void 0 ? {} : _selectProps$styles,
237
279
  otherSelectProps = (0, _objectWithoutProperties2.default)(selectProps, _excluded);
238
280
  var SelectComponent = timeIsEditable ? _creatableSelect.default : _default2.default;
281
+ var onInputChange = function onInputChange(inputValue, actionMeta) {
282
+ var _otherSelectProps$onI;
283
+ (_otherSelectProps$onI = otherSelectProps.onInputChange) === null || _otherSelectProps$onI === void 0 || _otherSelectProps$onI.call(otherSelectProps, inputValue, actionMeta);
284
+
285
+ // Keep the menu-opening behavior aligned with DatePicker: entering text
286
+ // opens the available options, even when the optional time button disables
287
+ // opening on focus.
288
+ if (actionMeta.action === 'input-change') {
289
+ setIsOpen(true);
290
+ }
291
+ };
239
292
 
240
293
  /**
241
294
  * There are multiple props that can change how the time is formatted.
@@ -280,7 +333,9 @@ var TimePicker = /*#__PURE__*/(0, _react.forwardRef)(function (_ref2, _ref) {
280
333
  } else {
281
334
  initialValue = null;
282
335
  }
336
+ var valueId = (0, _react.useId)();
283
337
  var SingleValue = (0, _singleValue.makeSingleValue)({
338
+ id: valueId,
284
339
  lang: locale
285
340
  });
286
341
  var selectComponents = _objectSpread({
@@ -291,6 +346,7 @@ var TimePicker = /*#__PURE__*/(0, _react.forwardRef)(function (_ref2, _ref) {
291
346
  ClearIndicator: _emptyComponent.EmptyComponent
292
347
  });
293
348
  var renderIconContainer = Boolean(!hideIcon && value);
349
+ var fullOpenTimeLabel = label ? "".concat(label, ", ").concat(openTimeLabel) : openTimeLabel;
294
350
  var isInputMotionEnabled = (0, _fg.fg)('platform-dst-motion-uplift-input');
295
351
  var mergedStyles = (0, _styles.mergeStyles)(selectStyles, {
296
352
  control: function control(base) {
@@ -315,7 +371,8 @@ var TimePicker = /*#__PURE__*/(0, _react.forwardRef)(function (_ref2, _ref) {
315
371
  });
316
372
  return /*#__PURE__*/_react.default.createElement("div", (0, _extends2.default)({}, innerProps, {
317
373
  ref: setInternalContainerRef,
318
- "data-testid": testId && "".concat(testId, "--container")
374
+ "data-testid": testId && "".concat(testId, "--container"),
375
+ className: (0, _runtime.ax)([styles.pickerContainer])
319
376
  }), /*#__PURE__*/_react.default.createElement("input", {
320
377
  name: name,
321
378
  type: "hidden",
@@ -323,7 +380,7 @@ var TimePicker = /*#__PURE__*/(0, _react.forwardRef)(function (_ref2, _ref) {
323
380
  "data-testid": testId && "".concat(testId, "--input"),
324
381
  onKeyDown: onSelectKeyDown
325
382
  }), /*#__PURE__*/_react.default.createElement(SelectComponent, (0, _extends2.default)({
326
- "aria-describedby": ariaDescribedBy,
383
+ "aria-describedby": ariaDescribedBy ? "".concat(ariaDescribedBy, " ").concat(valueId) : valueId,
327
384
  "aria-label": label || undefined,
328
385
  appearance: appearance,
329
386
  autoFocus: autoFocus,
@@ -335,7 +392,7 @@ var TimePicker = /*#__PURE__*/(0, _react.forwardRef)(function (_ref2, _ref) {
335
392
  isRequired: isRequired,
336
393
  menuIsOpen: isOpen && !isDisabled,
337
394
  menuPlacement: "auto",
338
- openMenuOnFocus: true,
395
+ openMenuOnFocus: !shouldShowTimeButton,
339
396
  onBlur: onBlur,
340
397
  onCreateOption: onCreateOption,
341
398
  onChange: onChange,
@@ -352,6 +409,21 @@ var TimePicker = /*#__PURE__*/(0, _react.forwardRef)(function (_ref2, _ref) {
352
409
  fixedLayerRef: containerRef,
353
410
  isInvalid: isInvalid,
354
411
  testId: testId
355
- }, otherSelectProps)));
412
+ }, otherSelectProps, {
413
+ onInputChange: onInputChange
414
+ })), shouldShowTimeButton && !isDisabled ? /*#__PURE__*/_react.default.createElement(_pickerButtonContainer.PickerButtonContainer, {
415
+ hasClearIndicator: renderIconContainer
416
+ }, /*#__PURE__*/_react.default.createElement(_button.default, {
417
+ appearance: "subtle",
418
+ label: fullOpenTimeLabel,
419
+ icon: function icon(iconProps) {
420
+ return /*#__PURE__*/_react.default.createElement(_clock.default, (0, _extends2.default)({}, iconProps, {
421
+ color: "var(--ds-icon, #292A2E)"
422
+ }));
423
+ },
424
+ onClick: onTimeButtonClick,
425
+ onKeyDown: onTimeButtonKeyDown,
426
+ testId: testId && "".concat(testId, "--open-time-button")
427
+ })) : null);
356
428
  });
357
429
  var _default = exports.default = TimePicker;
@@ -0,0 +1,8 @@
1
+ ._12l21b66{margin-inline-end:var(--ds-space-050,4px)}
2
+ ._12l2xy5q{margin-inline-end:var(--ds-space-400,2pc)}
3
+ ._152tze3t{inset-block-start:var(--ds-space-0,0)}
4
+ ._1e0c1txw{display:flex}
5
+ ._4cvr1h6o{align-items:center}
6
+ ._4t3i1osq{height:100%}
7
+ ._kqswstnw{position:absolute}
8
+ ._rjxpze3t{inset-inline-end:var(--ds-space-0,0)}
@@ -0,0 +1,24 @@
1
+ /* picker-button-container.tsx generated by @compiled/babel-plugin v3.0.2 */
2
+ "use strict";
3
+
4
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
5
+ Object.defineProperty(exports, "__esModule", {
6
+ value: true
7
+ });
8
+ exports.PickerButtonContainer = void 0;
9
+ require("./picker-button-container.compiled.css");
10
+ var _runtime = require("@compiled/react/runtime");
11
+ var _react = _interopRequireDefault(require("react"));
12
+ var styles = {
13
+ container: "_1e0c1txw _4t3i1osq _kqswstnw _4cvr1h6o _152tze3t _rjxpze3t",
14
+ withClearIndicator: "_12l2xy5q",
15
+ withoutClearIndicator: "_12l21b66"
16
+ };
17
+ var PickerButtonContainer = exports.PickerButtonContainer = function PickerButtonContainer(_ref) {
18
+ var children = _ref.children,
19
+ hasClearIndicator = _ref.hasClearIndicator,
20
+ xcss = _ref.xcss;
21
+ return /*#__PURE__*/_react.default.createElement("div", {
22
+ className: (0, _runtime.ax)([styles.container, hasClearIndicator ? styles.withClearIndicator : styles.withoutClearIndicator, xcss])
23
+ }, children);
24
+ };
@@ -1,15 +1,9 @@
1
- ._v564vrg3{transition:color .15s}._12l21b66{margin-inline-end:var(--ds-space-050,4px)}
2
- ._12l2xy5q{margin-inline-end:var(--ds-space-400,2pc)}
3
- ._152tze3t{inset-block-start:var(--ds-space-0,0)}
4
- ._1bah1h6o{justify-content:center}
1
+ ._v564vrg3{transition:color .15s}._1bah1h6o{justify-content:center}
5
2
  ._1e0c1txw{display:flex}
6
3
  ._1tke1k8s{min-height:1.5rem}
7
4
  ._1ul91k8s{min-width:1.5rem}
8
5
  ._4cvr1h6o{align-items:center}
9
- ._4t3i1osq{height:100%}
10
6
  ._i0dl1kw7{flex-basis:inherit}
11
7
  ._kqswh2mm{position:relative}
12
- ._kqswstnw{position:absolute}
13
- ._rjxpze3t{inset-inline-end:var(--ds-space-0,0)}
14
8
  ._syaz1rpy{color:var(--ds-text-subtlest,#6b6e76)}
15
9
  ._30l3azsu:hover{color:var(--ds-text-subtle,#505258)}
@@ -11,7 +11,6 @@ import { forwardRef, useCallback, useEffect, useMemo, useReducer, useRef, useSta
11
11
  import { isValid, parseISO } from 'date-fns';
12
12
  import { usePlatformLeafEventHandler } from '@atlaskit/analytics-next/usePlatformLeafEventHandler';
13
13
  import IconButton from '@atlaskit/button/icon/button';
14
- import { cx } from '@atlaskit/css';
15
14
  import { useId } from '@atlaskit/ds-lib/use-id';
16
15
  import CalendarIcon from '@atlaskit/icon/core/calendar';
17
16
  import { createLocalizationProvider } from '@atlaskit/locale/localization-provider';
@@ -30,15 +29,14 @@ import { isDateDisabled } from '../internal/is-date-disabled';
30
29
  import { Menu } from '../internal/menu';
31
30
  import { MenuTopLayer } from '../internal/menu-top-layer';
32
31
  import { parseDate } from '../internal/parse-date';
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.1.0";
35
+ const packageVersion = "19.2.0";
36
36
  const styles = {
37
37
  pickerContainerStyle: "_kqswh2mm",
38
38
  dropdownIndicatorStyles: "_1ul91k8s _1tke1k8s _1e0c1txw _4cvr1h6o _1bah1h6o",
39
- iconContainerStyles: "_v564vrg3 _1e0c1txw _4t3i1osq _kqswstnw _4cvr1h6o _i0dl1kw7 _syaz1rpy _152tze3t _rjxpze3t _30l3azsu",
40
- iconSpacingWithClearButtonStyles: "_12l2xy5q",
41
- iconSpacingWithoutClearButtonStyles: "_12l21b66"
39
+ iconContainerStyles: "_v564vrg3 _i0dl1kw7 _syaz1rpy _30l3azsu"
42
40
  };
43
41
  const analyticsAttributes = {
44
42
  componentName: 'datePicker',
@@ -606,8 +604,9 @@ const DatePicker = /*#__PURE__*/forwardRef((props, _forwardedRef) => {
606
604
  previousMonthLabel: previousMonthLabel,
607
605
  shouldSetFocusOnCurrentDay: calendarProps.shouldSetFocusOnCurrentDay,
608
606
  menuInnerWrapper: calendarProps.menuInnerWrapper
609
- })), shouldShowCalendarButton && !isDisabled ? /*#__PURE__*/React.createElement(Box, {
610
- xcss: cx(styles.iconContainerStyles, getterValue && !hideIcon ? styles.iconSpacingWithClearButtonStyles : styles.iconSpacingWithoutClearButtonStyles)
607
+ })), shouldShowCalendarButton && !isDisabled ? /*#__PURE__*/React.createElement(PickerButtonContainer, {
608
+ hasClearIndicator: Boolean(getterValue && !hideIcon),
609
+ xcss: styles.iconContainerStyles
611
610
  }, /*#__PURE__*/React.createElement(IconButton, {
612
611
  appearance: "subtle",
613
612
  label: !inputLabelId ? fullopenCalendarLabel : openCalendarLabel,
@@ -21,7 +21,7 @@ import { convertTokens } from '../internal/parse-tokens';
21
21
  import DatePicker from './date-picker';
22
22
  import TimePicker from './time-picker';
23
23
  const packageName = "@atlaskit/datetime-picker";
24
- const packageVersion = "19.1.0";
24
+ const packageVersion = "19.2.0";
25
25
  const analyticsAttributes = {
26
26
  componentName: 'dateTimePicker',
27
27
  packageName,
@@ -485,12 +485,14 @@ const DateTimePicker = /*#__PURE__*/forwardRef(({
485
485
  label: timePickerLabel,
486
486
  locale: timePickerProps.locale || locale,
487
487
  name: timePickerProps.name,
488
+ openTimeLabel: timePickerProps.openTimeLabel,
488
489
  onBlur: onTimeBlur,
489
490
  onChange: onTimeChange,
490
491
  onFocus: onTimeFocus,
491
492
  parseInputValue: timePickerProps.parseInputValue,
492
493
  placeholder: timePickerProps.placeholder,
493
494
  selectProps: mergedTimePickerSelectProps,
495
+ shouldShowTimeButton: timePickerProps.shouldShowTimeButton,
494
496
  spacing: timePickerProps.spacing || spacing,
495
497
  testId: timePickerProps.testId || testId && `${testId}--timepicker`,
496
498
  timeFormat: timePickerProps.timeFormat,
@@ -0,0 +1 @@
1
+ ._kqswh2mm{position:relative}
@@ -1,10 +1,15 @@
1
+ /* time-picker.tsx generated by @compiled/babel-plugin v3.0.2 */
1
2
  import _extends from "@babel/runtime/helpers/extends";
2
- import React, { forwardRef, useCallback, useEffect, useReducer, useState } from 'react';
3
+ import "./time-picker.compiled.css";
4
+ import { ax, ix } from "@compiled/react/runtime";
5
+ import React, { forwardRef, useCallback, useEffect, useId, useReducer, useState } from 'react';
3
6
 
4
7
  // oxlint-disable-next-line @atlassian/no-restricted-imports
5
8
  import { format, isValid } from 'date-fns';
6
9
  import { usePlatformLeafEventHandler } from '@atlaskit/analytics-next/usePlatformLeafEventHandler';
10
+ import IconButton from '@atlaskit/button/icon/button';
7
11
  import __noop from '@atlaskit/ds-lib/noop';
12
+ import ClockIcon from '@atlaskit/icon/core/clock';
8
13
  import { createLocalizationProvider } from '@atlaskit/locale/localization-provider';
9
14
  import { fg } from '@atlaskit/platform-feature-flags/fg';
10
15
  import { mergeStyles } from '@atlaskit/react-select/styles';
@@ -16,10 +21,11 @@ import { FixedLayerMenu } from '../internal/fixed-layer-menu';
16
21
  import { FixedLayerMenuTopLayer } from '../internal/fixed-layer-menu-top-layer';
17
22
  import parseTime from '../internal/parse-time';
18
23
  import { convertTokens } from '../internal/parse-tokens';
24
+ import { PickerButtonContainer } from '../internal/picker-button-container';
19
25
  import { placeholderDatetime } from '../internal/placeholder-date-time';
20
26
  import { makeSingleValue } from '../internal/single-value';
21
27
  const packageName = "@atlaskit/datetime-picker";
22
- const packageVersion = "19.1.0";
28
+ const packageVersion = "19.2.0";
23
29
  const defaultTimeFormat = 'h:mma';
24
30
  const menuStyles = {
25
31
  /* Need to remove default absolute positioning as that causes issues with position fixed */
@@ -29,6 +35,9 @@ const menuStyles = {
29
35
  /* React-Popper has already offset the menu so we need to reset the margin, otherwise the offset value is doubled */
30
36
  margin: 0
31
37
  };
38
+ const styles = {
39
+ pickerContainer: "_kqswh2mm"
40
+ };
32
41
  const analyticsAttributes = {
33
42
  componentName: 'timePicker',
34
43
  packageName,
@@ -62,12 +71,14 @@ const TimePicker = /*#__PURE__*/forwardRef(({
62
71
  label = '',
63
72
  locale = 'en-US',
64
73
  name = '',
74
+ openTimeLabel = 'Open time picker',
65
75
  onBlur: providedOnBlur = __noop,
66
76
  onChange: providedOnChange = __noop,
67
77
  onFocus: providedOnFocus = __noop,
68
78
  parseInputValue = (time, _timeFormat) => parseTime(time),
69
79
  placeholder,
70
80
  selectProps = {},
81
+ shouldShowTimeButton = false,
71
82
  spacing = 'default',
72
83
  testId,
73
84
  timeFormat,
@@ -85,6 +96,7 @@ const TimePicker = /*#__PURE__*/forwardRef(({
85
96
  // TODO: Remove isFocused? Does it do anything?
86
97
  const [_, setIsFocused] = useState(false);
87
98
  const [isOpen, setIsOpen] = useState(defaultIsOpen);
99
+ const [shouldFocusTimeInput, setShouldFocusTimeInput] = useState(false);
88
100
  const [value, setValue] = useState(defaultValue);
89
101
 
90
102
  // Hack to force update: https://legacy.reactjs.org/docs/hooks-faq.html#is-there-something-like-forceupdate
@@ -104,6 +116,14 @@ const TimePicker = /*#__PURE__*/forwardRef(({
104
116
  setIsOpen(providedIsOpen);
105
117
  }
106
118
  }, [providedIsOpen]);
119
+ useEffect(() => {
120
+ if (!isOpen || !shouldFocusTimeInput) {
121
+ return;
122
+ }
123
+ const innerCombobox = containerRef === null || containerRef === void 0 ? void 0 : containerRef.querySelector('[role="combobox"]');
124
+ innerCombobox === null || innerCombobox === void 0 ? void 0 : innerCombobox.focus();
125
+ setShouldFocusTimeInput(false);
126
+ }, [containerRef, isOpen, shouldFocusTimeInput]);
107
127
  const onChange = useCallback((newValue, action) => {
108
128
  const rawValue = newValue ? newValue.value || newValue : '';
109
129
  const finalValue = rawValue.toString();
@@ -177,6 +197,23 @@ const TimePicker = /*#__PURE__*/forwardRef(({
177
197
  setClearingFromIcon(false);
178
198
  }
179
199
  };
200
+ const onTimeButtonClick = event => {
201
+ const nextIsOpen = !isOpen;
202
+ setIsOpen(nextIsOpen);
203
+ if (nextIsOpen) {
204
+ var _otherSelectProps$onM;
205
+ (_otherSelectProps$onM = otherSelectProps.onMenuOpen) === null || _otherSelectProps$onM === void 0 ? void 0 : _otherSelectProps$onM.call(otherSelectProps);
206
+ } else {
207
+ var _otherSelectProps$onM2;
208
+ (_otherSelectProps$onM2 = otherSelectProps.onMenuClose) === null || _otherSelectProps$onM2 === void 0 ? void 0 : _otherSelectProps$onM2.call(otherSelectProps);
209
+ }
210
+ event.stopPropagation();
211
+ };
212
+ const onTimeButtonKeyDown = event => {
213
+ if (!isOpen && (event.key === ' ' || event.key === 'Enter')) {
214
+ setShouldFocusTimeInput(true);
215
+ }
216
+ };
180
217
  const ICON_PADDING = 2;
181
218
  const GRID_SIZE = 8;
182
219
  const l10n = createLocalizationProvider(locale);
@@ -185,6 +222,17 @@ const TimePicker = /*#__PURE__*/forwardRef(({
185
222
  ...otherSelectProps
186
223
  } = selectProps;
187
224
  const SelectComponent = timeIsEditable ? CreatableSelect : Select;
225
+ const onInputChange = (inputValue, actionMeta) => {
226
+ var _otherSelectProps$onI;
227
+ (_otherSelectProps$onI = otherSelectProps.onInputChange) === null || _otherSelectProps$onI === void 0 ? void 0 : _otherSelectProps$onI.call(otherSelectProps, inputValue, actionMeta);
228
+
229
+ // Keep the menu-opening behavior aligned with DatePicker: entering text
230
+ // opens the available options, even when the optional time button disables
231
+ // opening on focus.
232
+ if (actionMeta.action === 'input-change') {
233
+ setIsOpen(true);
234
+ }
235
+ };
188
236
 
189
237
  /**
190
238
  * There are multiple props that can change how the time is formatted.
@@ -229,7 +277,9 @@ const TimePicker = /*#__PURE__*/forwardRef(({
229
277
  } else {
230
278
  initialValue = null;
231
279
  }
280
+ const valueId = useId();
232
281
  const SingleValue = makeSingleValue({
282
+ id: valueId,
233
283
  lang: locale
234
284
  });
235
285
  const selectComponents = {
@@ -241,6 +291,7 @@ const TimePicker = /*#__PURE__*/forwardRef(({
241
291
  })
242
292
  };
243
293
  const renderIconContainer = Boolean(!hideIcon && value);
294
+ const fullOpenTimeLabel = label ? `${label}, ${openTimeLabel}` : openTimeLabel;
244
295
  const isInputMotionEnabled = fg('platform-dst-motion-uplift-input');
245
296
  const mergedStyles = mergeStyles(selectStyles, {
246
297
  control: base => {
@@ -267,7 +318,8 @@ const TimePicker = /*#__PURE__*/forwardRef(({
267
318
  });
268
319
  return /*#__PURE__*/React.createElement("div", _extends({}, innerProps, {
269
320
  ref: setInternalContainerRef,
270
- "data-testid": testId && `${testId}--container`
321
+ "data-testid": testId && `${testId}--container`,
322
+ className: ax([styles.pickerContainer])
271
323
  }), /*#__PURE__*/React.createElement("input", {
272
324
  name: name,
273
325
  type: "hidden",
@@ -275,7 +327,7 @@ const TimePicker = /*#__PURE__*/forwardRef(({
275
327
  "data-testid": testId && `${testId}--input`,
276
328
  onKeyDown: onSelectKeyDown
277
329
  }), /*#__PURE__*/React.createElement(SelectComponent, _extends({
278
- "aria-describedby": ariaDescribedBy,
330
+ "aria-describedby": ariaDescribedBy ? `${ariaDescribedBy} ${valueId}` : valueId,
279
331
  "aria-label": label || undefined,
280
332
  appearance: appearance,
281
333
  autoFocus: autoFocus,
@@ -287,7 +339,7 @@ const TimePicker = /*#__PURE__*/forwardRef(({
287
339
  isRequired: isRequired,
288
340
  menuIsOpen: isOpen && !isDisabled,
289
341
  menuPlacement: "auto",
290
- openMenuOnFocus: true,
342
+ openMenuOnFocus: !shouldShowTimeButton,
291
343
  onBlur: onBlur,
292
344
  onCreateOption: onCreateOption,
293
345
  onChange: onChange,
@@ -304,6 +356,19 @@ const TimePicker = /*#__PURE__*/forwardRef(({
304
356
  fixedLayerRef: containerRef,
305
357
  isInvalid: isInvalid,
306
358
  testId: testId
307
- }, otherSelectProps)));
359
+ }, otherSelectProps, {
360
+ onInputChange: onInputChange
361
+ })), shouldShowTimeButton && !isDisabled ? /*#__PURE__*/React.createElement(PickerButtonContainer, {
362
+ hasClearIndicator: renderIconContainer
363
+ }, /*#__PURE__*/React.createElement(IconButton, {
364
+ appearance: "subtle",
365
+ label: fullOpenTimeLabel,
366
+ icon: iconProps => /*#__PURE__*/React.createElement(ClockIcon, _extends({}, iconProps, {
367
+ color: "var(--ds-icon, #292A2E)"
368
+ })),
369
+ onClick: onTimeButtonClick,
370
+ onKeyDown: onTimeButtonKeyDown,
371
+ testId: testId && `${testId}--open-time-button`
372
+ })) : null);
308
373
  });
309
374
  export default TimePicker;
@@ -0,0 +1,8 @@
1
+ ._12l21b66{margin-inline-end:var(--ds-space-050,4px)}
2
+ ._12l2xy5q{margin-inline-end:var(--ds-space-400,2pc)}
3
+ ._152tze3t{inset-block-start:var(--ds-space-0,0)}
4
+ ._1e0c1txw{display:flex}
5
+ ._4cvr1h6o{align-items:center}
6
+ ._4t3i1osq{height:100%}
7
+ ._kqswstnw{position:absolute}
8
+ ._rjxpze3t{inset-inline-end:var(--ds-space-0,0)}
@@ -0,0 +1,16 @@
1
+ /* picker-button-container.tsx generated by @compiled/babel-plugin v3.0.2 */
2
+ import "./picker-button-container.compiled.css";
3
+ import { ax, ix } from "@compiled/react/runtime";
4
+ import React from 'react';
5
+ const styles = {
6
+ container: "_1e0c1txw _4t3i1osq _kqswstnw _4cvr1h6o _152tze3t _rjxpze3t",
7
+ withClearIndicator: "_12l2xy5q",
8
+ withoutClearIndicator: "_12l21b66"
9
+ };
10
+ export const PickerButtonContainer = ({
11
+ children,
12
+ hasClearIndicator,
13
+ xcss
14
+ }) => /*#__PURE__*/React.createElement("div", {
15
+ className: ax([styles.container, hasClearIndicator ? styles.withClearIndicator : styles.withoutClearIndicator, xcss])
16
+ }, children);
@@ -1,15 +1,9 @@
1
- ._v564vrg3{transition:color .15s}._12l21b66{margin-inline-end:var(--ds-space-050,4px)}
2
- ._12l2xy5q{margin-inline-end:var(--ds-space-400,2pc)}
3
- ._152tze3t{inset-block-start:var(--ds-space-0,0)}
4
- ._1bah1h6o{justify-content:center}
1
+ ._v564vrg3{transition:color .15s}._1bah1h6o{justify-content:center}
5
2
  ._1e0c1txw{display:flex}
6
3
  ._1tke1k8s{min-height:1.5rem}
7
4
  ._1ul91k8s{min-width:1.5rem}
8
5
  ._4cvr1h6o{align-items:center}
9
- ._4t3i1osq{height:100%}
10
6
  ._i0dl1kw7{flex-basis:inherit}
11
7
  ._kqswh2mm{position:relative}
12
- ._kqswstnw{position:absolute}
13
- ._rjxpze3t{inset-inline-end:var(--ds-space-0,0)}
14
8
  ._syaz1rpy{color:var(--ds-text-subtlest,#6b6e76)}
15
9
  ._30l3azsu:hover{color:var(--ds-text-subtle,#505258)}
@@ -19,7 +19,6 @@ import { forwardRef, useCallback, useEffect, useMemo, useReducer, useRef, useSta
19
19
  import { isValid, parseISO } from 'date-fns';
20
20
  import { usePlatformLeafEventHandler } from '@atlaskit/analytics-next/usePlatformLeafEventHandler';
21
21
  import IconButton from '@atlaskit/button/icon/button';
22
- import { cx } from '@atlaskit/css';
23
22
  import { useId } from '@atlaskit/ds-lib/use-id';
24
23
  import CalendarIcon from '@atlaskit/icon/core/calendar';
25
24
  import { createLocalizationProvider } from '@atlaskit/locale/localization-provider';
@@ -38,15 +37,14 @@ import { isDateDisabled } from '../internal/is-date-disabled';
38
37
  import { Menu } from '../internal/menu';
39
38
  import { MenuTopLayer } from '../internal/menu-top-layer';
40
39
  import { parseDate } from '../internal/parse-date';
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.1.0";
43
+ var packageVersion = "19.2.0";
44
44
  var styles = {
45
45
  pickerContainerStyle: "_kqswh2mm",
46
46
  dropdownIndicatorStyles: "_1ul91k8s _1tke1k8s _1e0c1txw _4cvr1h6o _1bah1h6o",
47
- iconContainerStyles: "_v564vrg3 _1e0c1txw _4t3i1osq _kqswstnw _4cvr1h6o _i0dl1kw7 _syaz1rpy _152tze3t _rjxpze3t _30l3azsu",
48
- iconSpacingWithClearButtonStyles: "_12l2xy5q",
49
- iconSpacingWithoutClearButtonStyles: "_12l21b66"
47
+ iconContainerStyles: "_v564vrg3 _i0dl1kw7 _syaz1rpy _30l3azsu"
50
48
  };
51
49
  var analyticsAttributes = {
52
50
  componentName: 'datePicker',
@@ -669,8 +667,9 @@ var DatePicker = /*#__PURE__*/forwardRef(function (props, _forwardedRef) {
669
667
  previousMonthLabel: previousMonthLabel,
670
668
  shouldSetFocusOnCurrentDay: calendarProps.shouldSetFocusOnCurrentDay,
671
669
  menuInnerWrapper: calendarProps.menuInnerWrapper
672
- })), shouldShowCalendarButton && !isDisabled ? /*#__PURE__*/React.createElement(Box, {
673
- xcss: cx(styles.iconContainerStyles, getterValue && !hideIcon ? styles.iconSpacingWithClearButtonStyles : styles.iconSpacingWithoutClearButtonStyles)
670
+ })), shouldShowCalendarButton && !isDisabled ? /*#__PURE__*/React.createElement(PickerButtonContainer, {
671
+ hasClearIndicator: Boolean(getterValue && !hideIcon),
672
+ xcss: styles.iconContainerStyles
674
673
  }, /*#__PURE__*/React.createElement(IconButton, {
675
674
  appearance: "subtle",
676
675
  label: !inputLabelId ? fullopenCalendarLabel : openCalendarLabel,
@@ -28,7 +28,7 @@ import { convertTokens } from '../internal/parse-tokens';
28
28
  import DatePicker from './date-picker';
29
29
  import TimePicker from './time-picker';
30
30
  var packageName = "@atlaskit/datetime-picker";
31
- var packageVersion = "19.1.0";
31
+ var packageVersion = "19.2.0";
32
32
  var analyticsAttributes = {
33
33
  componentName: 'dateTimePicker',
34
34
  packageName: packageName,
@@ -503,12 +503,14 @@ var DateTimePicker = /*#__PURE__*/forwardRef(function (_ref2, ref) {
503
503
  label: timePickerLabel,
504
504
  locale: timePickerProps.locale || locale,
505
505
  name: timePickerProps.name,
506
+ openTimeLabel: timePickerProps.openTimeLabel,
506
507
  onBlur: onTimeBlur,
507
508
  onChange: onTimeChange,
508
509
  onFocus: onTimeFocus,
509
510
  parseInputValue: timePickerProps.parseInputValue,
510
511
  placeholder: timePickerProps.placeholder,
511
512
  selectProps: mergedTimePickerSelectProps,
513
+ shouldShowTimeButton: timePickerProps.shouldShowTimeButton,
512
514
  spacing: timePickerProps.spacing || spacing,
513
515
  testId: timePickerProps.testId || testId && "".concat(testId, "--timepicker"),
514
516
  timeFormat: timePickerProps.timeFormat,
@@ -0,0 +1 @@
1
+ ._kqswh2mm{position:relative}
@@ -1,16 +1,21 @@
1
+ /* time-picker.tsx generated by @compiled/babel-plugin v3.0.2 */
1
2
  import _extends from "@babel/runtime/helpers/extends";
2
3
  import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
3
4
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
4
5
  import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
5
6
  var _excluded = ["styles"];
7
+ import "./time-picker.compiled.css";
8
+ import { ax, ix } from "@compiled/react/runtime";
6
9
  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; }
7
10
  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) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
8
- import React, { forwardRef, useCallback, useEffect, useReducer, useState } from 'react';
11
+ import React, { forwardRef, useCallback, useEffect, useId, useReducer, useState } from 'react';
9
12
 
10
13
  // oxlint-disable-next-line @atlassian/no-restricted-imports
11
14
  import { format, isValid } from 'date-fns';
12
15
  import { usePlatformLeafEventHandler } from '@atlaskit/analytics-next/usePlatformLeafEventHandler';
16
+ import IconButton from '@atlaskit/button/icon/button';
13
17
  import __noop from '@atlaskit/ds-lib/noop';
18
+ import ClockIcon from '@atlaskit/icon/core/clock';
14
19
  import { createLocalizationProvider } from '@atlaskit/locale/localization-provider';
15
20
  import { fg } from '@atlaskit/platform-feature-flags/fg';
16
21
  import { mergeStyles } from '@atlaskit/react-select/styles';
@@ -22,10 +27,11 @@ import { FixedLayerMenu } from '../internal/fixed-layer-menu';
22
27
  import { FixedLayerMenuTopLayer } from '../internal/fixed-layer-menu-top-layer';
23
28
  import parseTime from '../internal/parse-time';
24
29
  import { convertTokens } from '../internal/parse-tokens';
30
+ import { PickerButtonContainer } from '../internal/picker-button-container';
25
31
  import { placeholderDatetime } from '../internal/placeholder-date-time';
26
32
  import { makeSingleValue } from '../internal/single-value';
27
33
  var packageName = "@atlaskit/datetime-picker";
28
- var packageVersion = "19.1.0";
34
+ var packageVersion = "19.2.0";
29
35
  var defaultTimeFormat = 'h:mma';
30
36
  var menuStyles = {
31
37
  /* Need to remove default absolute positioning as that causes issues with position fixed */
@@ -35,6 +41,9 @@ var menuStyles = {
35
41
  /* React-Popper has already offset the menu so we need to reset the margin, otherwise the offset value is doubled */
36
42
  margin: 0
37
43
  };
44
+ var styles = {
45
+ pickerContainer: "_kqswh2mm"
46
+ };
38
47
  var analyticsAttributes = {
39
48
  componentName: 'timePicker',
40
49
  packageName: packageName,
@@ -82,6 +91,8 @@ var TimePicker = /*#__PURE__*/forwardRef(function (_ref2, _ref) {
82
91
  locale = _ref2$locale === void 0 ? 'en-US' : _ref2$locale,
83
92
  _ref2$name = _ref2.name,
84
93
  name = _ref2$name === void 0 ? '' : _ref2$name,
94
+ _ref2$openTimeLabel = _ref2.openTimeLabel,
95
+ openTimeLabel = _ref2$openTimeLabel === void 0 ? 'Open time picker' : _ref2$openTimeLabel,
85
96
  _ref2$onBlur = _ref2.onBlur,
86
97
  providedOnBlur = _ref2$onBlur === void 0 ? __noop : _ref2$onBlur,
87
98
  _ref2$onChange = _ref2.onChange,
@@ -95,6 +106,8 @@ var TimePicker = /*#__PURE__*/forwardRef(function (_ref2, _ref) {
95
106
  placeholder = _ref2.placeholder,
96
107
  _ref2$selectProps = _ref2.selectProps,
97
108
  selectProps = _ref2$selectProps === void 0 ? {} : _ref2$selectProps,
109
+ _ref2$shouldShowTimeB = _ref2.shouldShowTimeButton,
110
+ shouldShowTimeButton = _ref2$shouldShowTimeB === void 0 ? false : _ref2$shouldShowTimeB,
98
111
  _ref2$spacing = _ref2.spacing,
99
112
  spacing = _ref2$spacing === void 0 ? 'default' : _ref2$spacing,
100
113
  testId = _ref2.testId,
@@ -126,10 +139,14 @@ var TimePicker = /*#__PURE__*/forwardRef(function (_ref2, _ref) {
126
139
  _useState8 = _slicedToArray(_useState7, 2),
127
140
  isOpen = _useState8[0],
128
141
  setIsOpen = _useState8[1];
129
- var _useState9 = useState(defaultValue),
142
+ var _useState9 = useState(false),
130
143
  _useState0 = _slicedToArray(_useState9, 2),
131
- value = _useState0[0],
132
- setValue = _useState0[1];
144
+ shouldFocusTimeInput = _useState0[0],
145
+ setShouldFocusTimeInput = _useState0[1];
146
+ var _useState1 = useState(defaultValue),
147
+ _useState10 = _slicedToArray(_useState1, 2),
148
+ value = _useState10[0],
149
+ setValue = _useState10[1];
133
150
 
134
151
  // Hack to force update: https://legacy.reactjs.org/docs/hooks-faq.html#is-there-something-like-forceupdate
135
152
  var _useReducer = useReducer(function (x) {
@@ -151,6 +168,14 @@ var TimePicker = /*#__PURE__*/forwardRef(function (_ref2, _ref) {
151
168
  setIsOpen(providedIsOpen);
152
169
  }
153
170
  }, [providedIsOpen]);
171
+ useEffect(function () {
172
+ if (!isOpen || !shouldFocusTimeInput) {
173
+ return;
174
+ }
175
+ var innerCombobox = containerRef === null || containerRef === void 0 ? void 0 : containerRef.querySelector('[role="combobox"]');
176
+ innerCombobox === null || innerCombobox === void 0 || innerCombobox.focus();
177
+ setShouldFocusTimeInput(false);
178
+ }, [containerRef, isOpen, shouldFocusTimeInput]);
154
179
  var onChange = useCallback(function (newValue, action) {
155
180
  var rawValue = newValue ? newValue.value || newValue : '';
156
181
  var finalValue = rawValue.toString();
@@ -222,6 +247,23 @@ var TimePicker = /*#__PURE__*/forwardRef(function (_ref2, _ref) {
222
247
  setClearingFromIcon(false);
223
248
  }
224
249
  };
250
+ var onTimeButtonClick = function onTimeButtonClick(event) {
251
+ var nextIsOpen = !isOpen;
252
+ setIsOpen(nextIsOpen);
253
+ if (nextIsOpen) {
254
+ var _otherSelectProps$onM;
255
+ (_otherSelectProps$onM = otherSelectProps.onMenuOpen) === null || _otherSelectProps$onM === void 0 || _otherSelectProps$onM.call(otherSelectProps);
256
+ } else {
257
+ var _otherSelectProps$onM2;
258
+ (_otherSelectProps$onM2 = otherSelectProps.onMenuClose) === null || _otherSelectProps$onM2 === void 0 || _otherSelectProps$onM2.call(otherSelectProps);
259
+ }
260
+ event.stopPropagation();
261
+ };
262
+ var onTimeButtonKeyDown = function onTimeButtonKeyDown(event) {
263
+ if (!isOpen && (event.key === ' ' || event.key === 'Enter')) {
264
+ setShouldFocusTimeInput(true);
265
+ }
266
+ };
225
267
  var ICON_PADDING = 2;
226
268
  var GRID_SIZE = 8;
227
269
  var l10n = createLocalizationProvider(locale);
@@ -229,6 +271,17 @@ var TimePicker = /*#__PURE__*/forwardRef(function (_ref2, _ref) {
229
271
  selectStyles = _selectProps$styles === void 0 ? {} : _selectProps$styles,
230
272
  otherSelectProps = _objectWithoutProperties(selectProps, _excluded);
231
273
  var SelectComponent = timeIsEditable ? CreatableSelect : Select;
274
+ var onInputChange = function onInputChange(inputValue, actionMeta) {
275
+ var _otherSelectProps$onI;
276
+ (_otherSelectProps$onI = otherSelectProps.onInputChange) === null || _otherSelectProps$onI === void 0 || _otherSelectProps$onI.call(otherSelectProps, inputValue, actionMeta);
277
+
278
+ // Keep the menu-opening behavior aligned with DatePicker: entering text
279
+ // opens the available options, even when the optional time button disables
280
+ // opening on focus.
281
+ if (actionMeta.action === 'input-change') {
282
+ setIsOpen(true);
283
+ }
284
+ };
232
285
 
233
286
  /**
234
287
  * There are multiple props that can change how the time is formatted.
@@ -273,7 +326,9 @@ var TimePicker = /*#__PURE__*/forwardRef(function (_ref2, _ref) {
273
326
  } else {
274
327
  initialValue = null;
275
328
  }
329
+ var valueId = useId();
276
330
  var SingleValue = makeSingleValue({
331
+ id: valueId,
277
332
  lang: locale
278
333
  });
279
334
  var selectComponents = _objectSpread({
@@ -284,6 +339,7 @@ var TimePicker = /*#__PURE__*/forwardRef(function (_ref2, _ref) {
284
339
  ClearIndicator: EmptyComponent
285
340
  });
286
341
  var renderIconContainer = Boolean(!hideIcon && value);
342
+ var fullOpenTimeLabel = label ? "".concat(label, ", ").concat(openTimeLabel) : openTimeLabel;
287
343
  var isInputMotionEnabled = fg('platform-dst-motion-uplift-input');
288
344
  var mergedStyles = mergeStyles(selectStyles, {
289
345
  control: function control(base) {
@@ -308,7 +364,8 @@ var TimePicker = /*#__PURE__*/forwardRef(function (_ref2, _ref) {
308
364
  });
309
365
  return /*#__PURE__*/React.createElement("div", _extends({}, innerProps, {
310
366
  ref: setInternalContainerRef,
311
- "data-testid": testId && "".concat(testId, "--container")
367
+ "data-testid": testId && "".concat(testId, "--container"),
368
+ className: ax([styles.pickerContainer])
312
369
  }), /*#__PURE__*/React.createElement("input", {
313
370
  name: name,
314
371
  type: "hidden",
@@ -316,7 +373,7 @@ var TimePicker = /*#__PURE__*/forwardRef(function (_ref2, _ref) {
316
373
  "data-testid": testId && "".concat(testId, "--input"),
317
374
  onKeyDown: onSelectKeyDown
318
375
  }), /*#__PURE__*/React.createElement(SelectComponent, _extends({
319
- "aria-describedby": ariaDescribedBy,
376
+ "aria-describedby": ariaDescribedBy ? "".concat(ariaDescribedBy, " ").concat(valueId) : valueId,
320
377
  "aria-label": label || undefined,
321
378
  appearance: appearance,
322
379
  autoFocus: autoFocus,
@@ -328,7 +385,7 @@ var TimePicker = /*#__PURE__*/forwardRef(function (_ref2, _ref) {
328
385
  isRequired: isRequired,
329
386
  menuIsOpen: isOpen && !isDisabled,
330
387
  menuPlacement: "auto",
331
- openMenuOnFocus: true,
388
+ openMenuOnFocus: !shouldShowTimeButton,
332
389
  onBlur: onBlur,
333
390
  onCreateOption: onCreateOption,
334
391
  onChange: onChange,
@@ -345,6 +402,21 @@ var TimePicker = /*#__PURE__*/forwardRef(function (_ref2, _ref) {
345
402
  fixedLayerRef: containerRef,
346
403
  isInvalid: isInvalid,
347
404
  testId: testId
348
- }, otherSelectProps)));
405
+ }, otherSelectProps, {
406
+ onInputChange: onInputChange
407
+ })), shouldShowTimeButton && !isDisabled ? /*#__PURE__*/React.createElement(PickerButtonContainer, {
408
+ hasClearIndicator: renderIconContainer
409
+ }, /*#__PURE__*/React.createElement(IconButton, {
410
+ appearance: "subtle",
411
+ label: fullOpenTimeLabel,
412
+ icon: function icon(iconProps) {
413
+ return /*#__PURE__*/React.createElement(ClockIcon, _extends({}, iconProps, {
414
+ color: "var(--ds-icon, #292A2E)"
415
+ }));
416
+ },
417
+ onClick: onTimeButtonClick,
418
+ onKeyDown: onTimeButtonKeyDown,
419
+ testId: testId && "".concat(testId, "--open-time-button")
420
+ })) : null);
349
421
  });
350
422
  export default TimePicker;
@@ -0,0 +1,8 @@
1
+ ._12l21b66{margin-inline-end:var(--ds-space-050,4px)}
2
+ ._12l2xy5q{margin-inline-end:var(--ds-space-400,2pc)}
3
+ ._152tze3t{inset-block-start:var(--ds-space-0,0)}
4
+ ._1e0c1txw{display:flex}
5
+ ._4cvr1h6o{align-items:center}
6
+ ._4t3i1osq{height:100%}
7
+ ._kqswstnw{position:absolute}
8
+ ._rjxpze3t{inset-inline-end:var(--ds-space-0,0)}
@@ -0,0 +1,17 @@
1
+ /* picker-button-container.tsx generated by @compiled/babel-plugin v3.0.2 */
2
+ import "./picker-button-container.compiled.css";
3
+ import { ax, ix } from "@compiled/react/runtime";
4
+ import React from 'react';
5
+ var styles = {
6
+ container: "_1e0c1txw _4t3i1osq _kqswstnw _4cvr1h6o _152tze3t _rjxpze3t",
7
+ withClearIndicator: "_12l2xy5q",
8
+ withoutClearIndicator: "_12l21b66"
9
+ };
10
+ export var PickerButtonContainer = function PickerButtonContainer(_ref) {
11
+ var children = _ref.children,
12
+ hasClearIndicator = _ref.hasClearIndicator,
13
+ xcss = _ref.xcss;
14
+ return /*#__PURE__*/React.createElement("div", {
15
+ className: ax([styles.container, hasClearIndicator ? styles.withClearIndicator : styles.withoutClearIndicator, xcss])
16
+ }, children);
17
+ };
@@ -1,3 +1,7 @@
1
+ /**
2
+ * @jsxRuntime classic
3
+ * @jsx jsx
4
+ */
1
5
  import React from 'react';
2
6
  import { type TimePickerBaseProps } from '../types';
3
7
  /**
@@ -0,0 +1,13 @@
1
+ /**
2
+ * @jsxRuntime classic
3
+ * @jsx jsx
4
+ */
5
+ import React from 'react';
6
+ import { type StrictXCSSProp } from '@atlaskit/css';
7
+ type PickerButtonContainerProps = {
8
+ children: React.ReactNode;
9
+ hasClearIndicator: boolean;
10
+ xcss?: StrictXCSSProp<'flexBasis' | 'color' | 'transition', '&:hover'>;
11
+ };
12
+ export declare const PickerButtonContainer: ({ children, hasClearIndicator, xcss, }: PickerButtonContainerProps) => React.JSX.Element;
13
+ export {};
@@ -359,6 +359,13 @@ export interface TimePickerBaseProps extends WithAnalyticsEventsProps, PickerSel
359
359
  * The name of the field.
360
360
  */
361
361
  name?: string;
362
+ /**
363
+ * The accessible label for the button that opens the time picker. When `label` is provided,
364
+ * it is prefixed to this label.
365
+ *
366
+ * @default 'Open time picker'
367
+ */
368
+ openTimeLabel?: string;
362
369
  /**
363
370
  * Called when the field is blurred.
364
371
  */
@@ -405,6 +412,14 @@ export interface TimePickerBaseProps extends WithAnalyticsEventsProps, PickerSel
405
412
  * Hides icon for dropdown indicator.
406
413
  */
407
414
  hideIcon?: boolean;
415
+ /**
416
+ * Provides a functional clock button that opens the time picker. When enabled, focusing the
417
+ * input with the keyboard does not open the menu; use this button, click the input, or type to
418
+ * open it instead.
419
+ *
420
+ * @default false
421
+ */
422
+ shouldShowTimeButton?: boolean;
408
423
  /**
409
424
  * Format the time with a string that is accepted by [date-fns's format
410
425
  * function](https://date-fns.org/v1.29.0/docs/format). **This does not affect
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/datetime-picker",
3
- "version": "19.2.0",
3
+ "version": "19.3.0",
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/"
@@ -64,7 +64,7 @@
64
64
  "@atlaskit/code": "^20.0.0",
65
65
  "@atlaskit/codemod-utils": "^5.1.0",
66
66
  "@atlaskit/docs": "^12.3.0",
67
- "@atlaskit/form": "^18.1.0",
67
+ "@atlaskit/form": "^18.2.0",
68
68
  "@atlaskit/heading": "^8.0.0",
69
69
  "@atlaskit/link": "^5.1.0",
70
70
  "@atlaskit/modal-dialog": "^17.0.0",