Skip to content

Commit cfa34df

Browse files
use more common parts, clean up
1 parent ab301a6 commit cfa34df

File tree

4 files changed

+62
-342
lines changed

4 files changed

+62
-342
lines changed

src/components/DatePicker/Common.tsx

+6-6
Original file line numberDiff line numberDiff line change
@@ -217,14 +217,14 @@ type Week = {
217217

218218
export type WeekRenderer = (week: Week) => ReactNode;
219219

220-
interface CalendarRendererProps extends ContainerProps {
221-
calendarOptions: UseCalendarOptions;
222-
renderWeek: WeekRenderer;
220+
interface CalendarRendererProps extends React.HTMLAttributes<typeof Container> {
221+
calendarOptions?: UseCalendarOptions;
222+
weekRenderer: WeekRenderer;
223223
}
224224

225225
export const CalendarRenderer = ({
226-
calendarOptions,
227-
renderWeek,
226+
calendarOptions = {},
227+
weekRenderer,
228228
...props
229229
}: CalendarRendererProps) => {
230230
const { body, headers, month, navigation, year } = useCalendar({
@@ -286,7 +286,7 @@ export const CalendarRenderer = ({
286286
</thead>
287287
<tbody>
288288
{body.value.map(({ key: weekKey, value: week }) => {
289-
return <tr key={weekKey}>{week.map(renderWeek)}</tr>;
289+
return <tr key={weekKey}>{week.map(weekRenderer)}</tr>;
290290
})}
291291
</tbody>
292292
</DateTable>

src/components/DatePicker/DatePicker.tsx

+33-192
Original file line numberDiff line numberDiff line change
@@ -1,106 +1,7 @@
11
import { useEffect, useState } from "react";
2-
import { isSameDate, useCalendar, UseCalendarOptions } from "@h6s/calendar";
3-
import { styled } from "styled-components";
2+
import { isSameDate, UseCalendarOptions } from "@h6s/calendar";
43
import Dropdown from "../Dropdown/Dropdown";
5-
import { Container } from "../Container/Container";
6-
import { IconButton } from "../IconButton/IconButton";
7-
import { DatePickerInput } from "./Common";
8-
9-
const locale = "en-US";
10-
const weekdayFormatter = new Intl.DateTimeFormat(locale, { weekday: "short" });
11-
const headerDateFormatter = new Intl.DateTimeFormat(locale, {
12-
month: "short",
13-
year: "numeric",
14-
});
15-
16-
const explicitWidth = "250px";
17-
18-
const DatePickerContainer = styled(Container)`
19-
background: ${({ theme }) =>
20-
theme.click.datePicker.dateOption.color.background.default};
21-
`;
22-
23-
const UnselectableTitle = styled.h2`
24-
${({ theme }) => `
25-
color: ${theme.click.datePicker.color.title.default};
26-
font: ${theme.click.datePicker.typography.title.default};
27-
`}
28-
29-
user-select: none;
30-
`;
31-
32-
const DateTable = styled.table`
33-
border-collapse: separate;
34-
border-spacing: 0;
35-
font: ${({ theme }) => theme.typography.styles.product.text.normal.md}
36-
table-layout: fixed;
37-
user-select: none;
38-
width: ${explicitWidth};
39-
40-
thead tr {
41-
height: ${({ theme }) => theme.click.datePicker.dateOption.size.height};
42-
}
43-
44-
tbody {
45-
cursor: pointer;
46-
}
47-
48-
td, th {
49-
${({ theme }) =>
50-
`border: ${theme.click.datePicker.dateOption.stroke} solid ${theme.click.datePicker.dateOption.color.stroke.default}`};
51-
padding: 4px;
52-
}
53-
`;
54-
55-
const DateTableHeader = styled.th`
56-
${({ theme }) => `
57-
color: ${theme.click.datePicker.color.daytitle.default};
58-
font: ${theme.click.datePicker.typography.daytitle.default};
59-
`}
60-
61-
width: 14%;
62-
`;
63-
64-
const DateTableCell = styled.td<{
65-
$isCurrentMonth?: boolean;
66-
$isDisabled?: boolean;
67-
$isSelected?: boolean;
68-
$isToday?: boolean;
69-
}>`
70-
${({ theme }) => `
71-
border-radius: ${theme.click.datePicker.dateOption.radii.default};
72-
font: ${theme.click.datePicker.dateOption.typography.label.default};
73-
`}
74-
75-
${({ $isCurrentMonth, $isDisabled, theme }) =>
76-
(!$isCurrentMonth || $isDisabled) &&
77-
`
78-
color: ${theme.click.datePicker.dateOption.color.label.disabled};
79-
font: ${theme.click.datePicker.dateOption.typography.label.disabled};
80-
`}
81-
82-
${({ $isSelected, theme }) =>
83-
$isSelected &&
84-
`
85-
background: ${theme.click.datePicker.dateOption.color.background.active};
86-
color: ${theme.click.datePicker.dateOption.color.label.active};
87-
`}
88-
89-
90-
text-align: center;
91-
92-
${({ $isToday, theme }) =>
93-
$isToday && `font: ${theme.click.datePicker.dateOption.typography.label.active};`}
94-
95-
&:hover {
96-
${({ $isDisabled, theme }) =>
97-
`border: ${theme.click.datePicker.dateOption.stroke} solid ${
98-
$isDisabled
99-
? theme.click.datePicker.dateOption.color.stroke.disabled
100-
: theme.click.datePicker.dateOption.color.stroke.hover
101-
}`};
102-
}
103-
`;
4+
import { CalendarRenderer, DatePickerInput, DateTableCell, WeekRenderer } from "./Common";
1045

1056
interface CalendarProps {
1067
closeDatepicker: () => void;
@@ -115,104 +16,44 @@ const Calendar = ({
11516
selectedDate,
11617
setSelectedDate,
11718
}: CalendarProps) => {
118-
const calendarOptions: UseCalendarOptions = {
119-
defaultWeekStart: 1,
120-
};
19+
const calendarOptions: UseCalendarOptions = {};
12120

12221
if (selectedDate) {
12322
calendarOptions.defaultDate = selectedDate;
12423
}
125-
const { body, headers, month, navigation, year } = useCalendar(calendarOptions);
126-
127-
const handleNextClick = (): void => {
128-
navigation.toNext();
129-
};
13024

131-
const handlePreviousClick = (): void => {
132-
navigation.toPrev();
133-
};
134-
135-
const headerDate = new Date();
136-
headerDate.setMonth(month);
137-
headerDate.setFullYear(year);
138-
139-
return (
140-
<DatePickerContainer
141-
data-testid="datepicker-calendar-container"
142-
isResponsive={false}
143-
fillWidth={false}
144-
orientation="vertical"
145-
padding="sm"
146-
>
147-
<Container
148-
isResponsive={false}
149-
justifyContent="space-between"
150-
orientation="horizontal"
25+
const weekRenderer: WeekRenderer = ({
26+
date,
27+
isCurrentMonth,
28+
key: dayKey,
29+
value: fullDate,
30+
}) => {
31+
const isSelected = selectedDate ? isSameDate(selectedDate, fullDate) : false;
32+
const today = new Date();
33+
const isCurrentDate = isSameDate(today, fullDate);
34+
const isDisabled = futureDatesDisabled ? fullDate > today : false;
35+
36+
return (
37+
<DateTableCell
38+
$isCurrentMonth={isCurrentMonth}
39+
$isDisabled={isDisabled}
40+
$isSelected={isSelected}
41+
$isToday={isCurrentDate}
42+
key={dayKey}
43+
onClick={() => {
44+
if (isDisabled) {
45+
return false;
46+
}
47+
setSelectedDate(fullDate);
48+
closeDatepicker();
49+
}}
15150
>
152-
<IconButton
153-
icon="chevron-left"
154-
onClick={handlePreviousClick}
155-
size="sm"
156-
type="ghost"
157-
/>
158-
<UnselectableTitle>{headerDateFormatter.format(headerDate)}</UnselectableTitle>
159-
<IconButton
160-
icon="chevron-right"
161-
onClick={handleNextClick}
162-
size="sm"
163-
type="ghost"
164-
/>
165-
</Container>
166-
<DateTable>
167-
<thead>
168-
<tr>
169-
{headers.weekDays.map(({ key, value: date }) => {
170-
return (
171-
<DateTableHeader key={key}>
172-
{weekdayFormatter.format(date)}
173-
</DateTableHeader>
174-
);
175-
})}
176-
</tr>
177-
</thead>
178-
<tbody>
179-
{body.value.map(({ key: weekKey, value: week }) => {
180-
return (
181-
<tr key={weekKey}>
182-
{week.map(({ date, isCurrentMonth, key: dayKey, value: fullDate }) => {
183-
const isSelected = selectedDate
184-
? isSameDate(selectedDate, fullDate)
185-
: false;
186-
const today = new Date();
187-
const isCurrentDate = isSameDate(today, fullDate);
188-
const isDisabled = futureDatesDisabled ? fullDate > today : false;
51+
{date}
52+
</DateTableCell>
53+
);
54+
};
18955

190-
return (
191-
<DateTableCell
192-
$isCurrentMonth={isCurrentMonth}
193-
$isDisabled={isDisabled}
194-
$isSelected={isSelected}
195-
$isToday={isCurrentDate}
196-
key={dayKey}
197-
onClick={() => {
198-
if (isDisabled) {
199-
return false;
200-
}
201-
setSelectedDate(fullDate);
202-
closeDatepicker();
203-
}}
204-
>
205-
{date}
206-
</DateTableCell>
207-
);
208-
})}
209-
</tr>
210-
);
211-
})}
212-
</tbody>
213-
</DateTable>
214-
</DatePickerContainer>
215-
);
56+
return <CalendarRenderer weekRenderer={weekRenderer} />;
21657
};
21758

21859
export interface DatePickerProps {

src/components/DatePicker/DateRangePicker.stories.tsx

+4-4
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ import { DateRangePicker } from "./DateRangePicker";
33

44
const defaultStory = {
55
args: {
6-
onSelectDate: (date: Date) => {
7-
console.log("Date selected: ", date);
6+
onSelectDateRange: (startDate: Date, endDate: Date) => {
7+
console.log("Date range selected: ", startDate, endDate);
88
},
99
},
1010
argTypes: {
@@ -20,7 +20,7 @@ const defaultStory = {
2020
placeholder: {
2121
control: "text",
2222
},
23-
onSelectDate: {
23+
onSelectDateRange: {
2424
control: "object",
2525
},
2626
},
@@ -33,7 +33,7 @@ const defaultStory = {
3333
endDate={endDate}
3434
disabled={args.disabled}
3535
futureDatesDisabled={args.futureDatesDisabled}
36-
onSelectDate={args.onSelectDate}
36+
onSelectDateRange={args.onSelectDateRange}
3737
placeholder={args.placeholder}
3838
startDate={startDate}
3939
/>

0 commit comments

Comments
 (0)