- 캘린더 ui 구현 중
This commit is contained in:
@@ -10,6 +10,7 @@ import { DayButton, DayPicker, getDefaultClassNames } from "react-day-picker"
|
|||||||
|
|
||||||
import { cn } from "@/lib/utils"
|
import { cn } from "@/lib/utils"
|
||||||
import { Button, buttonVariants } from "@/components/ui/button"
|
import { Button, buttonVariants } from "@/components/ui/button"
|
||||||
|
import { format } from "date-fns"
|
||||||
|
|
||||||
function Calendar({
|
function Calendar({
|
||||||
className,
|
className,
|
||||||
@@ -36,8 +37,28 @@ function Calendar({
|
|||||||
)}
|
)}
|
||||||
captionLayout={captionLayout}
|
captionLayout={captionLayout}
|
||||||
formatters={{
|
formatters={{
|
||||||
|
formatCaption: (month) => format(month, "yyyy년 MM월"),
|
||||||
|
formatWeekdayName: (weekday) => {
|
||||||
|
switch(weekday.getDay()) {
|
||||||
|
case 0:
|
||||||
|
return '일';
|
||||||
|
case 1:
|
||||||
|
return '월';
|
||||||
|
case 2:
|
||||||
|
return '화';
|
||||||
|
case 3:
|
||||||
|
return '수';
|
||||||
|
case 4:
|
||||||
|
return '목';
|
||||||
|
case 5:
|
||||||
|
return '금';
|
||||||
|
case 6:
|
||||||
|
return '토';
|
||||||
|
}
|
||||||
|
return '';
|
||||||
|
},
|
||||||
formatMonthDropdown: (date) =>
|
formatMonthDropdown: (date) =>
|
||||||
date.toLocaleString("default", { month: "short" }),
|
date.toLocaleString("", { month: "short" }),
|
||||||
...formatters,
|
...formatters,
|
||||||
}}
|
}}
|
||||||
classNames={{
|
classNames={{
|
||||||
|
|||||||
@@ -134,6 +134,10 @@ input[type="number"]::-webkit-outer-spin-button {
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.rdp-day {
|
||||||
|
aspect-ratio: unset;
|
||||||
|
}
|
||||||
|
|
||||||
/* Firefox */
|
/* Firefox */
|
||||||
input[type="number"] {
|
input[type="number"] {
|
||||||
-moz-appearance: textfield;
|
-moz-appearance: textfield;
|
||||||
|
|||||||
101
src/ui/component/calendar/CustomCalendar.tsx
Normal file
101
src/ui/component/calendar/CustomCalendar.tsx
Normal file
@@ -0,0 +1,101 @@
|
|||||||
|
import { cn } from "@/lib/utils";
|
||||||
|
import { Calendar } from "@/components/ui/calendar";
|
||||||
|
import { useLayoutEffect, useRef, useState } from "react";
|
||||||
|
import { dateMatchModifiers, getDefaultClassNames } from "react-day-picker";
|
||||||
|
|
||||||
|
interface CustomCalendarProps {
|
||||||
|
data?: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const CustomCalendar = ({ data }: CustomCalendarProps) => {
|
||||||
|
const [weekCount, setWeekCount] = useState(5);
|
||||||
|
const defaultClassNames = getDefaultClassNames();
|
||||||
|
const containerRef = useRef<HTMLDivElement>(null);
|
||||||
|
const updateWeekCount = () => {
|
||||||
|
if (containerRef === null) return;
|
||||||
|
if (!containerRef.current) return;
|
||||||
|
|
||||||
|
const weeks = containerRef.current.querySelectorAll('.rdp-week');
|
||||||
|
|
||||||
|
if (weeks?.length) setWeekCount(weeks.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
useLayoutEffect(() => {
|
||||||
|
updateWeekCount();
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="w-full h-full"
|
||||||
|
ref={containerRef}
|
||||||
|
>
|
||||||
|
<Calendar
|
||||||
|
mode="single"
|
||||||
|
className="h-full w-full border rounded-lg"
|
||||||
|
onMonthChange={() => {
|
||||||
|
// month 바뀐 직후 DOM 변화가 생기므로 다음 프레임에서 계산
|
||||||
|
requestAnimationFrame(() => {
|
||||||
|
updateWeekCount();
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
labels={{
|
||||||
|
labelDayButton: (date, modifiers) => {
|
||||||
|
console.log(modifiers);
|
||||||
|
return `${date.getDate()}`
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
classNames={{
|
||||||
|
months: cn(
|
||||||
|
defaultClassNames.months,
|
||||||
|
"w-full h-full relative"
|
||||||
|
),
|
||||||
|
nav: cn(
|
||||||
|
defaultClassNames.nav,
|
||||||
|
"flex w-full item-center gap-1 justify-around absolute top-0 inset-x-0"
|
||||||
|
),
|
||||||
|
month: cn(
|
||||||
|
defaultClassNames.month,
|
||||||
|
"h-full w-full flex flex-col"
|
||||||
|
),
|
||||||
|
month_grid: cn(
|
||||||
|
defaultClassNames.month_grid,
|
||||||
|
"w-full h-full flex-1"
|
||||||
|
),
|
||||||
|
weeks: cn(
|
||||||
|
defaultClassNames.weeks,
|
||||||
|
"w-full h-full"
|
||||||
|
),
|
||||||
|
weekdays: cn(
|
||||||
|
defaultClassNames.weekdays,
|
||||||
|
"w-full"
|
||||||
|
),
|
||||||
|
week: cn(
|
||||||
|
defaultClassNames.week,
|
||||||
|
`w-full`
|
||||||
|
),
|
||||||
|
day: cn(
|
||||||
|
defaultClassNames.day,
|
||||||
|
`w-[calc(100%/7)]`
|
||||||
|
),
|
||||||
|
day_button: cn(
|
||||||
|
defaultClassNames.day_button,
|
||||||
|
"h-full w-full flex p-2 justify-start items-start"
|
||||||
|
),
|
||||||
|
selected: cn(
|
||||||
|
defaultClassNames.selected,
|
||||||
|
"h-full"
|
||||||
|
),
|
||||||
|
today: cn(
|
||||||
|
defaultClassNames.today,
|
||||||
|
"h-full"
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
styles={{
|
||||||
|
day: {
|
||||||
|
height: `calc(100%/${weekCount})`
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,23 +1,11 @@
|
|||||||
import { Calendar } from "@/components/ui/calendar";
|
import { CustomCalendar } from "@/ui/component/calendar/CustomCalendar";
|
||||||
import { cn } from "@/lib/utils";
|
|
||||||
import { getDefaultClassNames } from "react-day-picker";
|
|
||||||
|
|
||||||
export function ScheduleMainPage() {
|
export function ScheduleMainPage() {
|
||||||
const defaultClassNames = getDefaultClassNames();
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="w-full h-full p-2">
|
<div
|
||||||
<Calendar
|
className="w-full h-full p-2"
|
||||||
mode="single"
|
>
|
||||||
className="border w-full rounded-lg"
|
<CustomCalendar />
|
||||||
classNames={{
|
|
||||||
month_grid: cn(
|
|
||||||
defaultClassNames.month_grid,
|
|
||||||
"w-full"
|
|
||||||
),
|
|
||||||
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user