-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: update components and add comments (back) to make Martin happy
- Loading branch information
1 parent
433de7d
commit 2fee9e2
Showing
14 changed files
with
494 additions
and
100 deletions.
There are no files selected for viewing
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
'use client'; | ||
|
||
import { isValid, parse } from 'date-fns'; | ||
import { CalendarIcon } from 'lucide-react'; | ||
import { useTranslations } from 'next-intl'; | ||
import { useFormatter } from 'next-intl'; | ||
import * as React from 'react'; | ||
import type { DayPickerProps } from 'react-day-picker'; | ||
|
||
import { cx } from '@/lib/utils'; | ||
|
||
import { Button } from '@/components/ui/Button'; | ||
import { Calendar } from '@/components/ui/Calendar'; | ||
import { Input } from '@/components/ui/Input'; | ||
import { | ||
Popover, | ||
PopoverContent, | ||
PopoverTrigger, | ||
} from '@/components/ui/Popover'; | ||
|
||
type DatePickerProps = { | ||
className?: string; | ||
side?: 'top' | 'bottom' | 'left' | 'right'; | ||
avoidCollisions?: boolean; | ||
date: Date | undefined; | ||
setDate: (date: Date | undefined) => void; | ||
id: string; | ||
} & Omit<DayPickerProps, 'selected' | 'onSelect' | 'autoFocus' | 'mode'>; | ||
|
||
/** | ||
* This is a sligtly modified version of shadcn's Date Picker built on top of Calendar. | ||
* The component has a state, but also allows adding an additional date callback function which | ||
* provides a way to have side effects and/or state updates on the parent component whenever a new date is selected. | ||
* UPDATE: Now supports an input field so it actually works as a date picker in a form. State is passed to it via props | ||
* so it works in a form. Also included i18n support. | ||
*/ | ||
function DatePicker({ | ||
className, | ||
side, | ||
avoidCollisions = true, | ||
date, | ||
setDate, | ||
id, | ||
...props | ||
}: DatePickerProps) { | ||
const t = useTranslations('ui'); | ||
const format = useFormatter(); | ||
const [open, setOpen] = React.useState(false); | ||
const [month, setMonth] = React.useState(date); | ||
const [inputValue, setInputValue] = React.useState(''); | ||
|
||
function handleSelectDate(date: Date | undefined) { | ||
if (!date) { | ||
setInputValue(''); | ||
setDate(undefined); | ||
} else { | ||
setDate(date); | ||
setMonth(date); | ||
setInputValue( | ||
format.dateTime(date, { | ||
day: 'numeric', | ||
month: 'numeric', | ||
year: 'numeric', | ||
}), | ||
); | ||
} | ||
} | ||
|
||
function handleInputChange(e: React.ChangeEvent<HTMLInputElement>) { | ||
setInputValue(e.target.value); | ||
const parsedDate = parse(e.target.value, t('dateFormat'), new Date()); | ||
|
||
if (isValid(parsedDate)) { | ||
setMonth(parsedDate); | ||
} | ||
setDate(parsedDate); | ||
} | ||
|
||
return ( | ||
<Popover open={open} onOpenChange={setOpen}> | ||
<div className='relative'> | ||
<Input | ||
className={className} | ||
id={id} | ||
placeholder={t('dateFormat')} | ||
value={inputValue} | ||
onChange={handleInputChange} | ||
/> | ||
<PopoverTrigger asChild> | ||
<Button | ||
aria-label={t('pickDate')} | ||
variant={'secondary'} | ||
className={cx( | ||
'-translate-y-1/2 absolute top-1/2 right-1.5 h-7 rounded-sm border px-2 font-normal', | ||
!date && 'text-muted-foreground', | ||
)} | ||
> | ||
<CalendarIcon className='h-4 w-4' /> | ||
</Button> | ||
</PopoverTrigger> | ||
</div> | ||
<PopoverContent | ||
className='w-auto p-0' | ||
side={side} | ||
avoidCollisions={avoidCollisions} | ||
> | ||
<Calendar | ||
mode='single' | ||
month={month} | ||
onMonthChange={setMonth} | ||
selected={date} | ||
onSelect={handleSelectDate} | ||
autoFocus | ||
{...props} | ||
/> | ||
</PopoverContent> | ||
</Popover> | ||
); | ||
} | ||
|
||
export { DatePicker }; |
Oops, something went wrong.