Skip to content

Commit 6175356

Browse files
authored
fix(RelativeRangeDatePicker): correctly close popup on click outside (#71)
1 parent 4743ed3 commit 6175356

File tree

3 files changed

+24
-4
lines changed

3 files changed

+24
-4
lines changed

.eslintrc.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,12 @@
2525
"@typescript-eslint/consistent-type-imports": [
2626
"error",
2727
{"prefer": "type-imports", "fixStyle": "separate-type-imports"}
28+
],
29+
"jsx-a11y/no-autofocus": [
30+
"error",
31+
{
32+
"ignoreNonDOM": true
33+
}
2834
]
2935
},
3036
"overrides": [

src/components/RelativeRangeDatePicker/RelativeRangeDatePicker.tsx

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {block} from '../../utils/cn';
99
import type {Value} from '../RelativeDatePicker';
1010
import type {
1111
DomProps,
12+
FocusableProps,
1213
InputBase,
1314
RangeValue,
1415
StyleProps,
@@ -35,6 +36,7 @@ export interface RelativeRangeDatePickerProps
3536
InputBase,
3637
TextInputProps,
3738
Validation,
39+
FocusableProps,
3840
StyleProps {
3941
/** Format of the date when rendered in the input. [Available formats](https://day.js.org/docs/en/display/format) */
4042
format?: string;
@@ -70,16 +72,26 @@ export function RelativeRangeDatePicker(props: RelativeRangeDatePickerProps) {
7072
const [open, setOpen] = React.useState(false);
7173

7274
const {focusWithinProps} = useFocusWithin({
73-
isDisabled: props.disabled || isMobile,
74-
onFocusWithinChange: (isFocusedWithin) => {
75-
if (!isFocusedWithin) {
75+
isDisabled: props.disabled,
76+
onFocusWithin: (e) => {
77+
if (!isActive) {
78+
props.onFocus?.(e);
79+
}
80+
},
81+
onBlurWithin: (e) => {
82+
// when the popup is open and an user clicks outside, focus will be returned to the input
83+
const seemsIsClickOutsideInEmptySpace =
84+
open &&
85+
(document.activeElement === null || document.activeElement === document.body);
86+
if (!seemsIsClickOutsideInEmptySpace) {
7687
setIsActive(false);
88+
props.onBlur?.(e);
7789
}
7890
},
7991
});
8092

8193
const {alwaysShowAsAbsolute, presetTabs, getRangeTitle} = props;
82-
const format = props.format ?? 'L';
94+
const format = props.format || 'L';
8395
const text = React.useMemo(
8496
() =>
8597
typeof getRangeTitle === 'function'
@@ -116,6 +128,7 @@ export function RelativeRangeDatePicker(props: RelativeRangeDatePickerProps) {
116128
}
117129
>
118130
<TextInput
131+
autoFocus={props.autoFocus}
119132
controlRef={inputRef}
120133
value={text}
121134
placeholder={props.placeholder}

src/components/RelativeRangeDatePicker/components/PickerDialog/PickerDialog.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ export function PickerDialog({
5454
role="dialog"
5555
anchorRef={anchorRef}
5656
contentClassName={b('content', {size: props.size}, className)}
57+
autoFocus
5758
focusTrap
5859
restoreFocus
5960
>

0 commit comments

Comments
 (0)