Skip to content

Commit f6d34e0

Browse files
authored
website: fix playground month props sync and display (#2854)
* Fix playground month props sync * Fix typing Signed-off-by: gpbl <io@gpbl.dev> * Lint file Signed-off-by: gpbl <io@gpbl.dev> --------- Signed-off-by: gpbl <io@gpbl.dev>
1 parent 9ee9bbf commit f6d34e0

File tree

3 files changed

+96
-69
lines changed

3 files changed

+96
-69
lines changed

website/src/components/Playground/index.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,6 @@ export function Playground() {
5151
// @ts-expect-error calendar is not a prop of DayPicker
5252
calendar: undefined,
5353
locale: undefined,
54-
month: undefined,
5554
dir:
5655
(props.calendar === "persian" || props.calendar === "hebrew") &&
5756
props.dir === "rtl"

website/src/components/Playground/toJSX.ts

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,23 +5,27 @@ import type { DayPickerProps } from "react-day-picker";
55
* props as example
66
*/
77
export function toJSX(props: Partial<DayPickerProps>) {
8+
const formatDate = (value: Date) =>
9+
`={new Date(${value.getFullYear()}, ${value.getMonth()}, ${value.getDate()})}`;
10+
11+
const formatValue = (value: unknown) => {
12+
if (value === undefined || value === false) return null;
13+
if (value instanceof Date) return formatDate(value);
14+
if (typeof value === "string") return `="${value}"`;
15+
if (typeof value === "number") return `={${value}}`;
16+
if (value === true) return "";
17+
return `={${JSON.stringify(value)}}`;
18+
};
19+
820
return (
921
Object.keys(props)
1022
// @ts-expect-error abc
1123
.filter((key) => props[key] !== undefined && props[key] !== false)
1224
.sort((a, b) => a.localeCompare(b))
1325
.map((key) => {
1426
// @ts-expect-error abc
15-
const value = props[key] as string | number | boolean;
16-
const valueAsString =
17-
typeof value === "string"
18-
? `="${value}"`
19-
: typeof value === "number"
20-
? `={${value}}`
21-
: value
22-
? ""
23-
: `x={${JSON.stringify(value)}}`;
24-
return ` ${key}${valueAsString}`;
27+
const formattedValue = formatValue(props[key]);
28+
return formattedValue === null ? "" : ` ${key}${formattedValue}`;
2529
})
2630
.join("")
2731
);

website/src/components/Playground/useQueryStringSync.ts

Lines changed: 82 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ const qsProps = [
3333
"selected",
3434
"showOutsideDays",
3535
"showWeekNumber",
36+
"startMonth",
37+
"endMonth",
38+
"month",
3639
"timeZone",
3740
"toMonth",
3841
"weeksStartOn",
@@ -50,70 +53,89 @@ export function useQueryStringSync(basePath: string = "/playground") {
5053
const parseQueryString = (search: string): DayPickerPropsWithCalendar => {
5154
const params = new URLSearchParams(search);
5255
const parsedProps: DayPickerPropsWithCalendar = {};
53-
const typeMap: Record<string, "boolean" | "number" | "string" | "locale"> =
54-
{
55-
animate: "boolean",
56-
broadcastCalendar: "boolean",
57-
calendar: "string",
58-
captionLayout: "string",
59-
defaultMonth: "string",
60-
dir: "string",
61-
disabled: "string",
62-
disableNavigation: "boolean",
63-
firstDayOfWeek: "number",
64-
firstWeekContainsDate: "number",
65-
fixedWeeks: "boolean",
66-
fromMonth: "string",
67-
hideNavigation: "boolean",
68-
hideWeekdays: "boolean",
69-
ISOWeek: "boolean",
70-
locale: "locale",
71-
max: "number",
72-
min: "number",
73-
mode: "string",
74-
navLayout: "string",
75-
numberOfMonths: "number",
76-
numerals: "string",
77-
pagedNavigation: "boolean",
78-
required: "boolean",
79-
reverseMonths: "boolean",
80-
reverseYears: "boolean",
81-
selected: "string",
82-
showOutsideDays: "boolean",
83-
showWeekNumber: "boolean",
84-
timeZone: "string",
85-
toMonth: "string",
86-
weeksStartOn: "number",
87-
weekStartsOn: "number",
88-
};
56+
const typeMap: Record<
57+
string,
58+
"boolean" | "number" | "string" | "locale" | "date"
59+
> = {
60+
animate: "boolean",
61+
broadcastCalendar: "boolean",
62+
calendar: "string",
63+
captionLayout: "string",
64+
defaultMonth: "date",
65+
dir: "string",
66+
disabled: "string",
67+
disableNavigation: "boolean",
68+
endMonth: "date",
69+
firstDayOfWeek: "number",
70+
firstWeekContainsDate: "number",
71+
fixedWeeks: "boolean",
72+
fromMonth: "date",
73+
hideNavigation: "boolean",
74+
hideWeekdays: "boolean",
75+
ISOWeek: "boolean",
76+
locale: "locale",
77+
max: "number",
78+
min: "number",
79+
mode: "string",
80+
month: "date",
81+
navLayout: "string",
82+
numberOfMonths: "number",
83+
numerals: "string",
84+
pagedNavigation: "boolean",
85+
required: "boolean",
86+
reverseMonths: "boolean",
87+
reverseYears: "boolean",
88+
selected: "string",
89+
showOutsideDays: "boolean",
90+
showWeekNumber: "boolean",
91+
startMonth: "date",
92+
timeZone: "string",
93+
toMonth: "date",
94+
weeksStartOn: "number",
95+
weekStartsOn: "number",
96+
};
8997

9098
qsProps.forEach((key) => {
91-
if (params.has(key)) {
92-
const value = params.get(key) || true;
93-
try {
94-
switch (typeMap[key]) {
95-
case "boolean":
96-
parsedProps[key as keyof DayPickerPropsWithCalendar] = !!key;
97-
break;
98-
case "number":
99+
if (!params.has(key)) {
100+
return;
101+
}
102+
const value = params.get(key);
103+
try {
104+
switch (typeMap[key]) {
105+
case "boolean":
106+
parsedProps[key as keyof DayPickerPropsWithCalendar] = true;
107+
break;
108+
case "number":
109+
if (value !== null) {
99110
parsedProps[key as keyof DayPickerPropsWithCalendar] =
100111
Number(value);
101-
break;
102-
case "string":
103-
parsedProps[key as keyof DayPickerPropsWithCalendar] =
104-
value || "";
105-
break;
106-
case "locale":
107-
parsedProps.locale = Object.values(locales).find(
108-
(locale) => locale.code === value,
109-
);
110-
break;
111-
default:
112-
break;
112+
}
113+
break;
114+
case "string":
115+
parsedProps[key as keyof DayPickerPropsWithCalendar] = value ?? "";
116+
break;
117+
case "locale":
118+
if (!value) break;
119+
parsedProps.locale = Object.values(locales).find(
120+
(locale) => locale.code === value,
121+
);
122+
break;
123+
case "date": {
124+
if (!value) break;
125+
const timestamp = Number(value);
126+
const parsedDate = new Date(
127+
Number.isNaN(timestamp) ? value : timestamp,
128+
);
129+
if (!Number.isNaN(parsedDate.getTime())) {
130+
parsedProps[key as keyof DayPickerPropsWithCalendar] = parsedDate;
131+
}
132+
break;
113133
}
114-
} catch (error) {
115-
console.error(`Error parsing query string key "${key}":`, error);
134+
default:
135+
break;
116136
}
137+
} catch (error) {
138+
console.error(`Error parsing query string key "${key}":`, error);
117139
}
118140
});
119141
return parsedProps;
@@ -132,6 +154,8 @@ export function useQueryStringSync(basePath: string = "/playground") {
132154
if (key === "locale") {
133155
if (!value) return;
134156
qs.push(`locale=${value.code}`);
157+
} else if (value instanceof Date) {
158+
qs.push(`${key}=${value.getTime()}`);
135159
} else {
136160
qs.push(`${key}${value === true ? "" : `=${value}`}`);
137161
}

0 commit comments

Comments
 (0)