@atlaskit/datetime-picker 18.4.0 → 18.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +32 -0
- package/__tests__/playwright/top-layer-focus.spec.tsx +34 -37
- package/dist/cjs/components/date-picker.js +26 -17
- package/dist/cjs/components/date-time-picker.js +1 -1
- package/dist/cjs/components/time-picker.js +1 -1
- package/dist/cjs/internal/menu-top-layer.compiled.css +5 -0
- package/dist/cjs/internal/menu-top-layer.js +10 -50
- package/dist/es2019/components/date-picker.js +26 -17
- package/dist/es2019/components/date-time-picker.js +1 -1
- package/dist/es2019/components/time-picker.js +1 -1
- package/dist/es2019/internal/menu-top-layer.compiled.css +5 -0
- package/dist/es2019/internal/menu-top-layer.js +11 -52
- package/dist/esm/components/date-picker.js +26 -17
- package/dist/esm/components/date-time-picker.js +1 -1
- package/dist/esm/components/time-picker.js +1 -1
- package/dist/esm/internal/menu-top-layer.compiled.css +5 -0
- package/dist/esm/internal/menu-top-layer.js +11 -52
- package/dist/types/internal/menu-top-layer.d.ts +2 -4
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,37 @@
|
|
|
1
1
|
# @atlaskit/datetime-picker
|
|
2
2
|
|
|
3
|
+
## 18.4.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [`a7e63cfd84876`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/a7e63cfd84876) -
|
|
8
|
+
[ux] When `platform-dst-top-layer` is enabled, Select menus now use the native Popover API to
|
|
9
|
+
handle Escape and light-dismiss before synchronizing `menuIsOpen` through `onMenuClose`. This
|
|
10
|
+
ensures Escape dismisses a nested Select menu without also dismissing its containing popup.
|
|
11
|
+
|
|
12
|
+
Existing public props keep their behavior. The top-layer `Popover` implementation gains an
|
|
13
|
+
internal `source` prop for imperative native popover invokers. The public runtime differences
|
|
14
|
+
behind the feature gate are:
|
|
15
|
+
- Select no longer calls `preventDefault()` or `stopPropagation()` for Escape on the top-layer
|
|
16
|
+
path, whether its menu is open or closed. Successive Escape presses can therefore dismiss the
|
|
17
|
+
Select menu and then its containing native popover.
|
|
18
|
+
- `onMenuClose` is called from the native popover close lifecycle rather than synchronously during
|
|
19
|
+
Select's Escape `keydown` handler.
|
|
20
|
+
- `shouldPreventEscapePropagation` no longer stops Escape propagation while a top-layer menu is
|
|
21
|
+
open; its legacy-path behavior is unchanged.
|
|
22
|
+
- Top-layer Escape invokes `onInputChange` with the `menu-close` action once, after native
|
|
23
|
+
dismissal, instead of the legacy path's two calls.
|
|
24
|
+
- Controlled Selects must continue updating `menuIsOpen` to `false` in response to `onMenuClose`.
|
|
25
|
+
- `PopupSelect` delegates Escape dismissal and focus restoration to its native popover. A consumer
|
|
26
|
+
`onKeyDown` handler can therefore prevent the native dismissal with `preventDefault()`;
|
|
27
|
+
previously, `PopupSelect` closed before forwarding the event.
|
|
28
|
+
- DatePicker's top-layer calendar now uses the Select menu portal's native popover instead of
|
|
29
|
+
creating a nested manual popover.
|
|
30
|
+
- The internal Popover forwarding API accepts a native `source` element so imperative Select
|
|
31
|
+
popovers retain their trigger relationship for light-dismiss behavior.
|
|
32
|
+
|
|
33
|
+
- Updated dependencies
|
|
34
|
+
|
|
3
35
|
## 18.4.0
|
|
4
36
|
|
|
5
37
|
### Minor Changes
|
|
@@ -3,19 +3,15 @@ import { expect, test } from '@af/integration-testing';
|
|
|
3
3
|
/**
|
|
4
4
|
* Date picker: focus contract on the top-layer code path.
|
|
5
5
|
*
|
|
6
|
-
* `DatePicker`
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
* `top-layer/notes/architecture/focus.md` does NOT apply: dialogs always
|
|
10
|
-
* move focus into the popover (to the first focusable, here the
|
|
11
|
-
* previous-year navigation button).
|
|
6
|
+
* `DatePicker` renders its calendar inside the top-layer react-select menu.
|
|
7
|
+
* Opening from the input keeps DOM focus on the combobox; the calendar remains
|
|
8
|
+
* reachable in normal Tab order.
|
|
12
9
|
*
|
|
13
10
|
* The focus contract is therefore:
|
|
14
11
|
*
|
|
15
|
-
* 1. Open
|
|
16
|
-
* (the previous-year navigation button).
|
|
12
|
+
* 1. Open from the input: focus remains on the combobox.
|
|
17
13
|
* 2. Escape: the popover closes and focus is restored to the combobox input.
|
|
18
|
-
* 3. Tab
|
|
14
|
+
* 3. Tab: focus moves from the input into the calendar without closing it.
|
|
19
15
|
*
|
|
20
16
|
* See: `platform/packages/design-system/top-layer/notes/architecture/focus.md`.
|
|
21
17
|
*/
|
|
@@ -23,9 +19,7 @@ import { expect, test } from '@af/integration-testing';
|
|
|
23
19
|
const featureFlag = 'platform-dst-top-layer';
|
|
24
20
|
|
|
25
21
|
test.describe('Date picker: top-layer focus contract', () => {
|
|
26
|
-
test('
|
|
27
|
-
page,
|
|
28
|
-
}) => {
|
|
22
|
+
test('pointer interaction: clicking the input opens the calendar', async ({ page }) => {
|
|
29
23
|
await page.visitExample<typeof import('../../examples/testing-top-layer-focus.tsx')>(
|
|
30
24
|
'design-system',
|
|
31
25
|
'datetime-picker',
|
|
@@ -33,13 +27,27 @@ test.describe('Date picker: top-layer focus contract', () => {
|
|
|
33
27
|
{ featureFlag },
|
|
34
28
|
);
|
|
35
29
|
|
|
36
|
-
|
|
30
|
+
const combobox = page.getByRole('combobox');
|
|
31
|
+
await combobox.click();
|
|
37
32
|
|
|
38
|
-
|
|
39
|
-
await expect(
|
|
33
|
+
await expect(page.getByRole('grid')).toBeVisible();
|
|
34
|
+
await expect(combobox).toHaveAttribute('aria-expanded', 'true');
|
|
35
|
+
});
|
|
40
36
|
|
|
41
|
-
|
|
42
|
-
await
|
|
37
|
+
test('initial focus: opening from the input keeps focus on the combobox', async ({ page }) => {
|
|
38
|
+
await page.visitExample<typeof import('../../examples/testing-top-layer-focus.tsx')>(
|
|
39
|
+
'design-system',
|
|
40
|
+
'datetime-picker',
|
|
41
|
+
'testing-top-layer-focus',
|
|
42
|
+
{ featureFlag },
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
const combobox = page.getByRole('combobox');
|
|
46
|
+
await combobox.focus();
|
|
47
|
+
|
|
48
|
+
const calendar = page.getByRole('grid');
|
|
49
|
+
await expect(calendar).toBeVisible();
|
|
50
|
+
await expect(combobox).toBeFocused();
|
|
43
51
|
});
|
|
44
52
|
|
|
45
53
|
test('focus restoration: Escape closes the popover and focus returns to the combobox input', async ({
|
|
@@ -53,9 +61,9 @@ test.describe('Date picker: top-layer focus contract', () => {
|
|
|
53
61
|
);
|
|
54
62
|
|
|
55
63
|
const combobox = page.getByRole('combobox');
|
|
56
|
-
await
|
|
64
|
+
await combobox.focus();
|
|
57
65
|
|
|
58
|
-
const calendar = page.getByRole('
|
|
66
|
+
const calendar = page.getByRole('grid');
|
|
59
67
|
await expect(calendar).toBeVisible();
|
|
60
68
|
|
|
61
69
|
await page.keyboard.press('Escape');
|
|
@@ -63,9 +71,7 @@ test.describe('Date picker: top-layer focus contract', () => {
|
|
|
63
71
|
await expect(combobox).toBeFocused();
|
|
64
72
|
});
|
|
65
73
|
|
|
66
|
-
test('focus movement: Tab moves focus
|
|
67
|
-
page,
|
|
68
|
-
}) => {
|
|
74
|
+
test('focus movement: Tab moves focus from the input into the calendar', async ({ page }) => {
|
|
69
75
|
await page.visitExample<typeof import('../../examples/testing-top-layer-focus.tsx')>(
|
|
70
76
|
'design-system',
|
|
71
77
|
'datetime-picker',
|
|
@@ -73,25 +79,16 @@ test.describe('Date picker: top-layer focus contract', () => {
|
|
|
73
79
|
{ featureFlag },
|
|
74
80
|
);
|
|
75
81
|
|
|
76
|
-
|
|
82
|
+
const combobox = page.getByRole('combobox');
|
|
83
|
+
await combobox.focus();
|
|
77
84
|
|
|
78
|
-
const calendar = page.getByRole('
|
|
85
|
+
const calendar = page.getByRole('grid');
|
|
79
86
|
await expect(calendar).toBeVisible();
|
|
87
|
+
await expect(combobox).toBeFocused();
|
|
80
88
|
|
|
81
89
|
const previousYearButton = page.getByTestId('date-picker--calendar--previous-year');
|
|
82
|
-
await expect(previousYearButton).toBeFocused();
|
|
83
|
-
|
|
84
|
-
// `useFocusWrap` keeps Tab inside the dialog for role="dialog" popovers.
|
|
85
90
|
await page.keyboard.press('Tab');
|
|
86
|
-
await expect(previousYearButton).
|
|
87
|
-
|
|
88
|
-
// Focus must stay within the calendar dialog: for a role="dialog" popover
|
|
89
|
-
// `useFocusWrap` intercepts Tab so focus never escapes to page content
|
|
90
|
-
// behind the popover.
|
|
91
|
-
const focusWithinCalendar = await calendar.evaluate(
|
|
92
|
-
(calendarElement) =>
|
|
93
|
-
document.activeElement !== null && calendarElement.contains(document.activeElement),
|
|
94
|
-
);
|
|
95
|
-
expect(focusWithinCalendar).toBe(true);
|
|
91
|
+
await expect(previousYearButton).toBeFocused();
|
|
92
|
+
await expect(calendar).toBeVisible();
|
|
96
93
|
});
|
|
97
94
|
});
|
|
@@ -45,7 +45,7 @@ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r
|
|
|
45
45
|
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; }
|
|
46
46
|
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; }
|
|
47
47
|
var packageName = "@atlaskit/datetime-picker";
|
|
48
|
-
var packageVersion = "18.
|
|
48
|
+
var packageVersion = "18.4.0";
|
|
49
49
|
var styles = {
|
|
50
50
|
pickerContainerStyle: "_kqswh2mm",
|
|
51
51
|
dropdownIndicatorStyles: "_1ul91k8s _1tke1k8s _1e0c1txw _4cvr1h6o _1bah1h6o",
|
|
@@ -72,6 +72,7 @@ var DatePicker = /*#__PURE__*/(0, _react.forwardRef)(function (props, _forwarded
|
|
|
72
72
|
var containerRef = (0, _react.useRef)(null);
|
|
73
73
|
var calendarRef = (0, _react.useRef)(null);
|
|
74
74
|
var calendarButtonRef = (0, _react.useRef)(null);
|
|
75
|
+
var isPointerInteractionRef = (0, _react.useRef)(false);
|
|
75
76
|
var _props$appearance = props.appearance,
|
|
76
77
|
appearance = _props$appearance === void 0 ? 'default' : _props$appearance,
|
|
77
78
|
_props$autoFocus = props.autoFocus,
|
|
@@ -197,19 +198,15 @@ var DatePicker = /*#__PURE__*/(0, _react.forwardRef)(function (props, _forwarded
|
|
|
197
198
|
setLocale(propLocale);
|
|
198
199
|
}
|
|
199
200
|
(0, _react.useEffect)(function () {
|
|
200
|
-
//
|
|
201
|
+
// Only move focus when the dedicated calendar button opened the menu.
|
|
201
202
|
if (!isKeyDown) {
|
|
202
203
|
return;
|
|
203
204
|
}
|
|
204
205
|
if (isOpen && wasOpenedFromCalendarButton) {
|
|
206
|
+
var _calendarRef$current;
|
|
205
207
|
setIsKeyDown(false);
|
|
206
|
-
//
|
|
207
|
-
|
|
208
|
-
if (!(0, _fg.fg)('platform-dst-top-layer')) {
|
|
209
|
-
var _calendarRef$current;
|
|
210
|
-
// Focus on the first button within the calendar
|
|
211
|
-
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();
|
|
212
|
-
}
|
|
208
|
+
// Focus on the first button within the calendar
|
|
209
|
+
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();
|
|
213
210
|
}
|
|
214
211
|
}, [isKeyDown, calendarRef, isOpen, wasOpenedFromCalendarButton]);
|
|
215
212
|
var getValue = function getValue() {
|
|
@@ -256,6 +253,7 @@ var DatePicker = /*#__PURE__*/(0, _react.forwardRef)(function (props, _forwarded
|
|
|
256
253
|
var onContainerBlur = function onContainerBlur(event) {
|
|
257
254
|
var _containerRef$current2;
|
|
258
255
|
var newlyFocusedElement = event.relatedTarget;
|
|
256
|
+
isPointerInteractionRef.current = false;
|
|
259
257
|
if (!(containerRef !== null && containerRef !== void 0 && (_containerRef$current2 = containerRef.current) !== null && _containerRef$current2 !== void 0 && _containerRef$current2.contains(newlyFocusedElement))) {
|
|
260
258
|
setIsOpen(false);
|
|
261
259
|
setShouldSetFocusOnCurrentDay(false);
|
|
@@ -286,8 +284,12 @@ var DatePicker = /*#__PURE__*/(0, _react.forwardRef)(function (props, _forwarded
|
|
|
286
284
|
// Don't open menu if focussing after the user has clicked clear
|
|
287
285
|
setClearingFromIcon(false);
|
|
288
286
|
} else {
|
|
289
|
-
//
|
|
290
|
-
|
|
287
|
+
// Opening an auto popover during pointer focus allows the matching pointerup
|
|
288
|
+
// to immediately light-dismiss it. Let the subsequent click open it instead.
|
|
289
|
+
if (!(0, _fg.fg)('platform-dst-top-layer') || !isPointerInteractionRef.current) {
|
|
290
|
+
// Don't open when focused into via keyboard if the calendar button is present
|
|
291
|
+
setIsOpen(!shouldShowCalendarButton);
|
|
292
|
+
}
|
|
291
293
|
setCalendarValue(value);
|
|
292
294
|
setIsFocused(true);
|
|
293
295
|
setWasOpenedFromCalendarButton(false);
|
|
@@ -323,12 +325,7 @@ var DatePicker = /*#__PURE__*/(0, _react.forwardRef)(function (props, _forwarded
|
|
|
323
325
|
}
|
|
324
326
|
switch (keyPressed) {
|
|
325
327
|
case 'escape':
|
|
326
|
-
// Restore focus
|
|
327
|
-
// the legacy path because it has no built-in restoration, and
|
|
328
|
-
// the top-layer path because the menu uses `mode="manual"` to
|
|
329
|
-
// avoid the auto-popover light-dismiss closing the menu on the
|
|
330
|
-
// same click that opens it (see internal/menu-top-layer.tsx).
|
|
331
|
-
// `manual` mode disables the browser's native focus return.
|
|
328
|
+
// Restore focus because it may have moved from the input into the calendar.
|
|
332
329
|
if (wasOpenedFromCalendarButton) {
|
|
333
330
|
var _calendarButtonRef$cu2;
|
|
334
331
|
(_calendarButtonRef$cu2 = calendarButtonRef.current) === null || _calendarButtonRef$cu2 === void 0 || _calendarButtonRef$cu2.focus();
|
|
@@ -406,6 +403,9 @@ var DatePicker = /*#__PURE__*/(0, _react.forwardRef)(function (props, _forwarded
|
|
|
406
403
|
|
|
407
404
|
// This event handler is triggered from both keydown and click. It's weird.
|
|
408
405
|
var onCalendarButtonClick = function onCalendarButtonClick(e) {
|
|
406
|
+
if (!getIsOpen() && (0, _fg.fg)('platform-dst-top-layer')) {
|
|
407
|
+
setIsKeyDown(true);
|
|
408
|
+
}
|
|
409
409
|
setIsOpen(function (isOpen) {
|
|
410
410
|
if (isOpen) {
|
|
411
411
|
var _props$selectProps2, _props$selectProps2$o;
|
|
@@ -536,10 +536,19 @@ var DatePicker = /*#__PURE__*/(0, _react.forwardRef)(function (props, _forwarded
|
|
|
536
536
|
return /*#__PURE__*/React.createElement("div", (0, _extends2.default)({}, innerProps, {
|
|
537
537
|
"data-testid": testId && "".concat(testId, "--container"),
|
|
538
538
|
onBlur: onContainerBlur,
|
|
539
|
+
onClickCapture: function onClickCapture() {
|
|
540
|
+
isPointerInteractionRef.current = false;
|
|
541
|
+
},
|
|
539
542
|
onFocus: onContainerFocus,
|
|
540
543
|
onClick: onInputClick,
|
|
541
544
|
onInput: onTextInput,
|
|
542
545
|
onKeyDown: onInputKeyDown,
|
|
546
|
+
onPointerCancelCapture: function onPointerCancelCapture() {
|
|
547
|
+
isPointerInteractionRef.current = false;
|
|
548
|
+
},
|
|
549
|
+
onPointerDownCapture: function onPointerDownCapture() {
|
|
550
|
+
isPointerInteractionRef.current = true;
|
|
551
|
+
},
|
|
543
552
|
ref: getContainerRef
|
|
544
553
|
// Since the onclick, onfocus are passed down, adding role="presentation" prevents typecheck errors.
|
|
545
554
|
,
|
|
@@ -33,7 +33,7 @@ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t =
|
|
|
33
33
|
// for typing `process`
|
|
34
34
|
// oxlint-disable-next-line @atlassian/no-restricted-imports
|
|
35
35
|
var packageName = "@atlaskit/datetime-picker";
|
|
36
|
-
var packageVersion = "18.
|
|
36
|
+
var packageVersion = "18.4.0";
|
|
37
37
|
var analyticsAttributes = {
|
|
38
38
|
componentName: 'dateTimePicker',
|
|
39
39
|
packageName: packageName,
|
|
@@ -32,7 +32,7 @@ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r
|
|
|
32
32
|
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
33
|
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
34
|
var packageName = "@atlaskit/datetime-picker";
|
|
35
|
-
var packageVersion = "18.
|
|
35
|
+
var packageVersion = "18.4.0";
|
|
36
36
|
var defaultTimeFormat = 'h:mma';
|
|
37
37
|
var menuStyles = {
|
|
38
38
|
/* Need to remove default absolute positioning as that causes issues with position fixed */
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
._2rko1mok{border-radius:var(--ds-radius-large,8px)}._16qs130s{box-shadow:var(--ds-shadow-overlay,0 8px 9pt #1e1f2126,0 0 1px #1e1f214f)}
|
|
2
|
+
._1bsb1ris{width:max-content}
|
|
3
|
+
._1pfhu2gc{margin-block-start:var(--ds-space-100,8px)}
|
|
4
|
+
._6rthu2gc{margin-block-end:var(--ds-space-100,8px)}
|
|
5
|
+
._bfhk1bhr{background-color:var(--ds-surface-overlay,#fff)}
|
|
@@ -7,25 +7,14 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
7
7
|
value: true
|
|
8
8
|
});
|
|
9
9
|
exports.MenuTopLayer = void 0;
|
|
10
|
+
require("./menu-top-layer.compiled.css");
|
|
10
11
|
var _react = _interopRequireWildcard(require("react"));
|
|
11
12
|
var React = _react;
|
|
12
13
|
var _runtime = require("@compiled/react/runtime");
|
|
13
14
|
var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends"));
|
|
14
15
|
var _dateFns = require("date-fns");
|
|
15
16
|
var _calendar = _interopRequireDefault(require("@atlaskit/calendar/calendar"));
|
|
16
|
-
var _placementMap = require("@atlaskit/top-layer/placement-map");
|
|
17
|
-
var _popover = require("@atlaskit/top-layer/popover");
|
|
18
|
-
var _popoverSurface = require("@atlaskit/top-layer/popover-surface");
|
|
19
|
-
var _useAnchorPosition = require("@atlaskit/top-layer/use-anchor-position");
|
|
20
17
|
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
|
|
21
|
-
/**
|
|
22
|
-
* Bottom-start placement: calendar appears below and aligned to the
|
|
23
|
-
* start edge of the trigger (the select input).
|
|
24
|
-
*/
|
|
25
|
-
var popupPlacement = (0, _placementMap.fromLegacyPlacement)({
|
|
26
|
-
legacy: 'bottom-start'
|
|
27
|
-
});
|
|
28
|
-
|
|
29
18
|
/**
|
|
30
19
|
* @param isos A series of ISO dates.
|
|
31
20
|
* @returns The last valid date within the array of ISO strings.
|
|
@@ -40,19 +29,19 @@ function getValidDate(isos) {
|
|
|
40
29
|
} : acc;
|
|
41
30
|
}, {});
|
|
42
31
|
}
|
|
32
|
+
var styles = {
|
|
33
|
+
root: "_2rko1mok _1bsb1ris _bfhk1bhr _16qs130s _1pfhu2gc _6rthu2gc"
|
|
34
|
+
};
|
|
43
35
|
|
|
44
36
|
/**
|
|
45
37
|
* Top-layer version of the date picker menu.
|
|
46
38
|
*
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
* CSS Anchor Positioning. This avoids overflow clipping, z-index wars,
|
|
50
|
-
* and portal-based layering.
|
|
39
|
+
* The surrounding react-select menu portal owns the native popover and
|
|
40
|
+
* positioning. This component only supplies the calendar dialog content.
|
|
51
41
|
*
|
|
52
42
|
* Gated behind the `platform-dst-top-layer` feature flag.
|
|
53
43
|
*/
|
|
54
44
|
var MenuTopLayer = exports.MenuTopLayer = function MenuTopLayer(_ref) {
|
|
55
|
-
var _selectProps$calendar, _selectProps$calendar2;
|
|
56
45
|
var selectProps = _ref.selectProps,
|
|
57
46
|
innerProps = _ref.innerProps;
|
|
58
47
|
var calendarValue = selectProps.calendarValue,
|
|
@@ -62,20 +51,6 @@ var MenuTopLayer = exports.MenuTopLayer = function MenuTopLayer(_ref) {
|
|
|
62
51
|
day = _getValidDate.day,
|
|
63
52
|
month = _getValidDate.month,
|
|
64
53
|
year = _getValidDate.year;
|
|
65
|
-
|
|
66
|
-
// The select's container element is the anchor for the popup.
|
|
67
|
-
var triggerRef = (0, _react.useRef)((_selectProps$calendar = selectProps.calendarContainerRef) !== null && _selectProps$calendar !== void 0 ? _selectProps$calendar : null);
|
|
68
|
-
triggerRef.current = (_selectProps$calendar2 = selectProps.calendarContainerRef) !== null && _selectProps$calendar2 !== void 0 ? _selectProps$calendar2 : null;
|
|
69
|
-
var popoverRef = (0, _react.useRef)(null);
|
|
70
|
-
(0, _useAnchorPosition.useAnchorPosition)({
|
|
71
|
-
anchorRef: triggerRef,
|
|
72
|
-
popoverRef: popoverRef,
|
|
73
|
-
placement: popupPlacement,
|
|
74
|
-
// The Popover is rendered with `isOpen` always true while this
|
|
75
|
-
// component is mounted (react-select conditionally mounts/unmounts
|
|
76
|
-
// the menu), so positioning is always active.
|
|
77
|
-
isOpen: true
|
|
78
|
-
});
|
|
79
54
|
var onMenuMouseDown = function onMenuMouseDown(event) {
|
|
80
55
|
if (event.button !== 0) {
|
|
81
56
|
return;
|
|
@@ -84,25 +59,10 @@ var MenuTopLayer = exports.MenuTopLayer = function MenuTopLayer(_ref) {
|
|
|
84
59
|
event.preventDefault();
|
|
85
60
|
};
|
|
86
61
|
var Wrapper = typeof MenuInnerWrapper === 'function' ? MenuInnerWrapper : _react.Fragment;
|
|
87
|
-
return /*#__PURE__*/React.createElement(
|
|
88
|
-
|
|
89
|
-
role: "dialog",
|
|
90
|
-
label: "calendar",
|
|
91
|
-
isOpen: true
|
|
92
|
-
// `mode="manual"` opts out of native popover light-dismiss.
|
|
93
|
-
// react-select / DateTimePicker already own outside-click and
|
|
94
|
-
// Esc handling. Without this, the same click that opens the
|
|
95
|
-
// menu (which targets the select input outside the popover)
|
|
96
|
-
// also bubbles to the browser's auto-dismiss handler and
|
|
97
|
-
// immediately closes the popover.
|
|
98
|
-
,
|
|
99
|
-
mode: "manual",
|
|
100
|
-
placement: popupPlacement,
|
|
101
|
-
shouldAnimate: true,
|
|
102
|
-
testId: selectProps.testId && "".concat(selectProps.testId, "--popup")
|
|
103
|
-
}, /*#__PURE__*/React.createElement(_popoverSurface.PopoverSurface, null, /*#__PURE__*/React.createElement("div", (0, _extends2.default)({}, innerProps, {
|
|
62
|
+
return /*#__PURE__*/React.createElement("div", (0, _extends2.default)({}, innerProps, {
|
|
63
|
+
onMouseDown: onMenuMouseDown,
|
|
104
64
|
role: "presentation",
|
|
105
|
-
|
|
65
|
+
className: (0, _runtime.ax)([styles.root])
|
|
106
66
|
}), /*#__PURE__*/React.createElement(Wrapper, null, /*#__PURE__*/React.createElement(_calendar.default, {
|
|
107
67
|
day: day,
|
|
108
68
|
month: month,
|
|
@@ -121,5 +81,5 @@ var MenuTopLayer = exports.MenuTopLayer = function MenuTopLayer(_ref) {
|
|
|
121
81
|
locale: selectProps.calendarLocale,
|
|
122
82
|
testId: selectProps.testId && "".concat(selectProps.testId, "--calendar"),
|
|
123
83
|
weekStartDay: selectProps.calendarWeekStartDay
|
|
124
|
-
})))
|
|
84
|
+
})));
|
|
125
85
|
};
|
|
@@ -32,7 +32,7 @@ import { MenuTopLayer } from '../internal/menu-top-layer';
|
|
|
32
32
|
import { parseDate } from '../internal/parse-date';
|
|
33
33
|
import { makeSingleValue } from '../internal/single-value';
|
|
34
34
|
const packageName = "@atlaskit/datetime-picker";
|
|
35
|
-
const packageVersion = "18.
|
|
35
|
+
const packageVersion = "18.4.0";
|
|
36
36
|
const styles = {
|
|
37
37
|
pickerContainerStyle: "_kqswh2mm",
|
|
38
38
|
dropdownIndicatorStyles: "_1ul91k8s _1tke1k8s _1e0c1txw _4cvr1h6o _1bah1h6o",
|
|
@@ -59,6 +59,7 @@ const DatePicker = /*#__PURE__*/forwardRef((props, _forwardedRef) => {
|
|
|
59
59
|
const containerRef = useRef(null);
|
|
60
60
|
const calendarRef = useRef(null);
|
|
61
61
|
const calendarButtonRef = useRef(null);
|
|
62
|
+
const isPointerInteractionRef = useRef(false);
|
|
62
63
|
const {
|
|
63
64
|
appearance = 'default',
|
|
64
65
|
autoFocus = false,
|
|
@@ -126,19 +127,15 @@ const DatePicker = /*#__PURE__*/forwardRef((props, _forwardedRef) => {
|
|
|
126
127
|
setLocale(propLocale);
|
|
127
128
|
}
|
|
128
129
|
useEffect(() => {
|
|
129
|
-
//
|
|
130
|
+
// Only move focus when the dedicated calendar button opened the menu.
|
|
130
131
|
if (!isKeyDown) {
|
|
131
132
|
return;
|
|
132
133
|
}
|
|
133
134
|
if (isOpen && wasOpenedFromCalendarButton) {
|
|
135
|
+
var _calendarRef$current, _calendarRef$current$;
|
|
134
136
|
setIsKeyDown(false);
|
|
135
|
-
//
|
|
136
|
-
|
|
137
|
-
if (!fg('platform-dst-top-layer')) {
|
|
138
|
-
var _calendarRef$current, _calendarRef$current$;
|
|
139
|
-
// Focus on the first button within the calendar
|
|
140
|
-
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();
|
|
141
|
-
}
|
|
137
|
+
// Focus on the first button within the calendar
|
|
138
|
+
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();
|
|
142
139
|
}
|
|
143
140
|
}, [isKeyDown, calendarRef, isOpen, wasOpenedFromCalendarButton]);
|
|
144
141
|
const getValue = () => propValue !== null && propValue !== void 0 ? propValue : value;
|
|
@@ -183,6 +180,7 @@ const DatePicker = /*#__PURE__*/forwardRef((props, _forwardedRef) => {
|
|
|
183
180
|
const onContainerBlur = event => {
|
|
184
181
|
var _containerRef$current2;
|
|
185
182
|
const newlyFocusedElement = event.relatedTarget;
|
|
183
|
+
isPointerInteractionRef.current = false;
|
|
186
184
|
if (!(containerRef !== null && containerRef !== void 0 && (_containerRef$current2 = containerRef.current) !== null && _containerRef$current2 !== void 0 && _containerRef$current2.contains(newlyFocusedElement))) {
|
|
187
185
|
setIsOpen(false);
|
|
188
186
|
setShouldSetFocusOnCurrentDay(false);
|
|
@@ -213,8 +211,12 @@ const DatePicker = /*#__PURE__*/forwardRef((props, _forwardedRef) => {
|
|
|
213
211
|
// Don't open menu if focussing after the user has clicked clear
|
|
214
212
|
setClearingFromIcon(false);
|
|
215
213
|
} else {
|
|
216
|
-
//
|
|
217
|
-
|
|
214
|
+
// Opening an auto popover during pointer focus allows the matching pointerup
|
|
215
|
+
// to immediately light-dismiss it. Let the subsequent click open it instead.
|
|
216
|
+
if (!fg('platform-dst-top-layer') || !isPointerInteractionRef.current) {
|
|
217
|
+
// Don't open when focused into via keyboard if the calendar button is present
|
|
218
|
+
setIsOpen(!shouldShowCalendarButton);
|
|
219
|
+
}
|
|
218
220
|
setCalendarValue(value);
|
|
219
221
|
setIsFocused(true);
|
|
220
222
|
setWasOpenedFromCalendarButton(false);
|
|
@@ -250,12 +252,7 @@ const DatePicker = /*#__PURE__*/forwardRef((props, _forwardedRef) => {
|
|
|
250
252
|
}
|
|
251
253
|
switch (keyPressed) {
|
|
252
254
|
case 'escape':
|
|
253
|
-
// Restore focus
|
|
254
|
-
// the legacy path because it has no built-in restoration, and
|
|
255
|
-
// the top-layer path because the menu uses `mode="manual"` to
|
|
256
|
-
// avoid the auto-popover light-dismiss closing the menu on the
|
|
257
|
-
// same click that opens it (see internal/menu-top-layer.tsx).
|
|
258
|
-
// `manual` mode disables the browser's native focus return.
|
|
255
|
+
// Restore focus because it may have moved from the input into the calendar.
|
|
259
256
|
if (wasOpenedFromCalendarButton) {
|
|
260
257
|
var _calendarButtonRef$cu2;
|
|
261
258
|
(_calendarButtonRef$cu2 = calendarButtonRef.current) === null || _calendarButtonRef$cu2 === void 0 ? void 0 : _calendarButtonRef$cu2.focus();
|
|
@@ -333,6 +330,9 @@ const DatePicker = /*#__PURE__*/forwardRef((props, _forwardedRef) => {
|
|
|
333
330
|
|
|
334
331
|
// This event handler is triggered from both keydown and click. It's weird.
|
|
335
332
|
const onCalendarButtonClick = e => {
|
|
333
|
+
if (!getIsOpen() && fg('platform-dst-top-layer')) {
|
|
334
|
+
setIsKeyDown(true);
|
|
335
|
+
}
|
|
336
336
|
setIsOpen(isOpen => {
|
|
337
337
|
if (isOpen) {
|
|
338
338
|
var _props$selectProps, _props$selectProps$on;
|
|
@@ -464,10 +464,19 @@ const DatePicker = /*#__PURE__*/forwardRef((props, _forwardedRef) => {
|
|
|
464
464
|
return /*#__PURE__*/React.createElement("div", _extends({}, innerProps, {
|
|
465
465
|
"data-testid": testId && `${testId}--container`,
|
|
466
466
|
onBlur: onContainerBlur,
|
|
467
|
+
onClickCapture: () => {
|
|
468
|
+
isPointerInteractionRef.current = false;
|
|
469
|
+
},
|
|
467
470
|
onFocus: onContainerFocus,
|
|
468
471
|
onClick: onInputClick,
|
|
469
472
|
onInput: onTextInput,
|
|
470
473
|
onKeyDown: onInputKeyDown,
|
|
474
|
+
onPointerCancelCapture: () => {
|
|
475
|
+
isPointerInteractionRef.current = false;
|
|
476
|
+
},
|
|
477
|
+
onPointerDownCapture: () => {
|
|
478
|
+
isPointerInteractionRef.current = true;
|
|
479
|
+
},
|
|
471
480
|
ref: getContainerRef
|
|
472
481
|
// Since the onclick, onfocus are passed down, adding role="presentation" prevents typecheck errors.
|
|
473
482
|
,
|
|
@@ -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 = "18.
|
|
23
|
+
const packageVersion = "18.4.0";
|
|
24
24
|
const analyticsAttributes = {
|
|
25
25
|
componentName: 'dateTimePicker',
|
|
26
26
|
packageName,
|
|
@@ -19,7 +19,7 @@ import { convertTokens } from '../internal/parse-tokens';
|
|
|
19
19
|
import { placeholderDatetime } from '../internal/placeholder-date-time';
|
|
20
20
|
import { makeSingleValue } from '../internal/single-value';
|
|
21
21
|
const packageName = "@atlaskit/datetime-picker";
|
|
22
|
-
const packageVersion = "18.
|
|
22
|
+
const packageVersion = "18.4.0";
|
|
23
23
|
const defaultTimeFormat = 'h:mma';
|
|
24
24
|
const menuStyles = {
|
|
25
25
|
/* Need to remove default absolute positioning as that causes issues with position fixed */
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
._2rko1mok{border-radius:var(--ds-radius-large,8px)}._16qs130s{box-shadow:var(--ds-shadow-overlay,0 8px 9pt #1e1f2126,0 0 1px #1e1f214f)}
|
|
2
|
+
._1bsb1ris{width:max-content}
|
|
3
|
+
._1pfhu2gc{margin-block-start:var(--ds-space-100,8px)}
|
|
4
|
+
._6rthu2gc{margin-block-end:var(--ds-space-100,8px)}
|
|
5
|
+
._bfhk1bhr{background-color:var(--ds-surface-overlay,#fff)}
|
|
@@ -1,23 +1,11 @@
|
|
|
1
1
|
/* menu-top-layer.tsx generated by @compiled/babel-plugin v2.0.0 */
|
|
2
2
|
import _extends from "@babel/runtime/helpers/extends";
|
|
3
|
+
import "./menu-top-layer.compiled.css";
|
|
3
4
|
import * as React from 'react';
|
|
4
5
|
import { ax, ix } from "@compiled/react/runtime";
|
|
5
|
-
import { Fragment
|
|
6
|
+
import { Fragment } from 'react';
|
|
6
7
|
import { isValid, parseISO } from 'date-fns';
|
|
7
8
|
import Calendar from '@atlaskit/calendar/calendar';
|
|
8
|
-
import { fromLegacyPlacement } from '@atlaskit/top-layer/placement-map';
|
|
9
|
-
import { Popover } from '@atlaskit/top-layer/popover';
|
|
10
|
-
import { PopoverSurface } from '@atlaskit/top-layer/popover-surface';
|
|
11
|
-
import { useAnchorPosition } from '@atlaskit/top-layer/use-anchor-position';
|
|
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
9
|
/**
|
|
22
10
|
* @param isos A series of ISO dates.
|
|
23
11
|
* @returns The last valid date within the array of ISO strings.
|
|
@@ -32,14 +20,15 @@ function getValidDate(isos) {
|
|
|
32
20
|
} : acc;
|
|
33
21
|
}, {});
|
|
34
22
|
}
|
|
23
|
+
const styles = {
|
|
24
|
+
root: "_2rko1mok _1bsb1ris _bfhk1bhr _16qs130s _1pfhu2gc _6rthu2gc"
|
|
25
|
+
};
|
|
35
26
|
|
|
36
27
|
/**
|
|
37
28
|
* Top-layer version of the date picker menu.
|
|
38
29
|
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
* CSS Anchor Positioning. This avoids overflow clipping, z-index wars,
|
|
42
|
-
* and portal-based layering.
|
|
30
|
+
* The surrounding react-select menu portal owns the native popover and
|
|
31
|
+
* positioning. This component only supplies the calendar dialog content.
|
|
43
32
|
*
|
|
44
33
|
* Gated behind the `platform-dst-top-layer` feature flag.
|
|
45
34
|
*/
|
|
@@ -47,7 +36,6 @@ export const MenuTopLayer = ({
|
|
|
47
36
|
selectProps,
|
|
48
37
|
innerProps
|
|
49
38
|
}) => {
|
|
50
|
-
var _selectProps$calendar, _selectProps$calendar2;
|
|
51
39
|
const {
|
|
52
40
|
calendarValue,
|
|
53
41
|
calendarView,
|
|
@@ -58,20 +46,6 @@ export const MenuTopLayer = ({
|
|
|
58
46
|
month,
|
|
59
47
|
year
|
|
60
48
|
} = 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 popoverRef = useRef(null);
|
|
66
|
-
useAnchorPosition({
|
|
67
|
-
anchorRef: triggerRef,
|
|
68
|
-
popoverRef,
|
|
69
|
-
placement: popupPlacement,
|
|
70
|
-
// The Popover is rendered with `isOpen` always true while this
|
|
71
|
-
// component is mounted (react-select conditionally mounts/unmounts
|
|
72
|
-
// the menu), so positioning is always active.
|
|
73
|
-
isOpen: true
|
|
74
|
-
});
|
|
75
49
|
const onMenuMouseDown = event => {
|
|
76
50
|
if (event.button !== 0) {
|
|
77
51
|
return;
|
|
@@ -80,25 +54,10 @@ export const MenuTopLayer = ({
|
|
|
80
54
|
event.preventDefault();
|
|
81
55
|
};
|
|
82
56
|
const Wrapper = typeof MenuInnerWrapper === 'function' ? MenuInnerWrapper : Fragment;
|
|
83
|
-
return /*#__PURE__*/React.createElement(
|
|
84
|
-
|
|
85
|
-
role: "dialog",
|
|
86
|
-
label: "calendar",
|
|
87
|
-
isOpen: true
|
|
88
|
-
// `mode="manual"` opts out of native popover light-dismiss.
|
|
89
|
-
// react-select / DateTimePicker already own outside-click and
|
|
90
|
-
// Esc handling. Without this, the same click that opens the
|
|
91
|
-
// menu (which targets the select input outside the popover)
|
|
92
|
-
// also bubbles to the browser's auto-dismiss handler and
|
|
93
|
-
// immediately closes the popover.
|
|
94
|
-
,
|
|
95
|
-
mode: "manual",
|
|
96
|
-
placement: popupPlacement,
|
|
97
|
-
shouldAnimate: true,
|
|
98
|
-
testId: selectProps.testId && `${selectProps.testId}--popup`
|
|
99
|
-
}, /*#__PURE__*/React.createElement(PopoverSurface, null, /*#__PURE__*/React.createElement("div", _extends({}, innerProps, {
|
|
57
|
+
return /*#__PURE__*/React.createElement("div", _extends({}, innerProps, {
|
|
58
|
+
onMouseDown: onMenuMouseDown,
|
|
100
59
|
role: "presentation",
|
|
101
|
-
|
|
60
|
+
className: ax([styles.root])
|
|
102
61
|
}), /*#__PURE__*/React.createElement(Wrapper, null, /*#__PURE__*/React.createElement(Calendar, {
|
|
103
62
|
day: day,
|
|
104
63
|
month: month,
|
|
@@ -117,5 +76,5 @@ export const MenuTopLayer = ({
|
|
|
117
76
|
locale: selectProps.calendarLocale,
|
|
118
77
|
testId: selectProps.testId && `${selectProps.testId}--calendar`,
|
|
119
78
|
weekStartDay: selectProps.calendarWeekStartDay
|
|
120
|
-
})))
|
|
79
|
+
})));
|
|
121
80
|
};
|
|
@@ -38,7 +38,7 @@ import { MenuTopLayer } from '../internal/menu-top-layer';
|
|
|
38
38
|
import { parseDate } from '../internal/parse-date';
|
|
39
39
|
import { makeSingleValue } from '../internal/single-value';
|
|
40
40
|
var packageName = "@atlaskit/datetime-picker";
|
|
41
|
-
var packageVersion = "18.
|
|
41
|
+
var packageVersion = "18.4.0";
|
|
42
42
|
var styles = {
|
|
43
43
|
pickerContainerStyle: "_kqswh2mm",
|
|
44
44
|
dropdownIndicatorStyles: "_1ul91k8s _1tke1k8s _1e0c1txw _4cvr1h6o _1bah1h6o",
|
|
@@ -65,6 +65,7 @@ var DatePicker = /*#__PURE__*/forwardRef(function (props, _forwardedRef) {
|
|
|
65
65
|
var containerRef = useRef(null);
|
|
66
66
|
var calendarRef = useRef(null);
|
|
67
67
|
var calendarButtonRef = useRef(null);
|
|
68
|
+
var isPointerInteractionRef = useRef(false);
|
|
68
69
|
var _props$appearance = props.appearance,
|
|
69
70
|
appearance = _props$appearance === void 0 ? 'default' : _props$appearance,
|
|
70
71
|
_props$autoFocus = props.autoFocus,
|
|
@@ -190,19 +191,15 @@ var DatePicker = /*#__PURE__*/forwardRef(function (props, _forwardedRef) {
|
|
|
190
191
|
setLocale(propLocale);
|
|
191
192
|
}
|
|
192
193
|
useEffect(function () {
|
|
193
|
-
//
|
|
194
|
+
// Only move focus when the dedicated calendar button opened the menu.
|
|
194
195
|
if (!isKeyDown) {
|
|
195
196
|
return;
|
|
196
197
|
}
|
|
197
198
|
if (isOpen && wasOpenedFromCalendarButton) {
|
|
199
|
+
var _calendarRef$current;
|
|
198
200
|
setIsKeyDown(false);
|
|
199
|
-
//
|
|
200
|
-
|
|
201
|
-
if (!fg('platform-dst-top-layer')) {
|
|
202
|
-
var _calendarRef$current;
|
|
203
|
-
// Focus on the first button within the calendar
|
|
204
|
-
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();
|
|
205
|
-
}
|
|
201
|
+
// Focus on the first button within the calendar
|
|
202
|
+
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();
|
|
206
203
|
}
|
|
207
204
|
}, [isKeyDown, calendarRef, isOpen, wasOpenedFromCalendarButton]);
|
|
208
205
|
var getValue = function getValue() {
|
|
@@ -249,6 +246,7 @@ var DatePicker = /*#__PURE__*/forwardRef(function (props, _forwardedRef) {
|
|
|
249
246
|
var onContainerBlur = function onContainerBlur(event) {
|
|
250
247
|
var _containerRef$current2;
|
|
251
248
|
var newlyFocusedElement = event.relatedTarget;
|
|
249
|
+
isPointerInteractionRef.current = false;
|
|
252
250
|
if (!(containerRef !== null && containerRef !== void 0 && (_containerRef$current2 = containerRef.current) !== null && _containerRef$current2 !== void 0 && _containerRef$current2.contains(newlyFocusedElement))) {
|
|
253
251
|
setIsOpen(false);
|
|
254
252
|
setShouldSetFocusOnCurrentDay(false);
|
|
@@ -279,8 +277,12 @@ var DatePicker = /*#__PURE__*/forwardRef(function (props, _forwardedRef) {
|
|
|
279
277
|
// Don't open menu if focussing after the user has clicked clear
|
|
280
278
|
setClearingFromIcon(false);
|
|
281
279
|
} else {
|
|
282
|
-
//
|
|
283
|
-
|
|
280
|
+
// Opening an auto popover during pointer focus allows the matching pointerup
|
|
281
|
+
// to immediately light-dismiss it. Let the subsequent click open it instead.
|
|
282
|
+
if (!fg('platform-dst-top-layer') || !isPointerInteractionRef.current) {
|
|
283
|
+
// Don't open when focused into via keyboard if the calendar button is present
|
|
284
|
+
setIsOpen(!shouldShowCalendarButton);
|
|
285
|
+
}
|
|
284
286
|
setCalendarValue(value);
|
|
285
287
|
setIsFocused(true);
|
|
286
288
|
setWasOpenedFromCalendarButton(false);
|
|
@@ -316,12 +318,7 @@ var DatePicker = /*#__PURE__*/forwardRef(function (props, _forwardedRef) {
|
|
|
316
318
|
}
|
|
317
319
|
switch (keyPressed) {
|
|
318
320
|
case 'escape':
|
|
319
|
-
// Restore focus
|
|
320
|
-
// the legacy path because it has no built-in restoration, and
|
|
321
|
-
// the top-layer path because the menu uses `mode="manual"` to
|
|
322
|
-
// avoid the auto-popover light-dismiss closing the menu on the
|
|
323
|
-
// same click that opens it (see internal/menu-top-layer.tsx).
|
|
324
|
-
// `manual` mode disables the browser's native focus return.
|
|
321
|
+
// Restore focus because it may have moved from the input into the calendar.
|
|
325
322
|
if (wasOpenedFromCalendarButton) {
|
|
326
323
|
var _calendarButtonRef$cu2;
|
|
327
324
|
(_calendarButtonRef$cu2 = calendarButtonRef.current) === null || _calendarButtonRef$cu2 === void 0 || _calendarButtonRef$cu2.focus();
|
|
@@ -399,6 +396,9 @@ var DatePicker = /*#__PURE__*/forwardRef(function (props, _forwardedRef) {
|
|
|
399
396
|
|
|
400
397
|
// This event handler is triggered from both keydown and click. It's weird.
|
|
401
398
|
var onCalendarButtonClick = function onCalendarButtonClick(e) {
|
|
399
|
+
if (!getIsOpen() && fg('platform-dst-top-layer')) {
|
|
400
|
+
setIsKeyDown(true);
|
|
401
|
+
}
|
|
402
402
|
setIsOpen(function (isOpen) {
|
|
403
403
|
if (isOpen) {
|
|
404
404
|
var _props$selectProps2, _props$selectProps2$o;
|
|
@@ -529,10 +529,19 @@ var DatePicker = /*#__PURE__*/forwardRef(function (props, _forwardedRef) {
|
|
|
529
529
|
return /*#__PURE__*/React.createElement("div", _extends({}, innerProps, {
|
|
530
530
|
"data-testid": testId && "".concat(testId, "--container"),
|
|
531
531
|
onBlur: onContainerBlur,
|
|
532
|
+
onClickCapture: function onClickCapture() {
|
|
533
|
+
isPointerInteractionRef.current = false;
|
|
534
|
+
},
|
|
532
535
|
onFocus: onContainerFocus,
|
|
533
536
|
onClick: onInputClick,
|
|
534
537
|
onInput: onTextInput,
|
|
535
538
|
onKeyDown: onInputKeyDown,
|
|
539
|
+
onPointerCancelCapture: function onPointerCancelCapture() {
|
|
540
|
+
isPointerInteractionRef.current = false;
|
|
541
|
+
},
|
|
542
|
+
onPointerDownCapture: function onPointerDownCapture() {
|
|
543
|
+
isPointerInteractionRef.current = true;
|
|
544
|
+
},
|
|
536
545
|
ref: getContainerRef
|
|
537
546
|
// Since the onclick, onfocus are passed down, adding role="presentation" prevents typecheck errors.
|
|
538
547
|
,
|
|
@@ -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 = "18.
|
|
30
|
+
var packageVersion = "18.4.0";
|
|
31
31
|
var analyticsAttributes = {
|
|
32
32
|
componentName: 'dateTimePicker',
|
|
33
33
|
packageName: packageName,
|
|
@@ -25,7 +25,7 @@ import { convertTokens } from '../internal/parse-tokens';
|
|
|
25
25
|
import { placeholderDatetime } from '../internal/placeholder-date-time';
|
|
26
26
|
import { makeSingleValue } from '../internal/single-value';
|
|
27
27
|
var packageName = "@atlaskit/datetime-picker";
|
|
28
|
-
var packageVersion = "18.
|
|
28
|
+
var packageVersion = "18.4.0";
|
|
29
29
|
var defaultTimeFormat = 'h:mma';
|
|
30
30
|
var menuStyles = {
|
|
31
31
|
/* Need to remove default absolute positioning as that causes issues with position fixed */
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
._2rko1mok{border-radius:var(--ds-radius-large,8px)}._16qs130s{box-shadow:var(--ds-shadow-overlay,0 8px 9pt #1e1f2126,0 0 1px #1e1f214f)}
|
|
2
|
+
._1bsb1ris{width:max-content}
|
|
3
|
+
._1pfhu2gc{margin-block-start:var(--ds-space-100,8px)}
|
|
4
|
+
._6rthu2gc{margin-block-end:var(--ds-space-100,8px)}
|
|
5
|
+
._bfhk1bhr{background-color:var(--ds-surface-overlay,#fff)}
|
|
@@ -1,23 +1,11 @@
|
|
|
1
1
|
/* menu-top-layer.tsx generated by @compiled/babel-plugin v2.0.0 */
|
|
2
2
|
import _extends from "@babel/runtime/helpers/extends";
|
|
3
|
+
import "./menu-top-layer.compiled.css";
|
|
3
4
|
import * as React from 'react';
|
|
4
5
|
import { ax, ix } from "@compiled/react/runtime";
|
|
5
|
-
import { Fragment
|
|
6
|
+
import { Fragment } from 'react';
|
|
6
7
|
import { isValid, parseISO } from 'date-fns';
|
|
7
8
|
import Calendar from '@atlaskit/calendar/calendar';
|
|
8
|
-
import { fromLegacyPlacement } from '@atlaskit/top-layer/placement-map';
|
|
9
|
-
import { Popover } from '@atlaskit/top-layer/popover';
|
|
10
|
-
import { PopoverSurface } from '@atlaskit/top-layer/popover-surface';
|
|
11
|
-
import { useAnchorPosition } from '@atlaskit/top-layer/use-anchor-position';
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Bottom-start placement: calendar appears below and aligned to the
|
|
15
|
-
* start edge of the trigger (the select input).
|
|
16
|
-
*/
|
|
17
|
-
var popupPlacement = fromLegacyPlacement({
|
|
18
|
-
legacy: 'bottom-start'
|
|
19
|
-
});
|
|
20
|
-
|
|
21
9
|
/**
|
|
22
10
|
* @param isos A series of ISO dates.
|
|
23
11
|
* @returns The last valid date within the array of ISO strings.
|
|
@@ -32,19 +20,19 @@ function getValidDate(isos) {
|
|
|
32
20
|
} : acc;
|
|
33
21
|
}, {});
|
|
34
22
|
}
|
|
23
|
+
var styles = {
|
|
24
|
+
root: "_2rko1mok _1bsb1ris _bfhk1bhr _16qs130s _1pfhu2gc _6rthu2gc"
|
|
25
|
+
};
|
|
35
26
|
|
|
36
27
|
/**
|
|
37
28
|
* Top-layer version of the date picker menu.
|
|
38
29
|
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
* CSS Anchor Positioning. This avoids overflow clipping, z-index wars,
|
|
42
|
-
* and portal-based layering.
|
|
30
|
+
* The surrounding react-select menu portal owns the native popover and
|
|
31
|
+
* positioning. This component only supplies the calendar dialog content.
|
|
43
32
|
*
|
|
44
33
|
* Gated behind the `platform-dst-top-layer` feature flag.
|
|
45
34
|
*/
|
|
46
35
|
export var MenuTopLayer = function MenuTopLayer(_ref) {
|
|
47
|
-
var _selectProps$calendar, _selectProps$calendar2;
|
|
48
36
|
var selectProps = _ref.selectProps,
|
|
49
37
|
innerProps = _ref.innerProps;
|
|
50
38
|
var calendarValue = selectProps.calendarValue,
|
|
@@ -54,20 +42,6 @@ export var MenuTopLayer = function MenuTopLayer(_ref) {
|
|
|
54
42
|
day = _getValidDate.day,
|
|
55
43
|
month = _getValidDate.month,
|
|
56
44
|
year = _getValidDate.year;
|
|
57
|
-
|
|
58
|
-
// The select's container element is the anchor for the popup.
|
|
59
|
-
var triggerRef = useRef((_selectProps$calendar = selectProps.calendarContainerRef) !== null && _selectProps$calendar !== void 0 ? _selectProps$calendar : null);
|
|
60
|
-
triggerRef.current = (_selectProps$calendar2 = selectProps.calendarContainerRef) !== null && _selectProps$calendar2 !== void 0 ? _selectProps$calendar2 : null;
|
|
61
|
-
var popoverRef = useRef(null);
|
|
62
|
-
useAnchorPosition({
|
|
63
|
-
anchorRef: triggerRef,
|
|
64
|
-
popoverRef: popoverRef,
|
|
65
|
-
placement: popupPlacement,
|
|
66
|
-
// The Popover is rendered with `isOpen` always true while this
|
|
67
|
-
// component is mounted (react-select conditionally mounts/unmounts
|
|
68
|
-
// the menu), so positioning is always active.
|
|
69
|
-
isOpen: true
|
|
70
|
-
});
|
|
71
45
|
var onMenuMouseDown = function onMenuMouseDown(event) {
|
|
72
46
|
if (event.button !== 0) {
|
|
73
47
|
return;
|
|
@@ -76,25 +50,10 @@ export var MenuTopLayer = function MenuTopLayer(_ref) {
|
|
|
76
50
|
event.preventDefault();
|
|
77
51
|
};
|
|
78
52
|
var Wrapper = typeof MenuInnerWrapper === 'function' ? MenuInnerWrapper : Fragment;
|
|
79
|
-
return /*#__PURE__*/React.createElement(
|
|
80
|
-
|
|
81
|
-
role: "dialog",
|
|
82
|
-
label: "calendar",
|
|
83
|
-
isOpen: true
|
|
84
|
-
// `mode="manual"` opts out of native popover light-dismiss.
|
|
85
|
-
// react-select / DateTimePicker already own outside-click and
|
|
86
|
-
// Esc handling. Without this, the same click that opens the
|
|
87
|
-
// menu (which targets the select input outside the popover)
|
|
88
|
-
// also bubbles to the browser's auto-dismiss handler and
|
|
89
|
-
// immediately closes the popover.
|
|
90
|
-
,
|
|
91
|
-
mode: "manual",
|
|
92
|
-
placement: popupPlacement,
|
|
93
|
-
shouldAnimate: true,
|
|
94
|
-
testId: selectProps.testId && "".concat(selectProps.testId, "--popup")
|
|
95
|
-
}, /*#__PURE__*/React.createElement(PopoverSurface, null, /*#__PURE__*/React.createElement("div", _extends({}, innerProps, {
|
|
53
|
+
return /*#__PURE__*/React.createElement("div", _extends({}, innerProps, {
|
|
54
|
+
onMouseDown: onMenuMouseDown,
|
|
96
55
|
role: "presentation",
|
|
97
|
-
|
|
56
|
+
className: ax([styles.root])
|
|
98
57
|
}), /*#__PURE__*/React.createElement(Wrapper, null, /*#__PURE__*/React.createElement(Calendar, {
|
|
99
58
|
day: day,
|
|
100
59
|
month: month,
|
|
@@ -113,5 +72,5 @@ export var MenuTopLayer = function MenuTopLayer(_ref) {
|
|
|
113
72
|
locale: selectProps.calendarLocale,
|
|
114
73
|
testId: selectProps.testId && "".concat(selectProps.testId, "--calendar"),
|
|
115
74
|
weekStartDay: selectProps.calendarWeekStartDay
|
|
116
|
-
})))
|
|
75
|
+
})));
|
|
117
76
|
};
|
|
@@ -6,10 +6,8 @@ import type { MenuProps, OptionType } from '@atlaskit/select/types';
|
|
|
6
6
|
/**
|
|
7
7
|
* Top-layer version of the date picker menu.
|
|
8
8
|
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
* CSS Anchor Positioning. This avoids overflow clipping, z-index wars,
|
|
12
|
-
* and portal-based layering.
|
|
9
|
+
* The surrounding react-select menu portal owns the native popover and
|
|
10
|
+
* positioning. This component only supplies the calendar dialog content.
|
|
13
11
|
*
|
|
14
12
|
* Gated behind the `platform-dst-top-layer` feature flag.
|
|
15
13
|
*/
|
package/package.json
CHANGED