diff --git a/apps/web/src/assets/svgs/calendar/ic_next_chevron.svg b/apps/web/src/assets/svgs/calendar/ic_next_chevron.svg index 64f89a86..f3a22033 100644 --- a/apps/web/src/assets/svgs/calendar/ic_next_chevron.svg +++ b/apps/web/src/assets/svgs/calendar/ic_next_chevron.svg @@ -1,3 +1,3 @@ - + diff --git a/apps/web/src/assets/svgs/calendar/ic_prev_chevron.svg b/apps/web/src/assets/svgs/calendar/ic_prev_chevron.svg index 4f8b4ee7..c26bcb62 100644 --- a/apps/web/src/assets/svgs/calendar/ic_prev_chevron.svg +++ b/apps/web/src/assets/svgs/calendar/ic_prev_chevron.svg @@ -1,3 +1,3 @@ - + diff --git a/apps/web/src/component/common/dateTimePicker/Calendar.tsx b/apps/web/src/component/common/dateTimePicker/Calendar.tsx index 657a7c09..13186cfc 100644 --- a/apps/web/src/component/common/dateTimePicker/Calendar.tsx +++ b/apps/web/src/component/common/dateTimePicker/Calendar.tsx @@ -2,6 +2,7 @@ import ReactCalendar from "react-calendar"; import type { CalendarProps as ReactCalendarProps } from "react-calendar"; import { Icon } from "@/component/common/Icon"; +import { DESIGN_TOKEN_COLOR } from "@/style/designTokens"; type CalendarProps = ReactCalendarProps; @@ -10,8 +11,8 @@ export function Calendar({ ...props }: CalendarProps) { new Intl.DateTimeFormat("en", { day: "numeric" }).format(date)} - prevLabel={} - nextLabel={} + prevLabel={} + nextLabel={} {...props} /> ); diff --git a/apps/web/src/component/common/dateTimePicker/TimePicker.tsx b/apps/web/src/component/common/dateTimePicker/TimePicker.tsx index f004632e..82f40a45 100644 --- a/apps/web/src/component/common/dateTimePicker/TimePicker.tsx +++ b/apps/web/src/component/common/dateTimePicker/TimePicker.tsx @@ -1,5 +1,5 @@ import { css } from "@emotion/react"; -import { forwardRef } from "react"; +import { forwardRef, useEffect, useRef } from "react"; import { TIME_24 } from "@/component/common/dateTimePicker/time.const"; import { Radio, RadioButtonGroup } from "@/component/common/radioButton"; @@ -12,33 +12,93 @@ type TimePickerProps = { }; export const TimePicker = forwardRef(function ({ radioControl }, ref) { const { curTab, tabs, selectTab } = useTabs(["오전", "오후"] as const); + const radioButtonsContainerRef = useRef(null); + + const pmFirstItemRef = useRef(null); + const amFirstItemRef = useRef(null); + + /** + * 탭을 클릭해 scrollIntoView가 작동 중인지에 대한 상태 + */ + const isScrollingIntoView = useRef(false); + + useEffect(() => { + const checkPmInView = () => { + if (isScrollingIntoView.current) { + return; + } + + const pmFirstClientRect = pmFirstItemRef.current?.getBoundingClientRect(); + if (pmFirstClientRect && pmFirstClientRect.x < 200) { + selectTab("오후"); + } else { + selectTab("오전"); + } + }; + + const containerRef = radioButtonsContainerRef.current; + containerRef?.addEventListener("scroll", checkPmInView); + + return () => { + containerRef?.removeEventListener("scroll", checkPmInView); + }; + }, [selectTab]); + return (
- - - {curTab === "오전" && - TIME_24.slice(0, 12).map((time, index) => { + { + selectTab(tab); + isScrollingIntoView.current = true; + + if (tab === "오후") { + pmFirstItemRef.current?.scrollIntoView({ behavior: "smooth", inline: "start" }); + } + if (tab === "오전") { + amFirstItemRef.current?.scrollIntoView({ behavior: "smooth", inline: "start" }); + } + + setTimeout(() => { + isScrollingIntoView.current = false; + }, 1000); + }} + /> +
+ + {TIME_24.slice(0, 13).map((time, index) => { return ( - - {time} + + {time} ); })} - {curTab === "오후" && - TIME_24.slice(12).map((time, index) => { + {TIME_24.slice(13).map((time, index) => { return ( - - {`${Number(time.split(":")[0]) - 12}:00`} + + {time} ); })} - + +
); }); diff --git a/apps/web/src/component/common/dateTimePicker/time.const.ts b/apps/web/src/component/common/dateTimePicker/time.const.ts index 7a4c25a1..fe92cc00 100644 --- a/apps/web/src/component/common/dateTimePicker/time.const.ts +++ b/apps/web/src/component/common/dateTimePicker/time.const.ts @@ -1 +1 @@ -export const TIME_24 = Array.from({ length: 24 }, (_, i) => `${i + 1}:00`); +export const TIME_24 = Array.from({ length: 25 }, (_, i) => `${i === 0 ? "00" : i}:00`); diff --git a/apps/web/src/component/common/radioButton/Radio.tsx b/apps/web/src/component/common/radioButton/Radio.tsx index bd22d8d8..3a246918 100644 --- a/apps/web/src/component/common/radioButton/Radio.tsx +++ b/apps/web/src/component/common/radioButton/Radio.tsx @@ -1,5 +1,5 @@ import { css } from "@emotion/react"; -import { useContext } from "react"; +import { forwardRef, useContext } from "react"; import { RadioContext } from "./RadioButtonGroup"; @@ -11,10 +11,11 @@ type RadioProps = { children: React.ReactNode; } & Omit, "checked">; -export function Radio({ value, children, ...props }: RadioProps) { +export const Radio = forwardRef(function ({ value, children, ...props }, ref) { const radioContext = useContext(RadioContext); return ( ); -} +}); + +Radio.displayName = "Radio";