Created
May 18, 2023 18:37
-
-
Save fernandops26/da681c4b12e52191803b4fcb040cdebb to your computer and use it in GitHub Desktop.
DatetimePicker example using https://ui.shadcn.com
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as React from 'react'; | |
import { DateTime } from 'luxon'; | |
import { Calendar as CalendarIcon } from 'lucide-react'; | |
import { Button } from '@/components/ui/Button'; | |
import { Calendar } from '@/components/ui/Calendar'; | |
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/Popover'; | |
import { cn } from '@/lib/utils'; | |
import { SelectSingleEventHandler } from 'react-day-picker'; | |
import { Label } from '@/components/ui/Label'; | |
import { Input } from '@/components/ui/Input'; | |
interface DateTimePickerProps { | |
date: Date; | |
setDate: (date: Date) => void; | |
} | |
export function DateTimePicker({ date, setDate }: DateTimePickerProps) { | |
const [selectedDateTime, setSelectedDateTime] = React.useState<DateTime>( | |
DateTime.fromJSDate(date) | |
); | |
const handleSelect: SelectSingleEventHandler = (day, selected) => { | |
const selectedDay = DateTime.fromJSDate(selected); | |
const modifiedDay = selectedDay.set({ | |
hour: selectedDateTime.hour, | |
minute: selectedDateTime.minute, | |
}); | |
setSelectedDateTime(modifiedDay); | |
setDate(modifiedDay.toJSDate()); | |
}; | |
const handleTimeChange: React.ChangeEventHandler<HTMLInputElement> = (e) => { | |
const { value } = e.target; | |
const hours = Number.parseInt(value.split(':')[0] || '00', 10); | |
const minutes = Number.parseInt(value.split(':')[1] || '00', 10); | |
const modifiedDay = selectedDateTime.set({ hour: hours, minute: minutes }); | |
setSelectedDateTime(modifiedDay); | |
setDate(modifiedDay.toJSDate()); | |
}; | |
const footer = ( | |
<> | |
<div className="px-4 pt-0 pb-4"> | |
<Label>Time</Label> | |
<Input | |
type="time" | |
onChange={handleTimeChange} | |
value={selectedDateTime.toFormat('HH:mm')} | |
/> | |
</div> | |
{!selectedDateTime && <p>Please pick a day.</p>} | |
</> | |
); | |
return ( | |
<Popover> | |
<PopoverTrigger asChild className="z-10"> | |
<Button | |
variant={'outline'} | |
className={cn( | |
'w-[280px] justify-start text-left font-normal', | |
!date && 'text-muted-foreground' | |
)} | |
> | |
<CalendarIcon className="mr-2 h-4 w-4" /> | |
{date ? ( | |
selectedDateTime.toFormat('DDD HH:mm') | |
) : ( | |
<span>Pick a date</span> | |
)} | |
</Button> | |
</PopoverTrigger> | |
<PopoverContent className="w-auto p-0"> | |
<Calendar | |
mode="single" | |
selected={selectedDateTime.toJSDate()} | |
onSelect={handleSelect} | |
initialFocus | |
/> | |
{footer} | |
</PopoverContent> | |
</Popover> | |
); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thanks @fernandops26!