Skip to content

Instantly share code, notes, and snippets.

@abdasis
Created July 5, 2024 12:41
Show Gist options
  • Save abdasis/4a37785cbf63a398defae1252d29bd87 to your computer and use it in GitHub Desktop.
Save abdasis/4a37785cbf63a398defae1252d29bd87 to your computer and use it in GitHub Desktop.
Form input untuk handle tanggal
import React, { forwardRef, useState } from 'react';
import { format } from 'date-fns';
import { cn } from '@/lib/utils';
import { Button } from '@/components/ui/button';
import { Calendar } from '@/components/ui/calendar';
import { CalendarIcon } from '@radix-ui/react-icons';
import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import moment from 'moment/moment';
import { useNavigation } from 'react-day-picker';
import { id } from 'date-fns/locale/id';
import { IconChevronLeft, IconChevronRight } from '@tabler/icons-react';
const months = [...Array(12)].map((_, index) => {
const month_number = index.toString();
const month_name = new Intl.DateTimeFormat('id-ID', { month: 'long' }).format(new Date(2022, index));
return { month_number, month_name };
});
const MONTHS = [...Array(12)].map((_, index) => {
const month_name = new Intl.DateTimeFormat('id-ID', { month: 'long' }).format(new Date(2022, index));
return month_name;
});
const CustomCaption = () => {
const { goToMonth, nextMonth, previousMonth, goToDate, isDateDisplayed } = useNavigation();
const currentYear = new Date().getFullYear();
const currentMonth = new Date().getMonth();
const startYear = 1947; // Anda dapat mengganti tahun awal sesuai kebutuhan
const [month, setMonth] = useState('');
const [yearSelected, setYearSelected] = useState<string>('');
const [monthSelected, setMonthSelected] = useState<string>('');
return (
<div className={'flex py-1 justify-between items-center border-slate-100'}>
<Button size={'sm'} variant={'outline'} className={'px-2 shadow-none border-none'}>
<IconChevronLeft size={16} />
</Button>
<div className="dropdown-wrapper flex">
<div className="option-year flex items-center gap-2">
<Select
value={yearSelected}
onValueChange={value => {
goToDate(new Date(parseInt(value), 0, 1));
setYearSelected(value);
}}
>
<SelectTrigger
className={
'w-[80px] hover:bg-slate-50 focus-visible:bg-slate-50 focus:bg-slate-100 h-7 text-center border-0 shadow-none focus:ring-0 '
}
>
<SelectValue placeholder={new Date().getFullYear()} />
</SelectTrigger>
<SelectContent position="popper">
{Array.from(
{ length: new Date().getFullYear() - 1945 + 1 },
(_, i) => new Date().getFullYear() - i
).map(year => (
<SelectItem className={'cursor-pointer'} key={year} value={year.toString()}>
{year}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
<div className="option-month">
<Select
value={monthSelected || currentMonth.toString()}
onValueChange={value => {
goToDate(new Date(parseInt(yearSelected) || currentYear, parseInt(value), 1));
setMonthSelected(value);
}}
>
<SelectTrigger
className={
'w-[100px] hover:bg-slate-50 focus-visible:bg-slate-50 focus:bg-slate-100 h-7 text-center border-0 shadow-none focus:ring-0'
}
>
<SelectValue placeholder={monthSelected || currentMonth} />
</SelectTrigger>
<SelectContent>
{[...Array(12)].map((_, index) => {
const month_number = index.toString();
const month_name = new Intl.DateTimeFormat('id-ID', { month: 'long' }).format(
new Date(2022, index)
);
return (
<SelectItem key={month_name} value={month_number}>
{month_name}
</SelectItem>
);
})}
</SelectContent>
</Select>
</div>
</div>
<Button size={'sm'} variant={'outline'} className={'px-2 shadow-none border-none'}>
<IconChevronRight size={16} />
</Button>
</div>
);
};
const DateInput = forwardRef<HTMLInputElement, React.InputHTMLAttributes<HTMLInputElement>>(function DateInput() {
const [date, setDate] = React.useState<Date>();
const [year, setYear] = useState<string | undefined>(moment().format('YYYY'));
const [open, setOpen] = useState(false);
return (
<div className={'grid w-full gap-1.5'}>
<Popover open={open} onOpenChange={setOpen}>
<PopoverTrigger asChild>
<Button
variant={'outline'}
className={cn('w-[315px] justify-between text-left font-normal', !date && 'text-muted-foreground')}
>
{date ? format(date, 'dd, LLLL yyyy') : <span>Pilih Tanggal</span>}
<CalendarIcon className="mr-2 h-4 w-4" />
</Button>
</PopoverTrigger>
<PopoverContent className="w-auto p-4">
<Calendar
className={'p-0 w-auto'}
mode="single"
selected={date}
onSelect={e => {
setDate(e);
setOpen(!open);
}}
initialFocus
components={{
Caption: CustomCaption,
}}
locale={id}
styles={{
head_cell: {
width: '40px',
},
cell: {
width: '40px',
},
}}
showOutsideDays
/>
</PopoverContent>
</Popover>
</div>
);
});
export default DateInput;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment