@atlaskit/datetime-picker 17.8.0 → 17.8.2

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.
@@ -15,6 +15,7 @@ import { cx } from '@atlaskit/css';
15
15
  import { useId } from '@atlaskit/ds-lib/use-id';
16
16
  import CalendarIcon from '@atlaskit/icon/core/calendar';
17
17
  import { createLocalizationProvider } from '@atlaskit/locale';
18
+ import { fg } from '@atlaskit/platform-feature-flags';
18
19
  import { Box } from '@atlaskit/primitives/compiled';
19
20
  import Select, { mergeStyles } from '@atlaskit/select';
20
21
  import { EmptyComponent } from '../internal/empty-component';
@@ -26,10 +27,11 @@ import { getShortISOString } from '../internal/get-short-iso-string';
26
27
  import { IndicatorsContainer } from '../internal/indicators-container';
27
28
  import { isDateDisabled } from '../internal/is-date-disabled';
28
29
  import { Menu } from '../internal/menu';
30
+ import { MenuTopLayer } from '../internal/menu-top-layer';
29
31
  import { parseDate } from '../internal/parse-date';
30
32
  import { makeSingleValue } from '../internal/single-value';
31
33
  const packageName = "@atlaskit/datetime-picker";
32
- const packageVersion = "17.7.0";
34
+ const packageVersion = "17.8.1";
33
35
  const styles = {
34
36
  pickerContainerStyle: "_kqswh2mm",
35
37
  dropdownIndicatorStyles: "_1ul91k8s _1tke1k8s _1e0c1txw _4cvr1h6o _1bah1h6o",
@@ -128,10 +130,14 @@ const DatePicker = /*#__PURE__*/forwardRef((props, _forwardedRef) => {
128
130
  return;
129
131
  }
130
132
  if (isOpen && wasOpenedFromCalendarButton) {
131
- var _calendarRef$current, _calendarRef$current$;
132
133
  setIsKeyDown(false);
133
- // Focus on the first button within the calendar
134
- calendarRef === null || calendarRef === void 0 ? void 0 : (_calendarRef$current = calendarRef.current) === null || _calendarRef$current === void 0 ? void 0 : (_calendarRef$current$ = _calendarRef$current.querySelector('button')) === null || _calendarRef$current$ === void 0 ? void 0 : _calendarRef$current$.focus();
134
+ // When using top-layer, Popup.Content with role='dialog' automatically
135
+ // focuses the first focusable element no manual focus needed.
136
+ if (!fg('platform-dst-top-layer')) {
137
+ var _calendarRef$current, _calendarRef$current$;
138
+ // Focus on the first button within the calendar
139
+ calendarRef === null || calendarRef === void 0 ? void 0 : (_calendarRef$current = calendarRef.current) === null || _calendarRef$current === void 0 ? void 0 : (_calendarRef$current$ = _calendarRef$current.querySelector('button')) === null || _calendarRef$current$ === void 0 ? void 0 : _calendarRef$current$.focus();
140
+ }
135
141
  }
136
142
  }, [isKeyDown, calendarRef, isOpen, wasOpenedFromCalendarButton]);
137
143
  const getValue = () => propValue !== null && propValue !== void 0 ? propValue : value;
@@ -153,19 +159,17 @@ const DatePicker = /*#__PURE__*/forwardRef((props, _forwardedRef) => {
153
159
  setWasOpenedFromCalendarButton(false);
154
160
  onChangePropWithAnalytics(iso);
155
161
 
156
- // Yes, this is not ideal. The alternative is to be able to place a ref
157
- // on the inner input of Select itself, which would require a lot of
158
- // extra stuff in the Select component for only this one thing. While
159
- // this would be more "React-y", it doesn't seem to pose any other
160
- // benefits. Performance-wise, we are only searching within the
161
- // container, so it's quick.
162
- if (wasOpenedFromCalendarButton) {
163
- var _calendarButtonRef$cu;
164
- (_calendarButtonRef$cu = calendarButtonRef.current) === null || _calendarButtonRef$cu === void 0 ? void 0 : _calendarButtonRef$cu.focus();
165
- } else {
166
- var _containerRef$current;
167
- const innerCombobox = containerRef === null || containerRef === void 0 ? void 0 : (_containerRef$current = containerRef.current) === null || _containerRef$current === void 0 ? void 0 : _containerRef$current.querySelector('[role="combobox"]');
168
- innerCombobox === null || innerCombobox === void 0 ? void 0 : innerCombobox.focus();
162
+ // When using top-layer, PopupContent handles focus restoration automatically
163
+ // on close based on the role. Only manually restore focus for the legacy path.
164
+ if (!fg('platform-dst-top-layer')) {
165
+ if (wasOpenedFromCalendarButton) {
166
+ var _calendarButtonRef$cu;
167
+ (_calendarButtonRef$cu = calendarButtonRef.current) === null || _calendarButtonRef$cu === void 0 ? void 0 : _calendarButtonRef$cu.focus();
168
+ } else {
169
+ var _containerRef$current;
170
+ const innerCombobox = containerRef === null || containerRef === void 0 ? void 0 : (_containerRef$current = containerRef.current) === null || _containerRef$current === void 0 ? void 0 : _containerRef$current.querySelector('[role="combobox"]');
171
+ innerCombobox === null || innerCombobox === void 0 ? void 0 : innerCombobox.focus();
172
+ }
169
173
  }
170
174
  setIsOpen(false);
171
175
  };
@@ -245,12 +249,12 @@ const DatePicker = /*#__PURE__*/forwardRef((props, _forwardedRef) => {
245
249
  }
246
250
  switch (keyPressed) {
247
251
  case 'escape':
248
- // Yes, this is not ideal. The alternative is to be able to place a ref
249
- // on the inner input of Select itself, which would require a lot of
250
- // extra stuff in the Select component for only this one thing. While
251
- // this would be more "React-y", it doesn't seem to pose any other
252
- // benefits. Performance-wise, we are only searching within the
253
- // container, so it's quick.
252
+ // Restore focus on close. Both code paths handle this here:
253
+ // the legacy path because it has no built-in restoration, and
254
+ // the top-layer path because the menu uses `mode="manual"` to
255
+ // avoid the auto-popover light-dismiss closing the menu on the
256
+ // same click that opens it (see internal/menu-top-layer.tsx).
257
+ // `manual` mode disables the browser's native focus return.
254
258
  if (wasOpenedFromCalendarButton) {
255
259
  var _calendarButtonRef$cu2;
256
260
  (_calendarButtonRef$cu2 = calendarButtonRef.current) === null || _calendarButtonRef$cu2 === void 0 ? void 0 : _calendarButtonRef$cu2.focus();
@@ -399,7 +403,7 @@ const DatePicker = /*#__PURE__*/forwardRef((props, _forwardedRef) => {
399
403
  showClearIndicator: showClearIndicator
400
404
  }))
401
405
  } : {}),
402
- Menu,
406
+ Menu: fg('platform-dst-top-layer') ? MenuTopLayer : Menu,
403
407
  SingleValue,
404
408
  ...(!showClearIndicator && {
405
409
  ClearIndicator: EmptyComponent
@@ -16,7 +16,7 @@ import { convertTokens } from '../internal/parse-tokens';
16
16
  import DatePicker from './date-picker';
17
17
  import TimePicker from './time-picker';
18
18
  const packageName = "@atlaskit/datetime-picker";
19
- const packageVersion = "17.7.0";
19
+ const packageVersion = "17.8.1";
20
20
  const compiledStyles = {
21
21
  datePickerContainerStyles: "_i0dl1ssb _16jlkb7n _1o9zidpf",
22
22
  timePickerContainerStyles: "_i0dl1ssb _16jlkb7n",
@@ -368,4 +368,6 @@ const DateTimePicker = withAnalyticsContext({
368
368
  }
369
369
  })
370
370
  })(DateTimePickerComponent));
371
+
372
+ // eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
371
373
  export default DateTimePicker;
@@ -20,7 +20,7 @@ import { convertTokens } from '../internal/parse-tokens';
20
20
  import DatePicker from './date-picker';
21
21
  import TimePicker from './time-picker';
22
22
  const packageName = "@atlaskit/datetime-picker";
23
- const packageVersion = "17.7.0";
23
+ const packageVersion = "17.8.1";
24
24
  const analyticsAttributes = {
25
25
  componentName: 'dateTimePicker',
26
26
  packageName,
@@ -6,16 +6,18 @@ import { format, isValid } from 'date-fns';
6
6
  import { usePlatformLeafEventHandler } from '@atlaskit/analytics-next';
7
7
  import __noop from '@atlaskit/ds-lib/noop';
8
8
  import { createLocalizationProvider } from '@atlaskit/locale';
9
+ import { fg } from '@atlaskit/platform-feature-flags';
9
10
  import Select, { CreatableSelect, mergeStyles } from '@atlaskit/select';
10
11
  import { defaultTimes } from '../internal/default-times';
11
12
  import { EmptyComponent } from '../internal/empty-component';
12
13
  import { FixedLayerMenu } from '../internal/fixed-layer-menu';
14
+ import { FixedLayerMenuTopLayer } from '../internal/fixed-layer-menu-top-layer';
13
15
  import parseTime from '../internal/parse-time';
14
16
  import { convertTokens } from '../internal/parse-tokens';
15
17
  import { placeholderDatetime } from '../internal/placeholder-date-time';
16
18
  import { makeSingleValue } from '../internal/single-value';
17
19
  const packageName = "@atlaskit/datetime-picker";
18
- const packageVersion = "17.7.0";
20
+ const packageVersion = "17.8.1";
19
21
  const defaultTimeFormat = 'h:mma';
20
22
  const menuStyles = {
21
23
  /* Need to remove default absolute positioning as that causes issues with position fixed */
@@ -230,7 +232,7 @@ const TimePicker = /*#__PURE__*/forwardRef(({
230
232
  });
231
233
  const selectComponents = {
232
234
  DropdownIndicator: EmptyComponent,
233
- Menu: FixedLayerMenu,
235
+ Menu: fg('platform-dst-top-layer') ? FixedLayerMenuTopLayer : FixedLayerMenu,
234
236
  SingleValue,
235
237
  ...(hideIcon && {
236
238
  ClearIndicator: EmptyComponent
@@ -0,0 +1,103 @@
1
+ /* fixed-layer-menu-top-layer.tsx generated by @compiled/babel-plugin v0.39.1 */
2
+ import _extends from "@babel/runtime/helpers/extends";
3
+ import * as React from 'react';
4
+ import { ax, ix } from "@compiled/react/runtime";
5
+ import { useRef } from 'react';
6
+ import { components } from '@atlaskit/select';
7
+ import { slideAndFade } from '@atlaskit/top-layer/animations';
8
+ import { fromLegacyPlacement } from '@atlaskit/top-layer/placement-map';
9
+ import { Popup } from '@atlaskit/top-layer/popup';
10
+ const animation = slideAndFade();
11
+
12
+ /**
13
+ * Bottom-start placement: time options menu appears below and aligned to the
14
+ * start edge of the trigger (the select input).
15
+ */
16
+ const popupPlacement = fromLegacyPlacement({
17
+ legacy: 'bottom-start'
18
+ });
19
+
20
+ /**
21
+ * Top-layer version of the fixed layer menu used in the time picker.
22
+ *
23
+ * Uses `@atlaskit/top-layer/popup` (Popup.Content + Popup.Surface) so the
24
+ * time options list renders in the browser's top layer via the native Popover API
25
+ * and is positioned via CSS Anchor Positioning. This avoids overflow clipping,
26
+ * z-index wars, and portal-based layering.
27
+ *
28
+ * Gated behind the `platform-dst-top-layer` feature flag.
29
+ */
30
+ export const FixedLayerMenuTopLayer = ({
31
+ className,
32
+ clearValue,
33
+ cx,
34
+ getStyles,
35
+ getValue,
36
+ hasValue,
37
+ innerProps,
38
+ innerRef,
39
+ isLoading,
40
+ isMulti,
41
+ isRtl,
42
+ maxMenuHeight,
43
+ menuPlacement,
44
+ menuPosition,
45
+ menuShouldScrollIntoView,
46
+ minMenuHeight,
47
+ options,
48
+ placement,
49
+ selectOption,
50
+ selectProps,
51
+ setValue,
52
+ children,
53
+ ...rest
54
+ }) => {
55
+ var _selectProps$fixedLay, _selectProps$fixedLay2;
56
+ // The select's container element is the anchor for the popup.
57
+ // @ts-ignore -- fixedLayerRef is a custom prop passed through selectProps
58
+ const triggerRef = useRef((_selectProps$fixedLay = selectProps.fixedLayerRef) !== null && _selectProps$fixedLay !== void 0 ? _selectProps$fixedLay : null);
59
+ // @ts-ignore -- fixedLayerRef is a custom prop passed through selectProps
60
+ triggerRef.current = (_selectProps$fixedLay2 = selectProps.fixedLayerRef) !== null && _selectProps$fixedLay2 !== void 0 ? _selectProps$fixedLay2 : null;
61
+ return /*#__PURE__*/React.createElement(Popup.Content, {
62
+ role: "listbox",
63
+ isOpen: true
64
+ // `mode="manual"` opts out of the native popover light-dismiss
65
+ // (Esc / click-outside). react-select already owns those: opening
66
+ // the menu via a click on the input that lives outside the popover
67
+ // element triggers the browser's auto-dismiss as that very click
68
+ // bubbles, slamming the menu shut before the user sees it. With
69
+ // `manual`, react-select's existing onMenuClose / outside-click
70
+ // logic remains the single source of truth.
71
+ ,
72
+ mode: "manual",
73
+ placement: popupPlacement,
74
+ triggerRef: triggerRef,
75
+ animate: animation
76
+ // @ts-ignore -- testId is a custom prop passed through selectProps
77
+ ,
78
+ testId: selectProps.testId && `${selectProps.testId}--popup`
79
+ }, /*#__PURE__*/React.createElement(Popup.Surface, null, /*#__PURE__*/React.createElement(components.Menu, _extends({}, rest, {
80
+ // eslint-disable-next-line @atlaskit/design-system/no-unsafe-style-overrides, @atlaskit/ui-styling-standard/no-classname-prop
81
+ className: className,
82
+ clearValue: clearValue,
83
+ cx: cx,
84
+ getStyles: getStyles,
85
+ getValue: getValue,
86
+ hasValue: hasValue,
87
+ innerProps: innerProps,
88
+ innerRef: innerRef,
89
+ isLoading: isLoading,
90
+ isMulti: isMulti,
91
+ isRtl: isRtl,
92
+ maxMenuHeight: maxMenuHeight,
93
+ menuPlacement: menuPlacement,
94
+ menuPosition: menuPosition,
95
+ menuShouldScrollIntoView: false || menuShouldScrollIntoView,
96
+ minMenuHeight: minMenuHeight,
97
+ options: options,
98
+ placement: placement,
99
+ selectOption: selectOption,
100
+ selectProps: selectProps,
101
+ setValue: setValue
102
+ }), children)));
103
+ };
@@ -0,0 +1,111 @@
1
+ /* menu-top-layer.tsx generated by @compiled/babel-plugin v0.39.1 */
2
+ import _extends from "@babel/runtime/helpers/extends";
3
+ import * as React from 'react';
4
+ import { ax, ix } from "@compiled/react/runtime";
5
+ import { Fragment, useRef } from 'react';
6
+ import { isValid, parseISO } from 'date-fns';
7
+ import Calendar from '@atlaskit/calendar';
8
+ import { slideAndFade } from '@atlaskit/top-layer/animations';
9
+ import { fromLegacyPlacement } from '@atlaskit/top-layer/placement-map';
10
+ import { Popup } from '@atlaskit/top-layer/popup';
11
+ const animation = slideAndFade();
12
+
13
+ /**
14
+ * Bottom-start placement: calendar appears below and aligned to the
15
+ * start edge of the trigger (the select input).
16
+ */
17
+ const popupPlacement = fromLegacyPlacement({
18
+ legacy: 'bottom-start'
19
+ });
20
+
21
+ /**
22
+ * @param isos A series of ISO dates.
23
+ * @returns The last valid date within the array of ISO strings.
24
+ */
25
+ function getValidDate(isos) {
26
+ return isos.reduce((acc, iso) => {
27
+ const date = parseISO(iso);
28
+ return isValid(date) ? {
29
+ day: date.getDate(),
30
+ month: date.getMonth() + 1,
31
+ year: date.getFullYear()
32
+ } : acc;
33
+ }, {});
34
+ }
35
+
36
+ /**
37
+ * Top-layer version of the date picker menu.
38
+ *
39
+ * Uses `@atlaskit/top-layer/popup` (Popup.Content + Popup.Surface) so the
40
+ * calendar renders in the browser's top layer via the native Popover API
41
+ * and is positioned via CSS Anchor Positioning. This avoids overflow clipping,
42
+ * z-index wars, and portal-based layering.
43
+ *
44
+ * Gated behind the `platform-dst-top-layer` feature flag.
45
+ */
46
+ export const MenuTopLayer = ({
47
+ selectProps,
48
+ innerProps
49
+ }) => {
50
+ var _selectProps$calendar, _selectProps$calendar2;
51
+ const {
52
+ calendarValue,
53
+ calendarView,
54
+ menuInnerWrapper: MenuInnerWrapper
55
+ } = selectProps;
56
+ const {
57
+ day,
58
+ month,
59
+ year
60
+ } = getValidDate([calendarValue, calendarView]);
61
+
62
+ // The select's container element is the anchor for the popup.
63
+ const triggerRef = useRef((_selectProps$calendar = selectProps.calendarContainerRef) !== null && _selectProps$calendar !== void 0 ? _selectProps$calendar : null);
64
+ triggerRef.current = (_selectProps$calendar2 = selectProps.calendarContainerRef) !== null && _selectProps$calendar2 !== void 0 ? _selectProps$calendar2 : null;
65
+ const onMenuMouseDown = event => {
66
+ if (event.button !== 0) {
67
+ return;
68
+ }
69
+ event.stopPropagation();
70
+ event.preventDefault();
71
+ };
72
+ const Wrapper = typeof MenuInnerWrapper === 'function' ? MenuInnerWrapper : Fragment;
73
+ return /*#__PURE__*/React.createElement(Popup.Content, {
74
+ role: "dialog",
75
+ label: "calendar",
76
+ isOpen: true
77
+ // `mode="manual"` opts out of native popover light-dismiss.
78
+ // react-select / DateTimePicker already own outside-click and
79
+ // Esc handling. Without this, the same click that opens the
80
+ // menu (which targets the select input outside the popover)
81
+ // also bubbles to the browser's auto-dismiss handler and
82
+ // immediately closes the popover.
83
+ ,
84
+ mode: "manual",
85
+ placement: popupPlacement,
86
+ triggerRef: triggerRef,
87
+ animate: animation,
88
+ testId: selectProps.testId && `${selectProps.testId}--popup`
89
+ }, /*#__PURE__*/React.createElement(Popup.Surface, null, /*#__PURE__*/React.createElement("div", _extends({}, innerProps, {
90
+ role: "presentation",
91
+ onMouseDown: onMenuMouseDown
92
+ }), /*#__PURE__*/React.createElement(Wrapper, null, /*#__PURE__*/React.createElement(Calendar, {
93
+ day: day,
94
+ month: month,
95
+ year: year,
96
+ disabled: selectProps.calendarDisabled,
97
+ disabledDateFilter: selectProps.calendarDisabledDateFilter,
98
+ minDate: selectProps.calendarMinDate,
99
+ maxDate: selectProps.calendarMaxDate,
100
+ nextMonthLabel: selectProps.nextMonthLabel,
101
+ onChange: selectProps.onCalendarChange,
102
+ onSelect: selectProps.onCalendarSelect,
103
+ previousMonthLabel: selectProps.previousMonthLabel,
104
+ ref: selectProps.calendarRef,
105
+ selected: [selectProps.calendarValue],
106
+ shouldSetFocusOnCurrentDay: selectProps.shouldSetFocusOnCurrentDay,
107
+ locale: selectProps.calendarLocale,
108
+ testId: selectProps.testId && `${selectProps.testId}--calendar`,
109
+ weekStartDay: selectProps.calendarWeekStartDay
110
+ })))));
111
+ };
@@ -21,6 +21,7 @@ import { cx } from '@atlaskit/css';
21
21
  import { useId } from '@atlaskit/ds-lib/use-id';
22
22
  import CalendarIcon from '@atlaskit/icon/core/calendar';
23
23
  import { createLocalizationProvider } from '@atlaskit/locale';
24
+ import { fg } from '@atlaskit/platform-feature-flags';
24
25
  import { Box } from '@atlaskit/primitives/compiled';
25
26
  import Select, { mergeStyles } from '@atlaskit/select';
26
27
  import { EmptyComponent } from '../internal/empty-component';
@@ -32,10 +33,11 @@ import { getShortISOString } from '../internal/get-short-iso-string';
32
33
  import { IndicatorsContainer as _IndicatorsContainer } from '../internal/indicators-container';
33
34
  import { isDateDisabled } from '../internal/is-date-disabled';
34
35
  import { Menu } from '../internal/menu';
36
+ import { MenuTopLayer } from '../internal/menu-top-layer';
35
37
  import { parseDate } from '../internal/parse-date';
36
38
  import { makeSingleValue } from '../internal/single-value';
37
39
  var packageName = "@atlaskit/datetime-picker";
38
- var packageVersion = "17.7.0";
40
+ var packageVersion = "17.8.1";
39
41
  var styles = {
40
42
  pickerContainerStyle: "_kqswh2mm",
41
43
  dropdownIndicatorStyles: "_1ul91k8s _1tke1k8s _1e0c1txw _4cvr1h6o _1bah1h6o",
@@ -192,10 +194,14 @@ var DatePicker = /*#__PURE__*/forwardRef(function (props, _forwardedRef) {
192
194
  return;
193
195
  }
194
196
  if (isOpen && wasOpenedFromCalendarButton) {
195
- var _calendarRef$current;
196
197
  setIsKeyDown(false);
197
- // Focus on the first button within the calendar
198
- calendarRef === null || calendarRef === void 0 || (_calendarRef$current = calendarRef.current) === null || _calendarRef$current === void 0 || (_calendarRef$current = _calendarRef$current.querySelector('button')) === null || _calendarRef$current === void 0 || _calendarRef$current.focus();
198
+ // When using top-layer, Popup.Content with role='dialog' automatically
199
+ // focuses the first focusable element no manual focus needed.
200
+ if (!fg('platform-dst-top-layer')) {
201
+ var _calendarRef$current;
202
+ // Focus on the first button within the calendar
203
+ calendarRef === null || calendarRef === void 0 || (_calendarRef$current = calendarRef.current) === null || _calendarRef$current === void 0 || (_calendarRef$current = _calendarRef$current.querySelector('button')) === null || _calendarRef$current === void 0 || _calendarRef$current.focus();
204
+ }
199
205
  }
200
206
  }, [isKeyDown, calendarRef, isOpen, wasOpenedFromCalendarButton]);
201
207
  var getValue = function getValue() {
@@ -219,19 +225,17 @@ var DatePicker = /*#__PURE__*/forwardRef(function (props, _forwardedRef) {
219
225
  setWasOpenedFromCalendarButton(false);
220
226
  onChangePropWithAnalytics(iso);
221
227
 
222
- // Yes, this is not ideal. The alternative is to be able to place a ref
223
- // on the inner input of Select itself, which would require a lot of
224
- // extra stuff in the Select component for only this one thing. While
225
- // this would be more "React-y", it doesn't seem to pose any other
226
- // benefits. Performance-wise, we are only searching within the
227
- // container, so it's quick.
228
- if (wasOpenedFromCalendarButton) {
229
- var _calendarButtonRef$cu;
230
- (_calendarButtonRef$cu = calendarButtonRef.current) === null || _calendarButtonRef$cu === void 0 || _calendarButtonRef$cu.focus();
231
- } else {
232
- var _containerRef$current;
233
- var innerCombobox = containerRef === null || containerRef === void 0 || (_containerRef$current = containerRef.current) === null || _containerRef$current === void 0 ? void 0 : _containerRef$current.querySelector('[role="combobox"]');
234
- innerCombobox === null || innerCombobox === void 0 || innerCombobox.focus();
228
+ // When using top-layer, PopupContent handles focus restoration automatically
229
+ // on close based on the role. Only manually restore focus for the legacy path.
230
+ if (!fg('platform-dst-top-layer')) {
231
+ if (wasOpenedFromCalendarButton) {
232
+ var _calendarButtonRef$cu;
233
+ (_calendarButtonRef$cu = calendarButtonRef.current) === null || _calendarButtonRef$cu === void 0 || _calendarButtonRef$cu.focus();
234
+ } else {
235
+ var _containerRef$current;
236
+ var innerCombobox = containerRef === null || containerRef === void 0 || (_containerRef$current = containerRef.current) === null || _containerRef$current === void 0 ? void 0 : _containerRef$current.querySelector('[role="combobox"]');
237
+ innerCombobox === null || innerCombobox === void 0 || innerCombobox.focus();
238
+ }
235
239
  }
236
240
  setIsOpen(false);
237
241
  };
@@ -311,12 +315,12 @@ var DatePicker = /*#__PURE__*/forwardRef(function (props, _forwardedRef) {
311
315
  }
312
316
  switch (keyPressed) {
313
317
  case 'escape':
314
- // Yes, this is not ideal. The alternative is to be able to place a ref
315
- // on the inner input of Select itself, which would require a lot of
316
- // extra stuff in the Select component for only this one thing. While
317
- // this would be more "React-y", it doesn't seem to pose any other
318
- // benefits. Performance-wise, we are only searching within the
319
- // container, so it's quick.
318
+ // Restore focus on close. Both code paths handle this here:
319
+ // the legacy path because it has no built-in restoration, and
320
+ // the top-layer path because the menu uses `mode="manual"` to
321
+ // avoid the auto-popover light-dismiss closing the menu on the
322
+ // same click that opens it (see internal/menu-top-layer.tsx).
323
+ // `manual` mode disables the browser's native focus return.
320
324
  if (wasOpenedFromCalendarButton) {
321
325
  var _calendarButtonRef$cu2;
322
326
  (_calendarButtonRef$cu2 = calendarButtonRef.current) === null || _calendarButtonRef$cu2 === void 0 || _calendarButtonRef$cu2.focus();
@@ -466,7 +470,7 @@ var DatePicker = /*#__PURE__*/forwardRef(function (props, _forwardedRef) {
466
470
  }));
467
471
  }
468
472
  } : {}), {}, {
469
- Menu: Menu,
473
+ Menu: fg('platform-dst-top-layer') ? MenuTopLayer : Menu,
470
474
  SingleValue: SingleValue
471
475
  }, !showClearIndicator && {
472
476
  ClearIndicator: EmptyComponent
@@ -25,7 +25,7 @@ import { convertTokens } from '../internal/parse-tokens';
25
25
  import DatePicker from './date-picker';
26
26
  import TimePicker from './time-picker';
27
27
  var packageName = "@atlaskit/datetime-picker";
28
- var packageVersion = "17.7.0";
28
+ var packageVersion = "17.8.1";
29
29
  var compiledStyles = {
30
30
  datePickerContainerStyles: "_i0dl1ssb _16jlkb7n _1o9zidpf",
31
31
  timePickerContainerStyles: "_i0dl1ssb _16jlkb7n",
@@ -400,4 +400,6 @@ var DateTimePicker = withAnalyticsContext({
400
400
  }
401
401
  })
402
402
  })(DateTimePickerComponent));
403
+
404
+ // eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
403
405
  export default DateTimePicker;
@@ -27,7 +27,7 @@ import { convertTokens } from '../internal/parse-tokens';
27
27
  import DatePicker from './date-picker';
28
28
  import TimePicker from './time-picker';
29
29
  var packageName = "@atlaskit/datetime-picker";
30
- var packageVersion = "17.7.0";
30
+ var packageVersion = "17.8.1";
31
31
  var analyticsAttributes = {
32
32
  componentName: 'dateTimePicker',
33
33
  packageName: packageName,
@@ -12,16 +12,18 @@ import { format, isValid } from 'date-fns';
12
12
  import { usePlatformLeafEventHandler } from '@atlaskit/analytics-next';
13
13
  import __noop from '@atlaskit/ds-lib/noop';
14
14
  import { createLocalizationProvider } from '@atlaskit/locale';
15
+ import { fg } from '@atlaskit/platform-feature-flags';
15
16
  import Select, { CreatableSelect, mergeStyles } from '@atlaskit/select';
16
17
  import { defaultTimes } from '../internal/default-times';
17
18
  import { EmptyComponent } from '../internal/empty-component';
18
19
  import { FixedLayerMenu } from '../internal/fixed-layer-menu';
20
+ import { FixedLayerMenuTopLayer } from '../internal/fixed-layer-menu-top-layer';
19
21
  import parseTime from '../internal/parse-time';
20
22
  import { convertTokens } from '../internal/parse-tokens';
21
23
  import { placeholderDatetime } from '../internal/placeholder-date-time';
22
24
  import { makeSingleValue } from '../internal/single-value';
23
25
  var packageName = "@atlaskit/datetime-picker";
24
- var packageVersion = "17.7.0";
26
+ var packageVersion = "17.8.1";
25
27
  var defaultTimeFormat = 'h:mma';
26
28
  var menuStyles = {
27
29
  /* Need to remove default absolute positioning as that causes issues with position fixed */
@@ -274,7 +276,7 @@ var TimePicker = /*#__PURE__*/forwardRef(function (_ref2, _ref) {
274
276
  });
275
277
  var selectComponents = _objectSpread({
276
278
  DropdownIndicator: EmptyComponent,
277
- Menu: FixedLayerMenu,
279
+ Menu: fg('platform-dst-top-layer') ? FixedLayerMenuTopLayer : FixedLayerMenu,
278
280
  SingleValue: SingleValue
279
281
  }, hideIcon && {
280
282
  ClearIndicator: EmptyComponent
@@ -0,0 +1,105 @@
1
+ /* fixed-layer-menu-top-layer.tsx generated by @compiled/babel-plugin v0.39.1 */
2
+ import _extends from "@babel/runtime/helpers/extends";
3
+ import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
4
+ var _excluded = ["className", "clearValue", "cx", "getStyles", "getValue", "hasValue", "innerProps", "innerRef", "isLoading", "isMulti", "isRtl", "maxMenuHeight", "menuPlacement", "menuPosition", "menuShouldScrollIntoView", "minMenuHeight", "options", "placement", "selectOption", "selectProps", "setValue", "children"];
5
+ import * as React from 'react';
6
+ import { ax, ix } from "@compiled/react/runtime";
7
+ import { useRef } from 'react';
8
+ import { components } from '@atlaskit/select';
9
+ import { slideAndFade } from '@atlaskit/top-layer/animations';
10
+ import { fromLegacyPlacement } from '@atlaskit/top-layer/placement-map';
11
+ import { Popup } from '@atlaskit/top-layer/popup';
12
+ var animation = slideAndFade();
13
+
14
+ /**
15
+ * Bottom-start placement: time options menu appears below and aligned to the
16
+ * start edge of the trigger (the select input).
17
+ */
18
+ var popupPlacement = fromLegacyPlacement({
19
+ legacy: 'bottom-start'
20
+ });
21
+
22
+ /**
23
+ * Top-layer version of the fixed layer menu used in the time picker.
24
+ *
25
+ * Uses `@atlaskit/top-layer/popup` (Popup.Content + Popup.Surface) so the
26
+ * time options list renders in the browser's top layer via the native Popover API
27
+ * and is positioned via CSS Anchor Positioning. This avoids overflow clipping,
28
+ * z-index wars, and portal-based layering.
29
+ *
30
+ * Gated behind the `platform-dst-top-layer` feature flag.
31
+ */
32
+ var FixedLayerMenuTopLayer = function FixedLayerMenuTopLayer(_ref) {
33
+ var _selectProps$fixedLay, _selectProps$fixedLay2;
34
+ var className = _ref.className,
35
+ clearValue = _ref.clearValue,
36
+ cx = _ref.cx,
37
+ getStyles = _ref.getStyles,
38
+ getValue = _ref.getValue,
39
+ hasValue = _ref.hasValue,
40
+ innerProps = _ref.innerProps,
41
+ innerRef = _ref.innerRef,
42
+ isLoading = _ref.isLoading,
43
+ isMulti = _ref.isMulti,
44
+ isRtl = _ref.isRtl,
45
+ maxMenuHeight = _ref.maxMenuHeight,
46
+ menuPlacement = _ref.menuPlacement,
47
+ menuPosition = _ref.menuPosition,
48
+ menuShouldScrollIntoView = _ref.menuShouldScrollIntoView,
49
+ minMenuHeight = _ref.minMenuHeight,
50
+ options = _ref.options,
51
+ placement = _ref.placement,
52
+ selectOption = _ref.selectOption,
53
+ selectProps = _ref.selectProps,
54
+ setValue = _ref.setValue,
55
+ children = _ref.children,
56
+ rest = _objectWithoutProperties(_ref, _excluded);
57
+ // The select's container element is the anchor for the popup.
58
+ // @ts-ignore -- fixedLayerRef is a custom prop passed through selectProps
59
+ var triggerRef = useRef((_selectProps$fixedLay = selectProps.fixedLayerRef) !== null && _selectProps$fixedLay !== void 0 ? _selectProps$fixedLay : null);
60
+ // @ts-ignore -- fixedLayerRef is a custom prop passed through selectProps
61
+ triggerRef.current = (_selectProps$fixedLay2 = selectProps.fixedLayerRef) !== null && _selectProps$fixedLay2 !== void 0 ? _selectProps$fixedLay2 : null;
62
+ return /*#__PURE__*/React.createElement(Popup.Content, {
63
+ role: "listbox",
64
+ isOpen: true
65
+ // `mode="manual"` opts out of the native popover light-dismiss
66
+ // (Esc / click-outside). react-select already owns those: opening
67
+ // the menu via a click on the input that lives outside the popover
68
+ // element triggers the browser's auto-dismiss as that very click
69
+ // bubbles, slamming the menu shut before the user sees it. With
70
+ // `manual`, react-select's existing onMenuClose / outside-click
71
+ // logic remains the single source of truth.
72
+ ,
73
+ mode: "manual",
74
+ placement: popupPlacement,
75
+ triggerRef: triggerRef,
76
+ animate: animation
77
+ // @ts-ignore -- testId is a custom prop passed through selectProps
78
+ ,
79
+ testId: selectProps.testId && "".concat(selectProps.testId, "--popup")
80
+ }, /*#__PURE__*/React.createElement(Popup.Surface, null, /*#__PURE__*/React.createElement(components.Menu, _extends({}, rest, {
81
+ // eslint-disable-next-line @atlaskit/design-system/no-unsafe-style-overrides, @atlaskit/ui-styling-standard/no-classname-prop
82
+ className: className,
83
+ clearValue: clearValue,
84
+ cx: cx,
85
+ getStyles: getStyles,
86
+ getValue: getValue,
87
+ hasValue: hasValue,
88
+ innerProps: innerProps,
89
+ innerRef: innerRef,
90
+ isLoading: isLoading,
91
+ isMulti: isMulti,
92
+ isRtl: isRtl,
93
+ maxMenuHeight: maxMenuHeight,
94
+ menuPlacement: menuPlacement,
95
+ menuPosition: menuPosition,
96
+ menuShouldScrollIntoView: false || menuShouldScrollIntoView,
97
+ minMenuHeight: minMenuHeight,
98
+ options: options,
99
+ placement: placement,
100
+ selectOption: selectOption,
101
+ selectProps: selectProps,
102
+ setValue: setValue
103
+ }), children)));
104
+ };
105
+ export { FixedLayerMenuTopLayer };