Skip to content

Commit 6e9535d

Browse files
committed
[ #23, #78, #106] Customized shortcut 🎉
1 parent b4c780f commit 6e9535d

File tree

4 files changed

+60
-34
lines changed

4 files changed

+60
-34
lines changed

src/components/Datepicker.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ const Datepicker: React.FC<DatepickerType> = ({
2020
useRange = true,
2121
showFooter = false,
2222
showShortcuts = false,
23-
configs = null,
23+
configs = undefined,
2424
asSingle = false,
2525
placeholder = null,
2626
separator = "~",

src/components/Shortcuts.tsx

Lines changed: 54 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import dayjs from "dayjs";
22
import React, { useCallback, useContext, useMemo } from "react";
33

4-
import { TEXT_COLOR } from "../constants";
4+
import { DATE_FORMAT, TEXT_COLOR } from "../constants";
55
import DEFAULT_SHORTCUTS from "../constants/shortcuts";
66
import DatepickerContext from "../contexts/DatepickerContext";
77
import { Period, ShortcutsItem } from "../types";
@@ -66,8 +66,6 @@ const ItemTemplate = React.memo((props: ItemTemplateProps) => {
6666
]
6767
);
6868

69-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
70-
// @ts-ignore
7169
const children = props?.children;
7270

7371
return (
@@ -92,24 +90,56 @@ const Shortcuts: React.FC = () => {
9290
return typeof data === "function" ? data(numberValue) : null;
9391
}, []);
9492

95-
const shortcutOptions = useMemo(
96-
() =>
97-
configs
98-
? Object.entries(DEFAULT_SHORTCUTS).filter(([key]) => {
99-
return configs.shortcuts && Object.keys(configs.shortcuts).includes(key);
100-
})
101-
: Object.entries(DEFAULT_SHORTCUTS),
102-
[configs]
103-
);
93+
const shortcutOptions = useMemo<[string, ShortcutsItem | ShortcutsItem[]][]>(() => {
94+
let options;
95+
if (configs?.shortcuts && configs?.shortcuts) {
96+
const formatConfig = Object.keys(configs.shortcuts).map(item => {
97+
if (Object.keys(DEFAULT_SHORTCUTS).includes(item)) {
98+
return [item, DEFAULT_SHORTCUTS[item]];
99+
} else {
100+
if (configs.shortcuts && configs?.shortcuts[item]) {
101+
const customConfig = configs?.shortcuts[item];
102+
const text = customConfig?.text;
103+
const start = dayjs(customConfig?.period?.start);
104+
const end = dayjs(customConfig?.period?.end);
105+
if (
106+
text &&
107+
start.isValid() &&
108+
end.isValid() &&
109+
(start.isBefore(end) || start.isSame(end))
110+
) {
111+
return [
112+
item,
113+
{
114+
text,
115+
period: {
116+
start: start.format(DATE_FORMAT),
117+
end: end.format(DATE_FORMAT)
118+
}
119+
}
120+
];
121+
} else {
122+
return undefined;
123+
}
124+
}
125+
return undefined;
126+
}
127+
});
128+
options = formatConfig?.filter(item => !!item);
129+
} else {
130+
options = Object.entries(DEFAULT_SHORTCUTS);
131+
}
132+
return options as [string, ShortcutsItem | ShortcutsItem[]][];
133+
}, [configs]);
104134

105135
const printItemText = useCallback((item: ShortcutsItem) => {
106136
return item?.text ?? null;
107137
}, []);
108138

109-
return (
139+
return shortcutOptions?.length ? (
110140
<div className="md:border-b mb-3 lg:mb-0 lg:border-r lg:border-b-0 border-gray-300 dark:border-gray-700 pr-1">
111141
<ul className="w-full tracking-wide flex flex-wrap lg:flex-col pb-1 lg:pb-0">
112-
{shortcutOptions.map(([key, item], index) =>
142+
{shortcutOptions?.map(([key, item], index: number) =>
113143
Array.isArray(item) ? (
114144
item.map((item, index) => (
115145
<ItemTemplate key={index} item={item}>
@@ -118,7 +148,10 @@ const Shortcuts: React.FC = () => {
118148
configs?.shortcuts &&
119149
key in configs.shortcuts &&
120150
item.daysNumber
121-
? callPastFunction(configs.shortcuts[key], item.daysNumber)
151+
? callPastFunction(
152+
configs.shortcuts[key as "past"],
153+
item.daysNumber
154+
)
122155
: item.text}
123156
</>
124157
</ItemTemplate>
@@ -127,15 +160,19 @@ const Shortcuts: React.FC = () => {
127160
<ItemTemplate key={index} item={item}>
128161
<>
129162
{configs?.shortcuts && key in configs.shortcuts
130-
? configs.shortcuts[key as keyof typeof configs.shortcuts]
163+
? typeof configs.shortcuts[
164+
key as keyof typeof configs.shortcuts
165+
] === "object"
166+
? printItemText(item)
167+
: configs.shortcuts[key as keyof typeof configs.shortcuts]
131168
: printItemText(item)}
132169
</>
133170
</ItemTemplate>
134171
)
135172
)}
136173
</ul>
137174
</div>
138-
);
175+
) : null;
139176
};
140177

141178
export default Shortcuts;

src/contexts/DatepickerContext.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ interface DatepickerStore {
1515
input?: React.RefObject<HTMLInputElement>;
1616
asSingle?: boolean;
1717
primaryColor: string;
18-
configs?: Configs | null;
18+
configs?: Configs;
1919
calendarContainer: React.RefObject<HTMLDivElement> | null;
2020
arrowContainer: React.RefObject<HTMLDivElement> | null;
2121
hideDatepicker: () => void;
@@ -51,6 +51,7 @@ interface DatepickerStore {
5151
const DatepickerContext = createContext<DatepickerStore>({
5252
input: undefined,
5353
primaryColor: "blue",
54+
configs: undefined,
5455
calendarContainer: null,
5556
arrowContainer: null,
5657
// eslint-disable-next-line @typescript-eslint/no-empty-function

src/types/index.ts

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,11 @@ export interface Configs {
1212
past?: (period: number) => string;
1313
currentMonth?: string;
1414
pastMonth?: string;
15-
} | null;
15+
} & { [key: string]: ShortcutsItem };
1616
footer?: {
1717
cancel?: string;
1818
apply?: string;
19-
} | null;
19+
};
2020
}
2121

2222
export interface ShortcutsItem {
@@ -51,19 +51,7 @@ export interface DatepickerType {
5151
useRange?: boolean;
5252
showFooter?: boolean;
5353
showShortcuts?: boolean;
54-
configs?: {
55-
shortcuts?: {
56-
today?: string;
57-
yesterday?: string;
58-
past?: (period: number) => string;
59-
currentMonth?: string;
60-
pastMonth?: string;
61-
} | null;
62-
footer?: {
63-
cancel?: string;
64-
apply?: string;
65-
} | null;
66-
} | null;
54+
configs?: Configs;
6755
asSingle?: boolean;
6856
placeholder?: string;
6957
separator?: string;

0 commit comments

Comments
 (0)