'How to keep activation when click the button if modal is already opened with `focus-trap`
I'm using react-day-picker(v8) with input field.
Official CodeSandbox example uses focus-trap-react to keep focus and control activation of modal.
This example is mostly useful, but in this code, if I click the button,
- When mousedown, day-picker modal closes.
- When mouseup, day-picker modal opens.
I don't need No.1 behavior when the modal is already opened.
import React, { ChangeEventHandler, useRef, useState } from 'react';
import { format, isValid, parse } from 'date-fns';
import FocusTrap from 'focus-trap-react';
import { DayPicker } from 'react-day-picker';
import { usePopper } from 'react-popper';
export default function Example() {
const [selected, setSelected] = useState<Date>();
const [inputValue, setInputValue] = useState<string>('');
const [isPopperOpen, setIsPopperOpen] = useState(false);
const popperRef = useRef<HTMLDivElement>(null);
const buttonRef = useRef<HTMLButtonElement>(null);
const [popperElement, setPopperElement] = useState<HTMLDivElement | null>(
null
);
const popper = usePopper(popperRef.current, popperElement, {
placement: 'bottom-start'
});
const closePopper = () => {
setIsPopperOpen(false);
buttonRef?.current?.focus();
};
const handleInputChange: ChangeEventHandler<HTMLInputElement> = (e) => {
const { value } = e.currentTarget;
setInputValue(value);
const date = parse(value, 'y-MM-dd', new Date());
if (isValid(date)) {
setSelected(date);
} else {
setSelected(undefined);
}
};
const handleButtonClick = () => {
setIsPopperOpen(true);
};
const handleDaySelect = (date: Date) => {
setSelected(date);
if (date) {
setInputValue(format(date, 'y-MM-dd'));
closePopper();
} else {
setInputValue('');
}
};
return (
<div>
<div ref={popperRef}>
<input
type="text"
placeholder={format(new Date(), 'y-MM-dd')}
value={inputValue}
onChange={handleInputChange}
className="input-reset pa2 ma2 bg-white black ba"
/>
<button
ref={buttonRef}
type="button"
className="pa2 bg-white button-reset ba"
aria-label="Pick a date"
onClick={handleButtonClick}
>
<span role="img" aria-label="calendar icon">
📅
</span>
</button>
</div>
{isPopperOpen && (
<FocusTrap
active
focusTrapOptions={{
initialFocus: false,
allowOutsideClick: true,
clickOutsideDeactivates: true,
onDeactivate: closePopper
}}
>
<div
tabIndex={-1}
style={popper.styles.popper}
className="dialog-sheet"
{...popper.attributes.popper}
ref={setPopperElement}
role="dialog"
>
<DayPicker
initialFocus={isPopperOpen}
mode="single"
defaultMonth={selected}
selected={selected}
onSelect={handleDaySelect}
/>
</div>
</FocusTrap>
)}
</div>
);
}
How can I resolve this?
Thank you.
This is a documentation of Date Picker Dialog from react-day-picker.
https://react-day-picker.js.org/guides/date-picker-dialog
And also this is the Official CodeSandbox.
https://codesandbox.io/s/9489pv?file=/App.tsx&from-sandpack=true
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
