diff --git a/.jules/palette.md b/.jules/palette.md new file mode 100644 index 00000000..978e92ac --- /dev/null +++ b/.jules/palette.md @@ -0,0 +1,3 @@ +## 2024-07-12 - DateRangePicker 토글 버튼의 키보드 접근성 및 상태 인지 개선 +**Learning:** 여러 선택지 중 하나를 고르는 토글 형태의 버튼 그룹(예: 기간 선택 프리셋)에서는 시각적인 스타일(색상) 변화만으로 상태를 나타내면 스크린 리더 등 보조 기기 사용자가 현재 선택된 값을 인지하기 어렵습니다. 또한 키보드 네비게이션 시 포커스 링(`focus-visible` 클래스)이 빠져 있으면 사용자가 어떤 버튼에 위치해 있는지 시각적으로 확인하기 어렵습니다. +**Action:** 토글 형태의 버튼이나 탭에는 반드시 `aria-pressed={isActive}` 속성을 추가하여 상태를 명확히 전달하고, Tailwind CSS를 사용할 때는 `focus-visible:outline-none focus-visible:ring-2`와 같은 키보드 포커스 스타일을 반드시 포함하여 키보드 접근성을 확보해야 합니다. \ No newline at end of file diff --git a/packages/web/src/components/dashboard/date-range-picker.tsx b/packages/web/src/components/dashboard/date-range-picker.tsx index aef2f7be..e9780693 100644 --- a/packages/web/src/components/dashboard/date-range-picker.tsx +++ b/packages/web/src/components/dashboard/date-range-picker.tsx @@ -1,35 +1,35 @@ -'use client' +"use client"; -import { useSearchParams, useRouter } from 'next/navigation' -import { subDays, format, differenceInDays } from 'date-fns' -import { Suspense } from 'react' -import { cn } from '@/lib/utils' +import { useSearchParams, useRouter } from "next/navigation"; +import { subDays, format, differenceInDays } from "date-fns"; +import { Suspense } from "react"; +import { cn } from "@/lib/utils"; const PRESETS = [ - { days: 7, label: '7d' }, - { days: 30, label: '30d' }, - { days: 90, label: '90d' }, - { days: 3650, label: 'ALL' }, -] as const + { days: 7, label: "7d" }, + { days: 30, label: "30d" }, + { days: 90, label: "90d" }, + { days: 3650, label: "ALL" }, +] as const; function DateRangePickerContent() { - const router = useRouter() - const searchParams = useSearchParams() + const router = useRouter(); + const searchParams = useSearchParams(); - const currentFrom = searchParams.get('from') - const currentTo = searchParams.get('to') + const currentFrom = searchParams.get("from"); + const currentTo = searchParams.get("to"); - const today = new Date() - const sevenDaysAgo = subDays(today, 7) + const today = new Date(); + const sevenDaysAgo = subDays(today, 7); - const defaultFrom = currentFrom || format(sevenDaysAgo, 'yyyy-MM-dd') - const defaultTo = currentTo || format(today, 'yyyy-MM-dd') + const defaultFrom = currentFrom || format(sevenDaysAgo, "yyyy-MM-dd"); + const defaultTo = currentTo || format(today, "yyyy-MM-dd"); - const fromDate = new Date(defaultFrom) - const toDate = new Date(defaultTo) - const daysDiff = differenceInDays(toDate, fromDate) + const fromDate = new Date(defaultFrom); + const toDate = new Date(defaultTo); + const daysDiff = differenceInDays(toDate, fromDate); - const isToday = format(toDate, 'yyyy-MM-dd') === format(today, 'yyyy-MM-dd') + const isToday = format(toDate, "yyyy-MM-dd") === format(today, "yyyy-MM-dd"); const activePreset = isToday ? daysDiff === 6 ? 7 @@ -40,20 +40,20 @@ function DateRangePickerContent() { : daysDiff >= 3649 ? 3650 : null - : null + : null; const handlePreset = (days: number) => { - const to = format(today, 'yyyy-MM-dd') - const from = format(subDays(today, days), 'yyyy-MM-dd') + const to = format(today, "yyyy-MM-dd"); + const from = format(subDays(today, days), "yyyy-MM-dd"); - const newParams = new URLSearchParams(searchParams.toString()) - newParams.set('from', from) - newParams.set('to', to) + const newParams = new URLSearchParams(searchParams.toString()); + newParams.set("from", from); + newParams.set("to", to); // 페이지네이션 사용 중인 화면에서 날짜가 바뀌면 첫 페이지로 리셋 - newParams.delete('page') + newParams.delete("page"); - router.push(`?${newParams.toString()}`) - } + router.push(`?${newParams.toString()}`); + }; return (