Skip to content

Instantly share code, notes, and snippets.

@fernandops26
Created May 18, 2023 18:37
Show Gist options
  • Save fernandops26/da681c4b12e52191803b4fcb040cdebb to your computer and use it in GitHub Desktop.
Save fernandops26/da681c4b12e52191803b4fcb040cdebb to your computer and use it in GitHub Desktop.
DatetimePicker example using https://ui.shadcn.com
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>
);
}
@errorstudent
Copy link

Thanks @fernandops26!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment