| import { useEffect, useId, useRef, useState } from "react"; |
|
|
| import { format, isValid, parse } from "date-fns"; |
|
|
| import { DayPicker } from "./react-day-picker-v8"; |
|
|
| export function Dialog() { |
| const dialogRef = useRef<HTMLDialogElement>(null); |
| const dialogId = useId(); |
| const headerId = useId(); |
|
|
| |
| const [month, setMonth] = useState(new Date()); |
|
|
| |
| const [selectedDate, setSelectedDate] = useState<Date | undefined>(undefined); |
|
|
| |
| const [inputValue, setInputValue] = useState(""); |
|
|
| |
| const [isDialogOpen, setIsDialogOpen] = useState(false); |
|
|
| |
| const toggleDialog = () => setIsDialogOpen(!isDialogOpen); |
|
|
| |
| useEffect(() => { |
| const handleBodyScroll = (isOpen: boolean) => { |
| document.body.style.overflow = isOpen ? "hidden" : ""; |
| }; |
| if (!dialogRef.current) return; |
| if (isDialogOpen) { |
| handleBodyScroll(true); |
| dialogRef.current.showModal(); |
| } else { |
| handleBodyScroll(false); |
| dialogRef.current.close(); |
| } |
| return () => { |
| handleBodyScroll(false); |
| }; |
| }, [isDialogOpen]); |
|
|
| |
| |
| |
| |
| const handleDayPickerSelect = (date: Date | undefined) => { |
| if (!date) { |
| setInputValue(""); |
| setSelectedDate(undefined); |
| } else { |
| setSelectedDate(date); |
| setInputValue(format(date, "MM/dd/yyyy")); |
| } |
| dialogRef.current?.close(); |
| }; |
| |
| |
| |
| |
| const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => { |
| setInputValue(e.target.value); |
|
|
| const parsedDate = parse(e.target.value, "MM/dd/yyyy", new Date()); |
|
|
| if (isValid(parsedDate)) { |
| setSelectedDate(parsedDate); |
| setMonth(parsedDate); |
| } else { |
| setSelectedDate(undefined); |
| } |
| }; |
|
|
| return ( |
| <div> |
| <label htmlFor="date-input"> |
| <strong>Pick a Date: </strong> |
| </label> |
| <input |
| style={{ fontSize: "inherit" }} |
| id="date-input" |
| type="text" |
| value={inputValue} |
| placeholder={"MM/dd/yyyy"} |
| onChange={handleInputChange} |
| />{" "} |
| <button |
| style={{ fontSize: "inherit" }} |
| onClick={toggleDialog} |
| aria-controls="dialog" |
| aria-haspopup="dialog" |
| aria-expanded={isDialogOpen} |
| aria-label="Open calendar to choose booking date" |
| > |
| 📆 |
| </button> |
| <p aria-live="assertive" aria-atomic="true"> |
| {selectedDate !== undefined |
| ? selectedDate.toDateString() |
| : "Please type or pick a date"} |
| </p> |
| <dialog |
| role="dialog" |
| ref={dialogRef} |
| id={dialogId} |
| aria-modal |
| aria-labelledby={headerId} |
| onClose={() => setIsDialogOpen(false)} |
| > |
| <DayPicker |
| month={month} |
| onMonthChange={setMonth} |
| initialFocus |
| mode="single" |
| selected={selectedDate} |
| onSelect={handleDayPickerSelect} |
| footer={ |
| <p aria-live="assertive" aria-atomic="true"> |
| {selectedDate !== undefined && ( |
| <>Selected: {selectedDate.toDateString()}</> |
| )} |
| </p> |
| } |
| /> |
| </dialog> |
| </div> |
| ); |
| } |
|
|